Skip to content

Instantly share code, notes, and snippets.

@jevinskie
Created August 20, 2024 07:38
Show Gist options
  • Save jevinskie/240d9343a5230468664dbe74a5a9d170 to your computer and use it in GitHub Desktop.
Save jevinskie/240d9343a5230468664dbe74a5a9d170 to your computer and use it in GitHub Desktop.
SafariShared.framework embedded JavaScript and HTML - iOS 18.0 beta 6 22A5338b
// # sourceURL=__InjectedScript_AutomaticPasswords.js
/* Copyright (c) 2024 Apple Inc. All rights reserved. */
FormMetadata.prototype._collectExtraControlMetadata = function(t, o) {
let e = t.getAttribute("passwordrules");
o.ControlPasswordRules = e || void 0
}, FormMetadata.prototype.removeAutomaticStrongPasswordFromPasswordElement = function(t) {
let o = this.formControlWithUniqueID(t);
o && this._isTextField(o) && (this.clearField(t), this._updateAnnotationsForField(o), FormMetadataJSController.setInputElementAutofilled(o, !1))
};
let AutomaticPasswords = function() {};
AutomaticPasswords.prototype = {
removeAutomaticPasswordElements : function(t, o, e) {
for (let o of t)
FormMetadataJS.removeAutomaticStrongPasswordFromPasswordElement(o);
if (!e)
return;
let r = document.activeElement,
a = o ? FormMetadataJS.formControlWithUniqueID(o) : null;
a && a.blur(), a && a === r && a.focus()
},
blurControlWithID : function(t) {
let o = t ? FormMetadataJS.formControlWithUniqueID(t) : null;
o && o.blur()
},
setStrongPasswordElementViewableIfAppropriate : function(t, o) {
for (let e of t) {
let t = FormMetadataJS.formControlWithUniqueID(e);
if (!t)
return;
if ("text" === t.type)
return FormMetadataJSController.setInputElementAutoFilledAndViewable(t, !1), void FormMetadataJSController.setInputElementAutofilled(t, !1);
FormMetadataJSController.setInputElementAutoFilledAndViewable(t, o)
}
}
};
var AutomaticPasswordsJS = new AutomaticPasswords;
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, viewport-fit=cover">
<title class="l12n">This Connection Is Not Private</title>
<style>
body {
--font-color: #434343;
--compact-font-color: #434343;
--blue-color: rgb(0, 122, 255);
--horizontal-padding: 32px;
--compact-horizontal-padding: 20px;
--border-radius: 6px;
--ios-border-radius: 10px;
--title-color: #444;
--icon-element-color: #dc143c;
}
* {
padding: 0;
margin: 0;
}
body:not(.ios) * {
font-family: -apple-system-font;
}
html, body {
height: 100%;
width: 100%;
}
body {
font-size: 13px;
background: linear-gradient(30deg, #dfdfdf 0%, #fafafb 100%);
background-repeat: no-repeat;
background-attachment: fixed;
cursor: default;
-webkit-user-select: none;
}
#title {
overflow: hidden;
color: var(--title-color);
padding-top: 3px;
}
.alert {
background-color: white;
min-width: 320px;
max-width: 672px;
position: relative;
margin: 0 auto;
padding-top: 28px;
border-radius: var(--border-radius);
box-shadow: 0px 6px 10px rgba(0, 0, 0, 0.14);
}
.alert-body {
margin: 21px 0 0 0;
padding-left: var(--horizontal-padding);
padding-right: var(--horizontal-padding);
padding-bottom: 24px;
color: var(--font-color);
}
.alert-body p:first-of-type {
margin-bottom: 15px;
margin-top: 20px;
}
.alert-body p:last-of-type {
margin-bottom: 0;
}
.bottom-bar {
margin-top: 1.3em;
height: 22px;
}
.bottom-bar button {
float: right;
font-size: 13px;
line-height: 21px;
min-width: 90px;
margin: 0 4px;
vertical-align: bottom;
padding: 0 12px;
}
.bottom-bar .details {
float: left;
}
.bottom-bar .details a {
cursor: pointer;
font-size: 14px;
margin-top: 2px;
}
#details {
display: none;
padding: 22px var(--horizontal-padding) 10px var(--horizontal-padding);
border-top: 1px solid rgb(217, 217, 217);
color: var(--font-color);
background-color: rgb(243, 243, 243);
border-bottom-left-radius: var(--border-radius);
border-bottom-right-radius: var(--border-radius);
}
.bottom-bar.goBack .closePage, .bottom-bar.closePage .goBack, #ignoreWarning {
display: block;
}
#openDateAndTimeButton {
display: none;
}
a {
color: inherit;
text-decoration: underline;
cursor: pointer;
}
#lock, #clock {
float: left;
width: 30px;
top: 4px;
margin-right: 15px;
position: relative;
}
#clock {
display: none;
}
.lock-element {
fill: var(--icon-element-color);
}
.clock-element {
fill: var(--icon-element-color);
}
body.clockWarning #clock {
display: block;
}
body.clockWarning #lock {
display: none;
}
body.clockWarning #goBackButton {
display: none;
}
body.clockWarning #openDateAndTimeButton {
display: block;
}
h1 {
font-size: 2em;
font-weight: 700;
line-height: 30px;
padding: 0 var(--horizontal-padding);
margin-bottom: -6px;
}
p {
font-size: 14px;
line-height: 19px;
margin-bottom: 1em;
word-wrap: break-word;
}
body.ios .alert {
box-shadow: none;
border-radius: var(--ios-border-radius);
max-width: 640px;
}
body.ios .alert-body {
font: -apple-system-body;
}
body.ios #details {
font: -apple-system-body;
border-bottom-left-radius: var(--ios-border-radius);
border-bottom-right-radius: var(--ios-border-radius);
}
body.ios h1 {
font-size: 26px;
font-family: -webkit-system-font;
}
body.ios p {
font-size: 1.1em;
line-height: unset;
}
body.ios button {
background: none;
border: none;
color: var(--blue-color);
font: -apple-system-short-body;
}
body.ios #detailsButton {
color: var(--font-color);
}
@media screen and (max-width: 666px) {
/* iPhone 6 in landscape (667px) and smaller, including all iPhones in portrait */
body {
color: var(--compact-font-color);
}
.alert {
box-shadow: none;
background-color: var(--red-color);
}
.alert-body {
color: var(--compact-font-color);
padding-left: var(--compact-horizontal-padding);
padding-right: var(--compact-horizontal-padding);
padding-bottom: 30px;
}
h1 {
color: var(--compact-font-color);
padding: 0 var(--compact-horizontal-padding);
}
body.ios button,
body.ios #detailsButton {
text-decoration: underline;
}
#details {
background-color: var(--red-color);
padding: 22px var(--compact-horizontal-padding) 22px var(--compact-horizontal-padding);
border-top-width: 1px;
border-top-color: rgba(0, 0, 0, .15);
}
}
/* RTL support */
html[dir="rtl"] .bottom-bar button {
float: left;
}
html[dir="rtl"] :matches(#lock, #clock) {
float: right;
margin-left: 15px;
margin-right: 0;
}
</style>
<link rel=stylesheet type="text/css" href="safari-resource:/CertificateWarningExtras.css">
<script type="text/javascript" src="safari-resource:/Utilities.js" charset="utf-8"></script>
<script type="text/javascript" src="safari-resource:/WBSHTMLViewController.js" charset="utf-8"></script>
<script type="text/javascript">
// Should be kept in sync with WBSCertificateWarningCategory in WBSCertificateWarningPageContext.h.
var CertificateWarningCategory = {
Expired: 0,
InvalidCanBypass: 1,
InvalidCannotBypass: 2,
HostnameMismatch: 3,
IncorrectClock: 4,
LegacyTLS: 5,
};
var CertificateWarning = {
_host: undefined,
_canGoBack: undefined,
_warningCategory: undefined,
_numberOfDaysInvalid: undefined,
_expiredCertificateDetails: undefined,
_clockSkew: undefined,
get host()
{
return this._host;
},
set host(value)
{
if (this._host === value)
return;
this._host = value;
},
get canGoBack()
{
return this._canGoBack;
},
set canGoBack(value)
{
if (this._canGoBack === value)
return;
this._canGoBack = value;
},
get warningCategory()
{
return this._warningCategory;
},
set warningCategory(value)
{
if (this._warningCategory === value)
return;
this._warningCategory = value;
},
get numberOfDaysInvalid()
{
return this._numberOfDaysInvalid;
},
set numberOfDaysInvalid(value)
{
if (this._numberOfDaysInvalid === value)
return;
this._numberOfDaysInvalid = value;
},
get expiredCertificateDetails()
{
return this._expiredCertificateDetails;
},
set expiredCertificateDetails(value)
{
if (this._expiredCertificateDetails === value)
return;
this._expiredCertificateDetails = value;
},
get clockSkew()
{
return this._clockSkew;
},
set clockSkew(value)
{
if (this._clockSkew === value)
return;
this._clockSkew = value;
},
pageLoaded: function()
{
if (/Macintosh/g.test(navigator.userAgent))
document.body.classList.add("mac");
else
document.body.classList.add("ios");
HTMLViewController.pageLoaded();
CertificateWarningController.pageLoaded();
window.addEventListener("resize", layOut, false);
layOut();
},
currentSystemTime: function()
{
var dateFormatter = Intl.DateTimeFormat(undefined, { weekday: "long", day: "numeric", month: "long", year: "numeric" });
return dateFormatter.format(new Date());
},
showIncorrectClockWarning: function()
{
console.assert(this.warningCategory === CertificateWarningCategory.IncorrectClock);
console.assert(this.clockSkew !== 0);
document.body.classList.add("clockWarning");
var title = HTMLViewController.UIString("Your Clock Is Set Incorrectly");
document.title = title;
document.getElementById("title").textContent = title;
var incorrectClockHTMLTemplate = HTMLViewController.UIString("Safari can’t connect to “%hostname%” because your system clock is incorrectly set to %@. Set your system clock to the correct time and try again.").format(this.currentSystemTime());
var incorrectClockHTML = incorrectClockHTMLTemplate.replace("%hostname%", this.host);
var warningText = document.getElementById("warningText");
warningText.innerHTML = incorrectClockHTML;
var detailsTextHTMLTemplate = HTMLViewController.UIString("Because your system clock is set incorrectly, Safari can’t verify that your connection is private. If you understand the risks involved, you can %visit-this-site-link%.");
var detailsTextHTML = "<a role='button' onClick='CertificateWarningController.visitInsecureWebsiteWithTemporaryBypass();'>%@</a>".format(HTMLViewController.UIString("visit this website"));
var detailsText = detailsTextHTMLTemplate.replace("%visit-this-site-link%", detailsTextHTML);
document.getElementById("detailsText").innerHTML = detailsText;
setDetailsVisibility(false);
},
updateDetailsStrings: function()
{
if (this.warningCategory === CertificateWarningCategory.IncorrectClock) {
this.showIncorrectClockWarning();
return;
}
var warningText = document.getElementById("warningText");
var warningTextHTMLTemplate;
if (this.warningCategory === CertificateWarningCategory.LegacyTLS) {
if (this.canGoBack)
warningTextHTMLTemplate = HTMLViewController.UIString("This website has an outdated security configuration, which may allow an attacker to steal personal or financial information entered into “%hostname%”. You should go back to the previous page.");
else
warningTextHTMLTemplate = HTMLViewController.UIString("This website has an outdated security configuration, which may allow an attacker to steal personal or financial information entered into “%hostname%”. You should close this page.");
} else {
if (this.canGoBack)
warningTextHTMLTemplate = HTMLViewController.UIString("This website may be impersonating “%hostname%” to steal your personal or financial information. You should go back to the previous page.");
else
warningTextHTMLTemplate = HTMLViewController.UIString("This website may be impersonating “%hostname%” to steal your personal or financial information. You should close this page.");
}
var warningTextHTML = warningTextHTMLTemplate.replace("%hostname%", this.host);
warningText.innerHTML = warningTextHTML;
var bypassCertificateWarningHTMLTemplate = HTMLViewController.UIString("If you understand the risks involved, you can %visit-this-site-link%.");
var visitUnsafeWebsiteLinkHTML = "<a role='button' onClick='CertificateWarningController.visitInsecureWebsite();'>%@</a>".format(HTMLViewController.UIString("visit this website"));
var bypassCertificateWarningHTML = bypassCertificateWarningHTMLTemplate.replace("%visit-this-site-link%", visitUnsafeWebsiteLinkHTML);
var viewCertificateHTMLTemplate = HTMLViewController.UIString("To learn more, you can %view-the-certificate%.");
var viewCertificateLinkHTML = "<a role='button' onClick='CertificateWarningController.showCertificateInformation();'>%@</a>".format(HTMLViewController.UIString("view the certificate"));
var viewCertificateHTML = viewCertificateHTMLTemplate.replace("%view-the-certificate%", viewCertificateLinkHTML);
var detailsText = document.getElementById("detailsText");
switch (this.warningCategory) {
case CertificateWarningCategory.Expired:
var firstParagraphHTMLTemplate = HTMLViewController.UIString("Safari warns you when a website has %certificate-description%. %expiration-date-details%. This may happen if the website is misconfigured, an attacker has compromised your connection, or your system clock is incorrect. Your system clock is set to %@. If this is not right, %fixing-the-clock% may address this warning.");
var firstParagraphWithDateHTMLTemplate = firstParagraphHTMLTemplate.format(this.currentSystemTime());
var openClockSettingsLinkHTML = "<a role='button' onClick='CertificateWarningController.openClockSettings();'>%@</a>".format(HTMLViewController.UIString("fixing the clock"));
var firstParagraphWithClockHTMLTemplate = firstParagraphWithDateHTMLTemplate.replace("%fixing-the-clock%", openClockSettingsLinkHTML);
var firstParagraphWithExpirationDateDetails = firstParagraphWithClockHTMLTemplate.replace("%expiration-date-details%", this.expiredCertificateDetails);
var certificateDescription;
if (this.numberOfDaysInvalid > 0)
certificateDescription = HTMLViewController.UIString("an expired certificate");
else
certificateDescription = HTMLViewController.UIString("a certificate that is not valid");
var firstParagraph = firstParagraphWithExpirationDateDetails.replace("%certificate-description%", certificateDescription);
// Localizers: The space in between viewCertificateHTML and bypassCertificateWarningHTML should be translated to the appropriate space between two sentences.
detailsText.innerHTML = "<p>" + firstParagraph + "</p><p>" + viewCertificateHTML + " " + bypassCertificateWarningHTML + "</p>";
break;
case CertificateWarningCategory.HostnameMismatch:
case CertificateWarningCategory.InvalidCanBypass:
// FIXME 30320099: Hostname mismatch should be its own unique case.
var firstParagraph = HTMLViewController.UIString("Safari warns you when a website has a certificate that is not valid. This may happen if the website is misconfigured or an attacker has compromised your connection.");
// Localizers: The space in between viewCertificateHTML and bypassCertificateWarningHTML should be translated to the appropriate space between two sentences.
detailsText.innerHTML = "<p>" + firstParagraph + "</p><p>" + viewCertificateHTML + " " + bypassCertificateWarningHTML + "</p>";
break;
case CertificateWarningCategory.InvalidCannotBypass:
var firstParagraph = HTMLViewController.UIString("Safari warns you when a website has a certificate that is not valid. This may happen if an attacker has compromised your connection. For your protection, you can’t visit this website. You can check back later to see if this issue has been resolved. You can also contact the website owner to tell them about this error.");
// Localizers: The space in between firstParagraph and viewCertificateHTML should be translated to the appropriate space between two sentences.
detailsText.innerHTML = firstParagraph + " " + viewCertificateHTML;
break;
case CertificateWarningCategory.LegacyTLS:
var firstParagraph = HTMLViewController.UIString("Safari warns you when a website uses TLS 1.0 or TLS 1.1, which are not secure. This may allow an attacker to compromise your connection to steal your personal or financial information, including passwords, phone numbers, and credit cards.");
detailsText.innerHTML = "<p>" + firstParagraph + "</p><p>" + bypassCertificateWarningHTML + "</p>";
break;
default:
console.assert(false, "Invalid warning category given");
break;
}
setDetailsVisibility(false);
},
updateUI: function(host, warningCategory, canGoBack, numberOfDaysInvalid, expiredCertificateDetails, clockSkew)
{
this.warningCategory = warningCategory;
this.host = host;
this.canGoBack = canGoBack;
this.numberOfDaysInvalid = numberOfDaysInvalid;
this.expiredCertificateDetails = expiredCertificateDetails;
this.clockSkew = clockSkew;
if (!canGoBack)
document.getElementById("goBackButton").textContent = HTMLViewController.UIString("Close Page");
this.updateDetailsStrings();
},
setTextDirection: function(textDirection)
{
document.documentElement.setAttribute("dir", textDirection);
}
};
function setDetailsVisibility(show)
{
var detailsDiv = document.getElementById("details");
if (show) {
detailsDiv.style.display = "block";
document.getElementById("detailsButton").style.display = "none";
detailsDiv.scrollIntoViewIfNeeded();
} else {
detailsDiv.style.display = "none";
document.getElementById("detailsButton").style.display = "block";
}
layOut();
}
function layOut()
{
const minimumMarginTop = 22;
const maximumMarginTop = 156;
var alertBox = document.getElementById("alert");
var alertHeight = alertBox.getBoundingClientRect().height;
var viewportHeight = window.innerHeight;
if (viewportHeight > alertHeight + 2 * maximumMarginTop)
alertBox.style.top = maximumMarginTop + "px";
else
alertBox.style.top = Math.max(minimumMarginTop, (viewportHeight - alertHeight) / 2) + "px";
}
HTMLViewController.loadLocalizedStrings(CertificateWarningController);
window.addEventListener("load", function() { CertificateWarning.pageLoaded(); }, false);
</script>
</head>
<body>
<div id="alert" class="alert">
<h1>
<svg id="lock" x="0px" y="0px" viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
<polygon class="lock-element" points="9.9,19 9.9,20.2 38.8,47 40,47 "/>
<polygon class="lock-element" points="9.9,22.2 7.5,22.2 7.5,47 38.8,47 9.9,20.2 "/>
<path class="lock-element" d="M24.4,6.2c5.5,0,9.9,4.1,9.9,9.2v6.9h-3l10.4,9.5v-9.5h-2.5v-6.9c0-7.6-6.6-13.8-14.8-13.8c-4.4,0-8.3,1.8-11,4.6L17,9.4C18.8,7.4,21.4,6.2,24.4,6.2z"/>
<path class="lock-element" d="M49.3,47.9c1-0.9,1-2.4,0-3.3l-45-42c-1-0.9-2.6-0.9-3.6,0c-1,0.9-1,2.4,0,3.3l45,42C46.7,48.8,48.3,48.8,49.3,47.9z"/>
</svg>
<svg id="clock" x="0px" y="0px" viewBox="0 0 150 150" style="enable-background:new 0 0 150 150;" xml:space="preserve">
<path class="clock-element" d="M75,0C33.6,0,0,33.6,0,75c0,41.4,33.6,75,75,75s75-33.6,75-75C150,33.6,116.4,0,75,0z M81,68v7 c0,3.3-2.7,6-6,6H45c-3.3,0-6-2.7-6-6v-1c0-3.3,2.7-6,6-6h23V26c0-3.3,2.7-6,6-6h1c3.3,0,6,2.7,6,6V68z"/>
</svg>
<div id="title" class="l12n">This Connection Is Not Private</div>
</h1>
<div class="alert-body">
<div class="item">
<p id="warningText"></p>
</div>
<div class="bottom-bar goBack closePage" id="bottom-bar">
<button type="button" id="goBackButton" class="l12n goBack" onClick="CertificateWarningController.goBackSelected();">Go Back</button>
<button type="button" id="openDateAndTimeButton" class="l12n" onClick="CertificateWarningController.openClockSettings();">Open Date & Time…</button>
<button type="button" id="detailsButton" class="l12n" onClick="setDetailsVisibility(true);">Show Details</button>
</div>
</div>
<div id="details">
<p id="detailsText"></p>
</div>
</div>
</body>
</html>
/*
This file has a UTF-8 BOM in it so it can be included from a UTF-16 page
without specifying an explicit character set. When editing it, please be
sure to preserve the BOM (first three bytes of the file, EF BB BF).
*/
@media (prefers-dark-interface) {
body {
background: none;
background-color: rgb(30, 30, 30);
--font-color: rgb(181, 182, 184);
--compact-font-color: rgb(181, 182, 184);
--title-color: rgb(224, 225, 225);
}
.alert {
background-color: rgb(56, 57, 59);
box-shadow: 0 6px 12px rgba(0, 0, 0, .24);
}
#details {
background-color: rgb(46, 47, 49);
border-top-color: rgb(90, 92, 93);
}
}
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, viewport-fit=cover">
<title class="l12n">This Connection Is Not Private</title>
<style>
:root {
--bypass-feature-icon-color: #000000;
}
@media (prefers-color-scheme:dark) {
:root {
--bypass-feature-icon-color: #FFFFFF;
}
}
body {
--font-color: #434343;
--compact-font-color: #434343;
--blue-color: rgb(0, 122, 255);
--horizontal-padding: 32px;
--compact-horizontal-padding: 20px;
--border-radius: 6px;
--ios-border-radius: 10px;
--title-color: #444;
--icon-element-color: #dc143c;
}
* {
padding: 0;
margin: 0;
}
body:not(.ios) * {
font-family: -apple-system-font;
}
html, body {
height: 100%;
width: 100%;
}
body {
font-size: 13px;
background: linear-gradient(30deg, #dfdfdf 0%, #fafafb 100%);
background-repeat: no-repeat;
background-attachment: fixed;
cursor: default;
-webkit-user-select: none;
}
#title {
overflow: hidden;
color: var(--title-color);
padding-top: 3px;
}
.alert {
background-color: white;
min-width: 320px;
max-width: 672px;
position: relative;
margin: 0 auto;
padding-top: 28px;
border-radius: var(--border-radius);
box-shadow: 0px 6px 10px rgba(0, 0, 0, 0.14);
}
.alert-body {
margin: 21px 0 0 0;
padding-left: var(--horizontal-padding);
padding-right: var(--horizontal-padding);
padding-bottom: 24px;
color: var(--font-color);
}
.alert-body p:first-of-type {
margin-bottom: 15px;
margin-top: 20px;
}
.alert-body p:last-of-type {
margin-bottom: 0;
}
.bottom-bar {
margin-top: 1.3em;
height: 22px;
}
.bottom-bar button {
float: right;
font-size: 13px;
line-height: 21px;
min-width: 90px;
margin: 0 4px;
vertical-align: bottom;
padding: 0 12px;
}
.bottom-bar .details {
float: left;
}
.bottom-bar .details a {
cursor: pointer;
font-size: 14px;
margin-top: 2px;
}
#details {
display: none;
padding: 22px var(--horizontal-padding) 10px var(--horizontal-padding);
border-top: 1px solid rgb(217, 217, 217);
color: var(--font-color);
background-color: rgb(243, 243, 243);
border-bottom-left-radius: var(--border-radius);
border-bottom-right-radius: var(--border-radius);
}
.bottom-bar.goBack .closePage, .bottom-bar.closePage .goBack, #ignoreWarning {
display: block;
}
#openDateAndTimeButton {
display: none;
}
#bypassFeatureButton {
display: none;
}
a {
color: inherit;
text-decoration: underline;
cursor: pointer;
}
#lock, #clock {
float: left;
width: 30px;
top: 4px;
margin-right: 15px;
position: relative;
}
#clock {
display: none;
}
#bypassFeatureIcon {
display: none;
}
.lock-element {
fill: var(--icon-element-color);
}
.clock-element {
fill: var(--icon-element-color);
}
body.clockWarning #clock {
display: block;
}
body.clockWarning #lock {
display: none;
}
body.clockWarning #goBackButton {
display: none;
}
body.clockWarning #openDateAndTimeButton {
display: block;
}
body.bypassFeature #bypassFeatureButton {
display: block;
}
body.bypassFeature #detailsButton {
display: none;
}
body.bypassFeature #bypassFeatureIcon {
display: block;
float: left;
width: 34px;
top: 4px;
margin-right: 15px;
position: relative;
}
body.bypassFeature #lock {
display: none;
}
h1 {
font-size: 2em;
font-weight: 700;
line-height: 30px;
padding: 0 var(--horizontal-padding);
margin-bottom: -6px;
}
p {
font-size: 14px;
line-height: 19px;
margin-bottom: 1em;
word-wrap: break-word;
}
body.ios .alert {
box-shadow: none;
border-radius: var(--ios-border-radius);
max-width: 640px;
}
body.ios .alert-body {
font: -apple-system-body;
}
body.ios #details {
font: -apple-system-body;
border-bottom-left-radius: var(--ios-border-radius);
border-bottom-right-radius: var(--ios-border-radius);
}
body.ios h1 {
font-size: 26px;
font-family: -webkit-system-font;
}
body.ios p {
font-size: 1.1em;
line-height: unset;
}
body.ios button {
background: none;
border: none;
color: var(--blue-color);
font: -apple-system-short-body;
}
body.ios #detailsButton {
color: var(--font-color);
}
body.ios #bypassFeatureIcon {
fill: #000000;
}
body:not(.ios) #bypassFeatureIcon {
fill: var(--bypass-feature-icon-color);
}
@media screen and (max-width: 666px) {
/* iPhone 6 in landscape (667px) and smaller, including all iPhones in portrait */
body {
color: var(--compact-font-color);
}
.alert {
box-shadow: none;
background-color: var(--red-color);
}
.alert-body {
color: var(--compact-font-color);
padding-left: var(--compact-horizontal-padding);
padding-right: var(--compact-horizontal-padding);
padding-bottom: 30px;
}
h1 {
color: var(--compact-font-color);
padding: 0 var(--compact-horizontal-padding);
}
body.ios button,
body.ios #detailsButton {
text-decoration: underline;
}
#details {
background-color: var(--red-color);
padding: 22px var(--compact-horizontal-padding) 22px var(--compact-horizontal-padding);
border-top-width: 1px;
border-top-color: rgba(0, 0, 0, .15);
}
}
/* RTL support */
html[dir="rtl"] .bottom-bar button {
float: left;
}
html[dir="rtl"] :matches(#lock, #clock, #bypassFeatureIcon) {
float: right;
margin-left: 15px;
margin-right: 0;
}
</style>
<link rel=stylesheet type="text/css" href="safari-resource:/CertificateWarningExtras.css">
<script type="text/javascript" src="safari-resource:/Utilities.js" charset="utf-8"></script>
<script type="text/javascript" src="safari-resource:/WBSHTMLViewController.js" charset="utf-8"></script>
<script type="text/javascript">
// Should be kept in sync with WBSCertificateWarningCategory in WBSCertificateWarningPageContext.h.
var CertificateWarningCategory = {
Expired: 0,
InvalidCanBypass: 1,
InvalidCannotBypass: 2,
HostnameMismatch: 3,
IncorrectClock: 4,
LegacyTLS: 5,
// Placeholder
BypassFeatureNormal: 7,
BypassFeatureUnencrypted: 8,
};
var CertificateWarning = {
_host: undefined,
_canGoBack: undefined,
_warningCategory: undefined,
_numberOfDaysInvalid: undefined,
_expiredCertificateDetails: undefined,
_clockSkew: undefined,
get host()
{
return this._host;
},
set host(value)
{
if (this._host === value)
return;
this._host = value;
},
get canGoBack()
{
return this._canGoBack;
},
set canGoBack(value)
{
if (this._canGoBack === value)
return;
this._canGoBack = value;
},
get warningCategory()
{
return this._warningCategory;
},
set warningCategory(value)
{
if (this._warningCategory === value)
return;
this._warningCategory = value;
},
get numberOfDaysInvalid()
{
return this._numberOfDaysInvalid;
},
set numberOfDaysInvalid(value)
{
if (this._numberOfDaysInvalid === value)
return;
this._numberOfDaysInvalid = value;
},
get expiredCertificateDetails()
{
return this._expiredCertificateDetails;
},
set expiredCertificateDetails(value)
{
if (this._expiredCertificateDetails === value)
return;
this._expiredCertificateDetails = value;
},
get clockSkew()
{
return this._clockSkew;
},
set clockSkew(value)
{
if (this._clockSkew === value)
return;
this._clockSkew = value;
},
pageLoaded: function()
{
if (/Macintosh/g.test(navigator.userAgent))
document.body.classList.add("mac");
else
document.body.classList.add("ios");
HTMLViewController.pageLoaded();
CertificateWarningController.pageLoaded();
window.addEventListener("resize", layOut, false);
layOut();
},
currentSystemTime: function()
{
var dateFormatter = Intl.DateTimeFormat(undefined, { weekday: "long", day: "numeric", month: "long", year: "numeric" });
return dateFormatter.format(new Date());
},
showIncorrectClockWarning: function()
{
console.assert(this.warningCategory === CertificateWarningCategory.IncorrectClock);
console.assert(this.clockSkew !== 0);
document.body.classList.add("clockWarning");
var title = HTMLViewController.UIString("Your Clock Is Set Incorrectly");
document.title = title;
document.getElementById("title").textContent = title;
var incorrectClockHTMLTemplate = HTMLViewController.UIString("Safari can’t connect to “%hostname%” because your system clock is incorrectly set to %@. Set your system clock to the correct time and try again.").format(this.currentSystemTime());
var incorrectClockHTML = incorrectClockHTMLTemplate.replace("%hostname%", this.host);
var warningText = document.getElementById("warningText");
warningText.innerHTML = incorrectClockHTML;
var detailsTextHTMLTemplate = HTMLViewController.UIString("Because your system clock is set incorrectly, Safari can’t verify that your connection is private. If you understand the risks involved, you can %visit-this-site-link%.");
var detailsTextHTML = "<a role='button' onClick='CertificateWarningController.visitInsecureWebsiteWithTemporaryBypass();'>%@</a>".format(HTMLViewController.UIString("visit this website"));
var detailsText = detailsTextHTMLTemplate.replace("%visit-this-site-link%", detailsTextHTML);
document.getElementById("detailsText").innerHTML = detailsText;
setDetailsVisibility(false);
},
showBypassFeatureNavigationFailedWarning: function()
{
console.assert(this.warningCategory === CertificateWarningCategory.BypassFeatureNormal || this.warningCategory === CertificateWarningCategory.BypassFeatureUnencrypted);
document.body.classList.add("bypassFeature");
document.getElementById("title").textContent = CertificateWarningController.bypassFeatureTitleText();
document.getElementById("warningText").textContent = CertificateWarningController.bypassFeatureWarningText();
},
updateDetailsStrings: function()
{
if (this.warningCategory === CertificateWarningCategory.IncorrectClock) {
this.showIncorrectClockWarning();
return;
}
if (this.warningCategory === CertificateWarningCategory.BypassFeatureNormal || this.warningCategory === CertificateWarningCategory.BypassFeatureUnencrypted) {
this.showBypassFeatureNavigationFailedWarning();
return;
}
var warningText = document.getElementById("warningText");
var warningTextHTMLTemplate;
if (this.warningCategory === CertificateWarningCategory.LegacyTLS) {
if (this.canGoBack)
warningTextHTMLTemplate = HTMLViewController.UIString("This website has an outdated security configuration, which may allow an attacker to steal personal or financial information entered into “%hostname%”. You should go back to the previous page.");
else
warningTextHTMLTemplate = HTMLViewController.UIString("This website has an outdated security configuration, which may allow an attacker to steal personal or financial information entered into “%hostname%”. You should close this page.");
} else {
if (this.canGoBack)
warningTextHTMLTemplate = HTMLViewController.UIString("This website may be impersonating “%hostname%” to steal your personal or financial information. You should go back to the previous page.");
else
warningTextHTMLTemplate = HTMLViewController.UIString("This website may be impersonating “%hostname%” to steal your personal or financial information. You should close this page.");
}
var warningTextHTML = warningTextHTMLTemplate.replace("%hostname%", this.host);
warningText.innerHTML = warningTextHTML;
var bypassCertificateWarningHTMLTemplate = HTMLViewController.UIString("If you understand the risks involved, you can %visit-this-site-link%.");
var visitUnsafeWebsiteLinkHTML = "<a role='button' onClick='CertificateWarningController.visitInsecureWebsite();'>%@</a>".format(HTMLViewController.UIString("visit this website"));
var bypassCertificateWarningHTML = bypassCertificateWarningHTMLTemplate.replace("%visit-this-site-link%", visitUnsafeWebsiteLinkHTML);
var viewCertificateHTMLTemplate = HTMLViewController.UIString("To learn more, you can %view-the-certificate%.");
var viewCertificateLinkHTML = "<a role='button' onClick='CertificateWarningController.showCertificateInformation();'>%@</a>".format(HTMLViewController.UIString("view the certificate"));
var viewCertificateHTML = viewCertificateHTMLTemplate.replace("%view-the-certificate%", viewCertificateLinkHTML);
var detailsText = document.getElementById("detailsText");
switch (this.warningCategory) {
case CertificateWarningCategory.Expired:
var firstParagraphHTMLTemplate = HTMLViewController.UIString("Safari warns you when a website has %certificate-description%. %expiration-date-details%. This may happen if the website is misconfigured, an attacker has compromised your connection, or your system clock is incorrect. Your system clock is set to %@. If this is not right, %fixing-the-clock% may address this warning.");
var firstParagraphWithDateHTMLTemplate = firstParagraphHTMLTemplate.format(this.currentSystemTime());
var openClockSettingsLinkHTML = "<a role='button' onClick='CertificateWarningController.openClockSettings();'>%@</a>".format(HTMLViewController.UIString("fixing the clock"));
var firstParagraphWithClockHTMLTemplate = firstParagraphWithDateHTMLTemplate.replace("%fixing-the-clock%", openClockSettingsLinkHTML);
var firstParagraphWithExpirationDateDetails = firstParagraphWithClockHTMLTemplate.replace("%expiration-date-details%", this.expiredCertificateDetails);
var certificateDescription;
if (this.numberOfDaysInvalid > 0)
certificateDescription = HTMLViewController.UIString("an expired certificate");
else
certificateDescription = HTMLViewController.UIString("a certificate that is not valid");
var firstParagraph = firstParagraphWithExpirationDateDetails.replace("%certificate-description%", certificateDescription);
// Localizers: The space in between viewCertificateHTML and bypassCertificateWarningHTML should be translated to the appropriate space between two sentences.
detailsText.innerHTML = "<p>" + firstParagraph + "</p><p>" + viewCertificateHTML + " " + bypassCertificateWarningHTML + "</p>";
break;
case CertificateWarningCategory.HostnameMismatch:
case CertificateWarningCategory.InvalidCanBypass:
// FIXME 30320099: Hostname mismatch should be its own unique case.
var firstParagraph = HTMLViewController.UIString("Safari warns you when a website has a certificate that is not valid. This may happen if the website is misconfigured or an attacker has compromised your connection.");
// Localizers: The space in between viewCertificateHTML and bypassCertificateWarningHTML should be translated to the appropriate space between two sentences.
detailsText.innerHTML = "<p>" + firstParagraph + "</p><p>" + viewCertificateHTML + " " + bypassCertificateWarningHTML + "</p>";
break;
case CertificateWarningCategory.InvalidCannotBypass:
var firstParagraph = HTMLViewController.UIString("Safari warns you when a website has a certificate that is not valid. This may happen if an attacker has compromised your connection. For your protection, you can’t visit this website. You can check back later to see if this issue has been resolved. You can also contact the website owner to tell them about this error.");
// Localizers: The space in between firstParagraph and viewCertificateHTML should be translated to the appropriate space between two sentences.
detailsText.innerHTML = firstParagraph + " " + viewCertificateHTML;
break;
case CertificateWarningCategory.LegacyTLS:
var firstParagraph = HTMLViewController.UIString("Safari warns you when a website uses TLS 1.0 or TLS 1.1, which are not secure. This may allow an attacker to compromise your connection to steal your personal or financial information, including passwords, phone numbers, and credit cards.");
detailsText.innerHTML = "<p>" + firstParagraph + "</p><p>" + bypassCertificateWarningHTML + "</p>";
break;
default:
console.assert(false, "Invalid warning category given");
break;
}
setDetailsVisibility(false);
},
updateUI: function(host, warningCategory, canGoBack, numberOfDaysInvalid, expiredCertificateDetails, clockSkew)
{
this.warningCategory = warningCategory;
this.host = host;
this.canGoBack = canGoBack;
this.numberOfDaysInvalid = numberOfDaysInvalid;
this.expiredCertificateDetails = expiredCertificateDetails;
this.clockSkew = clockSkew;
if (!canGoBack)
document.getElementById("goBackButton").textContent = HTMLViewController.UIString("Close Page");
document.getElementById("bypassFeatureButton").textContent = CertificateWarningController.bypassFeatureButtonText();
var svg = document.getElementById("bypassFeatureIcon");
var path = document.createElementNS("http://www.w3.org/2000/svg", 'path');
var pathString = CertificateWarningController.bypassFeatureIconPath();
path.setAttribute("d", pathString);
path.style.opacity = 0.5;
svg.appendChild(path);
this.updateDetailsStrings();
},
setTextDirection: function(textDirection)
{
document.documentElement.setAttribute("dir", textDirection);
}
};
function setDetailsVisibility(show)
{
var detailsDiv = document.getElementById("details");
if (show) {
detailsDiv.style.display = "block";
document.getElementById("detailsButton").style.display = "none";
detailsDiv.scrollIntoViewIfNeeded();
} else {
detailsDiv.style.display = "none";
document.getElementById("detailsButton").style.display = "block";
}
layOut();
}
function layOut()
{
const minimumMarginTop = 22;
const maximumMarginTop = 156;
var alertBox = document.getElementById("alert");
var alertHeight = alertBox.getBoundingClientRect().height;
var viewportHeight = window.innerHeight;
if (viewportHeight > alertHeight + 2 * maximumMarginTop)
alertBox.style.top = maximumMarginTop + "px";
else
alertBox.style.top = Math.max(minimumMarginTop, (viewportHeight - alertHeight) / 2) + "px";
}
HTMLViewController.loadLocalizedStrings(CertificateWarningController);
window.addEventListener("load", function() { CertificateWarning.pageLoaded(); }, false);
</script>
</head>
<body>
<div id="alert" class="alert">
<h1>
<svg id="lock" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="33.6768" height="31.2098">
<rect height="30.1758" opacity="0" width="27.3834" x="0" y="0"/>
<path class="lock-element" d="M13.396 2.55615C16.1353 2.55615 18.5229 4.50439 18.5229 8.21045L18.5229 12.019L13.2056 12.019L23.4009 22.1851L23.4009 15.4907C23.4009 13.4692 22.5073 12.312 20.8374 12.0776L20.8374 8.51807C20.8374 3.01025 17.2339 0.344238 13.396 0.344238C10.3784 0.344238 7.56592 2.01416 6.49658 5.29541L8.37158 7.18506C8.75244 4.16748 10.9058 2.55615 13.396 2.55615ZM6.70166 29.0698L20.105 29.0698C20.7935 29.0698 21.3794 28.9087 21.8042 28.6304L5.42725 12.2681L5.29541 12.2681C4.09424 12.6636 3.40576 13.7769 3.40576 15.4907L3.40576 25.5835C3.40576 27.8979 4.54834 29.0698 6.70166 29.0698ZM25.4517 29.8462C25.9058 30.2856 26.6235 30.2856 27.0483 29.8462C27.4878 29.4067 27.5024 28.689 27.0483 28.2495L1.94092 3.14209C1.50146 2.70264 0.769043 2.70264 0.32959 3.14209C-0.109863 3.58154-0.109863 4.31396 0.32959 4.73877Z"/>
</svg>
<svg id="clock" x="0px" y="0px" viewBox="0 0 150 150" style="enable-background:new 0 0 150 150;" xml:space="preserve">
<path class="clock-element" d="M75,0C33.6,0,0,33.6,0,75c0,41.4,33.6,75,75,75s75-33.6,75-75C150,33.6,116.4,0,75,0z M81,68v7 c0,3.3-2.7,6-6,6H45c-3.3,0-6-2.7-6-6v-1c0-3.3,2.7-6,6-6h23V26c0-3.3,2.7-6,6-6h1c3.3,0,6,2.7,6,6V68z"/>
</svg>
<svg id="bypassFeatureIcon" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="33.6768" height="31.2098">
<rect height="31.2098" opacity="0" width="33.6768" x="0" y="0"/>
</svg>
<div id="title" class="l12n">This Connection Is Not Private</div>
</h1>
<div class="alert-body">
<div class="item">
<p id="warningText"></p>
</div>
<div class="bottom-bar goBack closePage" id="bottom-bar">
<button type="button" id="goBackButton" class="l12n goBack" onClick="CertificateWarningController.goBackSelected();">Go Back</button>
<button type="button" id="openDateAndTimeButton" class="l12n" onClick="CertificateWarningController.openClockSettings();">Open Date & Time…</button>
<button type="button" id="detailsButton" class="l12n" onClick="setDetailsVisibility(true);">Show Details</button>
<button type="button" id="bypassFeatureButton" class="l12n" onClick="CertificateWarningController.bypassFeatureVisitWebsite();">Continue</button>
</div>
</div>
<div id="details">
<p id="detailsText"></p>
</div>
</div>
</body>
</html>
// # sourceURL=__InjectedScript_FormMetadataClassification.js
/* Copyright (c) 2024 Apple Inc. All rights reserved. */
"use strict";
const WBSABAddressProperty = "Address",
WBSABPhoneProperty = "Phone",
_WBSABAddressZIPKey = "ZIP",
WBSFormControlMetadataDefaultMaxLength = 524288,
WBSIgnoredClassificationToken = "-sf-ignored",
WBSLocaleForCreditCardExpirationDate = "en_US",
WBSCreditCardTypeClassificationToken = "cc-type",
WBSCreditCardHolderNameClassificationToken = "cc-name",
WBSCreditCardNumberClassificationToken = "cc-number",
WBSCreditCardExpirationClassificationToken = "cc-exp",
WBSCreditCardSecurityCodeClassificationToken = "cc-csc",
WBSCreditCardHolderGivenNameClassificationToken = "cc-given-name",
WBSCreditCardHolderAdditionalNameClassificationToken = "cc-additional-name",
WBSCreditCardHolderFamilyNameClassificationToken = "cc-family-name",
WBSCreditCardExpirationMonthClassificationToken = "cc-exp-month",
WBSCreditCardExpirationYearClassificationToken = "cc-exp-year",
WBSCreditCardHolderNameClassificationDefaultOrderedParts = [ WBSCreditCardHolderGivenNameClassificationToken, WBSCreditCardHolderAdditionalNameClassificationToken, WBSCreditCardHolderFamilyNameClassificationToken ],
WBSCreditCardExpirationClassificationDefaultOrderedParts = [ WBSCreditCardExpirationMonthClassificationToken, WBSCreditCardExpirationYearClassificationToken ],
WBSCredentialUsernameClassificationToken = "username",
WBSCredentialCurrentPasswordClassificationToken = "current-password",
WBSCredentialNewPasswordClassificationToken = "new-password",
WBSContactNameClassificationToken = "name",
WBSContactGivenNameClassificationToken = "given-name",
WBSContactAdditionalNameClassificationToken = "additional-name",
WBSContactFamilyNameClassificationToken = "family-name",
WBSContactClassificationDefaultOrderedParts = [ WBSContactGivenNameClassificationToken, WBSContactAdditionalNameClassificationToken, WBSContactFamilyNameClassificationToken ],
WBSContactNamePartsSet = new Set(WBSContactClassificationDefaultOrderedParts),
WBSContactInstantMessageClassificationToken = "-sf-instant-message",
WBSContactPostalCodeClassificationToken = "postal-code",
WBSContactStreetAddressClassificationToken = "street-address",
WBSContactStreetAddressLine1ClassificationToken = "address-line1",
WBSContactStreetAddressLine2ClassificationToken = "address-line2",
WBSContactStreetAddressLine3ClassificationToken = "address-line3",
WBSContactTelephoneClassificationToken = "tel",
WBSContactTelephoneCountryCodeClassificationToken = "tel-country-code",
WBSContactTelephoneAreaCodeClassificationToken = "tel-area-code",
WBSContactTelephoneLocalPrefixClassificationToken = "tel-local-prefix",
WBSContactTelephoneLocalSuffixClassificationToken = "tel-local-suffix",
WBSContactTelephoneExtensionClassificationToken = "tel-extension",
WBSContactTelephoneDefaultOrderedParts = [ WBSContactTelephoneCountryCodeClassificationToken, WBSContactTelephoneAreaCodeClassificationToken, WBSContactTelephoneLocalPrefixClassificationToken, WBSContactTelephoneLocalSuffixClassificationToken, WBSContactTelephoneExtensionClassificationToken ],
WBSContactBirthdayClassificationToken = "bday",
WBSContactBirthdayDayClassificationToken = "bday-day",
WBSContactBirthdayMonthClassificationToken = "bday-month",
WBSContactBirthdayYearClassificationToken = "bday-year";
class FormMetadataClassification {
#t(t)
{
return null != t && "object" == typeof t
}
#e(t)
{
return this.#t(t) && "string" == typeof t.ControlTagName
}
#o(t)
{
return this.#t(t) && "string" == typeof t.property
}
fieldLooksLikeDateField(t)
{
return !!(t.ControlLooksLikeDayField || t.ControlLooksLikeMonthField || t.ControlLooksLikeYearField)
}
#i(t)
{
let e = t.ControlMaxLength;
return (void 0 === e || e < 0 || e > WBSFormControlMetadataDefaultMaxLength) && (e = WBSFormControlMetadataDefaultMaxLength), e
}
fieldLooksLikeItExpectsDataOfSize(t, e)
{
return (t.ControlSize ?? 0) <= e || this.#i(t) <= e
}
fieldCouldBeCreditCardNumberContinuation(t, e)
{
const o = 4;
if (e.length >= o)
return !1;
if (!e[0]?.ControlLooksLikeCreditCardNumberField)
return !1;
const i = 2;
if (t.ControlMaxLength === i)
return !1;
if (t.ControlLooksLikeCreditCardNumberField)
return !0;
if (t.ControlLooksLikeCreditCardSecurityCodeField)
return !1;
if (t.ControlLooksLikeCreditCardCompositeExpirationDateField)
return !1;
const n = 6;
if (!this.fieldLooksLikeItExpectsDataOfSize(t, n))
return !1;
const a = e.at(-1);
return !(a && !this.fieldLooksLikeItExpectsDataOfSize(a, n))
}
labelsCouldRepresentContinuation(t, e, o, i)
{
return !(!t || !o) && (t === o || !!e && (!i || e.property === i.property && (i.component && e.component === i.component)))
}
fieldCouldBePhoneNumberContinuation(t, e)
{
const o = 5;
if (e.length >= o)
return !1;
if (e[0]?.AddressBookValueSpecifier?.property !== WBSABPhoneProperty)
return !1;
const i = 5;
return !!this.fieldLooksLikeItExpectsDataOfSize(t, i)
}
fieldCouldBePostCodeContinuation(t, e)
{
const o = 3;
if (e.length >= o)
return !1;
if (e[0]?.AddressBookValueSpecifier?.component != _WBSABAddressZIPKey)
return !1;
const i = 6;
return !!this.fieldLooksLikeItExpectsDataOfSize(t, i)
}
fieldLooksLikeSameDataType(t, e)
{
const o = e.at(-1);
return !!this.labelsCouldRepresentContinuation(o?.AddressBookLabel, o?.AddressBookValueSpecifier, t?.AddressBookLabel, t?.AddressBookValueSpecifier) || (!!(o && this.fieldLooksLikeDateField(o) && this.fieldLooksLikeDateField(t)) || (!!this.fieldCouldBePhoneNumberContinuation(t, e) || (!!this.fieldCouldBePostCodeContinuation(t, e) || !!this.fieldCouldBeCreditCardNumberContinuation(t, e))))
}
#n(t)
{
return globalThis.DOMRect || (globalThis.DOMRect = class {
constructor(t, e, o, i)
{
this.left = t, this.right = t + o, this.top = e, this.bottom = e + i, this.width = o, this.height = i
}
}), t.ControlRectLeft || t.ControlRectTop || t.ControlRectWidth || t.ControlRectHeight ? new DOMRect(t.ControlRectLeft, t.ControlRectTop, t.ControlRectWidth, t.ControlRectHeight) : globalThis.FormMetadataJS ? FormMetadataJS.formControlWithUniqueID(t.ControlUniqueID)?.getBoundingClientRect()
: new DOMRect(0, 0, 0, 0)
}
fieldLooksLikeContinuation(t, e, o)
{
if (!t.ControlIsTextField && "SELECT" !== t.ControlTagName.toUpperCase())
return !1;
if (!this.fieldLooksLikeSameDataType(t, e))
return !1;
if (o)
return !0;
const i = this.#n(e.at(-1)),
n = this.#n(t);
if (Math.abs(i.top - n.top) > 3)
return !1;
let a, r;
return i.left < n.left ? (a = i, r = n) : (a = n, r = i), !(r.left - a.right > 60)
}
continuingFieldsInFormControls(t, e, o, i)
{
const n = [ t[e] ];
for (let a = e + 1; a < t.length; ++a) {
const e = t[a];
if (o && !e.ControlIsTextField)
break;
if (!this.fieldLooksLikeContinuation(e, n, i))
break;
n.push(e)
}
return n
}
classifyControlsRelatedToNameParts(t, e)
{
const o = t[e];
o.ControlClassification = WBSContactNameClassificationToken, o.ControlOrderedParts = [ o.AddressBookValueSpecifier?.classification ];
const i = new Set([ o.AddressBookValueSpecifier?.classification ]),
n = [ t[e] ];
for (let o = e + 1; o < t.length; ++o) {
const e = t[o];
if (!e.ControlIsTextField)
break;
const a = e.AddressBookValueSpecifier?.classification;
if (!a)
break;
if (!WBSContactNamePartsSet.has(a) || i.has(a))
break;
e.ControlClassification = WBSContactNameClassificationToken, e.ControlOrderedParts = [ a ], i.add(a), n.push(e)
}
return n
}
identifyDateFields(t)
{
let e, o, i, n = !1;
for (let a of t)
if (a.ControlLooksLikeDayField) {
if (e)
return [ !1 ];
e = a, n = !0
} else if (a.ControlLooksLikeMonthField) {
if (o)
return [ !1 ];
o = a, n = !0
} else if (a.ControlLooksLikeYearField) {
if (i)
return [ !1 ];
i = a, n = !0
}
return [ n, i, o, e ]
}
canonicalizedDateTemplate(t)
{
if (t && (t = t.replace(/\s/g, "")).length && !/[^dmyDMY\/.-]/g.test(t))
return t = (t = (t = t.replace(/D/g, "d")).replace(/m/g, "M")).replace(/Y/g, "y")
}
classifyDateFields(t, e, o, i, n, a, r)
{
if (t.length > 3)
return !1;
if (1 === t.length) {
if (!t[0].ControlIsTextField)
return !1;
let a = t[0].ControlRequiredFormatForDateTimeInput;
if (!a) {
const e = n ? new Date(1999, 11, 30) : new Date(1999, 11);
let o = this.#i(t[0]),
i = this.canonicalizedDateTemplate(t[0].ControlPlaceholder),
s = i?.length ? i : n ? "ddMMy"
: "MMyy";
a = FormMetadataJSController.dateFormatFromTemplate(s, r);
let l = FormMetadataJSController.stringFromDateFormat(a, e);
if (l.length > o && (s = n ? "dMMyy" : "MMyy", a = FormMetadataJSController.dateFormatFromTemplate(s, r), l = FormMetadataJSController.stringFromDateFormat(a, e), l.length > o && (s = n ? "dMyy" : "Myy", a = FormMetadataJSController.dateFormatFromTemplate(s, r), l = FormMetadataJSController.stringFromDateFormat(a, e))), l.length > o)
return !1
}
const s = [];
for (const t of a) {
let e;
"y" === t ? e = o : "M" === t ? e = i
: "d" === t && (e = n),
e && !s.includes(e) && s.push(e)
}
return t[0].ControlClassification = e, t[0].ControlOrderedParts = s, t[0].ControlRequiredFormatForDateTimeInput = a, !0
}
let [s, l, C, d] = this.identifyDateFields(t);
if (!s)
return !1;
if (d && !C)
return !1;
let c = 0;
for (const r of t)
r.ControlClassification = e, r.ControlContinuationID = a, r.ControlContinuationIndex = c++, r === d ? r.ControlOrderedParts = [ n ] : r === C ? r.ControlOrderedParts = [ i ]
: r === l && (r.ControlOrderedParts = [ o ]);
return !0
}
classify(t)
{
const e = t.FormControls,
o = e.length,
i = t.AutoFillFormType === WBSAutoFillFormTypeNewAccount,
n = t.AutoFillFormType === WBSAutoFillFormTypeChangePassword,
a = t.UsernameElementUniqueID,
r = t.PasswordElementUniqueID,
s = t.OldPasswordElementUniqueID,
l = t.ConfirmPasswordElementUniqueID;
for (let t of e)
(t.AutocompleteTokens || t.AddressBookLabel) && (t.AddressBookValueSpecifier = FormMetadataJSController.specifierForAutocompleteTokensAndAddressBookLabel(t.AutocompleteTokens, t.AddressBookLabel));
let C = !1,
d = !1,
c = !1,
f = !1,
k = !1,
S = 0;
for (let u = 0, T = 1; u < o; u += T, T = 1) {
const o = e[u];
if (o.ControlLooksLikeIgnoredDataTypeField) {
o.ControlClassification = WBSIgnoredClassificationToken;
continue
}
const B = o.ControlUniqueID;
if (B === r || B === l) {
o.ControlClassification = i || n ? WBSCredentialNewPasswordClassificationToken : WBSCredentialCurrentPasswordClassificationToken;
continue
}
if (B === s) {
o.ControlClassification = WBSCredentialCurrentPasswordClassificationToken;
continue
}
if (B === a) {
o.ControlClassification = WBSCredentialUsernameClassificationToken;
continue
}
if (!d && o.ControlLooksLikeCreditCardCardholderField) {
d = !0, o.ControlClassification = WBSCreditCardHolderNameClassificationToken, o.ControlOrderedParts = WBSCreditCardHolderNameClassificationDefaultOrderedParts;
continue
}
if (!C && o.ControlLooksLikeCreditCardNumberField) {
C = !0;
const t = this.continuingFieldsInFormControls(e, u, !0, !1);
let o = 0,
i = t.length > 1 ? ++S : 0;
for (let e of t)
e.ControlClassification = WBSCreditCardNumberClassificationToken, e.ControlContinuationID = i, e.ControlContinuationIndex = o++;
T = t.length;
continue
}
const h = this.fieldLooksLikeDateField(o) || o.ControlLooksLikeCreditCardCompositeExpirationDateField;
if ((f || d || C) && !c && h) {
c = !0;
const t = this.continuingFieldsInFormControls(e, u, !1, !0);
let o = t.length > 1 ? ++S : 0;
this.classifyDateFields(t, WBSCreditCardExpirationClassificationToken, WBSCreditCardExpirationYearClassificationToken, WBSCreditCardExpirationMonthClassificationToken, void 0, o, WBSLocaleForCreditCardExpirationDate), T = t.length;
continue
}
if (!k && o.ControlLooksLikeCreditCardSecurityCodeField) {
k = !0, o.ControlClassification = WBSCreditCardSecurityCodeClassificationToken;
continue
}
if (!f && o.ControlLooksLikeCreditCardTypeField) {
f = !0, o.ControlClassification = WBSCreditCardTypeClassificationToken;
continue
}
const m = o.AddressBookValueSpecifier?.classification;
if (m) {
const i = o.AddressBookValueSpecifier.classificationHint;
if (m === WBSContactNameClassificationToken) {
o.ControlClassification = m, o.ControlOrderedParts = WBSContactClassificationDefaultOrderedParts;
continue
}
if (WBSContactNamePartsSet.has(m)) {
const t = this.classifyControlsRelatedToNameParts(e, u);
if (t.length > 1) {
let e = ++S,
o = 0;
for (let i of t)
i.ControlContinuationID = e, i.ControlContinuationIndex = o++
}
T = t.length;
continue
}
if (m === WBSContactPostalCodeClassificationToken) {
const t = this.continuingFieldsInFormControls(e, u, !0, !1);
let o = t.length > 1 ? ++S : 0,
i = 0;
for (let e of t)
e.ControlClassification = WBSContactPostalCodeClassificationToken, e.ControlContinuationID = o, e.ControlContinuationIndex = i++;
T = t.length;
continue
}
if (m === WBSContactStreetAddressClassificationToken) {
const t = this.continuingFieldsInFormControls(e, u, !0, !0);
let o = t.length > 1 ? ++S : 0,
i = 0;
for (let e of t)
e.ControlClassification = WBSContactStreetAddressClassificationToken, e.ControlContinuationID = o, e.ControlContinuationIndex = i++;
1 === t.length ? t[0].ControlOrderedParts = [ WBSContactStreetAddressLine1ClassificationToken, WBSContactStreetAddressLine2ClassificationToken, WBSContactStreetAddressLine3ClassificationToken ] : 2 === t.length ? (t[0].ControlOrderedParts = [ WBSContactStreetAddressLine1ClassificationToken ], t[1].ControlOrderedParts = [ WBSContactStreetAddressLine2ClassificationToken, WBSContactStreetAddressLine3ClassificationToken ])
: t.length >= 3 && (t[0].ControlOrderedParts = [ WBSContactStreetAddressLine1ClassificationToken ], t[1].ControlOrderedParts = [ WBSContactStreetAddressLine2ClassificationToken ], t[2].ControlOrderedParts = [ WBSContactStreetAddressLine3ClassificationToken ]),
T = t.length;
continue
}
if (m === WBSContactInstantMessageClassificationToken) {
const t = this.continuingFieldsInFormControls(e, u, !0, !0);
1 === t.length && (t[0].ControlClassification = WBSContactInstantMessageClassificationToken, i && (t[0].ControlClassificationHints = [ i ])), T = t.length;
continue
}
if (m.startsWith(WBSContactTelephoneClassificationToken)) {
const t = this.continuingFieldsInFormControls(e, u, !0, !1);
if (1 == t.length) {
t[0].ControlClassification = WBSContactTelephoneClassificationToken, t[0].ControlOrderedParts = WBSContactTelephoneDefaultOrderedParts, i && (t[0].ControlClassificationHints = [ i ]);
continue
}
let o = ++S,
n = 0;
for (let e of t)
e.ControlClassification = WBSContactTelephoneClassificationToken, e.ControlContinuationID = o, e.ControlContinuationIndex = n++, i && (e.ControlClassificationHints = [ i ]);
2 === t.length ? (t[0].ControlOrderedParts = [ WBSContactTelephoneAreaCodeClassificationToken ], t[1].ControlOrderedParts = [ WBSContactTelephoneLocalPrefixClassificationToken, WBSContactTelephoneLocalSuffixClassificationToken ]) : 3 === t.length ? (t[0].ControlOrderedParts = [ WBSContactTelephoneAreaCodeClassificationToken ], t[1].ControlOrderedParts = [ WBSContactTelephoneLocalPrefixClassificationToken ], t[2].ControlOrderedParts = [ WBSContactTelephoneLocalSuffixClassificationToken ])
: 4 === t.length ? (t[0].ControlOrderedParts = [ WBSContactTelephoneCountryCodeClassificationToken ], t[1].ControlOrderedParts = [ WBSContactTelephoneAreaCodeClassificationToken ], t[2].ControlOrderedParts = [ WBSContactTelephoneLocalPrefixClassificationToken ], t[3].ControlOrderedParts = [ WBSContactTelephoneLocalSuffixClassificationToken ])
: (t[0].ControlOrderedParts = [ WBSContactTelephoneCountryCodeClassificationToken ], t[1].ControlOrderedParts = [ WBSContactTelephoneAreaCodeClassificationToken ], t[2].ControlOrderedParts = [ WBSContactTelephoneLocalPrefixClassificationToken ], t[3].ControlOrderedParts = [ WBSContactTelephoneLocalSuffixClassificationToken ], t[4].ControlOrderedParts = [ WBSContactTelephoneExtensionClassificationToken ]),
T = t.length;
continue
}
if (m === WBSContactBirthdayClassificationToken) {
const o = this.continuingFieldsInFormControls(e, u, !1, !1),
i = o.length > 1 ? ++S : void 0,
n = t.RequestType === WBSFormMetadataRequestTesting ? "en_US" : void 0;
this.classifyDateFields(o, WBSContactBirthdayClassificationToken, WBSContactBirthdayYearClassificationToken, WBSContactBirthdayMonthClassificationToken, WBSContactBirthdayDayClassificationToken, i, n), T = o.length;
continue
}
o.ControlClassification = m
} else
;
}
}
}
globalThis.FormMetadataClassificationJS = new FormMetadataClassification;
// # sourceURL=__InjectedScript_FormMetadata.js
/* Copyright (c) 2024 Apple Inc. All rights reserved. */
function legacyPlaceholderInfoForInputElement(e)
{
if ("text" !== e.type)
return null;
if (doctypeLooksLikeHTML5)
return null;
var t = e.value.trim();
if (!t)
return null;
for (var o = !1, r = !0, n = e.attributes, i = n.length, l = 0; l < i; ++l) {
var a = n[l];
if (t === a.value.trim() && (o = !0, "value" !== a.name.toLowerCase())) {
r = !1;
break
}
}
return o ? {
Text : t,
AttributeMatchedWasValue : r
}
: null
}
function placeholderInfoForElement(e)
{
var t = e.getAttribute("placeholder");
if (t)
return {
Text : t,
AttributeMatchedWasValue : !1
};
var o = e.getAttribute("data-placeholder");
return o && o.length ? {
Text : o,
AttributeMatchedWasValue : !1
}
: isInputElement(e) ? legacyPlaceholderInfoForInputElement(e)
: null
}
function sharedPrefixLength(e, t)
{
for (var o = 0, r = 0, n = e.length; r < n && e[r] === t[r]; ++r)
o++;
return o
}
function rowContainingLabelAboveRow(e)
{
for (var t = e.getBoundingClientRect(), o = e.previousElementSibling; o instanceof HTMLTableRowElement; o = o.previousElementSibling) {
if (o.querySelector("input, select, textarea"))
return null;
var r = o.getBoundingClientRect();
if (t.top - r.bottom > t.height / 2)
return null;
if (o.innerText.match(/\S/))
return o
}
return null
}
function cellVisuallyAbove(e)
{
let t = e.parentElementIncludingShadowDOMHost();
if (!(t && t instanceof HTMLTableRowElement))
return null;
var o = rowContainingLabelAboveRow(t);
if (!o)
return null;
for (var r = e.getBoundingClientRect(), n = o.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, r.right) - Math.max(c.left, r.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 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 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, o = t.length, r = 0; r < o; ++r) {
var n = t[r];
if (n.selected !== n.defaultSelected) {
if (n.defaultSelected)
return !1;
if (e.multiple || r)
return !1
}
}
return !0
}
function formActionAsAnchorElement(e, t)
{
if (!(e instanceof HTMLFormElement))
return null;
let o = e.getAttribute("action");
if (!o && t)
return null;
var r = document.createElement("a");
return r.href = o || "", r
}
function eventThatBubbles(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
}
function isValidUsernameOrEmail(e)
{
const t = /^[a-z_][a-z0-9_.]{2,30}$/i,
o = /^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$/i;
return !(!e || e.length < 3 || "true" === e || "false" === e) && (t.test(e) || o.test(e))
}
function selectorForElement(e)
{
let t = e.localName,
o = e.getAttribute("id");
o && (t += `#${o}`);
let r = e.classList,
n = r.length;
for (let e = 0; e < n; e++)
t += "." + r[e];
return t
}
function hasOwnProperties(e)
{
return Object.getOwnPropertyNames(e).length > 0
}
function defaultOptionForSelectElement(e)
{
for (var t = e.options, o = t.length, r = 0; r < o; ++r) {
var n = t[r];
if (n.defaultSelected)
return n
}
return t[0]
}
function selectElementOptionsSequenceAnalysis(e, t)
{
for (var o = e.options, r = o.length, n = 0, i = -1, l = -1, a = 0, s = 0; s < r; ++s) {
var u = o[s],
c = parseInt(u[t]);
isNaN(c) ? (a >= n && (n = a, i = l), l = -1, a = 0) : -1 === l ? (l = c, a = 1)
: c === l + 1 && (l = c, a++)
}
return a >= n && (n = a, i = l),
{
lengthOfLongestSequence: n,
lastNumberInSequence: i
}
}
function isElementPositionedToBeEffectivelyInvisible(e)
{
var t = !1;
for (let o = e; o; o = o.parentElementIncludingShadowDOMHost())
if ("fixed" === getComputedStyle(o).position) {
t = !0;
break
}
var o, r, n, i = e.getBoundingClientRect();
if (t)
o = i, r = window.innerWidth, n = window.innerHeight;
else {
var l = window.scrollY,
a = window.scrollX;
o = {
top : i.top + l,
right : i.right + a,
bottom : i.bottom + l,
left : i.left + a,
width : i.width,
height : i.height
},
r = document.documentElement.scrollWidth, n = Math.max(document.documentElement.scrollHeight, window.innerHeight)
}
return o.top >= n || o.right <= 0 || o.bottom <= 0 || o.left >= r
}
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 o = [];
for (const r of t)
e.hasAttribute(r) && o.push(e.getAttribute(r).trim().toLowerCase());
if (!o.length)
return null;
let r = o.join(" ").split(/\s+/).filter((function(e) {
return e.length && "off" !== e && "on" !== e
}));
return r.length ? r : null
}
function elementIDOrAutocompleteTokensHasToken(e, t, o)
{
return !!e.id?.includes(o) || !!t?.includes(o)
}
function controlAppearsToBePartOfPhotoTaggingInterface(e)
{
const t = /photo.*tag/i;
for (let o = e.parentElementIncludingShadowDOMHost(); o; o = o.parentElementIncludingShadowDOMHost())
if (t.test(o.className))
return !0;
return !1
}
function levenshteinDistance(e, t)
{
for (var o = e.length, r = t.length, n = new Array(o + 1), i = 0; i < o + 1; ++i)
n[i] = new Array(r + 1), n[i][0] = i;
for (var l = 0; l < r + 1; ++l)
n[0][l] = l;
for (l = 1; l < r + 1; ++l)
for (i = 1; i < o + 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[o][r]
}
function stringSimilarity(e, t)
{
var o = Math.max(e.length, t.length);
return o ? (o - levenshteinDistance(e, t)) / o : 0
}
function stripCommonPrefix(e, t)
{
const o = e.length,
r = t.length,
n = o < r ? o : r;
let i = 0;
for (; i < n && e[i] === t[i];)
i++;
return [ e.slice(i), t.slice(i) ]
}
function articleTitleAndSiteNameFromTitleString(e, t)
{
const o = [ " - ", " \u2013 ", " \u2014 ", ": ", " | ", " \xbb " ],
r = o.length,
n = .6;
for (var i, l, a = e.replace(/^(www|m|secure)\./, ""), s = a.replace(/\.(com|info|net|org|edu|gov)$/, "").toLowerCase(), u = 0; u < r; ++u) {
var c = t.split(o[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)),
p = Math.max(f, g);
(!l || p > l) && (l = p, 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 o = [];
for (let r of e.querySelectorAll("*"))
if (r.shadowRoot) {
let e = querySelectorAllIncludingWithinShadowRoots(r.shadowRoot, t);
e.length && (o = o.concat(e))
} else
r.matches(t) && o.push(r);
return o
}
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 o = e;
for (; o.previousElementSibling;)
o = o.previousElementSibling;
let r = [],
n = o;
for (; n;)
r.push(n), n = n.nextElementSibling;
return r
}
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 o of t)
for (let t of e)
if (o.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()
{
let e = document.activeElement,
t = e;
for (; t;)
t = t?.shadowRoot?.activeElement, t && (e = t);
return e
}
function elementAppearsToContinueCaptchaWidget(e)
{
return !!e.querySelector("iframe[title*=captcha i], input[type=hidden][name*=recaptcha]")
}
const WBSAutoFillFormTypeUndetermined = 0,
WBSAutoFillFormTypeAutoFillableStandard = 1,
WBSAutoFillFormTypeNonAutoFillable = 2,
WBSAutoFillFormTypeAutoFillableLogin = 3,
WBSAutoFillFormTypeNewAccount = 4,
WBSAutoFillFormTypeChangePassword = 5,
WBSFormMetadataRequestNormal = 0,
WBSFormMetadataRequestPreFill = 1,
WBSFormMetadataRequestTesting = 2,
WBSFormMetadataRequestTextChange = 3,
WBSFormMetadataRequestCollectMetadataFromDebugMenu = 4,
ShouldStopAfterFirstMatch = {
CollectAllMatches : 0,
StopAfterFirstMatch : 1
},
ShouldFocus = {
No : 0,
Yes : 1
},
ShouldBlur = {
No : 0,
Yes : 1
},
ShouldAbandonCharacterByCharacterEntryIfTooSlow = {
No : 0,
Yes : 1
},
ShouldObscure = {
No : 0,
Yes : 1
},
ShouldSetAutoFilled = {
No : 0,
Yes : 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 = .5,
UsernameCandidateScorePenaltyForReadOnlyElement = .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;
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
}, 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.nodeType == Node.TEXT_NODE ? e.parentElementIncludingShadowDOMHost() : e,
o = getComputedStyle(t, null);
if (e._isVisible = -visibilityCacheGeneration, "none" === o.display || "visible" !== o.visibility)
return !1;
let r = 0 === parseFloat(o.opacity) ? 6 : 2;
return !(t.offsetWidth < r) && (!(t.offsetHeight < r) && (e._isVisible = visibilityCacheGeneration, !0))
}, Object.defineProperty(Array.prototype, "joinFirstItems", {
value : function(e, t) {
t > this.length && (t = this.length);
for (var o = "", r = 0; r < t; ++r)
r > 0 && (o += e), o += this[r];
return o
}
}),
DOMRect.prototype.isZeroRect = function() {
return !(this.top || this.right || this.bottom || this.left)
}, 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 o = e[0],
r = e[1];
return o[0].x >= r[0].x && o[0].x < r[1].x || r[0].x >= o[0].x && r[0].x < o[1].x ? Math.abs(o[0].y - r[0].y) : o[0].y >= r[0].y && o[0].y < r[1].y || r[0].y >= o[0].y && r[0].y < o[1].y ? Math.abs(o[0].x - r[0].x)
: Math.sqrt(Math.min(t(o[0], r[1]), t(o[1], r[0])))
}
var o = [ {
x : this.left,
y : this.top
},
{
x : this.right,
y : this.top
} ],
r = [ {
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 ],
[ o, l ],
[ o, s ],
[ r, u ],
[ r, 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 o = this.allAncestorsAndSelfIncludingShadowDOMHosts().reverse(),
r = e.allAncestorsAndSelfIncludingShadowDOMHosts().reverse(),
n = Math.min(o.length, r.length),
i = null;
for (let e = 0; e < n; ++e) {
if (!(o[e] === r[e]))
break;
i = o[e]
}
return i || null
}, HTMLElement.prototype.isHiddenFromAccessibilityTree = function() {
const e = 2;
for (let o = 0, r = this; o <= e && r; ++o, r = r.parentElementIncludingShadowDOMHost()) {
var t = r.getAttribute("aria-hidden");
if (t && "true" === t.toLowerCase())
return !0
}
return !1
}, HTMLFormElement.prototype.isVisible = function() {
if (Node.prototype.isVisible.call(this))
return !0;
for (var e = this.elements, t = e.length, o = 0; o < t; ++o)
if (e[o].isVisible())
return !0;
return !1
}, LogicalForm = function(e, t, o) {
let r = e.length;
var n = e[0].form,
i = n;
!t && i || (i = 1 === r ? e[0] : e[0].closestCommonAncestor(e[r - 1])), n && n.contains(e[r - 1]) || (n = i);
let l = FormMetadataJSController.nextFormUniqueID;
i._logicalFormUniqueIDs || (i._logicalFormUniqueIDs = new Set), this._formUniqueID = l, i._logicalFormUniqueIDs.add(), this._metadata = {}, this._weakControls = Array.prototype.map.call(e, (e => new WeakRef(e))), this._weakFormElement = new WeakRef(n), this._weakBackingElement = new WeakRef(i), o || this.markElementsAsPartOfLogicalForm()
}, LogicalForm.prototype = {
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
},
containsControl : function(e) {
return "function" == typeof e._logicalFormUniqueIDs?.has ? e._logicalFormUniqueIDs.has(this.formUniqueID) : e.form === this.formElement
},
radioButtonsWithName : function(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 : function(e) {
let t = this.formElement;
if (t) {
var o = t._annotations;
if (o) {
for (var r in e) {
var n = e[r];
n ? o[r] = n : delete o[r]
}
hasOwnProperties(o) || delete t._annotations
} else
t._annotations = e
}
},
markElementsAsPartOfLogicalForm : function() {
let e = this._weakControls.length;
for (let t = 0; t < e; t++) {
let o = this._weakControls[t].deref();
o && (o._logicalFormUniqueIDs || (o._logicalFormUniqueIDs = new Set), o._logicalFormUniqueIDs.add(this.formUniqueID), t + 1 < e && (o._weakNextControlInLogicalForm = this._weakControls[t + 1]), t > 0 && (o._weakPreviousControlInLogicalForm = this._weakControls[t - 1]))
}
},
get annotations() {
return this.formElement?._annotations
},
get isAnnotated() {
return !!this.annotations
}
},
LogicalFormCache = function() {
this._logicalFormsByUniqueID = new Map
}, LogicalFormCache.prototype = {
get size() {
return this._logicalFormsByUniqueID.size
},
cleanupCache : function() {
let e = new Set;
for (let t of this._logicalFormsByUniqueID.values())
t.formElement || t.backingElement || e.add(t);
for (let t of e)
this._logicalFormsByUniqueID.delete(t.formUniqueID)
},
logicalFormForControl : function(e) {
this.cleanupCache();
for (let t of this._logicalFormsByUniqueID.values())
if (t.containsControl(e))
return t;
return null
},
allForms : function() {
return this.cleanupCache(), Array.from(this._logicalFormsByUniqueID.values())
},
addOrUpdate : function(e) {
this._logicalFormsByUniqueID.set(e.formUniqueID, e)
},
clearCacheAndAdd : function(e) {
this._logicalFormsByUniqueID.clear();
for (let t of e)
this.addOrUpdate(t)
},
logicalFormWithUniqueID : function(e) {
return this._logicalFormsByUniqueID.get(e)
}
},
FormMetadata = function() {
this._logicalFormsCache = new LogicalFormCache, this._elementsWithGeneratedPasswords = [], this._generatedPasswords = [], this._labels = queryAllBySelector(document, "label"), this._controlUniqueIDToWeakControlMap = new Map, this._mapOfFormTypeToExtraScoreProducer = function() {
let e = {};
return e[WBSAutoFillFormTypeNewAccount] = function() {
return 0
}, e[WBSAutoFillFormTypeAutoFillableLogin] = function(e) {
const t = 2,
o = function(e) {
return "checkbox" === e.type && FormMetadataJS._labelsForElement(e).some((e => /(remember|keep) me/i.test(e.innerText.trim()) && e.isVisible()))
};
return 1 === e.elements.filter((e => o(e))).length ? t : 0
}, e[WBSAutoFillFormTypeChangePassword] = function() {
return 0
}, e
}(), this._requiredFormatForDateTimeInput = DateTimeInputTypes.reduce((function(e, t) {
let o = document.createElement("input");
o.type = t;
let r = "a";
return o.value = r, e[t] = "" === o.value ? DateTimeInputTypeFormats[t] : "", e
}),
{})
}, FormMetadata.prototype = {
_getTagName : function(e) {
var t = e.tagName;
return "string" == typeof t || "string" == typeof (t = e.nodeName) ? t : void 0
},
_getNameOrId : function(e) {
return e.name && e.name.length ? e.name : e.id
},
controlUniqueID : function(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
},
_searchForLabelsAboveCell : function(e, t) {
var o = window.getComputedStyle(t, null);
if (!o || "table-cell" !== o.getPropertyValue("display"))
return null;
var r = cellVisuallyAbove(t);
if (!r)
return null;
for (var n = 0, i = r.firstChild; i; i = i.traverseNextNode(r))
if (i.nodeType == Node.TEXT_NODE && i.isVisible()) {
var l = i.nodeValue,
a = e.searchReverse(l);
if (a)
return {
Distance : n,
Match : a[0],
Property : a[1],
Category : a[2],
ParentProperty : a[3]
};
n += l.length
}
return null
},
_collectStringFromNodeForPageScan : function(e, t, o) {
var r = e.nodeValue,
n = r.length;
return o + n > PageScanMaxCharactersSearched && (r = r.substr(-(PageScanCharactersSearchedThreshold - o)), n = PageScanCharactersSearchedThreshold - o), (r = r.trim()).length && t.push(r), o
},
_dataForComputingMatchFromPageScanBeforeElement : function(e, t) {
function o(e)
{
return e && e.nodeType == Node.ELEMENT_NODE && e.matches("nav")
}
var r, 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(o); u && i < PageScanCharactersSearchedThreshold; u = u.traversePreviousNode(o)) {
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 || r) {
if ("tr" === c && r)
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
r = u
}
}
return [ n, r ]
},
_matchFromPageScanBeforeElement : function(e, t, o) {
var r = this._pageScanContext ? this._pageScanContext.backwardScanCache : null,
n = this._pageScanDataForElementWithCacheAndDataProducer(t, r, this._dataForComputingMatchFromPageScanBeforeElement.bind(this), o),
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
},
_isElementFollowedByForgotUserNameOrEmailAffordance : function(e, t) {
this._forgotUserNameRegularExpressions || (this._forgotUserNameRegularExpressions = regularExpressionsFromStrings(FormMetadataJSController.regularExpressionsForForgotUserNameAffordance)), this._forgotEmailRegularExpressions || (this._forgotEmailRegularExpressions = regularExpressionsFromStrings(FormMetadataJSController.regularExpressionsForForgotEmailAffordance));
let o = this._stringsToEvaluateToDetermineIfElementIsFollowedByAffordance(e, t);
return !!stringsMatchAnyRegularExpressions(o, this._forgotUserNameRegularExpressions) || !!stringsMatchAnyRegularExpressions(o, this._forgotEmailRegularExpressions)
},
_isElementFollowedByForgotPasswordAffordance : function(e, t) {
return this._forgotPasswordRegularExpressions || (this._forgotPasswordRegularExpressions = regularExpressionsFromStrings(FormMetadataJSController.regularExpressionsForForgotPasswordAffordance)), stringsMatchAnyRegularExpressions(this._stringsToEvaluateToDetermineIfElementIsFollowedByAffordance(e, t), this._forgotPasswordRegularExpressions)
},
_numberOfForgotUserNameEmailOrPasswordAffordancesFollowingElement : function(e, t) {
this._forgotEmailRegularExpressions || (this._forgotEmailRegularExpressions = regularExpressionsFromStrings(FormMetadataJSController.regularExpressionsForForgotEmailAffordance)), this._forgotPasswordRegularExpressions || (this._forgotPasswordRegularExpressions = regularExpressionsFromStrings(FormMetadataJSController.regularExpressionsForForgotPasswordAffordance)), this._forgotUserNameRegularExpressions || (this._forgotUserNameRegularExpressions = regularExpressionsFromStrings(FormMetadataJSController.regularExpressionsForForgotUserNameAffordance));
let o = this._stringsToEvaluateToDetermineIfElementIsFollowedByAffordance(e, t),
r = 0;
return stringsMatchAnyRegularExpressions(o, this._forgotUserNameRegularExpressions) && r++, stringsMatchAnyRegularExpressions(o, this._forgotEmailRegularExpressions) && r++, stringsMatchAnyRegularExpressions(o, this._forgotPasswordRegularExpressions) && r++, r
},
_stringsToEvaluateToDetermineIfElementIsFollowedByAffordance : function(e, t) {
let o = this._dataForComputingMatchFromPageScanAfterElement(e, "A");
if (!o.length) {
const t = e.traverseNextNode();
if (t) {
let e = t;
t instanceof Node && (e = t.parentElementIncludingShadowDOMHost());
const r = e.querySelector("a");
if (r) {
o.push(r.innerText);
const e = pathFromAnchorWithoutLeadingSlash(r);
e && o.push(e)
}
}
}
if (!o.length)
for (let r of queryAllBySelector(t, "a")) {
if (e.compareDocumentPosition(r) & Node.DOCUMENT_POSITION_FOLLOWING) {
o.push(r.innerText);
const e = pathFromAnchorWithoutLeadingSlash(r);
e && o.push(e)
}
}
const r = e._weakNextControlInLogicalForm?.deref();
return r && "button" === r.type && o.push(r.innerText), o
},
_dataForComputingMatchFromPageScanAfterElement : function(e, t, o) {
var r = [],
n = 0,
i = this._logicalFormsCache.logicalFormForControl(e);
if (!i)
return [];
var l = i.formElement,
a = l && l.isVisible();
let s = void 0 !== t;
o || (o = l);
for (var u = e.traverseNextNode(); u && n < PageScanCharactersSearchedThreshold; u = u.traverseNextNode()) {
var c = u.localName;
if (u === o) {
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, r, n), s)
break
}
}
}
return r
},
_matchFromPageScanAfterElement : function(e, t, o) {
var r = this._pageScanContext ? this._pageScanContext.forwardScanCache : null,
n = this._pageScanDataForElementWithCacheAndDataProducer(t, r, this._dataForComputingMatchFromPageScanAfterElement.bind(this), o);
return this._matchFromPatternMatcherAndStringsFromPageScan(e, n)
},
_pageScanDataForElementWithCacheAndDataProducer : function(e, t, o, r) {
if (!t)
return o(e, r);
if (n = t.get(e))
return n;
var n = o(e, r);
return t.set(e, n), n
},
_matchFromPatternMatcherAndStringsFromPageScan : function(e, t) {
for (var o = t.length, r = 0, n = 0; n < o; ++n) {
var i = t[n];
r += i.length;
var l = e.searchReverse(i);
if (l)
return
{
Distance: r,
Match: l[0],
Property: l[1],
Category: l[2],
ParentProperty: l[3]
}
}
return null
},
_matchPatternAgainstString : function(e, t) {
if (!t)
return null;
var o = t.replace(/[\d_.-]/g, " ");
return o = o.replace(/[a-z][A-Z]/g, (function(e) {
return e[0] + " " + e[1]
})),
e.longestMatch(o)
},
_controlsAreAllButtons : function(e) {
for (var t = e.length, o = 0; o < t; ++o) {
if (!(e[o] instanceof HTMLButtonElement))
return !1
}
return !0
},
_createLogicalFormsForControls : function(e, t, o) {
if (this._controlsAreAllButtons(e))
return [];
let r, n, i = e.map((function(e) {
return e.getBoundingClientRect()
})),
l = e.length,
a = 0;
i[0].isZeroRect() ? (r = 0, n = null) : (r = 1, n = i[0]);
for (let h = 1; h < l; ++h) {
let m = i[h];
if (!m.isZeroRect()) {
if (n) {
let F = n.distanceToRect(m);
F && (++r, a += F)
}
n = m
}
}
if (1 === r) {
function s(e)
{
return e.closest("header, footer, aside")
}
let f = [],
g = 0;
for (; g < l;) {
let p = [ e[g] ],
C = s(e[g]);
for (let _ = g + 1; _ < l; ++_) {
let A = e[_];
if (C !== s(e[_]))
break;
p.push(A)
}
f.push(new LogicalForm(p, t, o)), g += p.length
}
return f
}
let u = r ? a / r : 0,
c = [],
d = 0;
for (; d < l;) {
let b = [ e[d] ],
y = !1,
S = i[d].isZeroRect() ? null : i[d];
for (let T = d + 1; T < l; ++T) {
let E = e[T],
I = i[T];
if (!I.isZeroRect()) {
if (y) {
if (S && S.distanceToRect(I) > u)
break
} else
y = couldBeFormSubmissionControl(E);
S = I
}
b.push(E)
}
c.push(new LogicalForm(b, t, o)), d += b.length
}
return c
},
_formLooksLikeAspnetForm : function(e) {
const t = 3;
var o = 0;
"aspnetForm" === e.getAttribute("id") && ++o, "aspnetForm" === e.getAttribute("name") && ++o;
for (var r = queryAllBySelector(e, "input"), n = 0, i = r.length; n < i; ++n) {
var l = r[n],
a = l.getAttribute("id"),
s = l.getAttribute("name");
/ctl\d\d_/.test(a) && ++o, /ctl\d\d\$/.test(s) && ++o, "hidden" === l.getAttribute("type") && ("__VIEWSTATE" === s && "__VIEWSTATE" === a || "__EVENTTARGET" === s && "__EVENTTARGET" === a || "__EVENTARGUMENT" === s && "__EVENTARGUMENT" === a || "__LASTFOCUS" === s && "__LASTFOCUS" === a) && ++o
}
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 || ++o
}
}
return o >= t
},
_anchorLooksLikeSubmitButton : function(e) {
return /submit|button/i.test(e.getAttribute("id"))
},
_visibleInputAndSelectElementsInForm : function(e) {
let t = queryAllBySelector(e, "input:not([type='hidden']), select"),
o = [];
for (var r = 0, n = t.length; r < n; ++r) {
let e = t[r];
e.isVisible() && o.push(e)
}
return o
},
_elementsActingAsButtonsInForm : function(e) {
let t = Array.prototype.slice.call(queryAllBySelector(e, "input[type='submit'], input[type='image']")),
o = queryAllBySelector(e, "a");
for (var r = 0, n = o.length; r < n; ++r) {
let e = o[r];
this._anchorLooksLikeSubmitButton(e) && e.isVisible() && t.push(e)
}
return t
},
_logicalFormsForAspnetForm : function(e) {
function t(e)
{
var o = e.length;
if (o <= 1)
a.push(new LogicalForm(e, ForceNonFormElementAsLogicalBackingElement.Yes));
else {
var r = o - 1,
n = e[r];
if (e[0].closestCommonAncestor(n) instanceof HTMLTableRowElement) {
for (var i = 0; i < r; ++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 o = this._visibleInputAndSelectElementsInForm(e), r = o.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 o = e._aspNetIDComponents || [];
return (t._aspNetIDComponents || []).length - o.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 = r - 1; m >= 0; --m) {
var F = o[m],
f = F.getAttribute("id");
f && (f.startsWith(d) && (h.push(F), o.splice(m, 1)))
}
if (h.length && t(h.reverse()), !(r = o.length))
break
}
}
}
return r && t(o), a
},
_logicalFormsInPage : function(e, t) {
let o = [];
const r = document.querySelector("form form");
let n = {},
i = r ? document.forms : queryAllBySelector(document, "form"),
l = 0,
a = i.length,
s = new Set;
for (var u = 0; u < a; ++u) {
let a = i[u],
c = r ? a.elements : queryAllBySelector(a, "input, select, textarea, button, fieldset");
for (let e of c)
s.add(e);
if (c.length) {
if (l++, e && l >= e)
return o;
if (t) {
let e = [ a.method, a.name, a.action, a.className ].join("|"),
o = n[e] || 0;
if (o > t)
continue;
n[e] = o + 1
}
this._formLooksLikeAspnetForm(a) ? o = o.concat(this._logicalFormsForAspnetForm(a)) : o.push(new LogicalForm(c))
}
}
let c = [],
d = queryAllBySelector(document, "input, select, textarea, button"),
h = d.length;
for (let e = 0; e < h; ++e) {
let t = d[e];
if (s.has(t)) {
if (!c.length)
continue;
o = o.concat(this._createLogicalFormsForControls(c)), c = []
} else
(this._isRenderedFormControl(t) || autocompleteTokens(t)) && c.push(t)
}
c.length && (o = o.concat(this._createLogicalFormsForControls(c)));
let m = o.length;
for (u = 0; u < m - 1; ++u) {
let e = o[u],
t = e.backingElement,
r = t.getBoundingClientRect(),
n = o[u + 1],
i = n.backingElement,
l = i.getBoundingClientRect();
const a = 40;
if (t.nextElementSibling === i && t.action === i.action && r.height && l.height && r.x === l.x && r.width === l.width && r.bottom + a >= l.top) {
let t = 1 === e.elements.filter((function(e) {
return e.isVisible()
}))
.length,
r = e.elements.includes((function(e) {
return e.matches("input[type=submit], button") && e.isVisible()
}));
if (t && !r) {
let t = e.elements.concat(n.elements),
r = this._createLogicalFormsForControls(t, ForceNonFormElementAsLogicalBackingElement.Yes, LogicalFormCreationIsProvisional.Yes);
if (1 === r.length) {
let e = r[0];
e.markElementsAsPartOfLogicalForm(), o.splice(u, 2, e), m--
}
}
}
}
return o
},
_matchPatternAgainstElement : function(e, t, o) {
function r(e, t)
{
if (!e)
return null;
var r = o[t],
n = sharedPrefixLength(r, e[t]);
return n ? r.substr(n) : null
}
function n(e, t)
{
if (!t)
return null;
const o = t.text;
if (/^-.+-$/.test(o))
return o;
if (!t.value.length && o.length) {
const r = e.options,
n = r.length;
let i = !0;
for (let e = 0; e < n; ++e) {
const o = r[e];
if (o !== t && !o.value.length) {
i = !1;
break
}
}
if (i)
return o
}
return null
}
this._logicalFormsCache.logicalFormForControl(o);
var i = o._weakPreviousControlInLogicalForm?.deref(),
l = o._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] = r(i, h), c[d] = r(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, o[a[d]])); ++d)
;
const r = "select" === this._getTagName(o).toLowerCase();
if (!f && r) {
const e = r ? defaultOptionForSelectElement(o) : null,
t = r ? o.options[0] : null;
let i = n(o, e);
i || e === t || (i = n(o, 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 : function(e) {
if (e._cachedLabels)
return e._cachedLabels;
e._cachedLabels = [];
let t = e.getAttribute("aria-labelledby");
if (t && t.length) {
let r = t.split(" ");
for (var o = 0; o < r.length; o++) {
let t = getElementByID(r[o]);
t && e._cachedLabels.push(t)
}
}
if (e._cachedLabels.length)
return e._cachedLabels;
let r = 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 o = [],
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 = r(n);
e.length > 0 && e === r(t) && o.push(i)
}
}
}
if (0 === e._cachedLabels.length && 1 === o.length && (e._cachedLabels = o), 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 : function(e, t, o = !1) {
function r(e, o)
{
for (var r = 0; r < l; ++r) {
var n = t[r].searchReverse(e);
if (n && (i.push({
FoundByPageScan : !1,
Match : n[0].toLowerCase(),
Property : n[1],
Category : n[2],
ParentProperty : n[3],
Priority : r
}),
o === 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 : _.Match.toLowerCase(),
Property : _.Property,
Category : _.Category,
ParentProperty : _.ParentProperty,
Priority : y
}
: 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, r(c, ShouldStopAfterFirstMatch.StopAfterFirstMatch))
}
let d = placeholderInfoForElement(e);
d && !d.AttributeMatchedWasValue && r(d.Text, ShouldStopAfterFirstMatch.StopAfterFirstMatch);
var h = e.getAttribute("title");
h && r(h, ShouldStopAfterFirstMatch.StopAfterFirstMatch);
var m = this._labelForElementIfElementAndLabelAreOnlyElementsOfTheirKindAmongSiblingElements(e);
m?.innerText.length && (a = !0, r(m.innerText, ShouldStopAfterFirstMatch.CollectAllMatches));
let F = this._ariaLabelForElementOrParentOfElement(e);
F && r(F, ShouldStopAfterFirstMatch.StopAfterFirstMatch);
var f = e.getAttribute("formcontrolname");
f && f.length && r(f, ShouldStopAfterFirstMatch.StopAfterFirstMatch);
var g = this._pageScanContext,
p = !0,
C = !1;
if (g && (g.shouldUsePageScan && (p = g.shouldUsePageScan()), g.reportPageScanUsedSuccessfully && (C = !0)), !p)
return i;
if (a)
return C && g.reportPageScanUsedSuccessfully(!1), i;
if (!0 === o)
return i;
for (var _, A = null, b = null, y = 0; y < l; ++y)
A = n(_ = this._matchFromPageScanBeforeElement(t[y], e), A), g && g.forwardScanIsFutile || (b = n(_ = this._matchFromPageScanAfterElement(t[y], e), b));
var S = !1;
if (A && (i.push(A), S = !0), b)
for (var T = 0, E = i.length; T < E; ++T) {
var I = i[T];
if (b.Priority === I.Priority) {
i.push(b), S = !0;
break
}
}
return C && g.reportPageScanUsedSuccessfully(S), i.length && d && d.AttributeMatchedWasValue && r(d.Text, ShouldStopAfterFirstMatch.StopAfterFirstMatch), i
},
_bestMatchFromMatches : function(e) {
function t(e, t)
{
for (var o = e.length, r = {}, n = 0; n < o; ++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
}
r[i] ? r[i].Frequency += 1 : r[i] = {
Frequency : 1,
FirstMatchObject : l
}
}
var a = [];
for (var s in r)
a.push(r[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 r)
return u[n].FirstMatchObject
}
return u[0].Frequency > u[1].Frequency ? u[0].FirstMatchObject : void 0
}
var o = e.length;
if (0 === o)
return null;
if (1 === o)
return e[0];
var r = t(e, MatchCriteria.Property);
return r || ((r = t(e, MatchCriteria.Category)) ? r : e.sort((function(e, t) {
return e.Priority - t.Priority
}))[0])
},
_bestMatchForElement : function(e, t, o = !1) {
if (!e)
return null;
var r = this._matchesForElement(e, t, o);
return this._bestMatchFromMatches(r, e, t)
},
_labelForElementIfElementAndLabelAreOnlyElementsOfTheirKindAmongSiblingElements : function(e) {
for (var t = null, o = e.tagName, r = siblingsIncludingSelfForElement(e), n = r.length, i = 0; i < n; ++i) {
var l = r[i];
if (e !== l) {
if (o === l.tagName)
return null;
if (this._isLabelElement(l)) {
if (t)
return null;
t = l
}
}
}
return t
},
_ariaLabelForElementOrParentOfElement : function(e) {
var t = e;
let o = 3;
for (var r = 0; r < o && t; ++r) {
let e = t.getAttribute("aria-label");
if (e && !t.isHiddenFromAccessibilityTree())
return e;
t = t.parentElementIncludingShadowDOMHost()
}
return null
},
_cachedOneTimeCodePatternMatcher : function() {
return this._cachedPatternMatchers("oneTimeCodeFieldLabelPatternMatchers")[0]
},
_cachedPatternMatchers : function(e) {
let t = "_" + e,
o = this[t];
return o || (this[t] = FormMetadataJSController[e], o = this[t]), o
},
_cachedElementPatternMatch : function(e, t, o) {
var r = t + "_wasVisible",
n = e[r];
if (!0 === n)
return e[t];
var i = e.isVisible();
if (n === i)
return e[t];
e[r] = i;
let l = this._cachedPatternMatchers(o);
return e[t] = this._bestMatchForElement(e, l), e[t]
},
_isLabeledUsernameField : function(e) {
return !!this._isAutoFillableTextField(e) && null !== this._cachedElementPatternMatch(e, "_usernameFieldPatternMatch", "usernameFieldLabelPatternMatchers")
},
_isLabeledLoginField : function(e) {
return !!this._isAutoFillableTextField(e) && null !== this._cachedElementPatternMatch(e, "_loginFieldPatternMatch", "loginFormTypePatternMatchers")
},
_isLabeledSignUpField : function(e) {
return !!this._isAutoFillableTextField(e) && null !== this._cachedElementPatternMatch(e, "_signUpFieldPatternMatch", "newAccountFormTypePatternMatchers")
},
_isLabeledEmailField : function(e) {
return !!this._isAutoFillableTextField(e) && ("email" === e.type || null !== this._cachedElementPatternMatch(e, "_emailFieldPatternMatch", "emailFieldLabelPatternMatchers"))
},
_addressBookLabelForElement : function(e) {
if (!this._isAutoFillableTextField(e) && !this._isAutoFillableSelectElement(e) && !this._isAutoFillableTextAreaElement(e))
return null;
var t = this._cachedElementPatternMatch(e, "_addressBookPatternMatch", "addressBookFieldLabelPatternMatchers");
return t ? t.Match : null
},
_elementDisallowsAutocomplete : function(e) {
var t = e.getAttribute("autocomplete");
return t && "off" === t.toLowerCase()
},
_isTextArea : function(e) {
return e instanceof HTMLTextAreaElement
},
_isSelectElement : function(e) {
return e instanceof HTMLSelectElement
},
_isLabelElement : function(e) {
return e instanceof HTMLLabelElement
},
_isRenderedFormControl : function(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
}
|| e instanceof HTMLInputElement && (!!this._isElementAHiddenUsername(e) || (!e.type || "hidden" !== e.type))
},
_isEditablePlainTextField : function(e) {
return !!isInputElement(e) && (!e.disabled && !e.readOnly && (!e.type || "text" === e.type))
},
_isTextField : function(e) {
if (this._isTextArea(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
};
var o = e.type;
return !o || o in t
},
_isAutofocusedTextField : function(e) {
return !!this._isTextField(e) && !0 === e.autofocus
},
_isAutoFilledTextField : function(e) {
return !!this._isTextField(e) && e.matches(":-webkit-autofill")
},
_isSecureTextField : function(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"),
o = e.type;
if ("none" !== t || "password" === o)
return e._wasPreviouslySecureTextField = !0, !0;
if (o && "text" !== o)
return !1;
const r = e._weakNextControlInLogicalForm?.deref();
return !(!r || !this._looksLikeShowHidePasswordButton(r)) && (!!this._matchesPasswordFieldLabelPattern(e) && (e._wasPreviouslySecureTextField = !0, !0))
},
_isVerticalWritingMode : function(e) {
const t = getComputedStyle(e).writingMode;
return !("horizontal-tb" === t || "horizontal-bt" === t)
},
_looksLikePasswordCredentialField : function(e) {
if (!this._isSecureTextField(e))
return !1;
var t = e.getAttribute("maxlength");
return !(t && parseInt(t) < MinValueForMaxLengthAttributeToTreatAsPasswordField) && null === this._cachedElementPatternMatch(e, "_nonAccountPasswordSecureTextEntryFieldPatternMatch", "nonAccountPasswordSecureTextEntryFieldLabelPatternMatchers")
},
_looksLikeShowHidePasswordButton : function(e) {
return !(!this._isCustomFormButton(e) && !this._isCheckboxInputElement(e)) && !!this._cachedElementPatternMatch(e, "_showHideButtonPatternMatch", "showHideButtonLabelPatternMatchers")
},
_isAutoFillable : function(e) {
return !e.disabled && !e.readOnly
},
_isAutoFillableSelectElement : function(e) {
return this._isAutoFillable(e) && this._isSelectElement(e)
},
_isAutoFillableTextAreaElement : function(e) {
return this._isAutoFillable(e) && this._isTextArea(e)
},
_isAutoFillableTextField : function(e) {
return this._isAutoFillable(e) && this._isTextField(e)
},
_looksLikeCreditCardNumberField : function(e, t) {
if (!this._isAutoFillableTextField(e))
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 r = new RegExp("[0-9]{4}[ -][0-9]{4}[ -][0-9]{4}[ -][0-9]{4}");
if (o && r.test(o))
return !0;
let n = e.getAttribute("data-val-regex-pattern");
if (n) {
let e = regularExpressionFromUntrustedPatternAttributeString(n);
if (e && !e.test("12345"))
return !1
}
return null !== this._cachedElementPatternMatch(e, "_creditCardNumberPatternMatch", "creditCardNumberFieldLabelPatternMatchers")
},
_looksLikeCreditCardSecurityCodeField : function(e, t) {
if (!this._isAutoFillableTextField(e))
return !1;
if (elementIDOrAutocompleteTokensHasToken(e, t, "cc-csc"))
return !0;
let o = e.getAttribute("pattern");
if (o) {
let e = regularExpressionFromUntrustedPatternAttributeString(o);
if (e && !e.test("123") && !e.test("1234"))
return !1
}
return null !== this._cachedElementPatternMatch(e, "_creditCardSecurityCodePatternMatch", "creditCardSecurityCodeFieldLabelPatternMatchers")
},
_looksLikeCreditCardCardholderField : function(e, t) {
return !!this._isEditablePlainTextField(e) && (!!elementIDOrAutocompleteTokensHasToken(e, t, "cc-name") || null !== this._cachedElementPatternMatch(e, "_creditCardCardholderPatternMatch", "creditCardCardholderFieldLabelPatternMatchers"))
},
_looksLikeCreditCardCompositeExpirationDateField : function(e, t) {
return !(!this._isAutoFillableTextField(e) || this._isSecureTextField(e)) && (!!elementIDOrAutocompleteTokensHasToken(e, t, "cc-exp") || this._matchesCreditCardCompositeExpirationDateFieldLabelPatternMatchers(e))
},
_matchesCreditCardCompositeExpirationDateFieldLabelPatternMatchers : function(e) {
return null !== this._cachedElementPatternMatch(e, "_creditCardCompositeExpirationDateFieldPatternMatch", "creditCardCompositeExpirationDateFieldLabelPatternMatchers")
},
_looksLikeCreditCardTypeField : function(e, t) {
return !(!this._isSelectElement(e) && !isRadioButtonElement(e)) && (!!elementIDOrAutocompleteTokensHasToken(e, t, "cc-type") || null !== this._cachedElementPatternMatch(e, "_creditCardTypePatternMatch", "creditCardTypeFieldLabelPatternMatchers"))
},
_looksLikeEIDField : function(e, t) {
return !!elementIDOrAutocompleteTokensHasToken(e, t, "device-eid")
},
_looksLikeIMEIField : function(e, t) {
return !!elementIDOrAutocompleteTokensHasToken(e, t, "device-imei")
},
_looksLikeDayField : function(e) {
return !(!this._isAutoFillableTextField(e) && !this._isAutoFillableSelectElement(e)) && null !== this._cachedElementPatternMatch(e, "_dayFieldPatternMatch", "dayFieldLabelPatternMatchers")
},
_looksLikeMonthField : function(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 o = e.options.length;
if (12 === o || 13 === o)
for (var r = [ selectElementOptionsSequenceAnalysis(e, "text"), selectElementOptionsSequenceAnalysis(e, "value") ], n = r.length, i = 0; i < n; i++) {
var l = r[i],
a = l.lengthOfLongestSequence,
s = l.lastNumberInSequence;
if (a >= 11 && 12 === s)
return !0
}
return !1
},
_looksLikeYearField : function(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 o = selectElementOptionsSequenceAnalysis(e, "text"),
r = o.lengthOfLongestSequence,
n = o.lastNumberInSequence;
const i = 3;
return r >= e.options.length - i && 1e3 < n && n < 3e3
},
_looksLikeOneTimeCodeField : function(e, t, o, r, n, i) {
if (!this._isAutoFillableTextField(e) && !this._isAutoFillableSelectElement(e))
return !1;
if (elementIDOrAutocompleteTokensHasToken(e, t, "one-time-code"))
return !0;
const l = e.type;
if ("password" === l) {
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;
var a = e.getAttribute("maxlength");
if (a && parseInt(a) > MaxLengthForFieldAboveWhichToTreatPotentialOneTimeCodeFieldAsRequiringHigherScrutiny) {
if (!n)
return !1;
if (i.ControlLooksLikeIgnoredDataTypeField || i.ControlLooksLikeCreditCardCardholderField || i.ControlLooksLikeCreditCardNumberField || i.ControlLooksLikeCreditCardSecurityCodeField || i.ControlLooksLikeCreditCardTypeField || i.AddressBookLabel)
return !1
}
let s = e.pattern;
if (s) {
let e = regularExpressionFromUntrustedPatternAttributeString(s);
if (e && (e.test("1234") || e.test("123456") || e.test("12345678")) && !e.test("a") && !e.test("A"))
return !0
}
const u = "number" === l || "tel" === l,
c = a ? parseInt(a) : void 0;
if (1 === c) {
if (u || o || r)
return !0;
const t = this._cachedOneTimeCodePatternMatcher(),
n = e.closest("fieldset"),
i = n?.querySelector("legend"),
l = n ? Array.from(n.querySelectorAll("input")) : [],
a = e === l[0];
if (i && a && this._matchPatternAgainstString(t, i.innerText))
return !0;
const s = l.length;
if ((6 === s || 8 === s) && a && l.every((e => 1 === parseInt(e.maxLength))))
return !0
}
const d = null !== this._cachedElementPatternMatch(e, "_weakOneTimeCodePatternMatch", "weakOneTimeCodeFieldLabelPatternMatchers");
if (u && d)
return !0;
const h = e.placeholder;
if (h && d && /^[#]+$/.test(h.replace(/ /g, "")))
return !0;
if ((4 === c || 6 === c) && d)
return !0;
if (7 === c && h && /\d{3} \d{3}/.test(h))
return !0;
if (this._isAutofocusedTextField(e)) {
if (d)
return !0;
if ("0" === e.min && "9" === e.max)
return !0
}
if (n) {
let t = 0;
d && t++, o && t++, r && t++;
const n = this._cachedOneTimeCodePatternMatcher(),
i = this._logicalFormsCache.logicalFormForControl(e);
if (i) {
const e = i.backingElement;
if (e) {
const o = e.querySelector("h1, h2, h3");
if (o && this._matchPatternAgainstString(n, o.innerText))
t++;
else {
const o = e.closest("section")?.querySelector("h1, h2, h3");
o && this._matchPatternAgainstString(n, o.innerText) && t++
}
}
}
const l = e.dataset.valRequired;
if ("string" == typeof l && this._matchPatternAgainstString(n, l) && t++, t >= 2)
return !0;
const a = function(e) {
if (this._matchPatternAgainstString(n, e))
return !0;
const t = e.replaceAll("-", " ");
return e !== t && this._matchPatternAgainstString(n, t)
}.bind(this), s = window.location.protocol, u = "http:" === s || "https:" === s, c = lastPathComponentFromAnchor(window.location);
if (u && c && a(c))
return !0;
{
const e = document.querySelector("link[rel=canonical]"),
t = e ? lastPathComponentForURLString(e.href) : null;
if (t && a(t))
return !0
}
if (this._matchFromPageScanBeforeElement(n, e, document.body))
return !0
}
return !1
},
_looksLikeIgnoredDataTypeField : function(e, t) {
return !!this._isAutoFillableTextField(e) && (!t?.length && null !== this._cachedElementPatternMatch(e, "_ignoredDataTypePatternMatch", "ignoredDataTypeFieldLabelPatternMatchers"))
},
_collectTextSample : function(e) {
if (!e)
return "";
var t, o = "",
r = e;
do {
t = (o = r.innerText.replace(/\s+/g, " ").trim()).length, r = r.parentElementIncludingShadowDOMHost()
} while (t < MaximumNumberOfCharactersToCollectForLanguageIdentification && r);
return t > MaximumNumberOfCharactersToCollectForLanguageIdentification && (o = o.substr(0, MaximumNumberOfCharactersToCollectForLanguageIdentification)), o
},
_explicitMaxLength : function(e) {
var t = e.getAttribute("maxlength");
return t ? parseInt(t) : void 0
},
_explicitMinLength : function(e) {
let t = e.getAttribute("minlength");
return t ? parseInt(t) : void 0
},
_observedMaxLength : function(e) {
const t = 20;
if ("password" !== e.type)
return null;
const o = e.getAttribute("ng-pattern");
if (!o)
return null;
if (!o.startsWith("/") || !o.endsWith("/"))
return null;
let r = regularExpressionFromUntrustedPatternAttributeString(o);
if (!r)
return null;
let n, i = "a1Abbb",
l = !1;
for (; i.length <= t;) {
let e = r.test(i);
if (l && !e)
return n;
e && (l = !0, n = i.length), i += "b"
}
return null
},
_collectControlMetadata : function(e, t, o, r, n, i, l) {
var a = {
ControlTagName : this._getTagName(e),
ControlFieldName : this._getNameOrId(e),
ControlUniqueID : this.controlUniqueID(e)
};
e === innermostActiveElement() && (a.ControlIsActiveElement = !0), this._isAutoFilledTextField(e) && (a.ControlIsAutoFilledTextField = !0), e.disabled && (a.ControlIsDisabled = !0), e.readOnly && (a.ControlIsReadOnly = !0), this._isTextField(e) && (a.ControlIsTextField = !0), this._isSecureTextField(e) && (a.ControlIsSecureTextField = !0), this._isLabeledUsernameField(e) && (a.ControlIsLabeledUsernameField = !0), this._elementDisallowsAutocomplete(e) && (a.DisallowsAutocomplete = !0), this._isAutofocusedTextField(e) && (a.ControlIsAutofocusedTextField = !0);
const s = e.className;
s && s.length && (a.ControlFieldClass = s);
const u = e.id;
u && u.length && (a.ControlFieldID = u);
const c = e.value;
c && (a.ControlValue = c);
const d = this._associatedUsernameForControl(e);
d && (a.ControlAssociatedUsername = d);
const h = e.maxLength;
if (-1 !== h)
a.ControlMaxLength = h;
else {
const t = this._observedMaxLength(e);
t && (a.ControlMaxLength = t)
}
const m = this._explicitMinLength(e);
m && m > 0 && (a.ControlMinLength = m);
const F = e.size;
F > 0 && (a.ControlSize = F), e.isVisible() && (a.IsVisible = !0), isDateTimeInputElement(e) && (a.ControlRequiredFormatForDateTimeInput = this._requiredFormatForDateTimeInput[e.type]);
var f = autocompleteTokens(e);
f && (a.AutocompleteTokens = f, -1 !== f.indexOf("username") ? a.ControlClaimsToBeUsernameViaAutocompleteAttribute = !0 : -1 !== f.indexOf("current-password") ? a.ControlClaimsToBeCurrentPasswordViaAutocompleteAttribute = !0
: -1 !== f.indexOf("new-password") && (a.ControlClaimsToBeNewPasswordViaAutocompleteAttribute = !0)),
this._looksLikePasswordCredentialField(e) && (a.ControlLooksLikePasswordCredentialField = !0, "function" == typeof this._collectExtraControlMetadata && this._collectExtraControlMetadata(e, a), a.IsVisible && !o && (a.IsVisible = !isElementPositionedToBeEffectivelyInvisible(e)));
let g = t === WBSFormMetadataRequestPreFill,
p = a.ControlIsActiveElement || !g;
if (p) {
const t = this._collectSelectElementInfo(e);
t && (a.SelectElementInfo = t), this._isVerticalWritingMode(e) && (a.ControlIsVerticalWritingMode = !0);
var C = placeholderInfoForElement(e);
C && !C.AttributeMatchedWasValue && (a.ControlPlaceholder = C.Text)
}
if (this._looksLikeIgnoredDataTypeField(e, f) ? a.ControlLooksLikeIgnoredDataTypeField = !0 : this._looksLikeCreditCardCardholderField(e, f) ? a.ControlLooksLikeCreditCardCardholderField = !0
: this._looksLikeCreditCardNumberField(e, f) ? a.ControlLooksLikeCreditCardNumberField = !0
: this._looksLikeCreditCardSecurityCodeField(e, f) ? a.ControlLooksLikeCreditCardSecurityCodeField = !0
: this._looksLikeCreditCardTypeField(e, f) && (a.ControlLooksLikeCreditCardTypeField = !0),
p && (this._looksLikeMonthField(e, f) ? a.ControlLooksLikeMonthField = !0 : this._looksLikeYearField(e, f) ? a.ControlLooksLikeYearField = !0
: this._looksLikeDayField(e) ? a.ControlLooksLikeDayField = !0
: !a.ControlLooksLikeCreditCardSecurityCodeField && this._looksLikeCreditCardCompositeExpirationDateField(e, f) && (a.ControlLooksLikeCreditCardCompositeExpirationDateField = !0)),
g || (this._looksLikeEIDField(e, f) ? a.ControlLooksLikeEIDField = !0 : this._looksLikeIMEIField(e, f) && (a.ControlLooksLikeIMEIField = !0)), g || a.ControlLooksLikeIgnoredDataTypeField || a.ControlIsSecureTextField || a.ControlLooksLikeCreditCardNumberField || a.ControlLooksLikeCreditCardSecurityCodeField || a.ControlLooksLikeCreditCardTypeField || a.ControlLooksLikeCreditCardCompositeExpirationDateField || a.ControlLooksLikeEIDField || a.ControlLooksLikeIMEIField || (a.AddressBookLabel = this._addressBookLabelForElement(e)), a.ControlIsActiveElement || t === WBSFormMetadataRequestTesting || l) {
let t = i && a.IsVisible;
this._looksLikeOneTimeCodeField(e, f, r, n, t, a) && (a.ControlLooksLikeOneTimeCodeField = !0)
}
return a
},
_usesGeneratedPassword : function(e) {
for (var t = !1, o = this._elementsWithGeneratedPasswords.length, r = 0; r < o; ++r) {
var n = this._elementsWithGeneratedPasswords[r];
if (e.containsControl(n)) {
if (n.value !== this._generatedPasswords[r])
return !1;
t = !0
}
}
return t
},
_associatedUsernameForControl : function(e) {
return this._isAutoFillableTextField(e) ? e.getAttribute("data-username") : null
},
_collectSelectElementInfo : function(e) {
if (!this._isAutoFillableSelectElement(e))
return null;
if (!e.options.length)
return null;
for (var t = [], o = e.options, r = o.length, n = 0; n < r; ++n) {
var i = o[n];
i.disabled || (i.label || i.text) && t.push([ n, i.label ? i.label : i.text ])
}
return t.length ? t : null
},
_stringsToInspectForDeterminingFormType : function(e) {
let t = [],
o = e.formElement,
r = o.getAttribute("id"),
n = o.getAttribute("name");
r && t.push(r), n && t.push(n);
let i = queryAllBySelector(o, "legend");
1 === i.length && t.push(i[0].innerText);
let l = 0;
for (let e of this._logicalFormsCache.allForms())
e.formElement.isVisible() && l++;
const a = .8;
if (1 === l && o.isVisible() && !o.ownerDocument.defaultView.frameElement && o.getBoundingClientRect().top < a * document.documentElement.clientHeight) {
let e = documentTitleWithoutHostNamePrefix();
e && t.push(e);
const o = lastPathComponentFromAnchor(window.location);
o && o.length && t.push(o)
}
let s = [];
if (o.isVisible()) {
const e = function(e, t) {
return t.left <= e.left && e.right <= t.right && e.distanceToRect(t) < 100 || e.left - t.left == t.right - e.right && e.distanceToRect(t) < 200
};
let r = o.getBoundingClientRect(),
n = !1;
for (let i = 0, l = o; i <= 2 && l; ++i, l = l.parentElementIncludingShadowDOMHost()) {
let o = Array.prototype.slice.call(queryAllBySelector(l, "h1, h2, h3, [class*='header' i], [class*='heading' i]")),
i = [
[],
[],
[],
[]
];
for (headerElement of o) {
let e = headerElement.tagName;
"H1" === e ? i[0].push(headerElement) : "H2" === e ? i[1].push(headerElement)
: "H3" === e ? i[2].push(headerElement)
: i[3].push(headerElement)
}
let a = !0;
for (headerElementsOfType of i) {
let o = headerElementsOfType.length;
if (0 === o) {
a = !1;
continue
}
if (o > 1)
break;
let i = headerElementsOfType[0];
if (!i.isVisible())
break;
e(i.getBoundingClientRect(), r) && (t.push(i.innerText), n = !0);
break
}
if (a)
break
}
if (!n) {
let o = queryAllBySelector(document.documentElement, "h1");
if (1 === o.length) {
let n = o[0];
e(n.getBoundingClientRect(), r) && t.push(n.innerText)
}
}
for (let e = 0, t = o; e <= 2 && t; ++e, t = t.parentElementIncludingShadowDOMHost()) {
let e = Array.prototype.slice.call(queryAllBySelector(t, "button, input[type=submit]")).filter((function(e) {
if (!e.isVisible())
return !1;
let t = e.getBoundingClientRect();
return t.top > r.bottom && !o.contains(e) && r.left <= t.left && t.right <= r.right && t.distanceToRect(r) < 100
}));
if (e.length) {
s = e;
break
}
}
}
let u = !1,
c = [],
d = e.elements.concat(s);
for (const e of d) {
const o = e.type;
"password" === o && (u = !0), "submit" !== o && "button" !== o || u && (e.isVisible() ? this._addInterestingStringsForButton(e, t) : c.push(e))
}
if (0 === t.length)
for (control of c)
this._addInterestingStringsForButton(control, t);
return t
},
_addInterestingStringsForButton : function(e, t) {
const o = e.getAttribute("id");
o && t.push(o);
const r = e.getAttribute("value");
r && t.push(r);
const n = e.innerText;
n && n.length > 0 && t.push(n)
},
_autoFillFormTypeOfTypesUsingKeywordMatching : function(e, t, o, r) {
for (var n = t.length, i = [], l = 0; l < n; ++l) {
var a = (0, mapOfFormTypeToProducerOfAssociatedKeywords[t[l]])();
i.push(a)
}
var s = this._stringsToInspectForDeterminingFormType(e),
u = this._keywordsIndicatingNonAutoFillableFormType;
u || (u = FormMetadataJSController.keywordsIndicatingNonAutoFillableFormType, this._keywordsIndicatingNonAutoFillableFormType = u);
var c = u.length,
d = [];
for (l = 0; l < n; ++l)
d.push(0);
if (r)
for (const [e, o] of Object.entries(r))
d[t.indexOf(parseInt(e))] += o;
for (var h = s.length, m = 0; m < h; ++m) {
for (var F = s[m].toLowerCase(), f = 0; f < c; ++f)
if (-1 !== F.indexOf(u[f]))
return WBSAutoFillFormTypeNonAutoFillable;
for (l = 0; l < n; ++l) {
a = i[l];
for (var g in a)
-1 !== F.indexOf(g) && (d[l] += a[g])
}
}
for (let o = 0; o < n; ++o) {
const r = this._mapOfFormTypeToExtraScoreProducer[t[o]];
d[o] += r(e)
}
for (l = 0; l < n; ++l)
0 !== d[l] && 0;
var p = formActionAsAnchorElement(e.formElement, !0);
if (p) {
var C = p.pathname.toLowerCase() + p.search.toLowerCase();
for (l = 0; l < n; ++l) {
a = i[l];
for (var g in a)
-1 !== C.indexOf(g) && (d[l] += a[g])
}
}
var _ = [],
A = 0;
for (l = 0; l < n; ++l) {
var b = d[l];
b > 0 && (b >= A ? (A = b, _.unshift(l)) : _.push(l))
}
if (1 === _.length)
return t[_[0]];
if (_.length > 1) {
var y = _[0];
if (d[y] > d[_[1]])
return t[y]
}
return o
},
_matchesNonUsernameFieldLabelPattern : function(e) {
if (this._nonUsernameFieldPatternMatchers || (this._nonUsernameFieldPatternMatchers = FormMetadataJSController.nonUsernameFieldLabelPatternMatchers), this._bestMatchForElement(e, this._nonUsernameFieldPatternMatchers))
return !0;
const t = e.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 : function(e) {
if (this._searchFieldLabelPatternMatchers || (this._searchFieldLabelPatternMatchers = FormMetadataJSController.searchFieldLabelPatternMatchers), this._bestMatchForElement(e, this._searchFieldLabelPatternMatchers, !0))
return !0;
const t = e.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 : function(e) {
return this._nonEmailFieldPatternMatchers || (this._nonEmailFieldPatternMatchers = FormMetadataJSController.nonEmailFieldLabelPatternMatchers), !!this._bestMatchForElement(e, this._nonEmailFieldPatternMatchers)
},
_scoreForUsernameFieldCandidateFromLabelingAndPositionOfField : function(e, t, o) {
return this._isLabeledUsernameField(e) ? t ? UsernameCandidateScoreForUsernameLabeledFieldBelowPasswordField : UsernameCandidateScoreForUsernameLabeledFieldAbovePasswordField : this._isLabeledEmailField(e) && !this._matchesNonEmailFieldLabelPattern(e) ? t ? UsernameCandidateScoreForEmailLabeledFieldBelowPasswordField : UsernameCandidateScoreForEmailLabeledFieldAbovePasswordField
: o ? UsernameCandidateScoreForPlainTextFieldDirectlyBeforePasswordField
: UsernameCandidateScoreForPlainTextField
},
_scoreForUsernameFieldCandidate : function(e, t, o) {
var r = this._scoreForUsernameFieldCandidateFromLabelingAndPositionOfField(e, t, o);
return e.isVisible() && (r += UsernameCandidateScoreBonusForVisibleElement), this._matchesNonUsernameFieldLabelPattern(e) && (r -= UsernameCandidateScorePenaltyForMatchingNonUsernameFieldLabelPattern), this._matchSearchFieldLabelPattern(e) && (r -= UsernameCandidateScorePenaltyForMatchingSearchFieldLabelPattern), e.readOnly && (r -= UsernameCandidateScorePenaltyForReadOnlyElement), e.id || e.name || (r -= UsernameCandidateScorePenaltyForAnonymousElement), r
},
_matchesPasswordFieldLabelPattern : function(e) {
return this._passwordFieldPatternMatchers || (this._passwordFieldPatternMatchers = FormMetadataJSController.passwordFieldLabelPatternMatchers), !!this._bestMatchForElement(e, this._passwordFieldPatternMatchers)
},
_matchesConfirmPasswordFieldLabelPattern : function(e, t = !1) {
return this._confirmPasswordFieldPatternMatchers || (this._confirmPasswordFieldPatternMatchers = FormMetadataJSController.confirmPasswordFieldLabelPatternMatchers), !!this._bestMatchForElement(e, this._confirmPasswordFieldPatternMatchers, t)
},
_matchesConfirmEmailFieldLabelPattern : function(e) {
return !!this._isLabeledEmailField(e) && (this._confirmEmailFieldPatternMatchers || (this._confirmEmailFieldPatternMatchers = FormMetadataJSController.confirmEmailFieldLabelPatternMatchers), !!this._bestMatchForElement(e, this._confirmEmailFieldPatternMatchers))
},
_collectRadioButtonInfo : function(e, t) {
function o(e, t)
{
var o = e.trim();
o && t.push(o)
}
function r(e, t)
{
o(e.alt, t), o(e.title, t), o(lastPathComponentForURLString(e.src), t)
}
function n(e)
{
let t = [];
o(e.innerText, t);
let n = queryAllBySelector(e, "img"),
i = n.length;
for (let e = 0; e < i; ++e)
r(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]).value] = [ f.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.value] = s[f.value].concat(m))
}
}
if (a)
return s;
const F = 64;
for (u = 0; u < l; ++u) {
for (var f, g = "", p = (f = i[u]).traverseNextNode(); p && !this._isRenderedFormControl(p); p = p.traverseNextNode()) {
var C = p.localName;
if ("td" === C || "tr" === C || "ul" === C || "ol" === C || "dl" === C)
break;
if (p instanceof HTMLImageElement)
r(p, s[f.value]);
else if (p.nodeType === Node.TEXT_NODE) {
var _ = p.nodeValue.trim();
if (_ && (g += _.substr(0, F - g.length)), g.length >= F)
break
}
}
g && s[f.value].push(g)
}
return s
},
_bestUsernameFieldCandidate : function(e, t, o) {
var r = t.FormControls,
n = r.filter((function(e) {
return e.ControlClaimsToBeUsernameViaAutocompleteAttribute
}));
if (1 === n.length)
return n[0];
for (var i = 0, l = [], a = !1, s = r.indexOf(o), u = r.length, c = 0; c < u; ++c) {
var d = r[c];
if (d === o) {
a = !0;
continue
}
if (!d.ControlIsTextField || d.ControlIsSecureTextField)
continue;
if (t.IsVisible && !r[c].IsVisible && !d.ControlValue)
continue;
const n = 100;
let F = e[c];
if (!(F.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 r[l[0]];
default:
var f = e[s].getBoundingClientRect(),
g = {};
return l.forEach((function(t) {
g[t] = f.distanceToRect(e[t].getBoundingClientRect())
})),
r[l.sort((function(e, t) {
return g[e] - g[t]
}))[0]]
}
},
_autoFillFormTypeFromCandidateFormTypes : function(e, t, o) {
switch (t.length) {
case 1:
return t[0];
case 2:
return this._autoFillFormTypeOfTypesUsingKeywordMatching(e, [ t[0], t[1] ], o);
default:
return WBSAutoFillFormTypeAutoFillableStandard
}
},
_shouldTrustElementThatClaimsToBeCurrentPasswordViaAutocompleteAttribute : function(e) {
return !e.dataset.valRegexPattern
},
_identifyFormTypeAndPasswordFieldIndicesFromAutocompleteAttributes : function(e, t) {
const o = [ null, null ];
if (/^(.+\.)?roll20\.net\.?$/.test(document.location.hostname))
return o;
var r = t.length;
if (r > 3)
return o;
for (var n = [], i = [], l = 0; l < r; ++l) {
var a = t[l];
a.ControlClaimsToBeCurrentPasswordViaAutocompleteAttribute && this._shouldTrustElementThatClaimsToBeCurrentPasswordViaAutocompleteAttribute(e[l]) ? n.push(l) : a.ControlClaimsToBeNewPasswordViaAutocompleteAttribute && i.push(l)
}
var s = n.length,
u = i.length;
if (s + u !== r)
return o;
switch (r) {
case 0:
return o;
case 1:
if (s)
return [
[ WBSAutoFillFormTypeAutoFillableLogin ], {
PasswordFieldIndex : n[0]
}
];
if (u)
return [ null, null, WBSAutoFillFormTypeNewAccount ];
case 2:
if (1 === s && 1 === u)
return [
[ WBSAutoFillFormTypeChangePassword ], {
OldPasswordFieldIndex : n[0],
PasswordFieldIndex : i[0]
}
];
if (0 === s && 2 === u)
return [
[ WBSAutoFillFormTypeNewAccount, WBSAutoFillFormTypeChangePassword ], {
PasswordFieldIndex : i[0],
ConfirmationFieldIndex : i[1]
}
];
break;
case 3:
if (1 === s && 2 === u)
return [
[ WBSAutoFillFormTypeChangePassword ], {
OldPasswordFieldIndex : n[0],
PasswordFieldIndex : i[0],
ConfirmationFieldIndex : i[1]
}
]
}
return o
},
_identifyPasswordFieldIndices : function(e, t) {
var o = e.length;
if (0 === o)
return {};
if (1 === o)
return {
PasswordFieldIndex : 0
};
if (this._oldPasswordPatternMatchers || (this._oldPasswordPatternMatchers = FormMetadataJSController.oldPasswordFieldLabelPatternMatchers), 2 === o) {
return this._bestMatchForElement(t[0], this._oldPasswordPatternMatchers) ? {
OldPasswordFieldIndex : 0,
PasswordFieldIndex : 1
}
: this._bestMatchForElement(t[1], this._oldPasswordPatternMatchers) ? {
OldPasswordFieldIndex : 1,
PasswordFieldIndex : 0
}
: {
PasswordFieldIndex : 0,
ConfirmationFieldIndex : 1
}
}
return this._bestMatchForElement(t[o - 1], this._oldPasswordPatternMatchers) ? {
PasswordFieldIndex : o - 3,
ConfirmationFieldIndex : o - 2,
OldPasswordFieldIndex : o - 1
}
: {
PasswordFieldIndex : o - 2,
ConfirmationFieldIndex : o - 1,
OldPasswordFieldIndex : o - 3
}
},
_removePlaceholderTextForFormMetadata : function(e, t) {
for (var o = e.length, r = 0; r < o; ++r) {
var n = t.FormControls[r];
if (n.ControlValue && n.ControlIsTextField && !n.ControlIsSecureTextField && !n.ControlIsReadOnly) {
var i = legacyPlaceholderInfoForInputElement(e[r]);
i && (i.AttributeMatchedWasValue && n.ControlUniqueID === t.UsernameElementUniqueID || (n.ControlValue = ""))
}
}
},
_isPasswordConfirmPair : function(e, t) {
var o = this._matchesPasswordFieldLabelPattern(e),
r = this._matchesConfirmPasswordFieldLabelPattern(t);
return o && r
},
_trailingArgumentsForCollectControlMetadataFunction : function(e, t, o) {
let r = isElementPositionedToBeEffectivelyInvisible(e.backingElement),
n = !1,
i = !1;
if (innermostActiveElement() || t === WBSFormMetadataRequestTesting) {
let e = this._cachedOneTimeCodePatternMatcher();
if (n = !!this._matchPatternAgainstString(e, documentTitleWithoutHostNamePrefix()), o) {
let t = location.pathname.split("/"),
r = stripCommonPrefix(o.pathname.split("/"), t)[0].join("/");
r.length && (i = !!this._matchPatternAgainstString(e, r))
}
}
let l = !1;
for (let t of e.elements)
if (this._isTextField(t) && t.isVisible()) {
if (l) {
l = !1;
break
}
l = !0
}
return [ r, i, n, l ]
},
_collectFormMetadata : function(e, t) {
var o, r, n = (r = 0, {
backwardScanCache : new WeakMap,
forwardScanCache : new WeakMap,
shouldUsePageScan : function() {
return r < numberOfConsecutiveElementsWithoutSuccessfulPageScanAfterWhichPageScanIsAbandoned
},
willStartCollectingMetadataForControl : function() {
o = null
},
reportPageScanUsedSuccessfully : function(e) {
o = !(!e && !o)
},
didFinishCollectingMetadataForControl : function() {
!0 === o ? r = 0 : !1 === o && r++
}
});
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
};
this._elementDisallowsAutocomplete(i) && (l.DisallowsAutocomplete = !0), i instanceof HTMLFormElement && (l.FormIsSearchForm = this._isSearchForm(i, !0)), e.isAnnotated && (l.Annotations = e.annotations);
var a = i.getAttribute("rel");
a && "async" === a.toLowerCase() && (l.FormUsesRelAsync = !0);
let s = formActionAsAnchorElement(i);
if (s && s.href && (l.FormAction = s.href), t == WBSFormMetadataRequestCollectMetadataFromDebugMenu || t == WBSFormMetadataRequestTesting) {
let e = selectorForElement(i);
e && e.length && (l.LogicalFormElementSelector = e)
}
var u = e.elements,
c = !u.some(this._isSecureTextField.bind(this));
let [d, h, m, F] = this._trailingArgumentsForCollectControlMetadataFunction(e, t, s);
var f = 0,
g = !1,
p = [],
C = [],
_ = [],
A = [],
b = void 0,
y = void 0,
S = void 0,
T = void 0,
E = !1,
I = !1,
v = {},
P = [];
let w = !1;
for (var L = u.length, M = 0; M < L; ++M) {
var x = u[M];
if (c && !x.isVisible() && !x._relatesToCredentials)
continue;
var k = isRadioButtonElement(x),
B = x.name;
if (k && v[B])
continue;
n.willStartCollectingMetadataForControl();
const o = !w;
var U = this._collectControlMetadata(x, t, d, h, m, F, o);
if (n.didFinishCollectingMetadataForControl(), w = !0, M + 1 < L && (U.ControlNextFieldUniqueID = this.controlUniqueID(u[M + 1])), l.FormControls.push(U), P.push(x), U.IsVisible || !l.IsVisible || x._relatesToCredentials)
if (U.ControlIsActiveElement && (l.ContainsActiveElement = !0), B && k)
v[B] = 1, U.ControlValue = "", U.RadioButtonInfo = this._collectRadioButtonInfo(e, B);
else if (U.ControlIsTextField || U.SelectElementInfo)
if (!I && U.ControlLooksLikeCreditCardSecurityCodeField && (I = !0), E || !U.ControlLooksLikeCreditCardCardholderField && !U.ControlLooksLikeCreditCardNumberField) {
if (!(U.ControlLooksLikeDayField || U.ControlLooksLikeMonthField || U.ControlLooksLikeYearField || U.ControlLooksLikeCreditCardCompositeExpirationDateField)) {
if (U.ControlLooksLikePasswordCredentialField) {
if (U.ControlLooksLikeCreditCardSecurityCodeField || U.ControlLooksLikeCreditCardNumberField || U.ControlLooksLikeIgnoredDataTypeField)
continue;
x.isHiddenFromAccessibilityTree() ? (_.push(x), A.push(U)) : (p.push(x), C.push(U))
}
if (this._isLabeledEmailField(x)) {
if (++f > 2) {
g = !1;
continue
}
if (!(M + 1 < L && this._matchesConfirmEmailFieldLabelPattern(u[M + 1])))
continue;
g = !0
}
}
} else
E = !0, l.FirstCreditCardCardholderFieldOrCreditCardNumberFieldUniqueID = U.ControlUniqueID
}
!p.length && _.length && (p = _, C = A);
var D, W, N = this._identifyFormTypeAndPasswordFieldIndicesFromAutocompleteAttributes(p, C),
q = N[0],
O = N[1],
R = N[2],
V = O || this._identifyPasswordFieldIndices(C, p);
if (void 0 !== V.PasswordFieldIndex && (b = C[V.PasswordFieldIndex], l.PasswordElementUniqueID = b.ControlUniqueID, y = this._explicitMaxLength(p[V.PasswordFieldIndex])), void 0 !== V.ConfirmationFieldIndex && (S = C[V.ConfirmationFieldIndex], l.ConfirmPasswordElementUniqueID = S.ControlUniqueID, T = this._explicitMaxLength(p[V.ConfirmationFieldIndex])), void 0 !== V.OldPasswordFieldIndex) {
var H = C[V.OldPasswordFieldIndex];
l.OldPasswordElementUniqueID = H.ControlUniqueID
}
if (b && (D = this._bestUsernameFieldCandidate(P, l, b)), D ? l.UsernameElementUniqueID = D.ControlUniqueID : W = this._findHiddenUsernameElement(e, l, P), q)
l.AutoFillFormType = this._autoFillFormTypeFromCandidateFormTypes(e, q, q[0]);
else if (1 === p.length && g)
l.AutoFillFormType = this._autoFillFormTypeOfTypesUsingKeywordMatching(e, [ WBSAutoFillFormTypeNewAccount, WBSAutoFillFormTypeChangePassword ], WBSAutoFillFormTypeNewAccount);
else if (l.UsernameElementUniqueID)
switch (p.length) {
case 0:
break;
case 1:
if (I && l.UsernameElementUniqueID === l.FirstCreditCardCardholderFieldOrCreditCardNumberFieldUniqueID && C[0].ControlLooksLikeCreditCardNumberField)
break;
if (this._matchesConfirmPasswordFieldLabelPattern(p[0])) {
let t = {};
this._isElementFollowedByForgotPasswordAffordance(x, i) && (t[WBSAutoFillFormTypeAutoFillableLogin] = 2), l.AutoFillFormType = this._autoFillFormTypeOfTypesUsingKeywordMatching(e, [ WBSAutoFillFormTypeNewAccount, WBSAutoFillFormTypeChangePassword ], R || WBSAutoFillFormTypeAutoFillableLogin, t)
} else {
let t = p[0],
o = {},
r = 2 * this._numberOfForgotUserNameEmailOrPasswordAffordancesFollowingElement(t, i);
r && (o[WBSAutoFillFormTypeAutoFillableLogin] = r), l.AutoFillFormType = this._autoFillFormTypeOfTypesUsingKeywordMatching(e, [ WBSAutoFillFormTypeNewAccount, WBSAutoFillFormTypeAutoFillableLogin ], R || WBSAutoFillFormTypeAutoFillableLogin, o)
}
break;
case 2:
y === T ? l.AutoFillFormType = this._autoFillFormTypeOfTypesUsingKeywordMatching(e, [ WBSAutoFillFormTypeNewAccount, WBSAutoFillFormTypeChangePassword ], WBSAutoFillFormTypeNewAccount) : T ? this._isPasswordConfirmPair(p[0], p[1]) ? l.AutoFillFormType = this._autoFillFormTypeOfTypesUsingKeywordMatching(e, [ WBSAutoFillFormTypeNewAccount, WBSAutoFillFormTypeChangePassword ], WBSAutoFillFormTypeNonAutoFillable) : l.AutoFillFormType = WBSAutoFillFormTypeNonAutoFillable
: l.AutoFillFormType = this._autoFillFormTypeOfTypesUsingKeywordMatching(e, [ WBSAutoFillFormTypeNewAccount, WBSAutoFillFormTypeChangePassword ], WBSAutoFillFormTypeNonAutoFillable);
break;
case 3:
y === T || !T || this._isPasswordConfirmPair(p[V.PasswordFieldIndex], p[V.ConfirmationFieldIndex]) ? l.AutoFillFormType = WBSAutoFillFormTypeChangePassword : l.AutoFillFormType = WBSAutoFillFormTypeNonAutoFillable;
break;
default:
l.AutoFillFormType = WBSAutoFillFormTypeNonAutoFillable
}
else if (2 === p.length || 3 === p.length)
if (y !== T && T)
2 === p.length ? this._isPasswordConfirmPair(p[0], p[1]) ? l.AutoFillFormType = this._autoFillFormTypeOfTypesUsingKeywordMatching(e, [ WBSAutoFillFormTypeNewAccount, WBSAutoFillFormTypeChangePassword ], WBSAutoFillFormTypeNonAutoFillable) : l.AutoFillFormType = WBSAutoFillFormTypeNonAutoFillable : this._isPasswordConfirmPair(p[V.PasswordFieldIndex], p[V.ConfirmationFieldIndex]) ? l.AutoFillFormType = WBSAutoFillFormTypeChangePassword
: l.AutoFillFormType = WBSAutoFillFormTypeNonAutoFillable;
else {
let t = {};
this._isPasswordConfirmPair(p[V.PasswordFieldIndex], p[V.ConfirmationFieldIndex]) && (t[WBSAutoFillFormTypeChangePassword] = 2), l.AutoFillFormType = this._autoFillFormTypeOfTypesUsingKeywordMatching(e, [ WBSAutoFillFormTypeNewAccount, WBSAutoFillFormTypeChangePassword ], WBSAutoFillFormTypeChangePassword, t)
}
else if (1 === p.length) {
var Y = p[0];
if (this._matchesConfirmPasswordFieldLabelPattern(Y, !0)) {
let t = {};
this._isElementFollowedByForgotPasswordAffordance(x, i) && (t[WBSAutoFillFormTypeAutoFillableLogin] = 2), l.AutoFillFormType = this._autoFillFormTypeOfTypesUsingKeywordMatching(e, [ WBSAutoFillFormTypeAutoFillableLogin, WBSAutoFillFormTypeChangePassword ], WBSAutoFillFormTypeChangePassword, t)
} else if (this._matchesPasswordFieldLabelPattern(Y))
if (this._isElementFollowedByForgotPasswordAffordance(Y, i))
l.AutoFillFormType = WBSAutoFillFormTypeAutoFillableLogin;
else {
var J = [ WBSAutoFillFormTypeNewAccount, WBSAutoFillFormTypeAutoFillableLogin, WBSAutoFillFormTypeChangePassword ];
l.AutoFillFormType = this._autoFillFormTypeOfTypesUsingKeywordMatching(e, J, WBSAutoFillFormTypeNonAutoFillable), l.AutoFillFormType === WBSAutoFillFormTypeNonAutoFillable && W && (l.AutoFillFormType = WBSAutoFillFormTypeNewAccount)
}
else
l.AutoFillFormType = WBSAutoFillFormTypeNonAutoFillable
} else
0 !== p.length && (l.AutoFillFormType = WBSAutoFillFormTypeNonAutoFillable);
if (l.AutoFillFormType === WBSAutoFillFormTypeAutoFillableStandard) {
var G = null,
K = null,
z = null,
$ = 0,
j = P.length;
for (M = 0; M < j; ++M) {
x = P[M];
var Z = l.FormControls[M],
X = Z.IsVisible;
if (X && Z.ControlIsTextField && $++, $ > 1)
break;
if (x.closest("footer"))
continue;
let t = {};
this._isElementFollowedByForgotUserNameOrEmailAffordance(x, i) && (t[WBSAutoFillFormTypeAutoFillableLogin] = 2);
var Q = this._isLabeledEmailField(x);
if (X && (Z.ControlClaimsToBeUsernameViaAutocompleteAttribute || Z.ControlIsLabeledUsernameField || Q || this._isLabeledLoginField(x)) && !this._matchesNonUsernameFieldLabelPattern(x) && !this._matchSearchFieldLabelPattern(x) && !x.readOnly && "INPUT" === x.tagName && !this._isLabeledSignUpField(x)) {
let t = {};
this._isElementFollowedByForgotUserNameOrEmailAffordance(x, i) && (t[WBSAutoFillFormTypeAutoFillableLogin] = 2), this._autoFillFormTypeOfTypesUsingKeywordMatching(e, [ WBSAutoFillFormTypeNewAccount, WBSAutoFillFormTypeAutoFillableLogin ], Q ? WBSAutoFillFormTypeNewAccount : WBSAutoFillFormTypeAutoFillableLogin, t) === WBSAutoFillFormTypeAutoFillableLogin && (G = x, K = Z, z = WBSAutoFillFormTypeAutoFillableLogin)
}
const o = Z.AutocompleteTokens;
if (o) {
const r = o.includes("username"),
n = o.includes("webauthn");
if (r && n) {
G = x, K = Z, z = WBSAutoFillFormTypeAutoFillableLogin;
continue
}
r && Q && (G = x, K = Z, z = this._autoFillFormTypeOfTypesUsingKeywordMatching(e, [ WBSAutoFillFormTypeNewAccount, WBSAutoFillFormTypeAutoFillableLogin ], WBSAutoFillFormTypeAutoFillableLogin, t))
}
}
1 === $ && K && z && !controlAppearsToBePartOfPhotoTaggingInterface(G) && (l.AutoFillFormType = z, l.UsernameElementUniqueID = K.ControlUniqueID)
}
l.AutoFillFormType === WBSAutoFillFormTypeNewAccount && l.FirstCreditCardCardholderFieldOrCreditCardNumberFieldUniqueID === l.UsernameElementUniqueID && (l.UsernameElementUniqueID = void 0), !l.UsernameElementUniqueID && W && this._extractMetadataForHiddenUsernameElement(W, l, P), l.AutoFillFormType != WBSAutoFillFormTypeAutoFillableLogin && l.AutoFillFormType != WBSAutoFillFormTypeNewAccount && l.AutoFillFormType != WBSAutoFillFormTypeChangePassword && (l.UsernameElementUniqueID = void 0, l.OldPasswordElementUniqueID = void 0, l.PasswordElementUniqueID = void 0, l.ConfirmPasswordElementUniqueID = 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
}
var ee = FormMetadataJSController.shouldIncludeNonEmptyFields;
if (l.IsVisible)
for (M = (j = P.length) - 1; M >= 0; --M)
this._shouldIncludeControlMetadata(ee, l, P[M], l.FormControls[M]) || (t !== WBSFormMetadataRequestCollectMetadataFromDebugMenu ? (l.FormControls.splice(M, 1), P.splice(M, 1)) : l.FormControls[M].WOULD_NORMALLY_NOT_BE_SENT_TO_UI_PROCESS = !0);
return this._removePlaceholderTextForFormMetadata(P, l), delete this._pageScanContext, t !== WBSFormMetadataRequestPreFill && globalThis.FormMetadataClassificationJS && globalThis.FormMetadataClassificationJS.classify(l), l
},
_formIsEligibleForAutomaticLogin : function(e, t) {
if (e.AutoFillFormType !== WBSAutoFillFormTypeAutoFillableLogin)
return !1;
let o = !1;
for (const t of e.FormControls) {
const r = t.ControlUniqueID;
if (r === e.UsernameElementUniqueID || r === e.PasswordElementUniqueID)
continue;
if (t.ControlIsDisabled)
continue;
if (t.ControlIsReadOnly)
continue;
if (!t.IsVisible)
continue;
const n = this.formControlWithUniqueID(r);
if (!n)
continue;
if (this._isTextArea(n))
return !1;
if (this._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 (o)
return !1;
o = !0
}
}
return !t || !elementAppearsToContinueCaptchaWidget(t)
},
_oneTimeCodeIsEligibleForAutomaticLogin : function(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 (this._isSelectElement(t))
return !1;
if (this._isSubmitButton(t))
continue;
if (this._looksLikeShowHidePasswordButton(t))
continue;
if (!isInputElement(t))
continue;
const o = t.type;
if ("button" !== o && "reset" !== o && "submit" !== o && "image" !== o)
return !1
}
return !0
},
_shouldIncludeControlMetadata : function(e, t, o, r) {
if (o._relatesToCredentials)
return !0;
if (r.IsVisible) {
if (formControlHasBeenClassifiedInAnInterestingWay(r))
return !0;
if (e && r.ControlValue)
return !0
}
return !(!t.UsernameElementUniqueID || r.ControlUniqueID !== t.UsernameElementUniqueID)
},
_isElementAHiddenUsername : function(e) {
const t = /user|email/i;
return "hidden" === e.type && (!(!t.test(e.getAttribute("id")) && !t.test(e.getAttribute("name"))) && !!isValidUsernameOrEmail(e.value))
},
_findHiddenUsernameElement : function(e) {
var t = e.formElement;
if (!(t instanceof HTMLElement))
return;
let o = queryAllBySelector(t, "input"),
r = o.length;
for (let e = 0; e < r; ++e) {
let t = o[e];
if (this._isElementAHiddenUsername(t))
return t
}
return null
},
_extractMetadataForHiddenUsernameElement : function(e, t, o) {
var r = {
ControlTagName : this._getTagName(e),
ControlFieldName : this._getNameOrId(e),
ControlUniqueID : this.controlUniqueID(e),
ControlIsReadOnly : !0,
ControlValue : e.value
};
t.UsernameElementUniqueID = r.ControlUniqueID, t.FormControls.push(r), o.push(e)
},
_usernameFieldForPasswordField : function(e) {
let t = FormMetadataJS._cachedMetadataForLogicalForm(this._logicalFormsCache.logicalFormForControl(e));
return t && t.UsernameElementUniqueID ? FormMetadataJS.formControlWithUniqueID(t.UsernameElementUniqueID) : null
},
_cachedMetadataForLogicalForm : function(e) {
var t = e.metadata,
o = t?.FormControls,
r = o?.length ?? 0;
if (!r)
return null;
const n = innermostActiveElement();
for (var i = 0; i < r; ++i) {
var l = o[i],
a = this.formControlWithUniqueID(l.ControlUniqueID);
a && (l.ControlIsActiveElement = a === n, l.ControlValue = a.value, l.ControlIsAutoFilledTextField = this._isAutoFilledTextField(a))
}
return t.UsesGeneratedPassword = this._usesGeneratedPassword(e), t.Annotations = e.annotations, t
},
_markFormIsBestForPageLevelAutoFill : function() {
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 o = this._logicalFormWithHighestScoreIfGreaterThanZero((function(o) {
var r = o.PasswordElementUniqueID ? 0 : -1;
return e(o.AutoFillFormType) + t(o.IsVisible) + r
}));
null !== o && (o.metadata.FormIsBestForPageLevelAutoFill = !0)
},
_markFormIsBestForStreamlinedLogin : function() {
let e = this._logicalFormWithHighestScoreIfGreaterThanZero((function(e, t) {
if (!e.IsVisible)
return 0;
let o = t.getBoundingClientRect();
if (!rectIsWithinDocumentViewport(o))
return 0;
if (o.bottom + window.scrollY < 80) {
let e = !(location.hash || location.pathname && "/" !== location.pathname || location.search),
t = o.width / o.height;
if (!e && t > 4)
return 0
}
if (t.closest("footer"))
return 0;
let r = e.AutoFillFormType === WBSAutoFillFormTypeAutoFillableLogin,
n = 0,
i = e.FormControls,
l = i.length;
for (var a = 0; a < l; ++a) {
let t = i[a];
if (r) {
t.ControlIsAutofocusedTextField && (n += 1);
let o = t.ControlUniqueID;
if (o === e.UsernameElementUniqueID || o === e.PasswordElementUniqueID) {
n += 10;
continue
}
}
t.OneTimeCodeIsEligibleForAutomaticLogin && (n += 5)
}
return n
}));
null !== e && (e.metadata.FormIsBestForStreamlinedLogin = !0)
},
_logicalFormWithHighestScoreIfGreaterThanZero : function(e) {
let t = null,
o = null;
for (let n of this._logicalFormsCache.allForms()) {
var r = e(n.metadata, n.backingElement);
(null === t || r > t) && (o = n, t = r)
}
return t > 0 ? o : null
},
isAnyFormAnnotated : function() {
return this._logicalFormsCache.allForms().some((e => e.isAnnotated))
},
clearAnnotationsForFormWithID : function(e) {
let t = this._logicalFormsCache.logicalFormWithUniqueID(e);
t && t.clearAnnotations()
},
annotateFormWithID : function(e, t) {
let o = this._logicalFormsCache.logicalFormWithUniqueID(e);
o && o.annotate(t)
},
_collectMetadata : function(e) {
const t = 100,
o = 10;
var r = this._logicalFormsInPage(t, o);
this._logicalFormsCache.clearCacheAndAdd(r);
for (var n = r.length, i = 0; i < n; ++i) {
e === WBSFormMetadataRequestTesting && "function" == typeof willCollectFormMetadata && willCollectFormMetadata();
let t = this._collectFormMetadata(r[i], e);
e === WBSFormMetadataRequestTesting && "function" == typeof evaluateCustomJavaScript && (t.ResultFromEvaluatingCustomJavaScript = evaluateCustomJavaScript(r[i], t)), r[i].metadata = t
}
this._markFormIsBestForPageLevelAutoFill(), e !== WBSFormMetadataRequestNormal && this._markFormIsBestForStreamlinedLogin()
},
_collectAndCacheFormMetadata : function(e, t) {
let o = this._collectFormMetadata(e, t),
r = this._logicalFormsCache.logicalFormWithUniqueID(e.formUniqueID);
return r ? r.metadata = o : (e.metadata = o, this._logicalFormsCache.addOrUpdate(e)), o
},
_metadataForFormWithID : function(e) {
return this._logicalFormsCache.logicalFormWithUniqueID(e)?.metadata
},
_recollectMetadataForFormWithID : function(e) {
const t = this._logicalFormsCache.logicalFormWithUniqueID(e);
return t ? this._collectAndCacheFormMetadata(t, WBSFormMetadataRequestNormal) : null
},
_fillControlWithGeneratedPassword : function(e, t) {
var o = this._elementsWithGeneratedPasswords.indexOf(e);
-1 === o && (this._elementsWithGeneratedPasswords.push(e), o = this._elementsWithGeneratedPasswords.length - 1), this._generatedPasswords[o] = t, this._autoFillControlWithValueWithSingleValueUpdate(e, t, ShouldFocus.Yes, ShouldBlur.Yes, ShouldSetAutoFilled.Yes)
},
fillFormWithPassword : function(e, t, o) {
var r = this._metadataForFormWithID(e);
if (null === r)
return null;
const n = r.PasswordElementUniqueID,
i = n ? this.formControlWithUniqueID(n) : void 0,
l = o ? this.formControlWithUniqueID(o) : void 0;
var a = i || l;
const s = n || o;
if (!a)
return null;
this._fillControlWithGeneratedPassword(a, t);
let u = r.ConfirmPasswordElementUniqueID;
u || r.AutoFillFormType !== WBSAutoFillFormTypeChangePassword && r.AutoFillFormType !== WBSAutoFillFormTypeNewAccount || (u = (r = this._recollectMetadataForFormWithID(e) || r).ConfirmPasswordElementUniqueID);
let c = u ? this.formControlWithUniqueID(u) : null;
return c ? (this._fillControlWithGeneratedPassword(c, t), [ s, u ]) : [ s ]
},
fillFieldWithGeneratedPassword : function(e, t) {
var o = this.formControlWithUniqueID(e);
o && this._isTextField(o) && this._fillControlWithGeneratedPassword(o, t)
},
clearField : function(e) {
var t = this.formControlWithUniqueID(e);
this._clearFormField(t)
},
_clearFormField : function(e, t) {
if (e)
if (this._isSelectElement(e))
e.selectedIndex = 0;
else if (isDateTimeInputElement(e))
e.value = "";
else if (isRadioButtonElement(e)) {
let t = this._logicalFormsCache.logicalFormForControl(e).radioButtonsWithName(e.name),
o = t.length;
for (let e = 0; e < o; ++e)
t[e].checked = !1
} else if (this._isTextField(e) && e.value.length) {
var o = e.matches(":focus");
o || e.dispatchEvent(new Event("focus")), e.dispatchEvent(eventThatBubbles("keydown")), e.value = "", e.dispatchEvent(eventThatBubbles("input")), e.dispatchEvent(eventThatBubbles("keyup")), e.dispatchEvent(eventThatBubbles("change")), o || t === ShouldBlur.No || e.dispatchEvent(new Event("blur"))
}
},
focusFormForStreamlinedLogin : function(e) {
function t(e)
{
for (const t of e.FormControls) {
const o = t.ControlUniqueID;
if (o === e.UsernameElementUniqueID || o === e.PasswordElementUniqueID || t.ControlLooksLikeOneTimeCodeField)
return o
}
}
var o = this._metadataForFormWithID(e);
if (null !== o) {
var r = t(o);
if (r) {
var n = this.formControlWithUniqueID(r);
rectIsWithinDocumentViewport(n.getBoundingClientRect()) && n.focus()
}
}
},
formsAndMetadata : function(e) {
visibilityCacheGeneration++, this._collectMetadata(e);
let t = [],
o = [];
for (let e of this._logicalFormsCache.allForms())
t.push(e.formElement), o.push(e.metadata);
return [ t, o ]
},
formControlWithUniqueID : function(e) {
let t = this._controlUniqueIDToWeakControlMap.get(e)?.deref();
return t
},
formElementWithFormID : function(e) {
return this._logicalFormsCache.logicalFormWithUniqueID(e)?.formElement
},
selectIfTextField : function(e) {
this._isTextField(e) && e.select()
},
_getOrCreateCachedMetadataForLogicalForm : function(e, t) {
var o = this._cachedMetadataForLogicalForm(e);
return !o || null != t && o.RequestType === WBSFormMetadataRequestPreFill && t !== WBSFormMetadataRequestPreFill ? this._collectAndCacheFormMetadata(e, t) : o
},
_getOrCreateLogicalFormForTextFieldOrSelectElement : function(e) {
let t = this._logicalFormsCache.logicalFormForControl(e);
if (t)
for (var o = t.metadata, r = o?.FormControls, n = r?.length ?? 0, i = e._controlUniqueID, l = 0; l < n; ++l)
if (r[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 : function(e, t) {
if (!this._isTextField(e) && !this._isSelectElement(e))
return null;
var o = this._getOrCreateLogicalFormForTextFieldOrSelectElement(e);
return o ? this._getOrCreateCachedMetadataForLogicalForm(o, t) : null
},
_isAnyPasswordElementUniqueID : function(e, t) {
return e.PasswordElementUniqueID === t || e.ConfirmPasswordElementUniqueID === t || e.OldPasswordElementUniqueID === t
},
_isCurrentPasswordElementUniqueID : function(e, t) {
switch (e.AutoFillFormType) {
case WBSAutoFillFormTypeNewAccount:
case WBSAutoFillFormTypeChangePassword:
return e.OldPasswordElementUniqueID === t;
default:
return e.PasswordElementUniqueID === t
}
},
_isNewPasswordElementUniqueID : function(e, t) {
switch (e.AutoFillFormType) {
case WBSAutoFillFormTypeNewAccount:
case WBSAutoFillFormTypeChangePassword:
return e.PasswordElementUniqueID === t || e.ConfirmPasswordElementUniqueID === t;
default:
return !1
}
},
_updateAnnotationsForField : function(e) {
var t = this._getOrCreateLogicalFormForTextFieldOrSelectElement(e);
if (t) {
var o = this._getOrCreateCachedMetadataForLogicalForm(t);
if (o) {
var r = e._controlUniqueID;
this._isCurrentPasswordElementUniqueID(o, r) ? t.annotate({
CurrentPassword : e.value
})
: this._isNewPasswordElementUniqueID(o, r) ? t.annotate({
NewPassword : e.value
})
: o.UsernameElementUniqueID === r && t.annotate({
Username : e.value
}),
isCredentialElementUniqueID(o, r) && (e._relatesToCredentials = "" !== e.value)
}
}
},
textFieldOrSelectElementMetadata : function(e, t, o) {
visibilityCacheGeneration++, this._logicalFormsCache.cleanupCache();
var r = [ null, null ],
n = this._cachedMetadataForFormWithTextFieldOrSelectElement(e, t);
if (!n)
return r;
this._pageScanContext = {
backwardScanCache : new WeakMap,
forwardScanCache : new WeakMap
};
let i = this._logicalFormsCache.logicalFormWithUniqueID(n.FormID),
l = formActionAsAnchorElement(i.formElement),
[ a, s, u, c ] = this._trailingArgumentsForCollectControlMetadataFunction(i, t, l);
const d = !0;
var h = this._collectControlMetadata(e, WBSFormMetadataRequestNormal, a, s, u, c, d);
if (delete this._pageScanContext, h.ControlLooksLikeOneTimeCodeField && this._oneTimeCodeIsEligibleForAutomaticLogin(h, n) && (h.OneTimeCodeIsEligibleForAutomaticLogin = !0), h.SelectionStart = e.selectionStart, h.SelectionLength = e.selectionEnd - e.selectionStart, t === WBSFormMetadataRequestTextChange && (!n.UsernameElementUniqueID && this._isAnyPasswordElementUniqueID(n, h.ControlUniqueID) && i.isAnnotated && i.annotate({
Username : null
}),
this._updateAnnotationsForField(e)),
n.RequestType !== WBSFormMetadataRequestPreFill)
for (let e of n.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;
break
}
if (o) {
for (const e of n.FormControls)
e.ControlUniqueID == h.ControlUniqueID && (e.ControlValue = null);
const e = JSON.stringify(n);
this._cachedFormMetadata == e ? n = null : this._cachedFormMetadata = e
}
return r[0] = h, r[1] = n, r
},
clearTextFieldOrSelectElementMetadataCache : function() {
this._cachedFormMetadata = null
},
disableSpellCheckInFieldIfNeeded : function(e) {
if (e) {
var t = this.formControlWithUniqueID(e);
t && this._isAutoFillableTextField(t) && FormMetadataJSController.setInputElementSpellCheckEnabled(t, !1)
}
},
selectionRangeInField : function(e) {
var t = this.formControlWithUniqueID(e);
return t && this._isTextField(t) ? [ t.selectionStart, t.selectionEnd - t.selectionStart ] : null
},
setFormFieldSelection : function(e, t, o) {
var r = this.formControlWithUniqueID(e);
r && this._isTextField(r) && (r.selectionStart = t, r.selectionEnd = t + o)
},
replaceFormFieldRangeAndSelectTail : function(e, t, o, r, n) {
var i = this.formControlWithUniqueID(e);
if (i && this._isTextField(i)) {
var l = i.value,
a = l.substr(0, t) + r + l.substr(t + o);
i.value = a, i.selectionStart = n, i.selectionEnd = a.length, i.dispatchEvent(eventThatBubbles("input")), i.dispatchEvent(eventThatBubbles("change"))
}
},
_collectVisibleNonEmptyTextFieldsAndTextAreasInForm : function(e, t, o) {
visibilityCacheGeneration++;
for (var r = e.elements, n = r.length, i = 0; i < n; ++i) {
var l = r[i];
l.isVisible() && (null != l.value && l.value.length && (this._isTextField(l) ? t.push(l) : this._isTextArea(l) && o.push(l)))
}
},
visibleNonEmptyFormTextControls : function() {
var e = [],
t = [];
let o = queryAllBySelector(document, "form");
for (let r = 0; r < o.length; ++r)
this._collectVisibleNonEmptyTextFieldsAndTextAreasInForm(o[r], e, t);
return [ e, t ]
},
visibleNonEmptyFormTextControlsInForm : function(e) {
var t = [],
o = [];
return this._collectVisibleNonEmptyTextFieldsAndTextAreasInForm(e, t, o), [ t, o ]
},
_autoFillRadioButton : function(e, t, o) {
var r = this._logicalFormsCache.logicalFormForControl(e),
n = r?.radioButtonsWithName(e.name) ?? [];
for (let e of n)
if (e.value === t)
return e.dispatchEvent(eventThatBubbles("click")), e.checked = !0, void FormMetadataJSController.setInputElementAutofilled(e, o)
},
_autoFillControlWithValueWithSingleValueUpdate : function(e, t, o, r, n, i, l) {
o === ShouldFocus.Yes && e.dispatchEvent(new Event("focus")), e.dispatchEvent(eventThatBubbles("keydown")), e.value = t, this._updateAnnotationsForField(e), l || e.dispatchEvent(eventThatBubbles("input")), e.dispatchEvent(eventThatBubbles("keyup")), l || e.dispatchEvent(eventThatBubbles("change")), r === ShouldBlur.Yes && e.dispatchEvent(new Event("blur")), i === ShouldObscure.Yes ? FormMetadataJSController.setInputElementAutofilledAndObscured(e, t.length && n === ShouldSetAutoFilled.Yes) : FormMetadataJSController.setInputElementAutofilled(e, t.length && n === ShouldSetAutoFilled.Yes)
},
_autoFillControlWithValueCharacterByCharacter : function(e, t, o, r, n, i, l) {
let a = t.split(""),
s = a.length,
u = Date.now(),
c = !e;
const d = 100,
h = () => {
this._autoFillControlWithValueWithSingleValueUpdate(e, t, ShouldFocus.Yes, ShouldBlur.Yes, o, r), i?.()
};
let m = F => {
try {
if (F >= s)
return void i?.();
c && (e = innermostActiveElement());
let f = e.value,
g = a[F],
p = f.slice(-1);
if (p === g && F && !t.slice(F - 1).startsWith(p + g))
return void setTimeout(m, 0, F + 1);
let C = 0 === F ? ShouldFocus.Yes : ShouldFocus.No,
_ = F === s - 1,
A = _ ? ShouldBlur.Yes : ShouldBlur.No,
b = _ ? o : ShouldSetAutoFilled.No,
y = _ ? r : ShouldObscure.No,
S = f + g,
T = !_;
if (l && (T = !1), this._autoFillControlWithValueWithSingleValueUpdate(e, S, C, A, b, y, T), !c && !this._controlContainsAllCharactersFromFilling(e.value, t.substring(0, F + 1)))
return void h();
const E = Date.now() - u;
if (u = Date.now(), E > d && n === ShouldAbandonCharacterByCharacterEntryIfTooSlow.Yes)
return void h();
setTimeout(m, 0, F + 1)
} catch (e) {
}
};
m(0)
},
_controlContainsAllCharactersFromFilling : function(e, t) {
if (e.length < t.length)
return !1;
var o = t;
for (let r = 0; r < t.length; r++) {
-1 !== e.indexOf(t[r]) && (e = e.replace(t[r], ""), o = o.replace(t[r], ""))
}
return !o.length
},
_autoFillControlWithValueRecursively : function(e, t, o, r, n) {
if (isRadioButtonElement(e))
return this._autoFillRadioButton(e, t, o === ShouldSetAutoFilled.Yes), void (n && n());
if (this._isSelectElement(e))
return this._autoFillSelectWithOptionIndex(e, t, o === ShouldSetAutoFilled.Yes), void (n && n());
let i = this._logicalFormsCache.logicalFormForControl(e),
l = FormMetadataJS._cachedMetadataForLogicalForm(i);
if (!this._isTextField(e) || l && isCredentialElementUniqueID(l, e._controlUniqueID))
return this._autoFillControlWithValueWithSingleValueUpdate(e, t, ShouldFocus.Yes, ShouldBlur.Yes, o, r), void (n && n());
this._clearFormField(e, ShouldBlur.No);
let a = () => {
this._controlContainsAllCharactersFromFilling(e.value, t) || this._autoFillControlWithValueWithSingleValueUpdate(e, t, ShouldFocus.Yes, ShouldBlur.Yes, o, r), n && n()
};
this._autoFillControlWithValueCharacterByCharacter(e, t, o, r, ShouldAbandonCharacterByCharacterEntryIfTooSlow.Yes, a)
},
_autoFillSelectWithOptionIndex : function(e, t, o) {
e.dispatchEvent(eventThatBubbles("mousedown")), e.dispatchEvent(new Event("focus")), e.selectedIndex !== t && (e.selectedIndex = t, e.dispatchEvent(eventThatBubbles("input")), e.dispatchEvent(eventThatBubbles("change"))), e.dispatchEvent(eventThatBubbles("mouseup")), e.dispatchEvent(eventThatBubbles("click")), e.dispatchEvent(new Event("blur")), FormMetadataJSController.setInputElementAutofilled(e, o)
},
autoFillOneTimeCodeFieldsWithValue : function(e, t) {
let o = innermostActiveElement();
if (!this._isAutoFillableTextField(o))
return;
this._clearFormField(o);
let r = () => {
FormMetadataJSController.finishedAutoFillingOneTimeCode(e, t)
}, n = !0;
this._autoFillControlWithValueCharacterByCharacter(null, e, ShouldSetAutoFilled.Yes, ShouldObscure.No, ShouldAbandonCharacterByCharacterEntryIfTooSlow.No, r, n)
},
_removeGeneratedPasswordForElement : function(e) {
let t = this._elementsWithGeneratedPasswords.indexOf(e);
-1 !== t && (this._elementsWithGeneratedPasswords.splice(t, 1), this._generatedPasswords.splice(t, 1))
},
_shouldSelectElementAfterFillingForm : function(e) {
if (!/(^|\.)etrade\.com/.test(document.location.hostname))
return !0;
var t = this._cachedMetadataForLogicalForm(e);
return !t || t.AutoFillFormType !== WBSAutoFillFormTypeAutoFillableLogin
},
autoFillControlsByID : function(e, t, o, r, n, i) {
let l = arguments[arguments.length - 1],
a = o ? ShouldSetAutoFilled.Yes : ShouldSetAutoFilled.No,
s = r;
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) {
let e = this.formControlWithUniqueID(t)._logicalFormUniqueIDs;
for (let t of e)
u ||= this._logicalFormsCache.logicalFormWithUniqueID(t);
if (u)
break
}
var c = function() {
n ? innermostActiveElement().blur() : s && this._shouldSelectElementAfterFillingForm(u) && this.selectIfTextField(s), u?.backingElement && elementAppearsToContinueCaptchaWidget(u.backingElement) && (l = !1), FormMetadataJSController.finishedAutoFillingControlsInForm(this._getOrCreateCachedMetadataForLogicalForm(u), l)
}.bind(this);
if (t) {
var d = [];
for (var h in e)
e.hasOwnProperty(h) && d.push([ this.formControlWithUniqueID(h), e[h] ]);
this._synchronouslyAutoFillControls(d, a, c)
} else
this._asynchronouslyAutoFillControls(e, u, a, i, c)
},
_synchronouslyAutoFillControls : function(e, t, o) {
for (var r = e.length, n = 0; n < r; ++n) {
var i = e[n][0],
l = e[n][1];
this._autoFillControlWithValueRecursively(i, l, t)
}
o()
},
_asynchronouslyAutoFillControls : function(e, t, o, r, n) {
var i = t.elements,
l = i.length,
a = function(t) {
if (t >= l)
return void n();
var s = i[t],
u = e[s._controlUniqueID];
let c = () => {
a(t + 1)
};
if (void 0 !== u) {
let e = r.some((e => s._controlUniqueID.includes(e))) ? ShouldObscure.Yes : ShouldObscure.No;
this._autoFillControlWithValueRecursively(s, u, o, e, c)
} else
c()
}.bind(this);
a(0)
},
_isInputAllowedInSearchForm : function(e, t) {
var o = this._getTagName(e).toLowerCase();
if ("button" === o || "fieldset" === o)
return !0;
if ("select" === o)
return !t || isSelectInDefaultState(e);
if ("input" !== o && !this._textAreaElementLookLikeItIsPartOfASearchForm(e))
return !1;
var r = e.type;
return "radio" === r || "checkbox" === r ? !t || isCheckboxOrRadioButtonInDefaultState(e) : "hidden" === r || "reset" === r || "submit" === r || "button" === r || "image" === r || this._isTextField(e) && !this._isSecureTextField(e)
},
_isSearchForm : function(e, t) {
if ("get" !== e.method)
return !1;
for (var o = e.elements, r = o.length, n = 0; n < r; ++n)
if (!this._isInputAllowedInSearchForm(o[n], t))
return !1;
return !0
},
_textAreaElementLookLikeItIsPartOfASearchForm : function(e) {
return !!this._isTextArea(e) && ("search" === e.getAttribute("type") || ("search" === e.inputMode || "search" === e.getAttribute("enterkeyhint")))
},
_shouldInputBeIncludedInSearchURLQuery : function(e) {
if (e.disabled)
return !1;
if (!e.name.length)
return !1;
if (!e.value.length)
return !1;
if (this._isSelectElement(e))
return !0;
var t = this._getTagName(e).toLowerCase(),
o = e.type;
return "button" === t ? "submit" === o : "input" === t && ("submit" === o || ("checkbox" === o || "radio" === o ? e.checked : "hidden" === o || this._isTextField(e)))
},
_isSubmitButton : function(e) {
return (e instanceof HTMLButtonElement || e instanceof HTMLInputElement) && (e.type && "submit" === e.type)
},
_isCustomFormButton : function(e) {
return "button" === e.type && (e instanceof HTMLButtonElement || e instanceof HTMLInputElement)
},
_isCheckboxInputElement : function(e) {
return "checkbox" === e.type && e instanceof HTMLInputElement
},
_setQueryString : function(e, t) {
var o = document.createElement("a");
return o.href = e, o.search = t, o.href
},
searchTextFieldFormSubmissionURLString : function(e, t) {
if (visibilityCacheGeneration++, !this._isTextField(e) || this._isSecureTextField(e) || !e.isVisible())
return null;
var o = e.form;
if (!o)
return null;
var r = o.getAttribute("action");
if (!r || !r.length)
return null;
if (!/^https?:/i.test(o.action))
return null;
if (!this._isSearchForm(o, t))
return null;
for (var n = null, i = "", l = o.elements, a = l.length, s = 0; s < a; ++s) {
var u = l[s];
if ((u === e || this._shouldInputBeIncludedInSearchURLQuery(u)) && (!this._isSubmitButton(u) || (n || (n = u), u === n))) {
i.length && (i += "&");
var c = u === e ? "{searchTerms}" : urlEncode(u.value);
i += urlEncode(u.name) + "=" + c
}
}
return this._setQueryString(o.action, i)
}
};
var FormMetadataJS = new FormMetadata;
<!DOCTYPE html>
<html>
<head>
<title>Grant Permissions for Web Extension?</title>
<style>
@media (prefers-color-scheme: dark) {
:root {
color-scheme: dark !important;
}
body {
background: rgb(30, 30, 30) !important;
--font-color: hsl(0, 0%, 85%) !important;
--title-color: rgb(224, 225, 225) !important;
}
.alert-container {
background-color: rgb(56, 57, 59) !important;
box-shadow: 0 6px 12px rgba(0, 0, 0, .24) !important;
}
}
body {
--font-color: #434343;
--horizontal-padding: 32px;
--border-radius: 6px;
--title-color: #444;
}
* {
padding: 0;
margin: 0;
font-family: -apple-system-font;
}
:root {
color-scheme: light;
}
html, body {
height: 100%;
width: 100%;
}
body {
font-size: 13px;
background: linear-gradient(30deg, #dfdfdf 0%, #fafafb 100%);
background-repeat: no-repeat;
background-attachment: fixed;
cursor: default;
-webkit-user-select: none;
overflow: hidden;
}
.vertical-flex-container {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
flex-wrap: nowrap;
align-content: stretch;
padding-top: 156px;
}
@media (max-height: 30rem) {
.vertical-flex-container {
padding-top: min(calc(60vh - 150px), 156px);
}
}
.alert-container {
background-color: white;
min-width: 320px;
max-width: 672px;
position: relative;
margin: 0 auto;
padding-top: 24px;
border-radius: var(--border-radius);
box-shadow: 0px 6px 10px rgba(0, 0, 0, 0.14);
}
.alert-container h1 {
overflow: hidden;
color: var(--title-color);
padding-top: 3px;
}
.alert-body {
display: block;
margin: 21px 0 0 0;
padding-left: var(--horizontal-padding);
padding-right: var(--horizontal-padding);
padding-bottom: 28px;
color: var(--font-color);
}
.alert-body p:first-of-type {
margin-bottom: 15px;
margin-top: 20px;
}
.alert-body p:last-of-type {
margin-bottom: 0;
}
.button-bar {
display: flex;
justify-content: center;
align-items: center;
flex-direction: row;
flex-wrap: wrap;
align-content: stretch;
margin-top: 1.3em;
}
.button-bar button {
font-size: 13px;
line-height: 21px;
min-width: 90px;
margin: 4px;
vertical-align: bottom;
padding: 0 12px;
color: var(--font-color);
cursor: pointer;
}
.hidden {
display: none;
}
a {
color: inherit;
text-decoration: underline;
cursor: pointer;
}
h1 {
font-size: 1.5em;
font-weight: 700;
line-height: 30px;
padding: 0 var(--horizontal-padding);
margin-bottom: 1em;
}
p {
font-size: 14px;
line-height: 19px;
margin-bottom: 1em;
word-wrap: break-word;
}
</style>
<script>
// Note: these values are synonymous with the values of enum class Inspector::ExtensionError.
WI = {
WebInspectorExtension: {
ErrorCode: {
ContextDestroyed: "ContextDestroyed",
InternalError: "InternalError",
InvalidRequest: "InvalidRequest",
RegistrationFailed: "RegistrationFailed",
NotImplemented: "NotImplemented",
}
}
};
function addButtonEventListener(elementID, callback)
{
let button = document.getElementById(elementID);
if (!button)
return false;
button.addEventListener("click", callback);
return true;
}
// Note: this is expected to return a promise that fulfills when
// one of the buttons is clicked. The promise will be rejected if
// there are no buttons specified, and also just before the main
// frame navigates.
async function waitForPolicyDecision()
{
if (window._waitForPolicyDecisionPromiseData)
return window._waitForPolicyDecisionPromiseData.promise;
window._waitForPolicyDecisionPromiseData = {};
window._waitForPolicyDecisionPromiseData.promise = new Promise((resolve, reject) => {
window._waitForPolicyDecisionPromiseData.resolve = resolve;
window._waitForPolicyDecisionPromiseData.reject = reject;
});
let buttonNames = ["policy-1", "policy-2", "policy-3"];
let addedButtonsCount = buttonNames.filter((id) => addButtonEventListener(id, handlePolicyDecision)).length;
if (!addedButtonsCount)
window._waitForPolicyDecisionPromiseData.reject?.(WI.WebInspectorExtension.ErrorCode.InvalidRequest);
window.addEventListener("pagehide", () => {
window._waitForPolicyDecisionPromiseData.reject?.(WI.WebInspectorExtension.ErrorCode.ContextDestroyed);
});
return window._waitForPolicyDecisionPromiseData.promise;
}
function handlePolicyDecision(event)
{
if (!window._waitForPolicyDecisionPromiseData)
return;
// On the first button click, pull out the resolve and reject callbacks.
let {resolve, reject, promise} = window._waitForPolicyDecisionPromiseData;
if (!resolve || !reject)
return;
window._waitForPolicyDecisionPromiseData = { promise };
// One of 'policy-1', 'policy-2', 'policy-3'.
resolve(event.target.id);
}
function receivePayload(payload)
{
for (let placeholderID of ['titleText', 'descriptionText', 'policy-1', 'policy-2', 'policy-3']) {
let placeholderElement = document.getElementById(placeholderID);
if (!placeholderElement) {
console.error("Couldn't find placeholder element for placeholderID: " + placeholderID);
continue;
}
let payloadValue = payload[placeholderID];
placeholderElement.textContent = payloadValue ?? "LOCALIZED STRING NOT FOUND";
placeholderElement.classList.toggle("hidden", !payloadValue);
}
let anyButtonIsVisible = payload['policy-1'] || payload['policy-2'] || payload['policy-3'];
let bottomBarElement = document.getElementsByClassName('button-bar')[0];
bottomBarElement.classList.toggle("hidden", !anyButtonIsVisible);
}
</script>
</head>
<body>
<div class="vertical-flex-container">
<div id="alert-container" class="alert-container">
<h1 id="titleText">An extension would like to access this website</h1>
</h1>
<div class="alert-body">
<p id="descriptionText">The extension would be able to read and alter webpages and see your browsing history on this website. This could include sensitive information, including passwords, phone numbers, and credit cards.</p>
<div class="button-bar">
<button type="button" id="policy-1">Allow for One Day</button>
<button type="button" id="policy-2">Always Allow on This Website</button>
<button type="button" id="policy-3">Always Allow on Every Website...</button>
</div>
</div>
</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>Grant Permissions for Web Extension?</title>
<style>
@media (prefers-color-scheme: dark) {
:root {
color-scheme: dark;
}
body {
background: rgb(30, 30, 30) !important;
--font-color: hsl(0, 0%, 85%) !important;
--title-color: rgb(224, 225, 225) !important;
}
.alert {
background-color: rgb(56, 57, 59) !important;
box-shadow: 0 6px 12px rgba(0, 0, 0, .24) !important;
}
}
body {
--font-color: #434343;
--horizontal-padding: 32px;
--border-radius: 6px;
--title-color: #444;
}
* {
padding: 0;
margin: 0;
font-family: -apple-system-font;
}
:root {
color-scheme: light;
}
html, body {
height: 100%;
width: 100%;
}
body {
font-size: 13px;
background: linear-gradient(30deg, #dfdfdf 0%, #fafafb 100%);
background-repeat: no-repeat;
background-attachment: fixed;
cursor: default;
-webkit-user-select: none;
}
.alert {
background-color: white;
min-width: 320px;
max-width: 672px;
position: relative;
margin: 0 auto;
padding-top: 24px;
border-radius: var(--border-radius);
box-shadow: 0px 6px 10px rgba(0, 0, 0, 0.14);
}
.alert h1 {
overflow: hidden;
color: var(--title-color);
padding-top: 3px;
}
.alert-body {
margin: 21px 0 0 0;
padding-left: var(--horizontal-padding);
padding-right: var(--horizontal-padding);
padding-bottom: 28px;
color: var(--font-color);
}
.alert-body p:first-of-type {
margin-bottom: 15px;
margin-top: 20px;
}
.alert-body p:last-of-type {
margin-bottom: 0;
}
.bottom-bar {
margin-top: 1.3em;
height: 22px;
}
.bottom-bar button {
font-size: 13px;
line-height: 21px;
min-width: 90px;
margin: 0 4px;
vertical-align: bottom;
padding: 0 12px;
color: var(--font-color);
cursor: pointer;
}
a {
color: inherit;
text-decoration: underline;
cursor: pointer;
}
h1 {
font-size: 1.5em;
font-weight: 700;
line-height: 30px;
padding: 0 var(--horizontal-padding);
margin-bottom: 1em;
}
p {
font-size: 14px;
line-height: 19px;
margin-bottom: 1em;
word-wrap: break-word;
}
.hidden {
display: none;
}
/* RTL support */
html[dir="rtl"] .bottom-bar button {
float: right;
}
</style>
<script>
// Note: this is expected to return a promise that fulfills when
// one of the buttons is clicked.
async function waitForPolicyDecision()
{
if (window._waitForPolicyDecisionPromiseData)
return window._waitForPolicyDecisionPromiseData.promise;
window._waitForPolicyDecisionPromiseData = {};
window._waitForPolicyDecisionPromiseData.promise = new Promise((resolve, reject) => {
window._waitForPolicyDecisionPromiseData.resolve = resolve;
window._waitForPolicyDecisionPromiseData.reject = reject;
});
["policy-1", "policy-2", "policy-3"].forEach((id) => { addButtonEventListener(id, handlePolicyDecision); });
return window._waitForPolicyDecisionPromiseData.promise;
}
function receivePayload(payload)
{
for (let placeholderID of ['titleText', 'descriptionText', 'policy-1', 'policy-2', 'policy-3']) {
let placeholderElement = document.getElementById(placeholderID);
if (!placeholderElement) {
console.error("Couldn't find placeholder element for placeholderID: " + placeholderID);
continue;
}
let payloadValue = payload[placeholderID];
placeholderElement.textContent = payloadValue ?? "LOCALIZED STRING NOT FOUND";
placeholderElement.classList.toggle("hidden", !payloadValue);
}
let anyButtonIsVisible = payload['policy-1'] || payload['policy-2'] || payload['policy-3'];
let bottomBarElement = document.getElementsByClassName('bottom-bar')[0];
bottomBarElement.classList.toggle("hidden", !anyButtonIsVisible);
}
function addButtonEventListener(elementID, callback)
{
let button = document.getElementById(elementID);
if (!button)
return;
button.addEventListener("click", callback);
}
function handlePolicyDecision(event)
{
if (!window._waitForPolicyDecisionPromiseData)
return;
// On the first button click, pull out the resolve and reject callbacks.
let {resolve, reject, promise} = window._waitForPolicyDecisionPromiseData;
if (!resolve || !reject)
return;
window._waitForPolicyDecisionPromiseData = { promise };
// One of 'policy-1', 'policy-2', 'policy-3'.
resolve(event.target.id);
}
function pageLoaded()
{
window.addEventListener("resize", performLayout);
performLayout();
}
function performLayout()
{
const minimumMarginTop = 22;
const maximumMarginTop = 156;
let alertElement = document.getElementById("alert");
let alertElementHeight = alertElement.getBoundingClientRect().height;
let viewportHeight = window.innerHeight;
if (viewportHeight > alertElementHeight + 2 * maximumMarginTop)
alertElement.style.top = maximumMarginTop + "px";
else
alertElement.style.top = Math.max(minimumMarginTop, (viewportHeight - alertElementHeight) / 2) + "px";
}
window.addEventListener("load", () => { pageLoaded(); });
</script>
</head>
<body>
<div id="alert" class="alert">
<h1 id="titleText">An extension would like to access this website</h1>
</h1>
<div class="alert-body">
<p id="descriptionText">The extension would be able to read and alter webpages and see your browsing history on this website. This could include sensitive information, including passwords, phone numbers, and credit cards.</p>
<div class="bottom-bar">
<button type="button" id="policy-1">Allow for One Day</button>
<button type="button" id="policy-2">Always Allow on This Website</button>
<button type="button" id="policy-3">Always Allow on Every Website...</button>
</div>
</div>
</div>
</body>
</html>
// OpenSearch description document can be specified via the <link> tag with rel="search".
// See http://blog.whatwg.org/the-road-to-html-5-link-relations#rel-search.
// It should have the type "application/opensearchdescription+xml".
// See https://github.com/dewitt/opensearch/blob/master/opensearch-1-1-draft-6.md#mime-type-applicationopensearchdescriptionxml.
(function() {
if (!document.head)
return null;
var linkTags = document.head.getElementsByTagName("link");
var numberOfLinkTags = linkTags.length;
for (var i = 0; i < numberOfLinkTags; ++i) {
var linkTag = linkTags[i];
if (linkTag.getAttribute("rel") === "search" && linkTag.getAttribute("type") === "application/opensearchdescription+xml")
return linkTag.href;
}
return null;
})();
<!DOCTYPE html>
<html>
<head>
<meta name="disabled-adaptations" content="watch">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale=1">
<base>
<title>Reader</title>
<style id="article-content">
h1, h2, h3, h4, h5, h6 {
font-weight: bold;
}
h1 {
font-size: 1.5em;
line-height: 1.4em;
}
h2 {
font-size: 1.43em;
}
h3 {
font-size: 1.25em;
}
h4, h5, h6 {
font-size: 1em;
margin: 1em 0;
}
body.watch h1 {
font-size: 1.1875rem;
}
body.watch h2 {
font-size: 1.125rem;
}
body.watch h3 {
font-size: 1.0625rem;
}
body.watch :matches(h4, h5, h6) {
font-size: 1rem;
}
h1.title {
font-weight: bold;
font-size: 1.95552em;
line-height: 1.2141em;
margin-top: 0;
margin-bottom: 0.5em;
}
.subhead {
font-weight: normal;
}
.title, .subhead, .metadata {
text-align: start;
hyphens: manual;
display: none;
}
:nth-child(1 of .page) :matches(.title, .subhead, .metadata) {
display: block;
}
.subhead {
color: rgba(27, 27, 27, 0.65);
font-size: 1.46664em;
margin-top: -0.35em;
line-height: 1.27275em;
}
.metadata {
margin-top: -0.75em;
margin-bottom: 1.45em;
}
body.watch .metadata {
line-height: 1.3em;
}
.metadata * {
font-size: 1em !important;
font-weight: normal !important;
font-style: normal !important;
display: inline !important;
margin: 0;
}
.metadata :matches(.byline, .date) {
display: inline !important;
}
.metadata :matches(ul, ol, li) {
list-style-type: none;
-webkit-padding-start: 0;
}
.title + .metadata {
margin-top: -0.75em;
}
.subhead + .metadata {
margin-top: -0.7em;
}
.page {
text-align: start;
word-wrap: break-word;
}
body.watch .page {
hyphens: auto;
}
.page.rtl {
direction: rtl;
}
a {
text-decoration: none;
}
a[href] {
color: rgb(65, 110, 210);
}
#article {
text-rendering: optimizeLegibility;
}
#article * {
/* Scale down anything larger than our view. Max-width maintains aspect ratios on images. */
max-width: 100%;
}
#article img {
/* By default, images are centered on their own line. */
margin: 0.5em auto;
display: block;
height: auto;
}
#article img.reader-image-tiny {
display: inline;
margin: 0;
}
#article .leading-image, figure, .auxiliary {
margin-bottom: 1.15em;
}
#article .leading-image img {
margin: auto;
display: block;
clear: both;
}
#article .leading-image .credit {
margin: 0;
}
#article .leading-image,
#article figure {
font-size: 0.75em;
line-height: 1.5em;
}
body.watch #article .leading-image,
body.watch #article figure {
font-size: 0.8125rem;
}
#article .leading-image :matches(.caption, .credit),
#article figcaption {
margin-top: 0.8em;
width: 100%;
}
body.watch #article .leading-image :matches(.caption, .credit),
body.watch #article figcaption {
margin-top: 4px;
}
body.watch #article figure img {
margin-bottom: 0;
}
#article figcaption > * {
margin-top: 0.25em;
margin-bottom: 0.25em;
}
#article :matches(.leading-image, figure) p {
margin-top: 0.4em;
margin-bottom: 0.4em;
}
#article .leading-image .credit + .caption {
margin-top: 0.1em;
}
#article .auxiliary {
display: block;
clear: both;
font-size: 0.75em;
line-height: 1.4em;
text-align: start;
}
body.watch #article .auxiliary {
font-size: 0.9em;
}
#article .pullquote {
font-size: 1.42em;
line-height: 1.38em;
font-weight: 300;
font-style: italic;
}
#article .pullquote:not(.float) {
margin-top: 1em;
margin-bottom: 1em;
-webkit-margin-start: 1em;
max-width: calc(100% - 1em);
}
#article .auxiliary > *:not(img) {
-webkit-margin-start: 0;
}
#article .auxiliary.float img, #article .auxiliary > *:first-child:not(img) {
margin: 0;
}
/* If the element immediately after an image is inline, it might bump up against the image. */
#article .auxiliary img + * {
display: block;
}
#article .auxiliary figcaption {
font-size: 100%;
}
#article .auxiliary * {
margin-top: 0.5em;
margin-bottom: 0.5em;
}
body:not(.watch) #article .float.left {
float: left;
margin-right: 20px;
}
body:not(.watch) #article .float.right {
float: right;
margin-left: 20px;
}
body.watch #article .float {
width: auto !important;
}
#article .clear {
clear: both;
}
#article ul.list-style-type-none,
#article ol.list-style-type-none,
#article .list-style-type-none > li {
list-style-type: none;
-webkit-padding-start: 0;
}
#article .page .list-style-type-none.code-block code {
white-space: pre-wrap;
}
#article .page div.scrollable {
overflow-x: scroll;
word-wrap: normal;
}
#article .page div.scrollable table {
max-width: none;
}
#article .leading-image, #article figure, #article .auxiliary:not(.pullquote) {
font-family: -apple-system-font;
}
#article .leading-image, #article figure, #article .auxiliary, #article .pullquote {
color: rgba(0, 0, 0, 0.65);
}
figure {
margin: 0;
}
body:not(.watch) figure:not(.float) {
margin-top: 1.4em;
margin-bottom: 1.4em;
}
hr {
background: rgba(0, 0, 0, 0.2);
height: 1px;
border: 0;
}
pre {
font-family: -apple-system-ui-monospaced, Menlo;
font-size: 0.87em;
line-height: 1.45em;
}
blockquote, q {
color: rgba(0, 0, 0, 0.65);
}
blockquote:not(.pullquote) {
margin-left: 2px;
margin-right: 6px;
padding-left: 16px;
}
blockquote:not(.simple):not(.pullquote) {
border-left: 3px solid rgba(0, 0, 0, 0.1);
}
q.pullquote {
display: block;
}
.pullquote q::before, .pullquote q::after, q.pullquote::before, q.pullquote::after {
content: "";
}
/* Collapse excess whitespace. */
.page p > p:empty,
.page div > p:empty,
.page p > div:empty,
.page div > div:empty,
.page p + br,
.page img + br
{
display: none;
}
.page table {
font-size: 0.9em;
text-align: start;
word-wrap: break-word;
border-collapse: collapse;
}
.page table td, .page table th {
padding: 0.25em 0.5em;
border: 1px solid rgb(216, 216, 216);
}
body.watch .page > * {
margin-left: 0;
margin-right: 0;
}
body.watch .page ol {
padding: 0 0 0 35px;
}
body.watch .page ul {
padding: 0 0 0 20px;
}
body.watch .page li {
margin: 0.8em 0;
}
body.watch .page blockquote {
padding: 0 0 0 8px;
}
.delimiter {
margin-left: 0.45em;
margin-right: 0.45em;
margin-top: 0.07em;
padding: 0;
}
.metadata.singleline .delimiter::after {
content: "•";
}
.metadata:not(.singleline) .delimiter {
content: "";
display: block !important;
}
.page table th {
background-color: rgba(0, 0, 0, 0.025);
}
.page sup, .page sub {
line-height: 1;
font-size: 0.75em;
}
.hidden {
display: none;
}
/* Special Font Customizations */
.system { font-family: -apple-system-font; }
.watch.system { font: -apple-system-body; }
.yuantisc {
letter-spacing: 1px;
}
.yuantitc {
letter-spacing: 1px;
}
/* Printing and mailing. */
#article.exported {
font-size: 1.2em;
}
.exported {
line-height: 1.5em;
}
.exported a[href] {
text-decoration: underline;
}
#article.exported {
margin: 0;
padding: 0;
}
.exported .float {
float: none;
margin-top: 1.4em;
margin-bottom: 1.4em;
}
#article.exported .leading-image,
#article.exported figcaption {
font-size: 0.75rem;
color: rgba(0, 0, 0, 0.8);
}
.exported .delimiter::after {
content: "";
}
</style>
<style id="print">
@media print {
body {
margin: 2mm 9mm;
}
.original-url {
display: none;
}
#article .float.left {
float: left !important;
}
#article .float.right {
float: right !important;
}
#article .float {
margin-top: 0 !important;
margin-bottom: 0 !important;
}
}
</style>
<style id="reader-ui">
@media screen {
body {
margin: 0;
padding: 0;
-webkit-user-select: none;
overflow-x: hidden;
-webkit-text-size-adjust: none;
}
body.mac {
background-color: transparent;
}
#article {
pointer-events: auto;
-webkit-user-select: auto;
overflow: visible;
margin-bottom: 42vh !important;
}
#article:focus {
outline: none;
}
.page-number {
display: block;
}
#article :nth-child(1 of .page):nth-last-child(1 of .page) .page-number {
display: none;
}
body.watch #article :nth-child(1 of .page):nth-last-child(1 of .page) {
padding-top: 0.15em;
}
.page-number, #incoming-page-corner {
font-weight: bold;
position: absolute;
-webkit-user-select: none;
font: 12px "Helvetica Neue";
color: rgb(168, 168, 168);
cursor: default;
}
body.watch :matches(.page-number, #incoming-page-corner) {
top: 8px;
right: 16px;
}
.page {
margin-left: auto;
margin-right: auto;
padding-top: 35px;
padding-bottom: 35px;
position: relative;
border-top: 1px solid rgba(0, 0, 0, 0.2);
}
body.watch .page {
padding: 0 4px;
}
#article :nth-child(1 of .page) {
margin-top: 0;
border-top: none;
padding-top: 32px;
}
.page:last-of-type {
padding-bottom: 45px;
}
.page video {
height: auto;
position: relative;
}
#incoming-page-placeholder {
height: 30px;
margin-bottom: 0;
}
#incoming-page-corner {
position: absolute;
right: 10px;
top: 8px;
}
#incoming-page-text {
float: right;
-webkit-user-select: none;
}
#next-page-container {
position:absolute;
/* Workaround for <rdar://problem/8662842> iOS Reader: loading multiple pages stops at the 2nd page. */
left: -1000px;
/* The iframe needs to be wider than the width threshold value for Reader detection, see <rdar://problem/9599297>. */
width: 320px;
height: 0px;
}
.page div.scrollable {
-webkit-overflow-scrolling: touch;
}
}
@media screen and (-webkit-min-device-pixel-ratio:2) {
.page {
border-top-width: 0.5px;
}
hr {
height: 0.5px;
}
}
#article .extendsBeyondTextColumn {
max-width: none;
}
.iframe-wrapper {
background-color: black;
max-width: none;
text-align: center;
}
iframe {
border: 0;
}
@media screen and (min-width: 0px) {
/* Includes iPhone 5 in portrait */
.page { padding-left: 16px; padding-right: 16px; }
.page-number, #incoming-page-corner {
top: 8px;
right: 16px;
}
#article :nth-child(1 of .page):nth-last-child(1 of .page) {
padding-top: 14px;
}
}
@media screen and (min-width: 161px) {
/* Apple Watch 40mm */
body.watch .page {
padding: 0 8.5px;
}
}
@media screen and (min-width: 183px) {
/* Apple Watch 44mm */
body.watch .page {
padding: 0 9.5px;
}
}
@media screen and (min-width: 375px) {
/* iPhone 6 in portrait */
.page { padding-left: 18px; padding-right: 18px; }
.page-number, #incoming-page-corner {
top: 6px;
right: 18px;
}
#article :nth-child(1 of .page):nth-last-child(1 of .page) {
padding-top: 16px;
}
}
@media screen and (min-width: 414px) {
/* iPhone 6 Plus in portrait */
.page { padding-left: 20px; padding-right: 20px; }
.page-number, #incoming-page-corner {
top: 6px;
right: 20px;
}
#article :nth-child(1 of .page):nth-last-child(1 of .page) {
padding-top: 18px;
}
}
/* iPhone 5 in landscape (568px) */
@media screen and (min-width: 667px) {
/* iPhone 6 in landscape */
.page { padding-left: 40px; padding-right: 40px; }
.page-number, #incoming-page-corner {
/* Stop lining this text up with .page's right margin. */
top: 10px;
right: 10px;
}
#article :nth-child(1 of .page):nth-last-child(1 of .page) {
padding-top: 26px;
}
}
@media screen and (max-width: 569px) {
/* iPhone 5 in landscape (568px) and smaller, including all iPhones in portrait */
h1.title {
font-size: 1.5558em;
}
h1 {
font-size: 1.4em;
}
h2 {
font-size: 1.2777em;
}
h3 {
font-size: 1.15em;
}
.subhead {
font-size: 1.2222em;
}
.metadata {
font-size: 0.9em;
line-height: 1.6em;
}
.title + .metadata {
margin-top: -0.65em;
}
}
@media screen and (min-width: 704px) {
/* iPad in landscape with the sidebar open */
.page { padding-left: 42px; padding-right: 42px; }
}
@media screen and (min-width: 736px) {
/* iPhone 6 Plus in landscape */
.page { padding-left: 60px; padding-right: 60px; }
#article :nth-child(1 of .page):nth-last-child(1 of .page) {
padding-top: 46px;
}
}
@media only screen and (min-width: 780px) {
#article {
max-width: 800px;
margin: 0 auto;
}
/* Readable margins. */
body.system #article { max-width: 83.2ex; }
body.athelas #article { max-width: 104ex; }
body.charter #article { max-width: 86ex; }
body.georgia #article { max-width: 94ex; }
body.iowanoldstyle #article { max-width: 90ex; }
body.palatino #article { max-width: 97ex; }
body.seravek #article { max-width: 87ex; }
body.timesnewroman #article { max-width: 97ex; }
body.uiserif #article { max-width: 93ex; }
:matches(body.pingfangsc, body.pingfangtc) #article { max-width: 87.6ex; }
:matches(body.heitisc, body.heititc) #article { max-width: 74.8ex; }
:matches(body.songtisc, body.songtitc) #article { max-width: 102ex; }
:matches(body.kaitisc, body.kaititc) #article { max-width: 102ex; }
:matches(body.yuantisc, body.yuantitc) #article { max-width: 86.2ex; }
:matches(body.libiansc, body.libiantc) #article { max-width: 95ex; }
:matches(body.weibeisc, body.weibeitc) #article { max-width: 99ex; }
:matches(body.yuppysc, body.yuppytc) #article { max-width: 87.6ex; }
body.hiraginosansw3 #article { max-width: 75.7ex; }
body.hiraginokakugothicpron #article { max-width: 76.4ex; }
body.hiraginominchopron #article { max-width: 77.5ex; }
body.hiraginomarugothicpron #article { max-width: 75.1ex; }
body.applesdgothicneo #article { max-width: 82ex; }
body.nanumgothic #article { max-width: 88.6ex; }
body.nanummyeongjo #article { max-width: 94.1ex; }
.page {
/* We don't want the lines seperating pages to extend beyond the primary text column. */
padding-left: 0px;
padding-right: 0px;
margin-left: 70px;
margin-right: 70px;
}
}
#article {
-webkit-font-smoothing: subpixel-antialiased;
}
/* Reader's paper appearance. */
html.paper {
height: 100%;
}
html.paper body {
height: calc(100% - 44px);
}
html.paper body:after {
content: "";
height: 22px;
display: block;
}
/* Clearfix */
html.paper .page::after {
content: "";
display: table;
clear: both;
}
html.paper #article {
min-height: 100%;
margin: 22px auto 0 auto;
}
html.paper #article :nth-child(1 of .page), html.paper #article :nth-child(1 of .page):nth-last-child(1 of .page) {
padding-top: 53px;
}
html.paper #article .page-number, html.paper #article #incoming-page-corner {
/* Stop lining this text up with .page's right margin. */
top: 14px;
right: 0px;
}
/* End Reader's paper appearance. */
/* Use slightly smaller page padding when vertically constrained. */
@media screen and (max-height: 700px) {
.page {
padding-top: 32px;
padding-bottom: 32px;
}
}
</style>
<style id="theming">
body.white {
--body-font-color: rgb(27, 27, 27);
--horizontal-line-color: rgb(220, 220, 220);
--paper-shadow-color: rgba(0, 0, 0, 0.2);
}
body.sepia {
--body-font-color: rgb(79, 50, 28);
--horizontal-line-color: rgb(230, 218, 201);
--paper-shadow-color: rgba(0, 0, 0, 0.2);
}
body.gray {
--body-font-color: rgba(255, 255, 255, 0.78);
--horizontal-line-color: rgb(111, 111, 111);
}
body.night {
--body-font-color: rgb(176, 176, 176);
--horizontal-line-color: rgb(62, 62, 62);
}
body.night.oled {
--body-font-color: rgb(210, 210, 210);
--horizontal-line-color: rgba(210, 210, 210, 0.35);
}
body.watch.night.oled {
--body-font-color: rgb(174, 180, 191);
}
html:not(.paper) body.white, body.white #article {
background-color: white;
}
html:not(.paper) body.sepia, body.sepia #article {
background-color: rgb(248, 241, 227);
}
html:not(.paper) body.gray, body.gray #article {
background-color: rgb(74, 74, 77);
}
html:not(.paper) body.night, body.night #article {
background-color: rgb(18, 18, 18);
}
html:not(.paper) body.night.oled, body.night.oled #article {
background-color: black;
}
/* OS X Reader draws backdrop background colors outside of web content, so the follow set only applies to iOS. */
html.paper body.ios.white {
background-color: rgb(230, 230, 230);
}
html.paper body.ios.sepia {
background-color: rgb(224, 216, 200);
}
html.paper body.ios.gray {
background-color: rgb(50, 50, 51);
}
html.paper body.ios.night {
background-color: black;
}
body.watch.night .metadata * {
color: rgb(214, 217, 223) !important;
}
html.paper body.white #article, html.paper body.sepia #article {
box-shadow: 0px 6px 12px 3px var(--paper-shadow-color);
}
html.paper body.gray #article {
box-shadow: 0px 6px 12px 3px rgba(0, 0, 0, 0.24);
}
html.paper body.night #article {
outline: 1px solid #272727;
}
body.watch.night.oled :matches(h1, h2, h3, h4, h5, h6) {
color: white;
}
body.sepia #article :matches(.leading-image, figure, .auxiliary, .pullquote) {
color: rgba(79, 50, 28, 0.9);
}
body.gray #article :matches(.leading-image, figure, .auxiliary, .pullquote) {
color: rgba(255, 255, 255, 0.7);
}
body.night #article :matches(.leading-image, figure, .auxiliary, .pullquote) {
color: rgba(255, 255, 255, 0.67);
}
body.night.oled #article :matches(.leading-image, figure, .auxiliary, .pullquote) {
color: rgba(210, 210, 210, 0.9);
}
body.sepia #article a[href] {
color: rgb(209, 150, 0);
}
body.gray #article a[href], body.night #article a[href] {
color: rgb(90, 200, 250);
}
body.watch.night.oled #article a[href] {
color: rgb(32, 148, 250);
}
body #article :matches(.page, .metadata a[href]) {
color: var(--body-font-color);
}
body #article .page {
border-top-color: var(--horizontal-line-color);
}
body #article hr {
background: var(--horizontal-line-color);
}
body.sepia .subhead {
color: rgba(79, 50, 28, 0.72);
}
body.gray .subhead {
color: rgba(255, 255, 255, 0.65);
}
body.night .subhead {
color: rgba(185, 185, 185, 0.9);
}
body.night.oled .subhead {
color: rgba(210, 210, 210, 0.85);
}
body.sepia :matches(#article .page-number, #incoming-page-corner) {
color: rgba(63, 41, 23, 0.5);
}
body.gray :matches(#article .page-number, #incoming-page-corner) {
color: rgba(255, 255, 255, 0.45);
}
body.night :matches(#article .page-number, #incoming-page-corner) {
color: rgba(255, 255, 255, 0.55);
}
body.night.oled :matches(#article .page-number, #incoming-page-corner) {
color: rgba(210, 210, 210, 0.8);
}
body.sepia #article blockquote, body.sepia #article q {
color: rgb(140, 112, 79);
}
body.sepia #article blockquote:not(.simple):not(.pullquote) {
border-left-color: rgba(154, 128, 92, 0.1);
}
body.gray #article blockquote, body.gray #article q {
color: rgba(255, 255, 255, 0.6);
}
body.gray #article blockquote:not(.simple):not(.pullquote) {
border-left-color: rgba(255, 255, 255, 0.15);
}
body.night #article blockquote, body.night #article q {
color: rgba(255, 255, 255, 0.6);
}
body.night #article blockquote:not(.simple):not(.pullquote) {
border-left-color: rgba(255, 255, 255, 0.15);
}
body.night.oled #article blockquote, body.night.oled #article q {
color: rgba(210, 210, 210, 0.85);
}
body.night.oled #article blockquote:not(.simple):not(.pullquote) {
border-left-color: rgba(210, 210, 210, 0.2);
}
body.watch.night #article blockquote, body.watch.night #article q {
color: var(--body-font-color);
}
body.watch.night #article blockquote:not(.simple):not(.pullquote) {
border-left-color: rgb(51, 51, 51);
}
body.sepia table :matches(td, th) {
border-color: rgb(230, 218, 202);
}
body.sepia table th {
background-color: rgba(154, 128, 92, 0.06);
}
body.gray table :matches(td, th) {
border-color: rgb(106, 106, 106);
}
body.gray table th {
background-color: rgba(255, 255, 255, 0.035);
}
body.night table :matches(td, th) {
border-color: rgb(50, 50, 50);
}
body.night table th {
background-color: rgba(255, 255, 255, 0.045);
}
body.night.oled table th {
background-color: rgba(255, 255, 255, 0.075);
}
@media (inverted-colors) {
/* If the user has turned on the "smart invert" accessibility preference, they generally prefer
their images, such as photos, to not be inverted. Provide this by applying a filter that
inverts the colors again (effectively un-inverting). */
body:not(.gray):not(.night) #article :matches(img, video) {
filter: invert();
}
body:not(.gray):not(.night) #article picture {
filter: none !important;
}
body.gray, body.night {
filter: invert();
}
body:matches(.gray, .night) #article :matches(img:not(picture > img), picture, video) {
filter: none !important;
}
body:matches(.gray, .night) #article iframe {
filter: invert();
}
html.paper body.white #article, html.paper body.sepia #article {
--paper-shadow-color: rgba(255, 255, 255, 0.2);
}
/* The background color of <body> is not inverted by the filter. Achieve this by manually
setting the inverse color. */
html:not(.paper) body.gray {
background-color: rgb(165, 165, 163) !important;
}
html.paper body.gray {
background-color: rgb(205, 205, 204) !important;
}
html:not(.paper) body.night {
background-color: rgb(237, 237, 237) !important;
}
html:not(.paper) body.night.oled {
background-color: white !important;
}
html.paper body.night {
background-color: white !important;
}
}
</style>
<style id="locale-specific-adjustments">
.locale-ja .page {
text-align: justify;
}
.locale-zh-Hans .page {
text-align: justify;
}
.locale-zh-Hant .page {
text-align: justify;
word-break: break-all;
}
.locale-hi .title {
line-height: 1.65em;
}
/* See 32728279 and 54061051. */
.locale-ur.notonastaliqurdu :matches(h1, h2, h3, h4, h5, h6) {
font-weight: normal;
line-height: 2.55em;
}
</style>
<style id="dynamic-article-content"></style>
<!-- For Twitter’s script to find and script world to be created (see 34937240). -->
<script>
window.isReaderPage = true;
</script>
</head>
<body>
<iframe aria-hidden="true" id="next-page-container"></iframe>
<div id="article" role="article">
<!-- This node will contain a number of div.page. -->
</div>
</body>
</html>
// # sourceURL=__InjectedScript_ReaderArticleFinder.js
/* Copyright (c) 2024 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 N = n[f],
C = m.searchParams.get(N);
if (C && !isNaN(parseInt(C))) {
h = N;
break
}
}
if (d && h) {
var A = e.getAttribute("width"),
S = e.getAttribute("height");
if (!isNaN(parseInt(A)) && !isNaN(parseInt(S)))
return m.searchParams.set(d, A), m.searchParams.set(h, S), 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)
{
return EmbeddedTwitterIframeSrcRegEx.test(e.getAttribute("src")) && "Twitter Tweet" === e.getAttribute("title")
}
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" ],
[ /^(.*\.)?m\.wikipedia\.org\.?$/, "#content #bodyContent" ],
[ /^(.*\.)?theintercept\.com\.?$/, ".PostContent" ],
[ /^(.*\.)?tools\.ietf\.org\.?$/, "div.content" ],
[ /^(.+\.)?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 normalizedElementTagName(e)
{
return e.localName
}
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 = .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 = .75,
ArticleRegEx = /(?:(?:^|\s)(?:(post|hentry|entry)[-_]{0,2}(?:content|text|body)?|article[-_]{0,2}(?:content|text|body|page|copy)?)(?:\s|$))/i,
ArticleMatchBonus = .5,
CarouselRegEx = /carousel/i,
CarouselMatchPenalty = .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 = .1,
DefaultNumberOfTextNodesToCheckForLanguageMultiplier = 3,
NumberOfCharactersPerTextNodeToEvaluateForLanguageMultiplier = 12,
MinimumRatioOfCharactersForLanguageMultiplier = .5,
ScoreMultiplierForChineseJapaneseKorean = 3,
MinimumContentMediaHeight = 150,
MinimumContentMediaWidthToArticleWidthRatio = .25,
MaximumContentMediaAreaToArticleAreaRatio = .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 = .75,
SubheadRegex = /sub(head|title)|description|dec?k|abstract/i,
HeaderMinimumDistanceFromArticleTop = 200,
HeaderLevenshteinDistanceToLengthRatio = .75,
MinimumRatioOfListItemsBeingRelatedToSharingToPruneEntireList = .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 = .1,
TextNodeLengthPower = 1.25,
LazyLoadRegex = /lazy/i,
HeaderElementsSelector = "h1, h2, h3, h4, h5, h6",
PageType = {
homepage : "homepage",
searchResults : "search-results",
article : "article"
},
StringSimilarityToDeclareStringsNearlyIdentical = .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 && a.top - o.bottom > AppendedArticleCandidateMaximumVerticalDistanceFromArticle)
return null;
if (a.left > o.right || a.right < o.left)
return null;
if (elementLooksLikePartOfACarousel(e))
return null;
var l = new CandidateElement(e, n);
return l.isPrepended = r, l
}, 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 N = BaseFontSize;
return p && (N = E /= p), this.calculateLanguageScoreMultiplier(), h / g * 1e3 * (N / 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 -= .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 = .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) {
if (normalizedElementTagName(f = a.children[l]) === i && f.className === r.className && f !== r)
return !0
}
var s = r.classList;
if (s.length || (r = r.parentElement) && ((s = r.classList).length || (r = r.parentElement) && (s = r.classList)), s.length) {
e || (e = []);
var c = e.length;
for (l = 0; l < c; ++l)
e[l].element.candidateElement = e[l];
var u = elementsMatchingClassesInClassListIgnoringCommonLayoutClassNames(s, this.contentDocument),
m = !1,
d = elementDepth(r),
h = n(r),
g = u.length;
for (l = 0; l < g; ++l) {
var f;
if ((f = u[l]) !== r && (f.parentElement !== r && r.parentElement !== f && isElementVisible(f))) {
var p = f.candidateElement;
if ((p || (p = new CandidateElement(f, this.contentDocument))) && p.basicScore() * ReaderMinimumAdvantage > this.basicScore()) {
if (f.closest("section") && r.closest("section"))
return !1;
if (SectionRegex.test(f.className) && SectionRegex.test(r.className))
return !1;
if (n(f) && !h)
return !1;
if (!m && cachedElementBoundingRect(f).bottom < cachedElementBoundingRect(this.element).top) {
m = !0;
continue
}
if (t(r.previousElementSibling, f.previousElementSibling) || t(r.nextElementSibling, f.nextElementSibling)) {
var E = r.querySelector(HeaderElementsSelector),
v = f.querySelector(HeaderElementsSelector);
if (E && v && elementsHaveSameTagAndClassNames(E, v))
return !0;
if (E = r.previousElementSibling, v = f.previousElementSibling, E && v && elementIsAHeader(E) && elementIsAHeader(v) && elementsHaveSameTagAndClassNames(E, v))
return !0
}
if (elementDepth(f) === d)
for (; f.parentElement && r.parentElement && f.parentElement !== r.parentElement;)
f = f.parentElement, r = r.parentElement;
for (; r.childElementCount <= 1;) {
if (!r.childElementCount || !f.childElementCount)
return !1;
if (f.childElementCount > 1)
return !1;
if (normalizedElementTagName(r.firstElementChild) !== normalizedElementTagName(f.firstElementChild))
return !1;
r = r.firstElementChild, f = f.firstElementChild
}
if (f.childElementCount <= 1)
return !1;
v = f.firstElementChild;
var N = f.lastElementChild,
C = (E = r.firstElementChild, r.lastElementChild);
if (normalizedElementTagName(v) !== normalizedElementTagName(E))
return !1;
if (normalizedElementTagName(N) !== normalizedElementTagName(C))
return !1;
var A = v.className,
S = N.className,
b = E.className,
y = N.className,
T = y === b ? 2 : 1;
if (A.length || b.length) {
if (!A.length || !b.length)
return !1;
if (A === b && elementsMatchingClassesInClassList(E.classList, r).length <= T)
return !0
}
if (S.length || y.length) {
if (!S.length || !y.length)
return !1;
if (S === y && elementsMatchingClassesInClassList(N.classList, r).length <= T)
return !0
}
var x = E.clientHeight,
R = C.clientHeight;
return !(!x || !v.clientHeight) && (!(!R || !N.clientHeight) && (x === v.clientHeight || R === N.clientHeight))
}
}
}
for (l = 0; l < c; ++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
};
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 = {
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() {
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))
},
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() {
this.resetArticleInformation(), this.prepareToTransitionToReader()
},
prepareToTransitionToReader : function() {
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,
y = e.parentElement;
if (y)
for (var S = y.children, A = (u = 0, S.length); u < A; ++u) {
var N = S[u];
if (N !== e && (normalizedElementTagName(N) === v && N.className === T)) {
var b = CandidateElement.candidateIfElementIsViable(N, this.contentDocument, !0);
if (b && !(b.finalScore() < ReaderMinimumScore))
return void (this.article.element = y)
}
}
}
},
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 = .33,
r = .5,
a = .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 y = t.children,
S = y.length;
if (!S && !/\S/.test(e.innerText))
return !0;
var A = 0,
N = 0;
for (d = 0; d < S; ++d) {
var b = y[d];
if (SharingRegex.test(b.className))
A++;
else {
var x = b.children;
1 === x.length && SharingRegex.test(x[0].className) && A++
}
NegativeRegEx.test(y[d].className) && N++
}
return A / S >= MinimumRatioOfListItemsBeingRelatedToSharingToPruneEntireList || N / S >= MinimumRatioOfListItemsBeingRelatedToSharingToPruneEntireList
}
if (1 === e.childElementCount) {
var C = e.firstElementChild;
if ("a" === normalizedElementTagName(C))
return !1;
if ("span" === normalizedElementTagName(C) && "converted-anchor" === C.className && nearestAncestorElementWithTagName(C, "table"))
return !1
}
var D = e.getElementsByTagName("img"),
I = D.length;
if (I) {
var M = 0;
for (d = 0; d < I; ++d) {
var L = D[d].originalElement;
if (isElementVisible(L)) {
var R = cachedElementBoundingRect(L);
M += R.width / I * (R.height / I)
}
}
if (M > o)
return !1
}
if (!this.commaCountIsLessThan(e, 10))
return !1;
var w = e.getElementsByTagName("p").length,
F = e.getElementsByTagName("br").length,
_ = w + Math.floor(F / 2);
if (I > _ && "table" !== s)
return !0;
if (!e.closest("table") && !e._originalElementDepthInCollapsedArea && !T) {
if (e.getElementsByTagName("li").length > _ && dominantFontFamilyAndSizeForElement(t.querySelector("li")) !== n)
return !0;
if (e.textContent.length < l && 1 !== I)
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 / _ > i)
return !0;
if ("table" === s) {
if (removeWhitespace(e.innerText).length <= .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 || !this.leadingMediaIsAppropriateWidth(this._leadingMediaElement))
return null;
var e = this._leadingMediaElement.closest("figure");
if (e)
return this.cleanArticleNode(e, e.cloneNode(!0), CleaningType.LeadingMedia, !0);
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
},
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), y && (y += e), S && (S += e), A && (A += e), N && (N += e)
}
function a()
{
1 === T && (T = 0), 1 === y && (y = 0), 1 === S && (S = 0), 1 === A && (A = 0), 1 === N && (N = 0)
}
function l()
{
const t = .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 = .9;
return !(cachedElementBoundingRect(e).height > n * cachedElementBoundingRect(t).height)
}
function c(e, t)
{
const n = 1.1,
i = 1.4;
t && H && (e.matches(HeaderElementsSelector) || (t > i * H || V.test(b.className) && t > n * H) && !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,
y = 0,
S = 0,
A = 0,
N = 0,
b = e,
x = b.ownerDocument.defaultView,
C = t,
D = this.articleTitle(),
I = this._articleTitleElement,
M = (this.articleSubhead(), this._articleSubheadElement),
L = I && cachedElementBoundingRect(I).top > cachedElementBoundingRect(e).bottom,
R = isElementVisible(e),
w = new Set([ I, M ]),
F = new Set;
if (n === CleaningType.MainArticleContent) {
this.updateArticleBylineAndDateElementsIfNecessary();
var _ = this.articleBylineElement();
_ && F.add(_);
var O = this.articleDateElement();
O && F.add(O)
}
var B = this.dominantContentSelectorAndDepth(e),
P = l(),
k = new Set;
this.previouslyDiscoveredPageURLStrings.forEach((function(e) {
k.add(e)
}));
var q = this.nextPageURL();
q && k.add(q);
var z = null;
this._articleTitleElement && (z = cachedElementBoundingRect(this._articleTitleElement));
var W = this.functionToPreventPruningElementDueToInvisibility(),
U = dominantFontFamilyAndSizeForElement(e),
H = dominantFontSizeInPointsFromFontFamilyAndSizeString(U);
const V = /pull(ed)?quote/i;
for (var j = [], G = [], X = [], Y = [], K = []; b;) {
try {
var Q, J = null,
$ = normalizedElementTagName(C),
Z = !1,
ee = elementLooksLikeDropCap(b);
if (C.originalElement = b, !N && elementAppearsToBeCollapsed(b) && (N = 1), (d.has($) || this.isAMPPage() && f.has($)) && (J = C), !J && b !== e && w.has(b) ? J = C : !J && b !== e && F.has(b) ? (C.parentElementBeforePruning = C.parentElement, J = C, j.push(C))
: elementIsAHeader(C) && previousLeafElementForElement(b) === I && C.classList.add("protected"),
"twitter-widget" === $ && C.classList.add("protected"), !J && ("h1" === $ || "h2" === $))
if (b.offsetTop - e.offsetTop < HeaderMinimumDistanceFromArticleTop) {
var te = trimmedInnerTextIgnoringTextTransform(b),
ne = te.length * HeaderLevenshteinDistanceToLengthRatio;
levenshteinDistance(D, te) <= ne && (J = C)
}
if (J || this.isMediaWikiPage() && /editsection|icon-edit|edit-page|mw-empty-elt/.test(b.className) && (J = C), "video" === $)
if (C.getAttribute("src")) {
C.classList.add("protected");
var ie = cachedElementBoundingRect(b);
C.setAttribute("width", ie.width), C.setAttribute("height", ie.height), C.removeAttribute("style");
b.hasAttribute("autoplay") && b.hasAttribute("muted") && b.hasAttribute("loop") ? C.setAttribute("data-reader-silent-looped-animation", "") : (C.setAttribute("controls", !0), C.removeAttribute("autoplay"), C.removeAttribute("preload"))
} else
J = C;
J || (Q = getComputedStyle(b));
let t = function() {
if ("div" !== $ && "span" !== $)
return !1;
if (LazyLoadRegex.test(b.className))
return !0;
for (let e of attributesForElement(b))
if (/^data-/.test(e.name) && LazyLoadRegex.test(e.value) && cachedElementBoundingRect(b).height)
return !0;
return !1
}();
if (!J && t && (!b.innerText || b.previousElementSibling && "noscript" === normalizedElementTagName(b.previousElementSibling)))
if (Ie = lazyLoadingImageURLForElement(C, b.className)) {
var re = this.contentDocument.createElement("img");
re.setAttribute("src", Ie), C.parentNode.replaceChild(re, C), (C = re).originalElement = b, $ = normalizedElementTagName(C), J = C, C.classList.add("protected")
}
if (!J && "img" !== $ && /img/.test($)) {
lazyLoadingImageURLForElement(C, b.className) && ((C = changeElementType(C, "img")).originalElement = b, $ = "img")
}
if (!J && "div" === $ && C.parentNode) {
var ae = b.querySelectorAll("a, blockquote, dl, div, img, ol, p, pre, table, ul"),
le = T || "none" !== Q.float,
oe = null;
if (le || ae.length ? elementIndicatesItIsASchemaDotOrgImageObject(b) && !C.querySelector("figure, .auxiliary") ? oe = "figure" : ee && (oe = "span") : oe = "p", oe) {
for (var se = C.parentNode, ce = this.contentDocument.createElement(oe); C.firstChild;) {
var me = C.firstChild;
ce.appendChild(me)
}
se.replaceChild(ce, C), (C = ce).originalElement = b, $ = normalizedElementTagName(C)
}
}
if (b.dataset && b.dataset.mathml && b.querySelector("math") && X.push(C), !J && C.parentNode && h.has($) && (C._originalElementDepthInCollapsedArea = N, E.push(C)), J || (isElementPositionedOffScreen(b) ? J = C : b === e || T || "none" === Q.float || P || !(cachedElementBoundingRect(b).height >= FloatMinimumHeight || b.childElementCount > 1) || (T = 1)), !J) {
if (sanitizeElementByRemovingAttributes(C), n === CleaningType.MetadataContent)
if ("|" === C.innerText)
C.innerText = "", C.classList.add("delimiter");
else if ("time" === normalizedElementTagName(C)) {
var de = C.previousElementSibling;
if (de && "span" === normalizedElementTagName(de) && !de.classList.contains("delimiter")) {
var he = this.contentDocument.createElement("span");
he.classList.add("delimiter"), C.before(he)
}
} else
"figure" === $ && (J = C);
if ("both" === Q.clear && C.classList.add("clear"), "ul" === $ || "ol" === $ || "menu" === $) {
if (z && !N && cachedElementBoundingRect(b).top < z.top)
J = C;
else if ("none" === Q["list-style-type"] && "none" === Q["background-image"]) {
for (var ue = b.children, ge = ue.length, fe = !0, pe = 0; pe < ge; ++pe) {
var Ee = ue[pe],
ve = getComputedStyle(Ee);
if ("none" !== ve["list-style-type"] || 0 !== parseInt(ve["-webkit-padding-start"])) {
fe = !1;
break
}
var Te = getComputedStyle(Ee, ":before").content;
if (/\u2022|\u25e6|\u2023|\u2219|counter/.test(Te)) {
fe = !1;
break
}
}
fe && C.classList.add("list-style-type-none")
}
if (b.querySelector("code")) {
const e = /monospace|menlo|courier/i;
var ye = dominantFontFamilyAndSizeForElement(b);
e.test(ye) && (C.classList.add("code-block"), C.classList.add("protected"))
}
}
if (S || "normal" === Q.fontStyle || (u.has($) || C.style && (C.style.fontStyle = Q.fontStyle), S = 1), !A && "normal" !== Q.fontWeight) {
if (!g.has($)) {
var Se = parseInt(Q.fontWeight),
Ae = null;
isNaN(Se) ? Ae = Q.fontWeight : Se <= 400 || Se >= 500 && (Ae = "bold"), Ae && C.style && (C.style.fontWeight = Ae)
}
A = 1
}
if (T && "section" !== $ && s(b, e) || "aside" === $) {
ye = dominantFontFamilyAndSizeForElement(b);
var Ne = dominantFontSizeInPointsFromFontFamilyAndSizeString(ye),
be = ye && ye === U;
if (1 !== T || ee || (cachedElementBoundingRect(b).width <= MaximumFloatWidth ? C.setAttribute("class", "auxiliary float " + Q.float) : be || C.classList.add("auxiliary")), C.closest(".auxiliary") && b.style) {
var xe = b.style.getPropertyValue("width");
if ("table" === Q.display && /%/.test(xe) && parseInt(xe) < 2)
C.style.width = Q.width;
else if (xe)
C.style.width = xe;
else {
var Ce = x.getMatchedCSSRules(b, "", !0);
if (Ce)
for (pe = Ce.length - 1; pe >= 0; --pe) {
xe = Ce[pe].style.getPropertyValue("width");
var De = parseInt(xe);
if (xe && (isNaN(De) || De > 0)) {
C.style.width = xe;
break
}
}
}
1 !== T || xe || (C.style.width = cachedElementBoundingRect(b).width + "px")
}
ee || c(C, Ne)
}
if ("table" === $)
y || (y = 1);
else if ("img" === $) {
var Ie;
if (Ie = lazyLoadingImageURLForElement(C, b.className)) {
C.setAttribute("src", Ie);
var Me = !!C.closest("figure");
if (!Me) {
var Le = attributesForElement(b),
Re = Le.length;
for (pe = 0; pe < Re; ++pe)
if (p.test(Le[pe].nodeName)) {
Me = !0;
break
}
}
Me && C.classList.add("protected"), Z = !0
}
!Ie && C.hasAttribute("src") || !b.hasAttribute("data-srcset") || C.setAttribute("srcset", b.getAttribute("data-srcset")), C.removeAttribute("border"), C.removeAttribute("hspace"), C.removeAttribute("vspace");
var we = C.getAttribute("align");
if (C.removeAttribute("align"), "left" !== we && "right" !== we || (C.classList.add("float"), C.classList.add(we)), !T && !Z) {
var Fe, _e = (Fe = cachedElementBoundingRect(b)).width,
Oe = Fe.height;
hasClassMatchingRegexp(b, ProgressiveLoadingRegex) && b.nextElementSibling && "img" === normalizedElementTagName(b.nextElementSibling) ? J = C : imageIsContainedByContainerWithImageAsBackgroundImage(b) ? C.classList.add("protected")
: 1 === _e&& 1 === Oe || z&& Oe < MinimumHeightForImagesAboveTheArticleTitle&& Fe.bottom < z.top ? J = C
: _e < ImageSizeTiny && Oe < ImageSizeTiny && C.setAttribute("class", "reader-image-tiny")
}
if (n === CleaningType.MetadataContent)
((Fe = cachedElementBoundingRect(b)).width > MaximumWidthOrHeightOfImageInMetadataSection || Fe.height > MaximumWidthOrHeightOfImageInMetadataSection) && (J = C);
if (b.classList.contains("emoji")) {
let e = urlFromString(C.src);
if (e && "s.w.org" === e.hostname && e.pathname.startsWith("/images/core/emoji/")) {
let e = this.replaceImageWithAltText(C);
e && ((C = e).originalElement = b, $ = normalizedElementTagName(C), J = C, C.classList.add("protected"))
}
}
} else if ("font" === $)
C.removeAttribute("size"), C.removeAttribute("face"), C.removeAttribute("color");
else if ("a" === $ && C.parentNode) {
let e, t;
C instanceof HTMLAnchorElement ? (e = C.getAttribute("href"), t = HTMLAnchorElement) : C instanceof SVGAElement && (e = C.getAttribute("xlink:href"), t = SVGAElement);
let i = C.originalElement.ownerDocument.location,
r = urlStringShouldHaveItsAnchorMadeNonFunctional(e, i);
if (t === HTMLAnchorElement && "author" === b.getAttribute("itemprop"))
C.classList.add("protected");
else if (e && e.length && ("#" === e[0] || r)) {
const e = new Set([ "li", "sup" ]);
if (!y && !C.childElementCount && 1 === C.parentElement.childElementCount && !e.has(normalizedElementTagName(C.parentElement)))
this.contentDocument.evaluate("text()", C.parentElement, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null).snapshotLength || (J = C);
if (!J) {
ce = this.contentDocument.createElement("span");
if (1 === C.childElementCount && "img" === normalizedElementTagName(C.firstElementChild)) {
var Be = C.firstElementChild;
Be.width > AnchorImageMinimumWidth && Be.height > AnchorImageMinimumHeight && ce.setAttribute("class", "converted-image-anchor")
}
for (ce.className || ce.setAttribute("class", "converted-anchor"); C.firstChild;)
ce.appendChild(C.firstChild);
C.parentNode.replaceChild(ce, C), (C = ce).originalElement = b
}
} else if (AdvertisementHostRegex.test(C.host) && !C.innerText)
J = C;
else if (n !== CleaningType.MetadataContent && I && !L && I.compareDocumentPosition(b) & document.DOCUMENT_POSITION_PRECEDING && cachedElementBoundingRect(b).top < cachedElementBoundingRect(I).top)
G.push(C);
else {
var Pe = b.children;
1 === Pe.length && "img" === normalizedElementTagName(Pe[0]) && !b.innerText && anchorLooksLikeDownloadFlashLink(b) && (J = C)
}
r && (C.removeAttribute("xlink:href"), C.removeAttribute("href"))
} else if ("aside" === $ || "blockquote" === $ || "q" === $ || "div" === $ && V.test(b.className)) {
ye = dominantFontFamilyAndSizeForElement(b), Ne = dominantFontSizeInPointsFromFontFamilyAndSizeString(ye);
ee || c(C, Ne)
} else if ("cite" === $) {
var ke = pseudoElementContent(b, ":after") ?? "",
qe = document.createElement("span");
qe.innerText = ke, C.after(qe)
} else
"pre" === $ ? C.style.whiteSpace = Q.whiteSpace : "source" === $ && b.hasAttribute("data-srcset") ? (C.setAttribute("srcset", b.getAttribute("data-srcset")), C.classList.add("protected"))
: C instanceof SVGAnimateElement && "xlink:href" === C.attributes.attributeName.value && (J = C)
}
if (Q && R && !Z) {
var ze = "none" === Q.display || "visible" !== Q.visibility || computedStyleIndicatesElementIsInvisibleDueToClipping(Q);
if (ze || "img" === $ || (ze = "0" === Q.opacity && "absolute" === Q.position && !C.closest("figure")), ze && !N)
!!B && (v === B.depth && selectorForElement(b) === B.selector) || W(b, e) || (J = C)
}
if (!J && elementIsCommentBlock(b) && (J = C), !J && z && cachedElementBoundingRect(b).top < z.top && VeryLiberalCommentRegex.test(b.className) && C.parentElement && (J = C), !J && "a" === $ && k.has(b.href)) {
for (var We, Ue, He = b, Ve = C;
(He = He.parentElement) && (Ve = Ve.parentElement);) {
const t = 10;
if (cachedElementBoundingRect(He).top - cachedElementBoundingRect(b).top > t)
break;
if (He === e)
break;
o(He) && (We = He, Ue = Ve)
}
We && (J = Ue, b = We, (C = Ue).originalElement = b, $ = normalizedElementTagName(C)), He = null, Ve = null, We = null, Ue = null
}
} catch (e) {
J = C
}
if (!J || J.parentElement || i || (J = null), "div" === $ ? Y.push(C) : "aside" === $ && K.push(C), !J) {
let e = this._weakMapOfOriginalElementToUniqueID.get(C.originalElement);
e || (e = this._nextUniqueID()), this._mapOfUniqueIDToOriginalElement.set(e, C.originalElement), C.setAttribute(this.elementReaderUniqueIDAttributeKey(), e), this._weakMapOfOriginalElementToUniqueID.set(C.originalElement, e)
}
var je = J ? null : b.firstElementChild;
if (je)
b = je, C = C.firstElementChild, r(1);
else {
for (var Ge; b !== e && !(Ge = b.nextElementSibling);)
b = b.parentElement, C = C.parentElement, r(-1);
if (b === e) {
if (J && !elementIsProtected(J))
if (J.parentElement)
J.remove();
else if (i)
return null;
break
}
b = Ge, C = C.nextElementSibling, a()
}
if (J && !elementIsProtected(J))
if (J.parentElement)
J.remove();
else if (i)
return null
}
for (let e of t.querySelectorAll("iframe")) {
if (elementLooksLikeEmbeddedTweet(e.originalElement))
(Xe = this.adoptableSimpleTweetFromTwitterElement(e)) && e.parentElement.replaceChild(Xe, e);
e.classList.add("protected"), e.setAttribute("sandbox", "allow-scripts allow-same-origin")
}
for (let e of t.querySelectorAll("twitter-widget")) {
var Xe;
if (elementLooksLikeEmbeddedTweet(e.originalElement))
(Xe = this.adoptableSimpleTweetFromTwitterElement(e)) && e.parentElement.replaceChild(Xe, e);
e.classList.add("protected")
}
const Ye = t.querySelectorAll("blockquote"),
Ke = Ye.length;
for (pe = 0; pe < Ke; ++pe) {
const e = Ye[pe],
t = e.originalElement;
t && this.convertBlockquoteTweetToSimpleTweetIfAppropriate(e, t)
}
for (pe = E.length - 1; pe >= 0; --pe) {
(vt = E[pe]).parentNode && this.shouldPruneElement(vt, vt.originalElement, U) && vt.remove(), delete vt._originalElementDepthInCollapsedArea
}
var Qe = G.length;
for (pe = 0; pe < Qe; ++pe)
G[pe].remove();
var Je = t.querySelectorAll(".float");
for (pe = 0; pe < Je.length; ++pe) {
var $e = !1,
Ze = Je[pe];
if (!$e) {
var et = Ze.querySelectorAll("a, span.converted-image-anchor"),
tt = Ze.querySelectorAll("span.converted-anchor");
$e = Ze.parentNode && tt.length > et.length
}
if (!$e) {
var nt = Ze.querySelectorAll("embed, object").length,
it = Ze.originalElement.querySelectorAll("embed, object").length;
!nt && it && ($e = !0)
}
if (!$e) {
for (var rt = Ze.originalElement.getElementsByTagName("img"), at = rt.length, lt = 0, ot = 0; ot < at && (R && isElementVisible(rt[ot]) && lt++, !(lt > 1)); ++ot)
;
if (1 === lt)
Ze.getElementsByTagName("img").length || ($e = !0)
}
if (!$e) {
const e = "img, video, embed, iframe, object, svg";
/\S/.test(Ze.innerText) || Ze.matches(e) || Ze.querySelector(e) || ($e = !0)
}
$e && !elementIsProtected(Ze) && Ze.remove()
}
var st = t.querySelectorAll("br");
for (pe = st.length - 1; pe >= 0; --pe) {
var ct = st[pe];
ct.originalElement && "block" === getComputedStyle(ct.originalElement.parentElement).display && (m(ct, "nextSibling") || m(ct, "previousSibling")) && ct.remove()
}
if (i && !removeWhitespace(t.innerText).length && (n !== CleaningType.LeadingMedia || !t.querySelector("video, iframe, img")))
return null;
var mt = {},
dt = (et = t.querySelectorAll("a")).length;
for (pe = 0; pe < dt; ++pe) {
mt[ht = (ft = et[pe]).style.fontWeight] || (mt[ht] = []), mt[ht].push(ft)
}
for (var ht in mt) {
var ut = mt[ht],
gt = ut.length;
if (gt > .7 * dt)
for (pe = 0; pe < gt; ++pe) {
var ft;
(ft = ut[pe]).style.fontWeight = null, ft.getAttribute("style") || ft.removeAttribute("style")
}
}
var pt = t.querySelectorAll(".protected"),
Et = pt.length;
for (pe = 0; pe < Et; ++pe) {
var vt;
(vt = pt[pe]).classList.remove("protected"), vt.classList.length || vt.removeAttribute("class")
}
var Tt = t.querySelectorAll("p.auxiliary"),
yt = Tt.length;
for (pe = 0; pe < yt; ++pe) {
for (var St = Tt[pe], At = [ St ], Nt = St.nextElementSibling; Nt && "p" === normalizedElementTagName(Nt) && Nt.classList.contains("auxiliary");)
At.push(Nt), Nt = Nt.nextElementSibling;
var bt = At.length;
if (bt > 1) {
for (ot = 0; ot < bt; ++ot) {
var xt = At[ot];
xt.classList.remove("auxiliary"), xt.style && (xt.style.width = null), cleanStyleAndClassList(xt)
}
pe += bt - 1
}
}
for (pe = Y.length - 1; pe >= 0; --pe) {
var Ct = Y[pe];
Ct !== t && elementWouldAppearBetterAsFigureOrAuxiliary(Ct.originalElement, Ct) && changeElementType(Ct, "figure")
}
for (pe = K.length - 1; pe >= 0; --pe) {
var Dt = K[pe];
Dt !== t && elementWouldAppearBetterAsFigureOrAuxiliary(Dt.originalElement, Dt) && Dt.classList.add("auxiliary")
}
var It = j.length;
for (pe = 0; pe < It; ++pe) {
var Mt = j[pe],
Lt = Mt.parentElementBeforePruning,
Rt = null,
wt = null;
if (Lt)
Rt = depthOfElementWithinElement(Lt, t), wt = selectorForElement(Lt);
var Ft = Lt ? Lt.closest("ul") : null;
if (Ft)
Ft.remove();
else {
const e = 40;
Lt && cachedElementBoundingRect(Lt.originalElement).height < e && (!B || B.selector !== wt || B.depth !== Rt) ? Lt.remove() : Mt.remove()
}
}
var _t = X.length;
for (pe = 0; pe < _t; ++pe) {
var Ot = X[pe],
Bt = this.contentDocument.createElement("div");
Bt.innerHTML = Ot.dataset ? Ot.dataset.mathml : "", Ot.parentNode.replaceChild(Bt, Ot)
}
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 = "&mdash; " + 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 = .5,
i = .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 = .6,
g = 3,
f = 1.5,
p = .8,
E = .8,
v = 9,
T = 1.5,
y = /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), A = function() {
for (var e = this.articleNode(); e; e = e.parentElement)
if (elementIndicatesItIsASchemaDotOrgArticleContainer(e))
return e;
return null
}.bind(this)(), N = A ? this.contentFromUniqueMetadataSelector(A, "meta[itemprop=headline]") : "", b = A ? this.contentFromUniqueMetadataSelector(A, "meta[itemprop=alternativeHeadline]") : "", x = this.contentDocument, C = x.location, D = x.title, I = S(x, "meta[property='og:title']"), M = this.contentFromUniqueMetadataSelector(x, "meta[property='og:site_name']"), L = S(x, "meta[name='twitter:title']"), R = S(x, "meta[name='sailthru.headline']"), w = this.schemaDotOrgMetadataObjectForArticle(), F = w ? w.headline : null, _ = this.articleNode(), O = cachedElementBoundingRect(_);
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",
z = normalizedElementTagName(this.article.element);
"dl" !== z && "dd" !== z || (q += ", dt");
for (var W = [], U = x.querySelectorAll(q), H = U.length, V = 0; V < H; ++V) {
var j = U[V],
G = normalizedElementTagName(j);
if ("a" === G)
j.innerText === I && t(j, C) && (j.previousElementSibling || j.nextElementSibling ? W.push(j) : W.push(j.parentElement));
else if ("div" === G || "span" === G || "p" === G) {
if (hasClassMatchingRegexp(j, i) || i.test(j.getAttribute("id"))) {
var X = j.parentElement;
elementIsAHeader(X) || W.push(j)
}
} else
W.push(j)
}
W = Array.prototype.slice.call(W, 0);
const Y = 2;
var K = this.article.element;
for (V = 0; V < Y; ++V)
K.parentElement && (K = K.parentElement);
for (var Q, J = K.querySelectorAll("a:not(svg a)"), $ = (V = 0, J.length); V < $; ++V) {
var Z = J[V];
if (Z.offsetTop > _.offsetTop + a)
break;
if (t(Z, C) && "#" !== Z.getAttribute("href")) {
W.push(Z);
break
}
}
var ee = W.map(trimmedInnerTextIgnoringTextTransform),
te = W.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(D, e);
return me[e] = n, n
};
for (V = 0; V < te; ++V) {
var he = W[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 (I) {
const e = t(I);
n += e, e > StringSimilarityToDeclareStringsNearlyIdentical && re.push(he)
}
if (L) {
const e = t(L);
n += e, e > StringSimilarityToDeclareStringsNearlyIdentical && ae.push(he)
}
if (N) {
const e = t(N);
n += e, e > StringSimilarityToDeclareStringsNearlyIdentical && le.push(he)
}
if (b) {
const e = t(b);
n += e, e > StringSimilarityToDeclareStringsNearlyIdentical && oe.push(he)
}
if (R) {
const e = t(R);
n += e, e > StringSimilarityToDeclareStringsNearlyIdentical && se.push(he)
}
if (F) {
const e = t(F);
n += e, e > StringSimilarityToDeclareStringsNearlyIdentical && ce.push(he)
}
n === ne ? ie.push(he) : n > ne && (ne = n, ie = [ he ])
}
let ge = [];
for (let e of W) {
let t = e.nextElementSibling;
t && SubheadRegex.test(t.className) && ge.push(e)
}
if (1 === re.length ? (Q = re[0]).headerText = trimmedInnerTextIgnoringTextTransform(Q) : 1 === ae.length ? (Q = ae[0]).headerText = trimmedInnerTextIgnoringTextTransform(Q)
: 1 === le.length ? (Q = le[0]).headerText = trimmedInnerTextIgnoringTextTransform(Q)
: 1 === se.length ? (Q = se[0]).headerText = trimmedInnerTextIgnoringTextTransform(Q)
: 1 === ce.length && ((Q = ce[0]).headerText = trimmedInnerTextIgnoringTextTransform(Q)),
!Q)
for (V = 0; V < te; ++V) {
he = W[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),
ye = -1 !== ae.indexOf(he),
Se = he.classList.contains("instapaper_title"),
Ae = /\bheadline\b/.test(he.getAttribute("itemprop")),
Ne = -1 !== le.indexOf(he),
be = -1 !== oe.indexOf(he),
xe = -1 !== se.indexOf(he),
Ce = -1 !== ce.indexOf(he);
let t = ge.includes(he) && ve < 0;
var De = Te || ye || Se || Ae || Ne || be || xe || Ce || t,
Ie = Math.sqrt(Ee * Ee + ve * ve),
Me = De ? r : Math.max(r - Ie, 0),
Le = (ue = ee[V], he.getAttribute("property"));
if (Le) {
var Re = /dc.title/i.exec(Le);
if (Re && Re[0])
if (1 === this.contentDocument.querySelectorAll('*[property~="' + Re[0] + '"]').length) {
(Q = he).headerText = ue;
break
}
}
if (!y.test(he.className)) {
if (!De) {
if (Ie > r)
continue;
if (pe < O.left || pe > O.right)
continue
}
if (D && stringsAreNearlyIdentical(ue, D))
Me *= g;
else if (e(ue, D))
Me *= f;
else if (ue.length < l)
continue;
if (ue !== M || !I) {
var we = !1;
if (We = n(he)) {
if ("author" === We.getAttribute("rel"))
continue;
var Fe = We.host === C.host,
_e = We.pathname === C.pathname;
if (Fe && _e)
Me *= h;
else {
if (Fe && nearestAncestorElementWithTagName(he, "li"))
continue;
Me *= u, we = !0
}
}
var Oe = fontSizeFromComputedStyle(getComputedStyle(he));
we || (Me *= Oe / BaseFontSize), Me *= 1 + TitleCandidateDepthScoreMultiplier * elementDepth(he);
var Be = parseInt(this.contentTextStyle().fontSize);
parseInt(Oe) > Be * o && (Me *= s), (c.test(he.className) || c.test(he.getAttribute("id"))) && (Me *= m);
var Pe = he.parentElement;
Pe && (c.test(Pe.className) || c.test(Pe.getAttribute("id"))) && (Me *= m), -1 !== ie.indexOf(he) && (Me *= d);
_ = this.article.element;
for (var ke = he; ke && ke !== _; ke = ke.parentElement)
if (SidebarRegex.test(ke.className)) {
Me *= p;
break
}
he.closest("li") && (Me *= E), (!Q || Me > Q.headerScore) && ((Q = he).headerScore = Me, Q.headerText = ue)
}
}
}
var qe;
if (Q && domDistance(Q, _, v + 1) > v && parseInt(getComputedStyle(Q).fontSize) < T * Be && (Q = null), Q) {
this._articleTitleElement = Q;
var ze = Q.headerText.trim();
qe = I && e(I, ze) ? I : D && e(D, ze) ? D
: ze
}
this._leadingMediaElement || (this._leadingMediaElement = this.leadingImageNode()), this._leadingMediaElement || (this._leadingMediaElement = this.leadingVideoNode()), qe || (qe = I && e(I, D) ? I : D);
var We, Ue = null,
He = !1,
Ve = !1;
Q && ((We = n(Q)) && (Ue = We.href, He = "_blank" === We.getAttribute("target"), Ve = We.host !== C.host || We.pathname !== C.pathname));
let je = {
titleText : qe,
linkURL : Ue,
linkIsTargetBlank : He,
linkIsForExternalPage : Ve
};
if (this._articleTitleElement) {
const e = this.titleUniqueID();
this._mapOfUniqueIDToOriginalElement.set(e, Q), this._weakMapOfOriginalElementToUniqueID.set(Q, e)
}
return 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]"), y = T.length, S = 0; S < y; ++S) {
var A = T[S];
c.has(A.innerText.trim()) && p.push(A)
}
var N = p.length;
for (S = 0; S < N; ++S) {
var b = p[S];
if (!b)
continue;
if (b === i)
continue;
var x = b.className;
if (n.test(x))
continue;
var C = b.closest("a");
if (C) {
var D = C.host === l.host,
I = C.pathname === l.pathname;
if (!D || !I)
continue
}
var M, L = !1;
if (elementIsAHeader(b))
if (isNaN(o))
L = !0;
else
e(b) - 1 === o && (L = !0);
if (!L && SubheadRegex.test(x) && (L = !0), !L) {
const e = b.getAttribute("itemprop");
/\bdescription\b/.test(e) && !/\barticleBody\b/.test(e) && (L = !0)
}
if (!L && c.has(b.innerText) && (L = !0), !L && h && h === b.innerText && (L = !0), L || "summary" !== b.getAttribute("itemprop") || (L = !0), !L)
continue;
if ("meta" === normalizedElementTagName(b)) {
var R = b.getAttribute("content");
M = R ? R.trim() : "";
var w = b.nextElementSibling;
if (!w || trimmedInnerTextIgnoringTextTransform(w) !== M)
continue;
b = w
} else {
if (cachedElementBoundingRect(b).top < (s.bottom + s.top) / 2)
continue;
M = trimmedInnerTextIgnoringTextTransform(b).trim()
}
if (!M.length)
continue;
this._articleSubheadElement = b;
const t = this.subheadUniqueID();
this._mapOfUniqueIDToOriginalElement.set(t, b), this._weakMapOfOriginalElementToUniqueID.set(b, t), this._articleSubhead = M;
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 (y = e(Array.from(v.querySelectorAll(t))))
return y;
if (y = e(Array.from(v.querySelectorAll(n))))
return y
}
var T = m.previousElementSibling;
if (T) {
var y;
if (y = e(Array.from(T.querySelectorAll(t))))
return y;
if (y = e(Array.from(T.querySelectorAll(n))))
return y
}
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 y = 0; v[v.length - 1 - y] === T[T.length - 1 - y];)
y++;
y && (v = v.substring(0, v.length - y), T = T.substring(0, T.length - y));
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 A = !1;
if (e.search)
for (var N in linkParameters = n(e.search), referenceParameters = n(i.search), linkParameters) {
var b = linkParameters[N],
x = N in referenceParameters ? referenceParameters[N] : null;
if (x !== b)
if (null === x && (x = ""), null === b && (b = ""), b.length < x.length)
g++;
else if (t(x, b, p, this.pageNumber)) {
if (LinkURLSearchParameterKeyMatchRegex.test(N)) {
if (o.toLowerCase() !== s.toLowerCase())
return 0;
if (this.isWordPressSite() && h)
return 0;
A = !0
}
if (LinkURLBadSearchParameterKeyMatchRegex.test(N)) {
g++;
continue
}
f = Math.max(f, 1 / LinkNextOrdinalValueBase)
} else
g++
}
if (!f)
return 0;
if ((LinkURLPageSlashNumberMatchRegex.test(e.href) || LinkURLSlashDigitEndMatchRegex.test(e.href)) && (A = !0), !A && m === u && stringSimilarity(o, s) < LinkMinimumURLSimilarityRatio)
return 0;
if (LinkURLArchiveSlashDigitEndMatchRegex.test(e))
return 0;
var C = LinkMatchWeight * (Math.pow(LinkMismatchValueBase, -g) + f) + LinkVerticalDistanceFromArticleWeight * l / LinkMaxVerticalDistanceFromArticle;
A && (C += LinkURLSemanticMatchBonus), "li" === normalizedElementTagName(e.parentNode) && (C += LinkListItemBonus);
p = e.innerText;
return LinkNextMatchRegEx.test(p) && (C += LinkNextMatchBonus), LinkPageMatchRegEx.test(p) && (C += LinkPageMatchBonus), LinkContinueMatchRegEx.test(p) && (C += LinkContinueMatchBonus), C
},
elementContainsEnoughTextOfSameStyle : function(e, t, n) {
const i = 110;
var r = "body" === normalizedElementTagName(e),
a = getVisibleNonWhitespaceTextNodes(e, r ? 2 : 3, i, r, t);
const l = .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 = .8;
let p = s.title,
E = t(p);
E && (o.add(E), l.add(p));
let v = this.pointsToUseForHitTesting(),
T = v.length;
for (var y = 0; y < T; y++) {
let t = v[y][0],
n = v[y][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 += this.plaintextVersionOfNodeAppendingNewlinesBetweenBlockElements(a) + "\n"), n + t.innerText
}
},
plaintextVersionOfNodeAppendingNewlinesBetweenBlockElements : function(e) {
var t = this.contentDocument.createTreeWalker(e, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT, null),
n = "";
for (t.currentNode = e; t.nextNode();) {
var i = t.currentNode;
if (i.nodeType !== Node.TEXT_NODE) {
var r = normalizedElementTagName(i);
"p" !== r && "div" !== r || (n += "\n")
} else
n += i.textContent
}
return n
},
pageDescription : function() {
for (var e = this.contentDocument.querySelectorAll("head meta[name]"), t = e.length, n = 0; n < t; ++n) {
var i = e[n];
if ("description" === i.getAttribute("name").toLowerCase()) {
var r = i.getAttribute("content");
if (r)
return r.trim()
}
}
return null
},
articleTitleAndSiteNameFromTitleString : function(e) {
const t = [ " - ", " \u2013 ", " \u2014 ", ": ", " | ", " \xbb " ],
n = t.length,
i = .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.pageDescription(),
r = !1;
this.adoptableArticle() ? (n = this.articleTitle(), i = i || this.articleTextContent(), r = !0) : (n = this.contentDocument.title, this.contentDocument.body && (i = i || this.contentDocument.body.innerText));
var a = "",
l = this.buildMapOfMetaTags(),
o = this.pageImageURLFromMetadata(l);
if (o)
a = o;
else {
var s = this.mainImageNode();
s && (a = 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 = ""), i = i ? i.trim() : "", t && (i = i.substring(0, t)),
{
title: n,
previewText: i = i.replace(/[\s]+/g, " "),
siteName: c,
mainImageURL: a,
isReaderAvailable: r
}
},
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
},
longestPageMetadataDescriptionForTextAnalysis : function(e) {
var t = [];
const n = e["name:description"];
n && n.length && t.push(n);
const i = e["property:og:description"];
i && i.length && t.push(i);
const r = e["name:twitter:description"];
return r && r.length && t.push(r), t.length ? t.reduce((function(e, t) {
return e.length > t.length ? e : t
}))
: null
},
pageTypeForTextAnalysis : function(e) {
const t = this.contentDocument.documentElement.getAttribute("itemtype");
if ("http://schema.org/SearchResultsPage" === t || "https://schema.org/SearchResultsPage" === t)
return PageType.searchResults;
const n = e["name:section"];
if (n && "homepage" === n.toLowerCase())
return PageType.homepage;
const i = e["property:og:type"];
if (i) {
const e = i.toLowerCase();
if ("homepage" === e)
return PageType.homepage;
if ("article" === e)
return PageType.article
}
const r = e["property:analytics-s-channel"];
return r && "homepage" === r.toLowerCase() ? PageType.homepage : null
},
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
},
pageKeywordsForTextAnalysis : function(e) {
return e["name:keywords"]
},
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
},
pageMetadataForTextAnalysis : function() {
let e = this.pageMetadataCommonToTextAnalysisAndArticleContent();
const t = this.pageTypeForTextAnalysis(metadataMap);
t && (e.type = t);
const n = this.longestPageMetadataDescriptionForTextAnalysis(metadataMap);
n && (e.description = n);
const i = this.pageKeywordsForTextAnalysis(metadataMap);
return i && (e.keywords = i), e
},
extractedArticleContent : function() {
try {
const e = this.adoptableArticle(!0),
t = this.elementReaderUniqueIDAttributeKey();
for (let n of e.getElementsByTagName("*"))
n.removeAttribute(t);
let n = this.pageMetadataCommonToTextAnalysisAndArticleContent();
if (e) {
const t = e.innerHTML;
n.body = t
}
this.updateArticleBylineAndDateElementsIfNecessary();
const i = this.articleDateElement();
i && (n.publishedDate = trimmedInnerTextIgnoringTextTransform(i));
const r = this.articleBylineElement();
return !n.author && r && (n.author = trimmedInnerTextIgnoringTextTransform(r)), n
} 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
},
elementReaderUniqueIDAttributeKey : function() {
return "data-reader-unique-id"
},
titleUniqueID : function() {
return "titleElement"
},
subheadUniqueID : function() {
return "subheadElement"
},
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
},
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
}
};
var ReaderArticleFinderJS = new ReaderArticleFinder(document);
// # sourceURL=__InjectedScript_ReaderSharedUINormalWorld.js
/* Copyright (c) 2024 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)
})))
}
<!DOCTYPE html>
<html>
<head>
<meta name="disabled-adaptations" content="watch">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale=1">
<base>
<title>Reader</title>
<style id="assistant-content">
#summary-container {
pointer-events: auto;
-webkit-user-select: auto;
background: transparent;
}
#summary-header {
padding-top: 30px;
margin: 0px;
line-height: 1.6em;
}
#summary-text {
padding-top: 4px;
margin: 0px;
line-height: 1.6em;
padding-bottom: 30px
}
#tableOfContents-container {
padding-bottom: 34px;
}
#tableOfContents-header {
margin: 0px;
line-height: 1.6em;
padding-top: 30px
}
#tableOfContents-list {
margin-left: 0px;
margin-right: 0px;
margin-top: 4px;
padding-left: 1.8em;
line-height: 1.6em;
}
.innerTableOfContents-listItem {
border-bottom: 1px solid var(--separator-color);
margin-bottom: 6px;
margin-top: 6px;
}
.innerTableOfContents-listItem:last-child {
border-bottom: none;
}
.collapsible {
cursor: pointer;
font-weight: 600;
padding-left: 16px;
padding-top: 18px;
padding-bottom: 18px;
padding-right: 0px;
width: 100%;
outline: none
overflow: hidden;
background: transparent;
background-repeat: no-repeat;
text-align: left;
border: none;
-webkit-tap-highlight-color: transparent;
}
.collapsible:nth-of-type(2):not(:first-of-type) {
border-top: 1px solid var(--separator-color);
}
.collapsible:after {
content: url('data:image/svg+xml,<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="7.15323" height="12.4569"><g><rect height="12.4569" opacity="0" width="7.15323" x="0" y="0"/><path d="M7.15323 6.22406C7.15165 5.96742 7.06077 5.74734 6.85599 5.54414L1.51768 0.255233C1.35263 0.0829682 1.14362 0 0.897181 0C0.395505 0 0 0.386716 0 0.885228C0 1.12446 0.105292 1.35175 0.272634 1.53034L5.01961 6.22248L0.272634 10.9178C0.106874 11.0964 0 11.3164 0 11.5645C0 12.063 0.395505 12.4497 0.897181 12.4497C1.14204 12.4497 1.35263 12.3667 1.51768 12.1945L6.85599 6.90397C7.06235 6.70077 7.15323 6.47911 7.15323 6.22406Z" fill="%23868686" fill-opacity="0.95"/></g></svg>');
width: 12px;
height: 12px;
float: right;
padding-left: 12px;
padding-right: 22px;
}
.collapsedContent {
margin: 0;
padding: 0;
max-height: 0;
overflow: auto;
padding-left: 16px;
margin-right: 1.25em;
transition: max-height 0.2s ease-out;
}
.expandedContent:after {
content:url('data:image/svg+xml,<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="12.4569" height="7.76214"><g><rect height="7.76214" opacity="0" width="12.4569" x="0" y="0"/><path d="M6.23285 7.76214C6.48949 7.76056 6.72239 7.6681 6.91276 7.4649L12.2017 2.12501C12.3667 1.95995 12.4569 1.75095 12.4569 1.50451C12.4569 1.00283 12.0702 0.607328 11.5717 0.607328C11.3324 0.607328 11.098 0.71262 10.9266 0.879962L5.86564 5.99169L6.5976 5.99169L1.53192 0.879962C1.36054 0.714202 1.14046 0.607328 0.892435 0.607328C0.393923 0.607328 0 1.00283 0 1.50451C0 1.74937 0.0917573 1.95837 0.255233 2.12501L5.55293 7.4649C5.75051 7.66968 5.97058 7.76214 6.23285 7.76214Z" fill="%23868686" fill-opacity="0.95"/></g></svg>');
width: 12px;
height: 12px;
padding-right: 30px;
}
#innerAssistantContainer {
margin-top: 21px;
margin-bottom: 21px;
border-radius: 22px;
background: var(--narrow-assistant-background-color);
}
#onDeviceSummaryButton {
cursor: pointer;
font-weight: bold;
padding-left: 16px;
padding-right: 22px;
padding-top: 15px;
padding-bottom: 12px;
width: 100%;
outline: none
overflow: hidden;
background: var(--narrow-assistant-background-color);
background-repeat: no-repeat;
text-align: left;
font-size: 16px;
margin-top: 21px;
margin-bottom: 21px;
border-radius: 18px;
border: none;
}
#glyph {
height: 30px;
width: 30px;
float: left;
margin: -4px -4px 0px 0px;
}
#assistant-container {
background: var(--assistant-sidebar-color);
padding-top: 34px;
padding-bottom: 34px;
padding-left: 16px;
padding-right: 16px;
transition: right 0.5s cubic-bezier(.17,.67,.99,1);
width: 350px;
right: 20vw;
}
#sidebarButton {
margin-top: 40px;
position: fixed;
right: 19vw;
transition: right 0.5s cubic-bezier(.17,.67,.99,1);
}
#article {
transition: left 0.5s cubic-bezier(.17,.67,.99,1);
}
</style>
<style id="article-content">
h1, h2, h3, h4, h5, h6 {
font-weight: bold;
}
h1 {
font-size: 1.5em;
line-height: 1.4em;
}
h2 {
font-size: 1.43em;
}
h3 {
font-size: 1.25em;
}
h4, h5, h6 {
font-size: 1em;
margin: 1em 0;
}
body.watch h1 {
font-size: 1.1875rem;
}
body.watch h2 {
font-size: 1.125rem;
}
body.watch h3 {
font-size: 1.0625rem;
}
body.watch :matches(h4, h5, h6) {
font-size: 1rem;
}
h1.title {
font-weight: bold;
font-size: 1.95552em;
line-height: 1.2141em;
margin-top: 0;
margin-bottom: 0.5em;
}
.subhead {
font-weight: normal;
}
.title, .subhead, .metadata {
text-align: start;
hyphens: manual;
display: none;
}
:nth-child(1 of .page) :matches(.title, .subhead, .metadata) {
display: block;
}
.subhead {
color: rgba(27, 27, 27, 0.65);
font-size: 1.46664em;
margin-top: -0.35em;
line-height: 1.27275em;
}
.metadata {
margin-top: -0.75em;
margin-bottom: 1.45em;
}
body.watch .metadata {
line-height: 1.3em;
}
.metadata * {
font-size: 1em !important;
font-weight: normal !important;
font-style: normal !important;
display: inline !important;
margin: 0;
}
.metadata :matches(.byline, .date) {
display: inline !important;
}
.metadata :matches(ul, ol, li) {
list-style-type: none;
-webkit-padding-start: 0;
}
.title + .metadata {
margin-top: -0.75em;
}
.subhead + .metadata {
margin-top: -0.7em;
}
.page {
text-align: start;
word-wrap: break-word;
}
body.watch .page {
hyphens: auto;
}
.page.rtl {
direction: rtl;
}
a {
text-decoration: none;
}
a[href] {
color: rgb(65, 110, 210);
}
#article {
text-rendering: optimizeLegibility;
}
#article * {
/* Scale down anything larger than our view. Max-width maintains aspect ratios on images. */
max-width: 100%;
}
#article img {
/* By default, images are centered on their own line. */
margin: 0.5em auto;
display: block;
height: auto;
}
#article img.reader-image-tiny {
display: inline;
margin: 0;
}
#article .leading-image, figure, .auxiliary {
margin-bottom: 1.15em;
}
#article .leading-image img {
margin: auto;
display: block;
clear: both;
}
#article .leading-image .credit {
margin: 0;
}
#article .leading-image,
#article figure {
font-size: 0.75em;
line-height: 1.5em;
}
body.watch #article .leading-image,
body.watch #article figure {
font-size: 0.8125rem;
}
#article .leading-image :matches(.caption, .credit),
#article figcaption {
margin-top: 0.8em;
width: 100%;
}
body.watch #article .leading-image :matches(.caption, .credit),
body.watch #article figcaption {
margin-top: 4px;
}
body.watch #article figure img {
margin-bottom: 0;
}
#article figcaption > * {
margin-top: 0.25em;
margin-bottom: 0.25em;
}
#article :matches(.leading-image, figure) p {
margin-top: 0.4em;
margin-bottom: 0.4em;
}
#article .leading-image .credit + .caption {
margin-top: 0.1em;
}
#article .auxiliary {
display: block;
clear: both;
font-size: 0.75em;
line-height: 1.4em;
text-align: start;
}
body.watch #article .auxiliary {
font-size: 0.9em;
}
#article .pullquote {
font-size: 1.42em;
line-height: 1.38em;
font-weight: 300;
font-style: italic;
}
#article .pullquote:not(.float) {
margin-top: 1em;
margin-bottom: 1em;
-webkit-margin-start: 1em;
max-width: calc(100% - 1em);
}
#article .auxiliary > *:not(img) {
-webkit-margin-start: 0;
}
#article .auxiliary.float img, #article .auxiliary > *:first-child:not(img) {
margin: 0;
}
/* If the element immediately after an image is inline, it might bump up against the image. */
#article .auxiliary img + * {
display: block;
}
#article .auxiliary figcaption {
font-size: 100%;
}
#article .auxiliary * {
margin-top: 0.5em;
margin-bottom: 0.5em;
}
body:not(.watch) #article .float.left {
float: left;
margin-right: 20px;
}
body:not(.watch) #article .float.right {
float: right;
margin-left: 20px;
}
body.watch #article .float {
width: auto !important;
}
#article .clear {
clear: both;
}
#article ul.list-style-type-none,
#article ol.list-style-type-none,
#article .list-style-type-none > li {
list-style-type: none;
-webkit-padding-start: 0;
}
#article .page .list-style-type-none.code-block code {
white-space: pre-wrap;
}
#article .page div.scrollable {
overflow-x: scroll;
word-wrap: normal;
}
#article .page div.scrollable table {
max-width: none;
}
#article .leading-image, #article figure, #article .auxiliary:not(.pullquote) {
font-family: -apple-system-font;
}
#article .leading-image, #article figure, #article .auxiliary, #article .pullquote {
color: rgba(0, 0, 0, 0.65);
}
figure {
margin: 0;
}
body:not(.watch) figure:not(.float) {
margin-top: 1.4em;
margin-bottom: 1.4em;
}
hr {
background: rgba(0, 0, 0, 0.2);
height: 1px;
border: 0;
}
pre {
font-family: -apple-system-ui-monospaced, Menlo;
font-size: 0.87em;
line-height: 1.45em;
}
blockquote, q {
color: rgba(0, 0, 0, 0.65);
}
blockquote:not(.pullquote) {
margin-left: 2px;
margin-right: 6px;
padding-left: 16px;
}
blockquote:not(.simple):not(.pullquote) {
border-left: 3px solid rgba(0, 0, 0, 0.1);
}
q.pullquote {
display: block;
}
.pullquote q::before, .pullquote q::after, q.pullquote::before, q.pullquote::after {
content: "";
}
/* Collapse excess whitespace. */
.page p > p:empty,
.page div > p:empty,
.page p > div:empty,
.page div > div:empty,
.page p + br,
.page img + br
{
display: none;
}
.page table {
font-size: 0.9em;
text-align: start;
word-wrap: break-word;
border-collapse: collapse;
}
.page table td, .page table th {
padding: 0.25em 0.5em;
border: 1px solid rgb(216, 216, 216);
}
body.watch .page > * {
margin-left: 0;
margin-right: 0;
}
body.watch .page ol {
padding: 0 0 0 35px;
}
body.watch .page ul {
padding: 0 0 0 20px;
}
body.watch .page li {
margin: 0.8em 0;
}
body.watch .page blockquote {
padding: 0 0 0 8px;
}
.delimiter {
margin-left: 0.45em;
margin-right: 0.45em;
margin-top: 0.07em;
padding: 0;
}
.metadata.singleline .delimiter::after {
content: "•";
}
.metadata:not(.singleline) .delimiter {
content: "";
display: block !important;
}
.page table th {
background-color: rgba(0, 0, 0, 0.025);
}
.page sup, .page sub {
line-height: 1;
font-size: 0.75em;
}
.hidden {
display: none;
}
/* Special Font Customizations */
.system { font-family: -apple-system-font; }
.watch.system { font: -apple-system-body; }
.yuantisc {
letter-spacing: 1px;
}
.yuantitc {
letter-spacing: 1px;
}
/* Printing and mailing. */
#article.exported {
font-size: 1.2em;
}
.exported {
line-height: 1.5em;
}
.exported a[href] {
text-decoration: underline;
}
#article.exported {
margin: 0;
padding: 0;
}
.exported .float {
float: none;
margin-top: 1.4em;
margin-bottom: 1.4em;
}
#article.exported .leading-image,
#article.exported figcaption {
font-size: 0.75rem;
color: rgba(0, 0, 0, 0.8);
}
.exported .delimiter::after {
content: "";
}
</style>
<style id="print">
@media print {
body {
margin: 2mm 9mm;
}
.original-url {
display: none;
}
#article .float.left {
float: left !important;
}
#article .float.right {
float: right !important;
}
#article .float {
margin-top: 0 !important;
margin-bottom: 0 !important;
}
}
</style>
<style id="reader-ui">
@media screen {
body {
margin: 0;
padding: 0;
-webkit-user-select: none;
overflow-x: hidden;
-webkit-text-size-adjust: none;
}
body.mac {
background-color: transparent;
}
#article {
pointer-events: auto;
-webkit-user-select: auto;
overflow: visible;
margin-bottom: 42vh !important;
}
#article:focus {
outline: none;
}
.page-number {
display: block;
}
#article :nth-child(1 of .page):nth-last-child(1 of .page) .page-number {
display: none;
}
body.watch #article :nth-child(1 of .page):nth-last-child(1 of .page) {
padding-top: 0.15em;
}
.page-number, #incoming-page-corner {
font-weight: bold;
position: absolute;
-webkit-user-select: none;
font: 12px "Helvetica Neue";
color: rgb(168, 168, 168);
cursor: default;
}
body.watch :matches(.page-number, #incoming-page-corner) {
top: 8px;
right: 16px;
}
.page {
margin-left: auto;
margin-right: auto;
padding-top: 35px;
padding-bottom: 35px;
position: relative;
border-top: 1px solid rgba(0, 0, 0, 0.2);
}
body.watch .page {
padding: 0 4px;
}
#article :nth-child(1 of .page) {
margin-top: 0;
border-top: none;
padding-top: 32px;
}
.page:last-of-type {
padding-bottom: 45px;
}
.page video {
height: auto;
position: relative;
}
#incoming-page-placeholder {
height: 30px;
margin-bottom: 0;
}
#incoming-page-corner {
position: absolute;
right: 10px;
top: 8px;
}
#incoming-page-text {
float: right;
-webkit-user-select: none;
}
#next-page-container {
position:absolute;
/* Workaround for <rdar://problem/8662842> iOS Reader: loading multiple pages stops at the 2nd page. */
left: -1000px;
/* The iframe needs to be wider than the width threshold value for Reader detection, see <rdar://problem/9599297>. */
width: 320px;
height: 0px;
}
.page div.scrollable {
-webkit-overflow-scrolling: touch;
}
}
@media screen and (-webkit-min-device-pixel-ratio:2) {
.page {
border-top-width: 0.5px;
}
hr {
height: 0.5px;
}
}
#article .extendsBeyondTextColumn {
max-width: none;
}
.iframe-wrapper {
background-color: black;
max-width: none;
text-align: center;
}
iframe {
border: 0;
}
@media screen and (min-width: 0px) {
/* Includes iPhone 5 in portrait */
.page { padding-left: 16px; padding-right: 16px; }
.page-number, #incoming-page-corner {
top: 8px;
right: 16px;
}
#article :nth-child(1 of .page):nth-last-child(1 of .page) {
padding-top: 14px;
}
}
@media screen and (min-width: 161px) {
/* Apple Watch 40mm */
body.watch .page {
padding: 0 8.5px;
}
}
@media screen and (min-width: 183px) {
/* Apple Watch 44mm */
body.watch .page {
padding: 0 9.5px;
}
}
@media screen and (min-width: 375px) {
/* iPhone 6 in portrait */
.page { padding-left: 18px; padding-right: 18px; }
.page-number, #incoming-page-corner {
top: 6px;
right: 18px;
}
#article :nth-child(1 of .page):nth-last-child(1 of .page) {
padding-top: 16px;
}
}
@media screen and (min-width: 414px) {
/* iPhone 6 Plus in portrait */
.page { padding-left: 20px; padding-right: 20px; }
.page-number, #incoming-page-corner {
top: 6px;
right: 20px;
}
#article :nth-child(1 of .page):nth-last-child(1 of .page) {
padding-top: 18px;
}
}
/* iPhone 5 in landscape (568px) */
@media screen and (min-width: 667px) {
/* iPhone 6 in landscape */
.page { padding-left: 40px; padding-right: 40px; }
.page-number, #incoming-page-corner {
/* Stop lining this text up with .page's right margin. */
top: 10px;
right: 10px;
}
#article :nth-child(1 of .page):nth-last-child(1 of .page) {
padding-top: 26px;
}
}
@media screen and (max-width: 569px) {
/* iPhone 5 in landscape (568px) and smaller, including all iPhones in portrait */
h1.title {
font-size: 1.5558em;
}
h1 {
font-size: 1.4em;
}
h2 {
font-size: 1.2777em;
}
h3 {
font-size: 1.15em;
}
.subhead {
font-size: 1.2222em;
}
.metadata {
font-size: 0.9em;
line-height: 1.6em;
}
.title + .metadata {
margin-top: -0.65em;
}
}
@media screen and (min-width: 704px) {
/* iPad in landscape with the sidebar open */
.page { padding-left: 42px; padding-right: 42px; }
}
@media screen and (min-width: 736px) {
/* iPhone 6 Plus in landscape */
.page { padding-left: 60px; padding-right: 60px; }
#article :nth-child(1 of .page):nth-last-child(1 of .page) {
padding-top: 46px;
}
}
@media only screen and (min-width: 780px) {
#article {
max-width: 800px;
margin: 0 auto;
}
/* Readable margins. */
body.system #article { max-width: 83.2ex; }
body.athelas #article { max-width: 104ex; }
body.charter #article { max-width: 86ex; }
body.georgia #article { max-width: 94ex; }
body.iowanoldstyle #article { max-width: 90ex; }
body.palatino #article { max-width: 97ex; }
body.seravek #article { max-width: 87ex; }
body.timesnewroman #article { max-width: 97ex; }
body.uiserif #article { max-width: 93ex; }
:matches(body.pingfangsc, body.pingfangtc) #article { max-width: 87.6ex; }
:matches(body.heitisc, body.heititc) #article { max-width: 74.8ex; }
:matches(body.songtisc, body.songtitc) #article { max-width: 102ex; }
:matches(body.kaitisc, body.kaititc) #article { max-width: 102ex; }
:matches(body.yuantisc, body.yuantitc) #article { max-width: 86.2ex; }
:matches(body.libiansc, body.libiantc) #article { max-width: 95ex; }
:matches(body.weibeisc, body.weibeitc) #article { max-width: 99ex; }
:matches(body.yuppysc, body.yuppytc) #article { max-width: 87.6ex; }
body.hiraginosansw3 #article { max-width: 75.7ex; }
body.hiraginokakugothicpron #article { max-width: 76.4ex; }
body.hiraginominchopron #article { max-width: 77.5ex; }
body.hiraginomarugothicpron #article { max-width: 75.1ex; }
body.applesdgothicneo #article { max-width: 82ex; }
body.nanumgothic #article { max-width: 88.6ex; }
body.nanummyeongjo #article { max-width: 94.1ex; }
.page {
/* We don't want the lines seperating pages to extend beyond the primary text column. */
padding-left: 0px;
padding-right: 0px;
margin-left: 70px;
margin-right: 70px;
}
}
#article {
-webkit-font-smoothing: subpixel-antialiased;
}
/* Reader's paper appearance. */
html.paper {
height: 100%;
}
html.paper body {
height: calc(100% - 44px);
}
html.paper body:after {
content: "";
height: 22px;
display: block;
}
/* Clearfix */
html.paper .page::after {
content: "";
display: table;
clear: both;
}
html.paper #article {
min-height: 100%;
margin: 22px auto 0 auto;
}
html.paper #article :nth-child(1 of .page), html.paper #article :nth-child(1 of .page):nth-last-child(1 of .page) {
padding-top: 53px;
}
html.paper #article .page-number, html.paper #article #incoming-page-corner {
/* Stop lining this text up with .page's right margin. */
top: 14px;
right: 0px;
}
/* End Reader's paper appearance. */
/* Use slightly smaller page padding when vertically constrained. */
@media screen and (max-height: 700px) {
.page {
padding-top: 32px;
padding-bottom: 32px;
}
}
</style>
<style id="theming">
body.white {
--body-font-color: rgb(27, 27, 27);
--assistant-secondary-color: rgb(27, 27, 27, 0.5);
--horizontal-line-color: rgb(220, 220, 220);
--assistant-sidebar-color: rgb(220, 220, 220);
--paper-shadow-color: rgba(0, 0, 0, 0.2);
--separator-color: rgb(220, 220, 220);
--assistant-sidebar-color: rgb(220, 220, 220);
--narrow-assistant-background-color: rgba(18, 18, 18, 0.1);
}
body.sepia {
--body-font-color: rgb(79, 50, 28);
--assistant-secondary-color: rgb(79, 50, 28, 0.5);
--horizontal-line-color: rgb(230, 218, 201);
--separator-color: rgb(204, 191, 157);
--assistant-sidebar-color: rgb(230, 218, 201);
--paper-shadow-color: rgba(0, 0, 0, 0.2);
--narrow-assistant-background-color: rgba(18, 18, 18, 0.1);
}
body.gray {
--body-font-color: rgba(255, 255, 255, 0.78);
--assistant-secondary-color: rgba(255, 255, 255, 0.39);
--horizontal-line-color: rgb(111, 111, 111);
--separator-color: rgb(111, 111, 111);
--assistant-sidebar-color: rgb(111, 111, 111);
--narrow-assistant-background-color: rgba(18, 18, 18, 0.1);
}
body.night {
--body-font-color: rgb(176, 176, 176);
--assistant-secondary-color: rgb(176, 176, 176, 0.5);
--horizontal-line-color: rgb(62, 62, 62);
--separator-color: rgb(62, 62, 62);
--assistant-sidebar-color: rgb(62, 62, 62);
--narrow-assistant-background-color: rgba(50, 50, 50, 0.3);
}
body.night.oled {
--body-font-color: rgb(210, 210, 210);
--assistant-secondary-color: rgb(210, 210, 210, 0.5);
--horizontal-line-color: rgba(210, 210, 210, 0.35);
--separator-color: rgba(210, 210, 210, 0.35);
--assistant-sidebar-color: rgba(210, 210, 210, 0.35);
--narrow-assistant-background-color: rgba(50, 50, 50, 0.3);
}
body.watch.night.oled {
--body-font-color: rgb(174, 180, 191);
}
html:not(.paper) body.white, body.white #article {
background-color: white;
}
html:not(.paper) body.sepia, body.sepia #article {
background-color: rgb(248, 241, 227);
}
html:not(.paper) body.gray, body.gray #article {
background-color: rgb(74, 74, 77);
}
html:not(.paper) body.night, body.night #article {
background-color: rgb(18, 18, 18);
}
html:not(.paper) body.night.oled, body.night.oled #article {
background-color: black;
}
/* OS X Reader draws backdrop background colors outside of web content, so the follow set only applies to iOS. */
html.paper body.ios.white {
background-color: rgb(230, 230, 230);
}
html.paper body.ios.sepia {
background-color: rgb(224, 216, 200);
}
html.paper body.ios.gray {
background-color: rgb(50, 50, 51);
}
html.paper body.ios.night {
background-color: black;
}
body.watch.night .metadata * {
color: rgb(214, 217, 223) !important;
}
html.paper body.white #article, html.paper body.sepia #article {
box-shadow: 0px 6px 12px 3px var(--paper-shadow-color);
}
html.paper body.gray #article {
box-shadow: 0px 6px 12px 3px rgba(0, 0, 0, 0.24);
}
html.paper body.night #article {
outline: 1px solid #272727;
}
body.watch.night.oled :matches(h1, h2, h3, h4, h5, h6) {
color: white;
}
body.sepia #article :matches(.leading-image, figure, .auxiliary, .pullquote) {
color: rgba(79, 50, 28, 0.9);
}
body.gray #article :matches(.leading-image, figure, .auxiliary, .pullquote) {
color: rgba(255, 255, 255, 0.7);
}
body.night #article :matches(.leading-image, figure, .auxiliary, .pullquote) {
color: rgba(255, 255, 255, 0.67);
}
body.night.oled #article :matches(.leading-image, figure, .auxiliary, .pullquote) {
color: rgba(210, 210, 210, 0.9);
}
body.sepia #article a[href] {
color: rgb(209, 150, 0);
}
body.gray #article a[href], body.night #article a[href] {
color: rgb(90, 200, 250);
}
body.watch.night.oled #article a[href] {
color: rgb(32, 148, 250);
}
body #article :matches(.page, .metadata a[href]) {
color: var(--body-font-color);
}
body #article .page {
border-top-color: var(--horizontal-line-color);
}
body #article hr {
background: var(--horizontal-line-color);
}
body #assistant-container p {
color: var(--assistant-secondary-color);
}
body #assistant-container ol {
color: var(--assistant-secondary-color);
}
body #assistant-container h2 {
color: var(--body-font-color);
font-size: 1.43em;
}
body #assistant-container h3 {
color: var(--body-font-color);
font-size: 1.25em;
}
body #assistant-container h1 {
font-size: 1.5em;
line-height: 1.4em;
color: var(--body-font-color);
margin: 0px;
}
body #assistant-container a {
color: var(--assistant-secondary-color);
}
body #summary-container p {
color: var(--assistant-secondary-color);
margin: 0px;
padding-top: 4px;
}
body #summary-container h2 {
color: var(--body-font-color);
}
body #summary-container h1 {
color: var(--body-font-color);
}
body #tableOfContentsInsideArticle-list a {
color: var(--body-font-color);
font-size: 1em;
}
body #innerAssistantContainer p {
color: var(--body-font-color);
margin-top: 0;
margin-bottom: 0.4em;
}
body #innerAssistantContainer ol {
color: var(--body-font-color);
}
body #innerAssistantContainer li {
margin-left: 2em;
}
body #innerAssistantContainer ol li::marker {
color: var(--assistant-secondary-color);
}
body #innerAssistantContainer button {
color: var(--body-font-color);
font-size: 1em;
}
body #onDeviceSummaryButton {
color: var(--body-font-color);
}
body.sepia .subhead {
color: rgba(79, 50, 28, 0.72);
}
body.gray .subhead {
color: rgba(255, 255, 255, 0.65);
}
body.night .subhead {
color: rgba(185, 185, 185, 0.9);
}
body.night.oled .subhead {
color: rgba(210, 210, 210, 0.85);
}
body.sepia :matches(#article .page-number, #incoming-page-corner) {
color: rgba(63, 41, 23, 0.5);
}
body.gray :matches(#article .page-number, #incoming-page-corner) {
color: rgba(255, 255, 255, 0.45);
}
body.night :matches(#article .page-number, #incoming-page-corner) {
color: rgba(255, 255, 255, 0.55);
}
body.night.oled :matches(#article .page-number, #incoming-page-corner) {
color: rgba(210, 210, 210, 0.8);
}
body.sepia #article blockquote, body.sepia #article q {
color: rgb(140, 112, 79);
}
body.sepia #article blockquote:not(.simple):not(.pullquote) {
border-left-color: rgba(154, 128, 92, 0.1);
}
body.gray #article blockquote, body.gray #article q {
color: rgba(255, 255, 255, 0.6);
}
body.gray #article blockquote:not(.simple):not(.pullquote) {
border-left-color: rgba(255, 255, 255, 0.15);
}
body.night #article blockquote, body.night #article q {
color: rgba(255, 255, 255, 0.6);
}
body.night #article blockquote:not(.simple):not(.pullquote) {
border-left-color: rgba(255, 255, 255, 0.15);
}
body.night.oled #article blockquote, body.night.oled #article q {
color: rgba(210, 210, 210, 0.85);
}
body.night.oled #article blockquote:not(.simple):not(.pullquote) {
border-left-color: rgba(210, 210, 210, 0.2);
}
body.watch.night #article blockquote, body.watch.night #article q {
color: var(--body-font-color);
}
body.watch.night #article blockquote:not(.simple):not(.pullquote) {
border-left-color: rgb(51, 51, 51);
}
body.sepia table :matches(td, th) {
border-color: rgb(230, 218, 202);
}
body.sepia table th {
background-color: rgba(154, 128, 92, 0.06);
}
body.gray table :matches(td, th) {
border-color: rgb(106, 106, 106);
}
body.gray table th {
background-color: rgba(255, 255, 255, 0.035);
}
body.night table :matches(td, th) {
border-color: rgb(50, 50, 50);
}
body.night table th {
background-color: rgba(255, 255, 255, 0.045);
}
body.night.oled table th {
background-color: rgba(255, 255, 255, 0.075);
}
@media (inverted-colors) {
/* If the user has turned on the "smart invert" accessibility preference, they generally prefer
their images, such as photos, to not be inverted. Provide this by applying a filter that
inverts the colors again (effectively un-inverting). */
body:not(.gray):not(.night) #article :matches(img, video) {
filter: invert();
}
body:not(.gray):not(.night) #article picture {
filter: none !important;
}
body.gray, body.night {
filter: invert();
}
body:matches(.gray, .night) #article :matches(img:not(picture > img), picture, video) {
filter: none !important;
}
body:matches(.gray, .night) #article iframe {
filter: invert();
}
html.paper body.white #article, html.paper body.sepia #article {
--paper-shadow-color: rgba(255, 255, 255, 0.2);
}
/* The background color of <body> is not inverted by the filter. Achieve this by manually
setting the inverse color. */
html:not(.paper) body.gray {
background-color: rgb(165, 165, 163) !important;
}
html.paper body.gray {
background-color: rgb(205, 205, 204) !important;
}
html:not(.paper) body.night {
background-color: rgb(237, 237, 237) !important;
}
html:not(.paper) body.night.oled {
background-color: white !important;
}
html.paper body.night {
background-color: white !important;
}
}
</style>
<style id="locale-specific-adjustments">
.locale-ja .page {
text-align: justify;
}
.locale-zh-Hans .page {
text-align: justify;
}
.locale-zh-Hant .page {
text-align: justify;
word-break: break-all;
}
.locale-hi .title {
line-height: 1.65em;
}
/* See 32728279 and 54061051. */
.locale-ur.notonastaliqurdu :matches(h1, h2, h3, h4, h5, h6) {
font-weight: normal;
line-height: 2.55em;
}
</style>
<style id="dynamic-article-content"></style>
<!-- For Twitter’s script to find and script world to be created (see 34937240). -->
<script>
window.isReaderPage = true;
</script>
</head>
<body>
<iframe aria-hidden="true" id="next-page-container"></iframe>
<div id="article" role="article">
<!-- This node will contain a number of div.page. -->
</div>
</body>
</html>
/*
* Copyright (C) 2010 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// Utilities taken from WebCore/inspector/front-end/utilities.js with some additions for Safari.
Object.type = function(obj, win)
{
if (obj === null)
return "null";
var type = typeof obj;
if (type !== "object" && type !== "function")
return type;
win = win || window;
if (obj instanceof win.Node)
return "node";
if (obj instanceof win.String)
return "string";
if (obj instanceof win.Array)
return "array";
if (obj instanceof win.Boolean)
return "boolean";
if (obj instanceof win.Number)
return "number";
if (obj instanceof win.Date)
return "date";
if (obj instanceof win.RegExp)
return "regexp";
if (obj instanceof win.Error)
return "error";
return type;
}
Function.prototype.bind = function(thisObject)
{
var func = this;
var args = Array.prototype.slice.call(arguments, 1);
return function() { return func.apply(thisObject, args.concat(Array.prototype.slice.call(arguments, 0))) };
}
String.prototype.format = function()
{
var stringParts = this.split("%@");
for (var i = 0; i < arguments.length; ++i)
stringParts.splice(i * 2 + 1, 0, arguments[i].toString());
return stringParts.join("");
}
Element.prototype.indexOfChildNode = function(childNode)
{
var childNodes = this.childNodes;
for (var i = 0; i < childNodes.length; ++i) {
if (childNodes[i] === childNode)
return i;
}
return -1;
}
Element.prototype.removeChildren = function()
{
while (this.firstChild)
this.removeChild(this.firstChild);
}
Element.prototype.__defineGetter__("totalOffsetLeft", function()
{
var total = 0;
for (var element = this; element; element = element.offsetParent)
total += element.offsetLeft + (this !== element ? element.clientLeft : 0);
return total;
});
Element.prototype.__defineGetter__("totalOffsetTop", function()
{
var total = 0;
for (var element = this; element; element = element.offsetParent)
total += element.offsetTop + (this !== element ? element.clientTop : 0);
return total;
});
Element.prototype.__defineGetter__("totalScrollTop", function()
{
var total = 0;
for (var element = this; element; element = element.offsetParent)
total += element.scrollTop;
return total;
});
Array.prototype.remove = function(value, onlyFirst)
{
if (onlyFirst) {
var index = this.indexOf(value);
if (index !== -1)
this.splice(index, 1);
return;
}
var length = this.length;
for (var i = 0; i < length; ++i) {
if (this[i] === value)
this.splice(i, 1);
}
}
// @param element (HTML Element) The element whose total offset from left edge of the
// page is desired.
// @return (integer) The total offset from the left edge of the page if the element is
// not null or undefined or does not have a defined offsetLeft. -1 otherwise.
function totalLeftOffset(element)
{
if (!element || typeof element.offsetLeft === "undefined")
return -1;
return element.totalOffsetLeft;
}
// @param element (HTML Element) The element whose total offset from top edge of the
// page is desired.
// @return (integer) The total offset from the top edge of the page if the element is
// not null or undefined or does not have a defined offsetTop. -1 otherwise.
function totalTopOffset(element)
{
if (!element || typeof element.offsetTop === "undefined")
return -1;
return element.totalOffsetTop;
}
Node.prototype.enclosingNodeOrSelfWithNodeNameInArray = function(nameArray)
{
for (var node = this; node && node !== this.ownerDocument; node = node.parentNode)
for (var i = 0; i < nameArray.length; ++i)
if (node.nodeName.toLowerCase() === nameArray[i].toLowerCase())
return node;
return null;
}
Node.prototype.enclosingNodeOrSelfWithNodeName = function(nodeName)
{
return this.enclosingNodeOrSelfWithNodeNameInArray([nodeName]);
}
Number.constrain = function(num, min, max)
{
if (num < min)
num = min;
else if (num > max)
num = max;
return num;
}
// JS class inheritance. NOTE: You should use the __proto__ approach instead of this.
var JSClass = {
inherit: function(subclass, baseClass) {
function inheritance() { }
inheritance.prototype = baseClass.prototype;
subclass.prototype = new inheritance();
subclass.prototype.constructor = subclass;
subclass.baseConstructor = baseClass;
subclass.superClass = baseClass.prototype;
}
}
// Dragging utilities ---------------------------------------------------------
var Direction = {
HORIZONTAL: 0,
VERTICAL: 1,
};
var Dragger = {
// Sets up and starts the drag of an HTML element.
//
// @param element (HTML element) Element to drag.
// @param elementDragging (function (event)) Function to be called while
// element is dragging.
// @param elementDragEnd (function (event)) Function to be called when the
// drag ends.
// @param event (event) The event that triggered the drag.
// @param cursor (string) The cursor style to use while dragging.
elementDragStart: function(element, elementDragging, elementDragEnd, event, cursor)
{
if (this._elementDraggingEventListener || this._elementEndDraggingEventListener)
this.elementDragEnd(event);
this._elementDraggingEventListener = elementDragging;
this._elementEndDraggingEventListener = elementDragEnd;
document.addEventListener("mousemove", elementDragging, true);
document.addEventListener("mouseup", elementDragEnd, true);
document.body.style.cursor = cursor;
event.preventDefault();
},
// Finishes and tears down the drag of an element.
//
// @param event (event) Event that causes the drag to end.
elementDragEnd: function(event)
{
document.removeEventListener("mousemove", this._elementDraggingEventListener, true);
document.removeEventListener("mouseup", this._elementEndDraggingEventListener, true);
document.body.style.removeProperty("cursor");
delete this._elementDraggingEventListener;
delete this._elementEndDraggingEventListener;
event.preventDefault();
},
// Updates the position of the element and all the elements around it.
// If the direction of movement is horizontal (Dragger.HORIZONTAL), then A
// is "left" and B is "right".
// If the direction of movement is vertical (Dragger.VERTICAL), then A is
// "above" and B is "below".
//
// @param element (HTML element) The element whose position to update.
// @param direction (Direction.HORIZONTAL | Direction.VERTICAL) The direction
// in which the element is moving.
// @param elementsToA (array of HTML elements) The elements to the A of the
// element.
// @param elementsToB (array of HTML elements) The elements to the B of the
// element.
// @param distanceToDragPoint (integer) The distance in pixels from the
// dragPoint to where the element should be placed.
// @param minPos (integer) The minimum position the element can be at.
// @param maxPos (integer) The maximum position the element can be at.
// @param dragPoint (integer) The point at which the element has been
// dragged to.
updateElementPosition: function(element, direction, elementsToA, elementsToB,
distanceToDragPoint, minPos, maxPos, dragPoint)
{
if ((direction == Direction.HORIZONTAL && elementsToA[0].offsetWidth <= 0)
|| (elementsToA[0].offsetHeight <= 0)) {
// The stylesheet hasn't loaded yet or the window is closed,
// so we can't calculate what is need. Return early.
return;
}
if (!("_currentElementPosition" in elementsToA[0])) {
if (direction == Direction.HORIZONTAL)
elementsToA[0]._currentElementPosition = elementsToA[0].offsetWidth;
else
elementsToA[0]._currentElementPosition = elementsToA[0].offsetHeight;
}
if (typeof dragPoint === "undefined")
dragPoint = elementsToA[0]._currentElementPosition;
dragPoint = Number.constrain(dragPoint, minPos, maxPos);
elementsToA[0]._currentElementPosition = dragPoint;
for (var i = 0; i < elementsToA.length; i++) {
if (direction == Direction.HORIZONTAL)
elementsToA[i].style.width = dragPoint + "px";
else
elementsToA[i].style.height = dragPoint + "px";
}
for (var j = 0; j < elementsToB.length; j++) {
if (direction == Direction.HORIZONTAL)
elementsToB[j].style.left = dragPoint + "px";
else
elementsToB[j].style.top = dragPoint + "px";
}
if (direction == Direction.HORIZONTAL)
element.style.left = (dragPoint - distanceToDragPoint) + "px";
else
element.style.top = (dragPoint - distanceToDragPoint) + "px";
}
};
// Listeners (taken from the WebInspector.Object in
// WebCore\inspector\frontend\Object.js)
Listeners = function() {
}
Listeners.prototype = {
addEventListener: function(eventType, listener, thisObject) {
if (!("_listeners" in this))
this._listeners = {};
if (!(eventType in this._listeners))
this._listeners[eventType] = [];
this._listeners[eventType].push({ thisObject: thisObject, listener: listener });
},
removeEventListener: function(eventType, listener, thisObject) {
if (!("_listeners" in this) || !(eventType in this._listeners))
return;
var listeners = this._listeners[eventType];
for (var i = 0; i < listeners.length; ++i) {
if (listener && listeners[i].listener === listener && listeners[i].thisObject === thisObject)
listeners.splice(i, 1);
else if (!listener && thisObject && listeners[i].thisObject === thisObject)
listeners.splice(i, 1);
}
if (!listeners.length)
delete this._listeners[eventType];
},
dispatchEventToListeners: function(eventType) {
if (!("_listeners" in this) || !(eventType in this._listeners))
return;
var stoppedPropagation = false;
function stopPropagation()
{
stoppedPropagation = true;
}
function preventDefault()
{
this.defaultPrevented = true;
}
var event = {target: this, type: eventType, defaultPrevented: false};
event.stopPropagation = stopPropagation.bind(event);
event.preventDefault = preventDefault.bind(event);
var listeners = this._listeners[eventType];
for (var i = 0; i < listeners.length; ++i) {
listeners[i].listener.call(listeners[i].thisObject, event);
if (stoppedPropagation)
break;
}
return event.defaultPrevented;
}
}
{
"1rx.io": {
"d": "RhythmOne"
},
"2mdn.net": {
"d": "Google"
},
"2o7.net": {
"d": "Adobe"
},
"33across.com": {
"d": "33Across"
},
"360yield.com": {
"d": "Improve Digital"
},
"3lift.com": {
"d": "TripleLift"
},
"abtasty.com": {
"d": "AB Tasty"
},
"acuityplatform.com": {
"d": "AcuityAds"
},
"addthis.com": {
"d": "Oracle"
},
"addtoany.com": {
"d": "AddToAny"
},
"adentifi.com": {
"d": "AdTheorent"
},
"adform.net": {
"d": "Adform"
},
"adgrx.com": {
"d": "AdGear"
},
"adhigh.net": {
"d": "GetIntent"
},
"adition.com": {
"d": "Virtual Minds"
},
"adkernel.com": {
"d": "Adkernel"
},
"adlightning.com": {
"d": "Ad Lightning"
},
"admedo.com": {
"d": "Admedo"
},
"admixer.net": {
"d": "Admixer"
},
"adnxs.com": {
"d": "Microsoft"
},
"adobedtm.com": {
"d": "Adobe"
},
"adotmob.com": {
"d": "A.Mob"
},
"adriver.ru": {
"d": "Internest-holding"
},
"adroll.com": {
"d": "AdRoll"
},
"ads-twitter.com": {
"d": "Twitter"
},
"adsafeprotected.com": {
"d": "Integral Ad Science"
},
"adscale.de": {
"d": "Ströer Group"
},
"adsco.re": {
"d": "Adscore"
},
"adsrvr.org": {
"d": "The Trade Desk"
},
"adstanding.com": {
"d": "AdStanding"
},
"adswizz.com": {
"d": "Sirius XM"
},
"adtdp.com": {
"d": "CyberAgent"
},
"adthrive.com": {
"d": "AdThrive"
},
"advertising.com": {
"d": "Verizon Media"
},
"affec.tv": {
"d": "Affectv"
},
"agkn.com": {
"d": "Neustar"
},
"aidata.io": {
"d": "Aidata"
},
"amazon-adsystem.com": {
"d": "Amazon"
},
"amplitude.com": {
"d": "Amplitude"
},
"amung.us": {
"d": "whos.amung.us"
},
"app.link": {
"d": "Branch Metrics"
},
"appdynamics.com": {
"d": "Cisco Systems"
},
"appier.net": {
"d": "Appier"
},
"attn.tv": {
"d": "Attentive Mobile"
},
"basis.net": {
"d": "Centro"
},
"betrad.com": {
"d": "Crownpeak"
},
"betweendigital.com": {
"d": "SSP Network"
},
"bfmio.com": {
"d": "Beachfront Media"
},
"bidr.io": {
"d": "Beeswax"
},
"bidswitch.net": {
"d": "IPONWEB"
},
"bing.com": {
"d": "Microsoft"
},
"bkrtx.com": {
"d": "Oracle"
},
"blismedia.com": {
"d": "Blis"
},
"bluecava.com": {
"d": "ALC"
},
"blueconic.net": {
"d": "BlueConic"
},
"bluekai.com": {
"d": "Oracle"
},
"bounceexchange.com": {
"d": "Bounce Exchange"
},
"branch.io": {
"d": "Branch Metrics"
},
"brealtime.com": {
"d": "EMX Digital"
},
"browser-update.org": {
"d": "Browser Update"
},
"bttrack.com": {
"d": "Bidtellect"
},
"buysellads.com": {
"d": "BuySellAds"
},
"casalemedia.com": {
"d": "Index Exchange"
},
"cdnwidget.com": {
"d": "CDNWIDGET.COM"
},
"chartbeat.com": {
"d": "Chartbeat"
},
"chaturbate.com": {
"d": "Chaturbate"
},
"clickagy.com": {
"d": "Clickagy"
},
"clickcertain.com": {
"d": "ClickCertain"
},
"clicktale.net": {
"d": "ClickTale"
},
"colossusssp.com": {
"d": "Colossus Media"
},
"company-target.com": {
"d": "Demandbase"
},
"consentmanager.net": {
"d": "ConsentManager"
},
"contentsquare.net": {
"d": "ContentSquare"
},
"contextweb.com": {
"d": "Pulsepoint"
},
"cookiepro.com": {
"d": "OneTrust"
},
"cpx.to": {
"d": "Captify"
},
"cquotient.com": {
"d": "Salesforce.com"
},
"crazyegg.com": {
"d": "Crazy Egg"
},
"creative-serving.com": {
"d": "Platform161"
},
"creativecdn.com": {
"d": "RTB House"
},
"criteo.com": {
"d": "Criteo"
},
"criteo.net": {
"d": "Criteo"
},
"crsspxl.com": {
"d": "Cross Pixel Media"
},
"crwdcntrl.net": {
"d": "Lotame Solutions"
},
"ctnsnet.com": {
"d": "Crimtan Holdings"
},
"cxense.com": {
"d": "Piano Software"
},
"deepintent.com": {
"d": "DeepIntent"
},
"demandbase.com": {
"d": "Demandbase"
},
"demdex.net": {
"d": "Adobe"
},
"disqus.com": {
"d": "Disqus"
},
"dotomi.com": {
"d": "Conversant"
},
"doubleclick.net": {
"d": "Google"
},
"doubleverify.com": {
"d": "DoubleVerify"
},
"driftt.com": {
"d": "Drift.com"
},
"dtscout.com": {
"d": "DTS"
},
"dwin1.com": {
"d": "Awin"
},
"dynamicyield.com": {
"d": "Dynamic Yield"
},
"e-planning.net": {
"d": "Teroa"
},
"eloqua.com": {
"d": "Oracle"
},
"emxdgt.com": {
"d": "Engine USA"
},
"en25.com": {
"d": "Oracle"
},
"ensighten.com": {
"d": "Ensighten"
},
"everestjs.net": {
"d": "Adobe"
},
"everesttech.net": {
"d": "Adobe"
},
"evidon.com": {
"d": "Crownpeak"
},
"exelator.com": {
"d": "The Nielsen Company"
},
"exoclick.com": {
"d": "ExoClick"
},
"exosrv.com": {
"d": "ExoClick"
},
"exponential.com": {
"d": "Exponential Interactive"
},
"eyeota.net": {
"d": "eyeota"
},
"ezoic.net": {
"d": "Ezoic"
},
"facebook.com": {
"d": "Facebook"
},
"facebook.net": {
"d": "Facebook"
},
"fastly-insights.com": {
"d": "Fastly"
},
"flashtalking.com": {
"d": "Flashtalking"
},
"foresee.com": {
"d": "ForeSee Results"
},
"forter.com": {
"d": "Forter"
},
"fullstory.com": {
"d": "FullStory"
},
"fwmrm.net": {
"d": "FreeWheel"
},
"gemius.pl": {
"d": "Gemius"
},
"getclicky.com": {
"d": "Roxr Software"
},
"getsitecontrol.com": {
"d": "GetWebCraft"
},
"go-mpulse.net": {
"d": "Akamai"
},
"google-analytics.com": {
"d": "Google"
},
"googleadservices.com": {
"d": "Google"
},
"googlesyndication.com": {
"d": "Google"
},
"googletagmanager.com": {
"d": "Google"
},
"googletagservices.com": {
"d": "Google"
},
"gumgum.com": {
"d": "GumGum"
},
"heapanalytics.com": {
"d": "Heap"
},
"hellobar.com": {
"d": "Crazy Egg"
},
"histats.com": {
"d": "wisecode"
},
"hotjar.com": {
"d": "Hotjar"
},
"hs-analytics.net": {
"d": "HubSpot"
},
"hsadspixel.net": {
"d": "HubSpot"
},
"hsleadflows.net": {
"d": "HubSpot"
},
"hubspot.com": {
"d": "HubSpot"
},
"hybrid.ai": {
"d": "Hybrid Adtech"
},
"ib-ibi.com": {
"d": "KBM Group"
},
"id5-sync.com": {
"d": "ID5"
},
"igodigital.com": {
"d": "Salesforce.com"
},
"impactradius-event.com": {
"d": "Impact"
},
"imrworldwide.com": {
"d": "The Nielsen Company"
},
"indexww.com": {
"d": "Index Exchange"
},
"innovid.com": {
"d": "Innovid Media"
},
"insightexpressai.com": {
"d": "Kantar Operations"
},
"inspectlet.com": {
"d": "Inspectlet"
},
"instagram.com": {
"d": "Facebook"
},
"intentiq.com": {
"d": "Intent IQ"
},
"ipredictive.com": {
"d": "Adelphic"
},
"ispot.tv": {
"d": "iSpot.tv"
},
"juicyads.com": {
"d": "JuicyAds"
},
"justpremium.com": {
"d": "JustPremium"
},
"kampyle.com": {
"d": "Medallia"
},
"kargo.com": {
"d": "Kargo"
},
"klaviyo.com": {
"d": "Klaviyo"
},
"krxd.net": {
"d": "Salesforce.com"
},
"liadm.com": {
"d": "LiveIntent"
},
"lijit.com": {
"d": "Sovrn Holdings"
},
"linkedin.com": {
"d": "Microsoft"
},
"linksynergy.com": {
"d": "Rakuten"
},
"list-manage.com": {
"d": "Intuit"
},
"listrak.com": {
"d": "Listrak"
},
"listrakbi.com": {
"d": "Listrak"
},
"livechatinc.com": {
"d": "LiveChat"
},
"liveperson.net": {
"d": "LivePerson"
},
"lkqd.net": {
"d": "Nexstar Media Group"
},
"loopme.me": {
"d": "LoopMe"
},
"lpsnmedia.net": {
"d": "LivePerson"
},
"mail.ru": {
"d": "VK"
},
"mailchimp.com": {
"d": "Intuit"
},
"marketo.com": {
"d": "Adobe"
},
"marketo.net": {
"d": "Adobe"
},
"mathtag.com": {
"d": "MediaMath"
},
"maxmind.com": {
"d": "MaxMind"
},
"media.net": {
"d": "Media.net Advertising"
},
"media6degrees.com": {
"d": "Dstillery"
},
"mediarithmics.com": {
"d": "mediarithmics"
},
"mediavine.com": {
"d": "Mediavine"
},
"mediawallahscript.com": {
"d": "MediaWallah"
},
"mfadsrvr.com": {
"d": "IPONWEB"
},
"mgid.com": {
"d": "MGID"
},
"micpn.com": {
"d": "Movable Ink"
},
"microad.jp": {
"d": "MicroAd"
},
"mktoresp.com": {
"d": "Adobe"
},
"ml314.com": {
"d": "Bombora"
},
"moatads.com": {
"d": "Oracle"
},
"monetate.net": {
"d": "Monetate"
},
"mookie1.com": {
"d": "WPP"
},
"mouseflow.com": {
"d": "Mouseflow"
},
"mxpnl.com": {
"d": "Mixpanel"
},
"mxptint.net": {
"d": "Valassis Digital"
},
"navdmp.com": {
"d": "Navegg"
},
"newrelic.com": {
"d": "New Relic"
},
"ninthdecimal.com": {
"d": "NinthDecimal"
},
"npttech.com": {
"d": "Piano Software"
},
"nr-data.net": {
"d": "New Relic"
},
"ntv.io": {
"d": "Nativo"
},
"o333o.com": {
"d": "AdSpyglass"
},
"olark.com": {
"d": "Olark"
},
"omnitagjs.com": {
"d": "Adyoulike"
},
"omtrdc.net": {
"d": "Adobe"
},
"onesignal.com": {
"d": "OneSignal"
},
"online-metrix.net": {
"d": "RELX Group"
},
"openx.net": {
"d": "OpenX"
},
"opmnstr.com": {
"d": "Retyp"
},
"optimizely.com": {
"d": "Optimizely"
},
"outbrain.com": {
"d": "Outbrain"
},
"owneriq.net": {
"d": "Inmar"
},
"pardot.com": {
"d": "Salesforce.com"
},
"parsely.com": {
"d": "Parsely"
},
"paypal.com": {
"d": "PayPal"
},
"permutive.com": {
"d": "Permutive"
},
"pingdom.net": {
"d": "Pingdom"
},
"pippio.com": {
"d": "LiveRamp"
},
"postrelease.com": {
"d": "Nativo"
},
"pro-market.net": {
"d": "Datonics"
},
"pswec.com": {
"d": "Proclivity Media"
},
"pubmatic.com": {
"d": "PubMatic"
},
"px-cloud.net": {
"d": "Human Security"
},
"qualtrics.com": {
"d": "SAP"
},
"quantserve.com": {
"d": "Quantcast"
},
"quora.com": {
"d": "Quora"
},
"rambler.ru": {
"d": "Rambler Internet Holding"
},
"realsrv.com": {
"d": "ExoClick"
},
"reddit.com": {
"d": "Reddit"
},
"redditstatic.com": {
"d": "Reddit"
},
"reson8.com": {
"d": "Resonate Networks"
},
"revcontent.com": {
"d": "RevContent"
},
"rezync.com": {
"d": "Zeta Global"
},
"rfihub.com": {
"d": "Zeta Global"
},
"rfihub.net": {
"d": "Zeta Global"
},
"rkdms.com": {
"d": "Merkle"
},
"rlcdn.com": {
"d": "LiveRamp"
},
"rmtag.com": {
"d": "Rakuten"
},
"rqtrk.eu": {
"d": "Roq.ad"
},
"rtmark.net": {
"d": "Propeller Ads"
},
"rubiconproject.com": {
"d": "Magnite"
},
"rutarget.ru": {
"d": "RuTarget"
},
"s-onetag.com": {
"d": "Sovrn Holdings"
},
"s3xified.com": {
"d": "AdMedia"
},
"sail-horizon.com": {
"d": "CM Group"
},
"salesforceliveagent.com": {
"d": "Salesforce.com"
},
"samplicio.us": {
"d": "Lucid Holdings"
},
"sascdn.com": {
"d": "Smartadserver"
},
"sc-static.net": {
"d": "Snap"
},
"scarabresearch.com": {
"d": "SAP"
},
"scorecardresearch.com": {
"d": "comScore"
},
"securedvisit.com": {
"d": "4Cite Marketing"
},
"segment.com": {
"d": "Segment.io"
},
"segment.io": {
"d": "Segment.io"
},
"semasio.net": {
"d": "Semasio"
},
"serving-sys.com": {
"d": "Amazon"
},
"shareaholic.com": {
"d": "Shareaholic"
},
"sharethis.com": {
"d": "ShareThis"
},
"sharethrough.com": {
"d": "Sharethrough"
},
"simpli.fi": {
"d": "Simplifi Holdings"
},
"siteimproveanalytics.com": {
"d": "Siteimprove"
},
"sitescout.com": {
"d": "Centro"
},
"skimresources.com": {
"d": "Skimbit"
},
"smaato.net": {
"d": "Smaato"
},
"smartadserver.com": {
"d": "Smartadserver"
},
"snapchat.com": {
"d": "Snap"
},
"socdm.com": {
"d": "Supership"
},
"sojern.com": {
"d": "Sojern"
},
"sonobi.com": {
"d": "Sonobi"
},
"springserve.com": {
"d": "SpringServe"
},
"stackadapt.com": {
"d": "Collective Roll"
},
"statcounter.com": {
"d": "StatCounter"
},
"steelhousemedia.com": {
"d": "Steel House"
},
"stickyadstv.com": {
"d": "FreeWheel"
},
"storygize.net": {
"d": "Storygize"
},
"sundaysky.com": {
"d": "SundaySky"
},
"t.co": {
"d": "Twitter"
},
"taboola.com": {
"d": "Taboola"
},
"tagcommander.com": {
"d": "Fjord"
},
"tapad.com": {
"d": "Tapad"
},
"teads.tv": {
"d": "Teads"
},
"tealiumiq.com": {
"d": "Tealium"
},
"technoratimedia.com": {
"d": "Synacor"
},
"thrtle.com": {
"d": "Throtle"
},
"tinypass.com": {
"d": "Piano Software"
},
"tiqcdn.com": {
"d": "Tealium"
},
"tns-counter.ru": {
"d": "ADFACT"
},
"trackcmp.net": {
"d": "ActiveCampaign"
},
"treasuredata.com": {
"d": "Treasure Data"
},
"tremorhub.com": {
"d": "Telaria"
},
"tribalfusion.com": {
"d": "Exponential Interactive"
},
"tru.am": {
"d": "trueAnthem"
},
"truoptik.com": {
"d": "21 Productions"
},
"truste.com": {
"d": "TrustArc"
},
"trustpilot.com": {
"d": "Trustpilot"
},
"tsyndicate.com": {
"d": "Traffic Stars"
},
"tubemogul.com": {
"d": "Adobe"
},
"turn.com": {
"d": "Amobee"
},
"tvsquared.com": {
"d": "TVSquared"
},
"twitter.com": {
"d": "Twitter"
},
"tynt.com": {
"d": "33Across"
},
"ubembed.com": {
"d": "Unbounce"
},
"undertone.com": {
"d": "Undertone Networks"
},
"unrulymedia.com": {
"d": "Unruly Group"
},
"usabilla.com": {
"d": "Momentive"
},
"usemessages.com": {
"d": "HubSpot"
},
"usercentrics.eu": {
"d": "Usercentrics"
},
"userreport.com": {
"d": "AudienceProject"
},
"viglink.com": {
"d": "Sovrn Holdings"
},
"visualwebsiteoptimizer.com": {
"d": "Wingify"
},
"vk.com": {
"d": "VK"
},
"w55c.net": {
"d": "Roku"
},
"walmart.com": {
"d": "Walmart"
},
"weborama.fr": {
"d": "Weborama"
},
"webvisor.org": {
"d": "Yandex"
},
"xg4ken.com": {
"d": "Kenshoo TLD"
},
"xiti.com": {
"d": "AT Internet"
},
"yadro.ru": {
"d": "ECO PC - Complex Solutions"
},
"yahoo.co.jp": {
"d": "LY-Corporation"
},
"yahoo.com": {
"d": "Verizon Media"
},
"yandex.ru": {
"d": "Yandex"
},
"yieldlab.net": {
"d": "Virtual Minds"
},
"yieldmo.com": {
"d": "YieldMo"
},
"yieldoptimizer.com": {
"d": "WarnerMedia"
},
"yimg.jp": {
"d": "LY-Corporation"
},
"yotpo.com": {
"d": "Yotpo"
},
"ywxi.net": {
"d": "PathDefender"
},
"zemanta.com": {
"d": "Outbrain"
},
"zopim.com": {
"d": "Zendesk"
}
}
{
"LoginFormTypeKeywords": {
"@me": 1,
"welcome back": 1,
"log on": 1,
"登录": 1,
"iniciar sesión": 1,
"login": 1,
"log in": 1,
"sign in": 1,
"forgot user": 1,
"enter your password": 2,
"登入": 1,
"signon": 1,
"reauth": 2,
"anmelden": 1,
"signin": 1,
"log_on": 1,
"sign on": 1,
"connexion": 1,
"absenden": 1,
"logg inn": 1
},
"ForgotEmailAffordanceRegularExpressions": [
"^forgot.*email",
"email\\?$"
],
"ForgotUserNameAffordanceRegularExpressions": [
"^forgot.*user.*name"
],
"NonAccountPasswordSecureTextEntryFieldLabels": [
"debit",
"answer",
"account number",
"routing number",
"date of birth",
"zip code"
],
"ChangePasswordFormTypeKeywords": {
"forgotpassword": 1,
"forgot password": 1,
"reset": 1,
"update": 1,
"change": 1,
"再設定": 1
},
"NewAccountFormTypeKeywords": {
"set up": 1,
"signup": 1,
"create": 1,
"create an account": 1,
"create account": 1,
"setup": 1,
"sign up": 1,
"enrollment": 1,
"reg": 1,
"activate": 1,
"注册": 1
},
"IgnoredDataTypeFieldLabels": [
"search",
"social security",
"socialsecurity",
"tax id number",
"ssn",
"ssno",
"ssnum",
"airport",
"gate code",
"relationship"
],
"NonAutoFillableFormTypeKeywords": [
"import"
],
"OldPasswordFieldLabels": [
"current",
"old",
"original"
],
"ConfirmEmailFieldLabels": [
"confirm"
],
"ConfirmPasswordFieldLabels": [
"repeat",
"retype",
"confirm",
"verify",
"new"
],
"ShowHideButtonLabels": [
"show",
"hide"
],
"SearchFieldLabels": [
"search"
],
"NonUsernameFieldLabels": [
"login code",
"otpcode",
"password",
"captcha",
"recaptcha",
"sound",
"answer",
"confirmation code",
"verification code",
"zip code",
"stock symbol",
"chart",
"table",
"certificate",
"cash card number"
],
"PasswordFieldLabels": [
"password",
"passwd",
"设置密码",
"passwort"
],
"ForgotPasswordAffordanceRegularExpressions": [
"^forgot.*password"
],
"NonEmailFieldLabels": [
"確認コード"
],
"UsernameFieldLabels": [
"username",
"user name",
"screenname",
"screen name",
"loginname",
"login name",
"account name",
"userID",
"user ID",
"loginID",
"accountID",
"Online ID",
"GmailAddress",
"Gmail Address",
"usuario",
"Library Card Number",
"E-Mail-Adresse"
],
"OneTimeCodeFieldLabels": [
"security code",
"login code",
"enter the code",
"enter code",
"otp",
"onetimecode",
"onetimepasscode",
"one time password",
"one time passcode",
"verification code",
"verificationCode",
"confirmation code",
"identification code",
"identificationCode",
"activation code",
"access code",
"SMS",
"digit code",
"2fa",
"twofactor",
"two-factor",
"two factor",
"authentication code",
"two step sign in",
"two-step sign in",
"MFA code",
"sign-in code",
"passcode texted",
"passcode expires",
"验证码",
"校验码",
"驗證碼",
"驗証碼",
"確認碼",
"認證碼",
"確認コード",
"認証コード",
"인증번호",
"확인코드",
"code de sécurité",
"code de vérification",
"code de validation",
"code d'identification",
"code d'authentification",
"code d'autorisation",
"code de confirmation",
"code SMS de vérification",
"code de connexion",
"Authorisierungscode",
"Sicherheitscode",
"Überprüfungscode",
"Bestätigungscode",
"Bestatigungscode",
"Verifizierungscode",
"Aktivierungscode",
"Codice di sicurezza",
"Codice attivazione",
"codice di attivazione",
"codice di conferma",
"codice di verifica",
"Kod bezpieczeństwa",
"Kod autoryzacyjny",
"Kod weryfikacyjny",
"código de seguridad",
"código de confirmación",
"código de seguranca",
"digite o codigo",
"código de verificación",
"código de verificação",
"código de confirmacao",
"Код проверки",
"код безопасности",
"код подтверждения",
"Код аутентификации",
"код підтвердження",
"dogrulama kodu",
"mã bảo mật",
"Mã Xác Minh",
"mã kích hoạt",
"รหัสความปลอดภัย",
"รหัสยืนยัน",
"รหัสOTP",
"รหัสการตรวจสอบยืนยัน",
"รหัสการยืนยัน",
"Kode keamanan",
"Kode konfirmasi",
"Kode verifikasi",
"सत्यापन कोड",
"Kod pengesahan",
"Masukkan Kod",
"Codul de confirmare"
],
"WeakOneTimeCodeFieldLabels": [
"code",
"passcode",
"PIN",
"token",
"código",
"코드",
"コード",
"код"
],
"DayFieldLabels": [
"day",
"jour"
],
"MonthFieldLabels": [
"month",
"date m",
"date mo",
"mois"
],
"YearFieldLabels": [
"year",
"date y",
"date yr",
"année"
]
}
var pageArguments = {};
var HTMLViewController = {
trySubmit: function(button)
{
var computedStyle = window.getComputedStyle(button);
// Don't use button.type here, since the default type for button is annoyingly "submit".
// Check for an explicit type attribute value of "submit".
if (button.getAttribute("type") !== "submit" || computedStyle.visibility === "hidden" || computedStyle.display === "none")
return false;
button.click();
return true;
},
// On Mac, the submit button always has the default button look.
keyDown: function(event)
{
if (event.target.tagName === "TEXTAREA" || event.keyIdentifier !== "Enter")
return;
var buttons = document.getElementsByTagName("button");
for (var i = 0; i < buttons.length; ++i) {
if (HTMLViewController.trySubmit(buttons[i])) {
event.preventDefault();
return;
}
}
var inputButtons = document.getElementsByTagName("input");
for (var i = 0; i < inputButtons.length; ++i) {
if (HTMLViewController.trySubmit(inputButtons[i])) {
event.preventDefault();
return;
}
}
},
setItemText: function(itemID, value)
{
var ele = document.getElementById(itemID);
if (ele.tagName == "INPUT" || ele.tagName == "SELECT" || ele.tagName == "TEXTAREA")
ele.value = value;
else
ele.innerText = value;
},
itemText: function(itemID)
{
var ele = document.getElementById(itemID);
if (ele.tagName == "INPUT" || ele.tagName == "SELECT" || ele.tagName == "TEXTAREA")
return ele.value;
else if (ele.firstChild)
return ele.firstChild.data;
else return "";
},
setItemChecked: function(itemID, value)
{
document.getElementById(itemID).checked = value;
},
itemChecked: function(itemID)
{
return document.getElementById(itemID).checked;
},
setItemEnabled: function(itemID, value)
{
var item = document.getElementById(itemID);
item.disabled = !value;
if (item.parentElement.tagName == "LABEL") {
if (value)
item.parentElement.classList.remove("disabled");
else
item.parentElement.classList.add("disabled");
}
},
insertOptionInSelect: function(selectID, position, label, value)
{
var select = document.getElementById(selectID);
var option = document.createElement("option");
option.appendChild(document.createTextNode(label));
option.value = value;
select.add(option, select.options[position]);
},
appendToSelect: function(itemID, label, itemValue, itemStyle)
{
var selectEle = document.getElementById(itemID);
var o;
if (label == "")
o = document.createElement("hr");
else {
o = document.createElement("option");
o.appendChild(document.createTextNode(label));
o.value = itemValue ? itemValue : selectEle.length;
o.style.cssText = itemStyle;
}
selectEle.add(o, null);
},
setSelectIndex: function(itemID, index)
{
var selectEle = document.getElementById(itemID);
selectEle.selectedIndex = index;
},
setOptionEnabled: function(selectID, optionIndex, enabled)
{
document.getElementById(selectID)[optionIndex].disabled = !enabled;
},
indexOfItemWithValue: function(selectID, value)
{
var select = document.getElementById(selectID);
for (var i = 0; i < select.options.length; ++i) {
if (select.options[i].value == value)
return i;
}
return -1;
},
clearSelect: function(itemID)
{
var selectEle = document.getElementById(itemID);
selectEle.removeChildren();
},
setWidth: function(width)
{
window.resizeTo(width);
},
htmlOffsetHeight: function()
{
return document.getElementsByTagName("html")[0].offsetHeight;
},
addClass: function(itemID, itemClass)
{
document.getElementById(itemID).classList.add(itemClass);
},
removeClass: function(itemID, itemClass)
{
document.getElementById(itemID).classList.remove(itemClass);
},
setAttribute: function(itemID, attrName, attrValue)
{
document.getElementById(itemID).setAttribute(attrName, attrValue);
},
setTitle: function(newTitle)
{
document.title = newTitle;
},
focusItem: function(itemID)
{
var ele = document.getElementById(itemID);
ele.focus();
ele.selectionStart = 0;
ele.selectionEnd = ele.value.length;
},
contextMenu: function(event)
{
if (event.target.tagName === "TEXTAREA")
return;
if (event.target.tagName === "INPUT" && (event.target.type === "password" || event.target.type === "text" || event.target.type == "search"))
return;
event.preventDefault();
},
pageLoaded: function()
{
var query = document.location.search;
if (query) {
query = query.substr(1);
var args = query.split("&");
for (var i = 0; i < args.length; i++) {
var nameValue = args[i].split("=");
pageArguments[nameValue[0]] = nameValue[1];
}
}
document.body.addEventListener("keydown", HTMLViewController.keyDown);
document.addEventListener("contextmenu", HTMLViewController.contextMenu);
HTMLViewController.localize();
},
UIString: function(string)
{
if (window.localizedStrings && string in window.localizedStrings)
string = window.localizedStrings[string];
else {
console.error("Localized string \"" + string + "\" not found.");
string = "LOCALIZED STRING NOT FOUND";
}
return string;
},
loadLocalizedStrings: function(controller)
{
document.write("<script type='text/javascript' charset='utf-8' src='safari-resource:/WBSLocalizedStrings.js'></" + "script>");
},
localize: function()
{
var elements = document.getElementsByClassName("l12n");
for (var i = 0; i < elements.length; ++i)
elements[i].firstChild.data = HTMLViewController.UIString(elements[i].firstChild.data);
var toolTipElements = document.getElementsByClassName("l12n-tooltip");
for (var i = 0; i < toolTipElements.length; ++i)
toolTipElements[i].title = HTMLViewController.UIString(toolTipElements[i].title);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment