Skip to content

Instantly share code, notes, and snippets.

@eugeneware
Forked from hackerxian/safari_reader.js
Created June 14, 2017 11:44
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save eugeneware/bb69a5bce8c8c48178845429435458e2 to your computer and use it in GitHub Desktop.
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*/
function characterNeedsScoreMultiplier(e) {
if (!e || e.length === 0)
return !1;
var t = e.charCodeAt(0);
return t > 11904 && t < 12031?!0 : t > 12352 && t < 12543?!0 : t > 12736 && t < 19903?!0 : t > 19968 && t < 40959?!0 : t > 44032 && t < 55215?!0 : t > 63744 && t < 64255?!0 : t > 65072 && t < 65103?!0 : t > 131072 && t < 173791?!0 : t > 194560 && t < 195103?!0 : !1
}
function domDistance(e, t, n) {
var r = [], i = e;
while (i)
r.unshift(i), i = i.parentNode;
var s = [];
i = t;
while (i)
s.unshift(i), i = i.parentNode;
var o = Math.min(r.length, s.length), u = Math.abs(r.length - s.length);
for (var a = o; a >= 0; --a) {
if (r[a] === s[a])
break;
u += 2;
if (n && u >= n)
return n
}
return u
}
function fontSizeFromComputedStyle(e, t) {
var n = parseInt(e.fontSize);
return isNaN(n) && (n = t ? t : BaseFontSize), n
}
function contentTextStyleForNode(e, t) {
function n(e) {
if (isNodeWhitespace(e))
return null;
var t = getComputedStyle(e.parentNode);
return t.float !== "none" ? null : t
}
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), s = i.snapshotLength;
for (var o = 0; o < s; ++o) {
var u = i.snapshotItem(o), a=!1;
for (var f = u.parentElement; f !== t; f = f.parentElement)
if (NegativeRegEx.test(f.className)) {
a=!0;
break
}
if (a)
continue;
var l = n(u);
if (l)
return l
}
return null
}
function isNodeWhitespace(e) {
return !e || e.nodeType !== Node.TEXT_NODE?!1 : !/\S/.test(e.data)
}
function removeWhitespace(e) {
return e.replace(/\s+/g, "")
}
function isElementNode(e) {
return e && e.nodeType === Node.ELEMENT_NODE?!0 : !1
}
function computedStyleIndicatesElementIsInvisibleDueToClipping(e) {
if (e.position !== "absolute")
return !1;
var t = e.clip.match(/^rect\((\d+px|auto), (\d+px|auto), (\d+px|auto), (\d+px|auto)\)$/);
if (!t || t.length !== 5)
return !1;
var n = t.map(function(e) {
return parseInt(e)
}), r = n[1];
isNaN(r) && (r = 0);
var i = n[2], s = n[3], o = n[4];
return isNaN(o) && (o = 0), r >= s || i >= o
}
function isElementVisible(e) {
var t = getComputedStyle(e);
if (t.visibility !== "visible" || t.display === "none")
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?!1 : t.bottom <= 0 || t.right <= 0?!0 : !1
}
function elementDepth(e) {
var t = 0;
for (; e; e = e.parentElement)
t++;
return t
}
function depthOfElementWithinElement(e, t) {
var n = 0;
for (; e !== t; e = e.parentElement)
n++;
return n
}
function nearestAncestorElementWithTagName(e, t) {
while (e = e.parentElement)
if (e.tagName === t)
return e;
return null
}
function cachedElementBoundingRect(e) {
if (e._cachedElementBoundingRect)
return e._cachedElementBoundingRect;
var t = e.getBoundingClientRect();
return ReaderArticleFinderJS._elementsWithCachedBoundingRects.push(e), !ReaderArticleFinderJS._cachedScrollX&&!ReaderArticleFinderJS._cachedScrollY ? (e._cachedElementBoundingRect = t, e._cachedElementBoundingRect) : (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)
}
function clearCachedElementBoundingRects() {
var e = ReaderArticleFinderJS._elementsWithCachedBoundingRects, t = e.length;
for (var n = 0; n < t; ++n)
e[n]._cachedElementBoundingRect = null;
ReaderArticleFinderJS._elementsWithCachedBoundingRects = []
}
function innerTextOrTextContent(e) {
var t = e.innerText;
return /\S/.test(t) || (t = e.textContent), t
}
function levenshteinDistance(e, t) {
var n = e.length, r = t.length, i = new Array(n + 1);
for (var s = 0; s < n + 1; ++s)
i[s] = new Array(r + 1), i[s][0] = s;
for (var o = 0; o < r + 1; ++o)
i[0][o] = o;
for (var o = 1; o < r + 1; ++o)
for (var s = 1; s < n + 1; ++s)
if (e[s - 1] === t[o - 1])
i[s][o] = i[s - 1][o - 1];
else {
var u = i[s - 1][o] + 1, a = i[s][o - 1] + 1, f = i[s - 1][o - 1] + 1;
i[s][o] = Math.min(u, a, f)
}
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?!0 : stringSimilarity(e, t) > StringSimilarityToDeclareStringsNearlyIdentical
}
function elementIsCommentBlock(e) {
if (/(^|\s)comment/.test(e.className))
return !0;
var t = e.getAttribute("id");
return t && t.indexOf("comment") === 0?!0 : !1
}
function elementLooksLikeEmbeddedTweet(e) {
const t = /http.+twitter.com.*status.*[0-9]+/i;
if (e.tagName !== "IFRAME")
return !1;
if (!e.contentDocument)
return !1;
var n = e.contentDocument.documentElement, r = 0, i = n.querySelector("blockquote");
return i && t.test(i.getAttribute("cite"))&&++r, e.classList.contains("twitter-tweet")&&++r, n.querySelector("[data-iframe-title='Embedded Tweet']")&&++r, n.querySelector("[data-tweet-id]")&&++r, r > 2
}
function elementLooksLikePartOfACarousel(e) {
const t = /carousel-|carousel_|-carousel|_carousel/, n = 3;
var r = e;
for (var i = 0; i < n; ++i) {
if (!r)
return !1;
if (t.test(r.className) || t.test(r.getAttribute("data-analytics")))
return !0;
r = r.parentElement
}
}
function shouldPruneIframe(e, t) {
return HostnamesKnownToContainEmbeddableMediaRegex.test(anchorForURL(e.src, t).hostname)?!1 : elementLooksLikeEmbeddedTweet(e.originalElement)?!1 : !0
}
function languageScoreMultiplierForTextNodes(e) {
if (!e ||!e.length)
return 1;
var t = Math.min(e.length, DefaultNumberOfTextNodesToCheckForLanguageMultiplier), n = 0, r = 0;
for (var i = 0; i < t; i++) {
var s = e[i].nodeValue.trim(), o = Math.min(s.length, NumberOfCharactersPerTextNodeToEvaluateForLanguageMultiplier);
for (var u = 0; u < o; u++)
characterNeedsScoreMultiplier(s[u]) && n++;
r += o
}
return n >= r * MinimumRatioOfCharactersForLanguageMultiplier ? ScoreMultiplierForChineseJapaneseKorean : 1
}
function scoreMultiplierForElementTagNameAndAttributes(e) {
var t = 1;
for (var n = e; n; n = n.parentElement) {
var r = n.getAttribute("id");
r && (ArticleRegEx.test(r) && (t += ArticleMatchBonus), CommentRegEx.test(r) && (t -= CommentMatchPenalty));
var i = n.className;
i && (ArticleRegEx.test(i) && (t += ArticleMatchBonus), CommentRegEx.test(i) && (t -= CommentMatchPenalty)), n.tagName === "ARTICLE" && (t += ArticleMatchBonus)
}
return t < 0 ? 0 : t
}
function elementAtPoint(e, t) {
if (typeof ReaderArticleFinderJSController != "undefined" && ReaderArticleFinderJSController.nodeAtPoint) {
var n = ReaderArticleFinderJSController.nodeAtPoint(e, t);
return n && n.nodeType !== Node.ELEMENT_NODE && (n = n.parentElement), n
}
return document.elementFromPoint(e, t)
}
function userVisibleURLString(e) {
return typeof ReaderArticleFinderJSController != "undefined" && ReaderArticleFinderJSController.userVisibleURLString ? ReaderArticleFinderJSController.userVisibleURLString(e) : e
}
function anchorForURL(e, t) {
var n = t.createElement("a");
return n.href = e, n
}
function anchorLinksToAttachment(e) {
return /\battachment\b/i.test(e.getAttribute("rel"))
}
function anchorLinksToTagOrCategoryPage(e) {
return /\bcategory|tag\b/i.test(e.getAttribute("rel"))
}
function elementsHaveSameTagAndClassNames(e, t) {
return e.tagName === t.tagName && e.className === t.className
}
function selectorForElement(e) {
var t = e.tagName, n = e.classList, r = n.length;
for (var i = 0; i < r; i++)
t += "." + n[i];
return t
}
function elementFingerprintForDepth(e, t) {
function s(e, t) {
if (!e)
return "";
var o = [];
o.push(selectorForElement(e));
var u = e.children, a = u.length;
if (a && t > 0) {
o.push(n);
for (var f = 0; f < a; ++f)
o.push(s(u[f], t - 1)), f !== a - 1 && o.push(i);
o.push(r)
}
return o.join("")
}
const n = " / ", r = " \\", i = " | ";
return s(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)
return;
var r = e.children, i = r.length, s = t - 1;
for (var o = 0; o < i; ++o)
walkElementSubtree(r[o], s, n);
n(e, t)
}
function childrenWithParallelStructure(e) {
var t = e.children;
if (!t)
return [];
var n = t.length;
if (!n)
return [];
var r = {};
for (var i = 0; i < n; ++i) {
var s = t[i];
if (CandidateTagNamesToIgnore[s.tagName] ||!s.className)
continue;
var o = s.classList, u = o.length;
for (var a = 0; a < u; ++a) {
var f = o[a], l = r[f];
l ? l.push(s) : r[f] = [s]
}
}
var c = Math.floor(n / 2);
for (var f in r) {
var l = r[f];
if (l.length > c)
return l
}
return []
}
const ReaderMinimumScore = 1600, ReaderMinimumAdvantage = 15, ArticleMinimumScoreDensity = 4.25, BlacklistedHostsAllowedPathRegexMap = {
"www.apple.com": /^\/([a-z]{2,4}\/){0,2}pr\/|^\/hotnews\//,
"extensions.apple.com": null
}, ListOfHostnameAndTrustedArticleNodeSelectorPairs = [[/.*\.apple.com$/, "article"]], CandidateMinimumWidth = 280, CandidateMinimumHeight = 295, CandidateMinimumArea = 17e4, CandidateMaximumTop = 1300, CandidateMinimumWidthPortionForIndicatorElements = .5, CandidateMinumumListItemLineCount = 4, CandidateTagNamesToIgnore = {
A: 1,
EMBED: 1,
FORM: 1,
HTML: 1,
IFRAME: 1,
OBJECT: 1,
OL: 1,
OPTION: 1,
SCRIPT: 1,
STYLE: 1,
svg: 1,
UL: 1
}, PrependedArticleCandidateMinimumHeight = 50, AppendedArticleCandidateMinimumHeight = 200, AppendedArticleCandidateMaximumVerticalDistanceFromArticle = 150, StylisticClassNames = {
justfy: 1,
justify: 1,
left: 1,
right: 1,
small: 1
}, CommentRegEx = /comment|meta|footer|footnote/, CommentMatchPenalty = .75, ArticleRegEx = /(?:(?:^|\s)(?:(post|hentry|entry)[-_]?(?:content|text|body)?|article[-_]?(?:content|text|body|page)?)(?:\s|$))/i, ArticleMatchBonus = .5, DensityExcludedElementSelector = "#disqus_thread, #comments, .userComments", AttributesToRemoveRegEx = /^on|^id$|^class$|^style$/, PositiveRegEx = /article|body|content|entry|hentry|page|pagination|post|text/i, NegativeRegEx = /advertisement|breadcrumb|combx|comment|contact|disqus|footer|link|meta|mod-conversations|promo|related|scroll|share|shoutbox|sidebar|social|sponsor|subscribe|tags|toolbox|widget|_ad$/i, VeryPositiveClassNameRegEx = /instapaper_body/, VeryNegativeClassNameRegEx = /instapaper_ignore/, SharingRegex = /email|print|rss|digg|slashdot|delicious|reddit|share/i, HostnamesKnownToContainEmbeddableMediaRegex = /youtube|vimeo|dailymotion/, 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, HeaderMinimumDistanceFromArticleTop = 200, HeaderLevenshteinDistanceToLengthRatio = .75, MinimumRatioOfListItemsBeingRelatedToSharingToPruneEntireList = .5, FloatMinimumHeight = 130, ImageSizeTiny = 32, ToleranceForLeadingImageWidthToArticleWidthForFullWidthPresentation = 50, MaximumFloatWidth = 325, AnchorImageMinimumWidth = 100, AnchorImageMinimumHeight = 100, MinimumHeightForImagesAboveTheArticleTitle = 50, MainImageMinimumWidthAndHeight = 83, BaseFontSize = 16, BaseLineHeightRatio = 1.125, MaximumExactIntegralValue = 9007199254740992, TitleCandidateDepthScoreMultiplier = .1, DocumentPositionDisconnected = 1, DocumentPositionPreceding = 2, DocumentPositionFollowing = 4, DocumentPositionContains = 8, DocumentPositionContainedBy = 16, TextNodeLengthPower = 1.25, KnownImageLazyLoadingAttributes = {
"data-lazy-src": 1,
"data-original": 1,
"data-src": 1,
"original-src": 1,
"rel:bf_image_src": 1
}, StringSimilarityToDeclareStringsNearlyIdentical = .97;
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(t, n, r, i) {
const s = "a, b, strong, i, em, u, span";
var o = cachedElementBoundingRect(t), u = cachedElementBoundingRect(n.element);
if (i && o.height < PrependedArticleCandidateMinimumHeight ||!i && o.height < AppendedArticleCandidateMinimumHeight)
if (t.childElementCount && t.querySelectorAll("*").length !== t.querySelectorAll(s).length)
return null;
if (i) {
if (o.bottom > u.top)
return null
} else if (o.top < u.bottom)
return null;
if (!i) {
var a = o.top - u.bottom;
if (a > AppendedArticleCandidateMaximumVerticalDistanceFromArticle)
return null
}
if (o.left > u.right || o.right < u.left)
return null;
if (elementLooksLikePartOfACarousel(t))
return null;
var f = new CandidateElement(t, r);
return f.isPrepended = i, f
}, CandidateElement.candidateIfElementIsViable = function(t, n, r) {
var i = cachedElementBoundingRect(t);
return i.width < CandidateMinimumWidth || i.height < CandidateMinimumHeight ? null : i.width * i.height < CandidateMinimumArea ? null : !r && i.top > CandidateMaximumTop ? null : CandidateElement.candidateElementAdjustedHeight(t) < CandidateMinimumHeight ? null : new CandidateElement(t, n)
}, CandidateElement.candidateElementAdjustedHeight = function(t) {
var n = cachedElementBoundingRect(t), r = n.height, i = t.getElementsByTagName("form"), s = i.length;
for (var o = 0; o < s; ++o) {
var u = i[o], a = cachedElementBoundingRect(u);
a.width > n.width * CandidateMinimumWidthPortionForIndicatorElements && (r -= a.height)
}
var f = t.querySelectorAll("ol, ul"), l = f.length, c = null;
for (var o = 0; o < l; ++o) {
var h = f[o];
if (c && c.compareDocumentPosition(h) & DocumentPositionContainedBy)
continue;
var p = h.getElementsByTagName("li"), d = p.length, v = cachedElementBoundingRect(h);
if (!d) {
r -= v.height;
continue
}
var m = v.height / d, g = getComputedStyle(p[0]), y = parseInt(g.lineHeight);
if (isNaN(y)) {
var b = fontSizeFromComputedStyle(g);
y = b * BaseLineHeightRatio
}
v.width > n.width * CandidateMinimumWidthPortionForIndicatorElements && m / y < CandidateMinumumListItemLineCount && (r -= v.height, c = h)
}
return r
}, CandidateElement.prototype = {
calculateRawScore: function() {
var t = 0, n = this.textNodes, r = n.length;
for (var i = 0; i < r; ++i)
t += this.rawScoreForTextNode(n[i]);
return t
},
calculateElementTagNameAndAttributesScoreMultiplier: function() {
return scoreMultiplierForElementTagNameAndAttributes(this.element)
},
calculateLanguageScoreMultiplier: function() {
if (this.languageScoreMultiplier !== 0)
return;
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 t = 0, n = this.element.querySelector(DensityExcludedElementSelector);
n && (t = n.clientWidth * n.clientHeight);
var r = this.element.children || [], i = r.length;
for (var s = 0; s < i; ++s) {
var o = r[s];
elementIsCommentBlock(o) && (t += o.clientWidth * o.clientHeight)
}
var u = cachedElementBoundingRect(this.element).width * cachedElementBoundingRect(this.element).height, a = u * MaximumContentMediaAreaToArticleAreaRatio, f = cachedElementBoundingRect(this.element).width * MinimumContentMediaWidthToArticleWidthRatio, l = this.element.querySelectorAll("img, object, video"), c = l.length;
for (var s = 0; s < c; ++s) {
var h = cachedElementBoundingRect(l[s]);
if (h.width >= f && h.height > MinimumContentMediaHeight) {
var p = h.width * h.height;
p < a && (t += p)
}
}
var d = this.basicScore(), v = u - t, m = this.textNodes.length, g = 0, y = 0;
for (var s = 0; s < m; ++s) {
var b = this.textNodes[s].parentNode;
b && (y += fontSizeFromComputedStyle(getComputedStyle(b)), g++)
}
var w = BaseFontSize;
return g && (w = y/=g), this.calculateLanguageScoreMultiplier(), d / v * 1e3 * (w / BaseFontSize) * this.languageScoreMultiplier
},
usableTextNodesInElement: function(t) {
var n = [];
if (!t)
return n;
const r = {
A: 1,
DD: 1,
DT: 1,
NOSCRIPT: 1,
OL: 1,
OPTION: 1,
PRE: 1,
SCRIPT: 1,
STYLE: 1,
TD: 1,
UL: 1,
IFRAME: 1
};
var i = this.contentDocument, s = function(e) {
const t = "text()|*/text()|*/a/text()|*/li/text()|*/span/text()|*/em/text()|*/i/text()|*/strong/text()|*/b/text()|*/font/text()|blockquote/*/text()|div[count(./p)=count(./*)]/p/text()";
var s = i.evaluate(t, e, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null), o = s.snapshotLength;
for (var u = 0; u < o; ++u) {
var a = s.snapshotItem(u);
if (r[a.parentNode.tagName] || a._countedTextNode || isNodeWhitespace(a))
continue;
a._countedTextNode=!0, n.push(a)
}
};
s(t);
var o = childrenWithParallelStructure(t), u = o.length;
for (var a = 0; a < u; ++a) {
var f = o[a];
s(f)
}
var l = n.length;
for (var a = 0; a < l; ++a)
delete n[a]._countedTextNode;
return n
},
addTextNodesFromCandidateElement: function(t) {
var n = this.textNodes.length;
for (var r = 0; r < n; ++r)
this.textNodes[r].alreadyCounted=!0;
var i = t.textNodes, s = i.length;
for (var r = 0; r < s; ++r)
i[r].alreadyCounted || this.textNodes.push(i[r]);
var n = this.textNodes.length;
for (var r = 0; r < n; ++r)
this.textNodes[r].alreadyCounted = null;
this.rawScore = this.calculateRawScore()
},
rawScoreForTextNode: function(t) {
const n = 20;
if (!t)
return 0;
var r = t.length;
if (r < n)
return 0;
var i = t.parentNode;
if (!isElementVisible(i))
return 0;
var s = 1;
while (i && i !== this.element)
s -= .1, i = i.parentNode;
return Math.pow(r * s, TextNodeLengthPower)
},
shouldDisqualifyDueToScoreDensity: function() {
return this.scoreDensity() < ArticleMinimumScoreDensity?!0 : !1
},
shouldDisqualifyDueToHorizontalRuleDensity: function() {
var t = this.element.getElementsByTagName("hr"), n = t.length, r = 0, i = cachedElementBoundingRect(this.element), s = i.width * .7;
for (var o = 0; o < n; ++o)
t[o].clientWidth > s && r++;
if (r) {
var u = i.height / r;
if (u < MinimumAverageDistanceBetweenHRElements)
return !0
}
return !1
},
shouldDisqualifyDueToHeaderDensity: function() {
var t = "(h1|h2|h3|h4|h5|h6|*/h1|*/h2|*/h3|*/h4|*/h5|*/h6)[a[@href]]", n = this.contentDocument.evaluate(t, this.element, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null), r = n.snapshotLength;
if (r > 2) {
var i = 0, s = cachedElementBoundingRect(this.element), o = s.height * PortionOfCandidateHeightToIgnoreForHeaderCheck;
for (var u = 0; u < r; ++u) {
var a = n.snapshotItem(u), f = cachedElementBoundingRect(a);
f.top - s.top > o && s.bottom - f.bottom > o && i++
}
var l = s.height / i;
if (l < MinimumAverageDistanceBetweenHeaderElements)
return !0
}
return !1
},
shouldDisqualifyDueToSimilarElements: function(t) {
function i(e) {
return !!{
H1: 1,
H2: 1,
H3: 1,
H4: 1,
H5: 1,
H6: 1
}
[e.tagName]
}
function s(e, t) {
if (!e ||!t)
return !1;
const n = 1;
return e.className ? e.className === t.className : elementFingerprintForDepth(e, n) === elementFingerprintForDepth(t, n)
}
const n = /clearfix/i, r = "h1, h2, h3, h4, h5, h6";
var o = this.element;
if (o.tagName === "LI" || o.tagName === "DD") {
var u = o.parentNode, a = u.children.length;
for (var f = 0; f < a; ++f) {
var l = u.children[f];
if (l.tagName === o.tagName && l.className === o.className && l !== o)
return !0
}
}
var c = o.getAttribute("class");
c || (o = o.parentElement, o && (c = o.getAttribute("class"), c || (o = o.parentElement, o && (c = o.getAttribute("class")))));
if (c) {
t || (t = []);
var h = t.length;
for (var f = 0; f < h; ++f)
t[f].element.candidateElement = t[f];
var p;
try {
var d = c.split(" "), v = "";
for (var f = 0; f < d.length; ++f) {
if (n.test(d[f]))
continue;
d[f].length && (v += "." + d[f])
}
p = this.contentDocument.querySelectorAll(v)
} catch (m) {
p = []
}
var g=!1, y = elementDepth(o), b = p.length;
for (var f = 0; f < b; ++f) {
var l = p[f];
if (l === o)
continue;
if (l.parentElement === o || o.parentElement === l)
continue;
if (!isElementVisible(l))
continue;
var w = l.candidateElement;
if (!w) {
w = new CandidateElement(l, this.contentDocument);
if (!w)
continue
}
if (w.basicScore() * ReaderMinimumAdvantage > this.basicScore()) {
if (!g && cachedElementBoundingRect(l).bottom < cachedElementBoundingRect(this.element).top) {
g=!0;
continue
}
if (s(o.previousElementSibling, l.previousElementSibling) || s(o.nextElementSibling, l.nextElementSibling)) {
var E = o.querySelector(r), S = l.querySelector(r);
if (E && S && elementsHaveSameTagAndClassNames(E, S))
return !0;
E = o.previousElementSibling, S = l.previousElementSibling;
if (E && S && i(E) && i(S) && elementsHaveSameTagAndClassNames(E, S))
return !0
}
if (elementDepth(l) === y)
while (l.parentElement && o.parentElement) {
if (l.parentElement === o.parentElement)
break;
l = l.parentElement, o = o.parentElement
}
while (o.childElementCount <= 1) {
if (!o.childElementCount ||!l.childElementCount)
return !1;
if (l.childElementCount > 1)
return !1;
if (o.firstElementChild.tagName !== l.firstElementChild.tagName)
return !1;
o = o.firstElementChild, l = l.firstElementChild
}
if (l.childElementCount <= 1)
return !1;
var S = l.firstElementChild, x = l.lastElementChild, E = o.firstElementChild, T = o.lastElementChild;
if (S.tagName !== E.tagName)
return !1;
if (x.tagName !== T.tagName)
return !1;
var N = S.className, C = x.className, k = E.className, L = x.className, A = L === k ? 2: 1;
if (N.length || k.length) {
if (!N.length ||!k.length)
return !1;
if (N === k && o.querySelectorAll("." + k.replace(/\s+/, ".")).length <= A)
return !0
}
if (C.length || L.length) {
if (!C.length ||!L.length)
return !1;
if (C === L && o.querySelectorAll("." + L.replace(/\s+/, ".")).length <= A)
return !0
}
var O = E.clientHeight, M = T.clientHeight;
return !O ||!S.clientHeight?!1 : !M ||!x.clientHeight?!1 : O === S.clientHeight || M === x.clientHeight?!0 : !1
}
}
for (var f = 0; f < h; ++f)
t[f].element.candidateElement = null
}
return !1
},
shouldDisqualifyForDeepLinking: function() {
function n(e) {
var t = e.pathname.substring(1).split("/");
return t[t.length - 1] || t.pop(), t
}
const t = 5;
var r = this.element, i = this.contentDocument.location, s = n(i), o = s.length, u = [], a = r.getElementsByTagName("a"), f = a.length;
for (var l = 0; l < f; l++) {
var c = a[l];
if (i.host !== c.host)
continue;
if (n(c).length <= o)
continue;
if ((c.host + c.pathname).indexOf(i.host + i.pathname) !== 0)
continue;
if (anchorLinksToAttachment(c))
continue;
u.push(c);
if (u.length < t)
continue;
var h = r.offsetTop + r.offsetHeight / t;
return u[0].offsetTop < h
}
return !1
}
}, String.prototype.lastInteger = function() {
const t = /[0-9]+/g;
var n = this.match(t);
return n ? parseInt(n[n.length - 1]) : NaN
}, String.prototype.escapeCharacters = function(e) {
var t=!1, n = e.length;
for (var r = 0; r < n; ++r)
if (this.indexOf(e.charAt(r))!==-1) {
t=!0;
break
}
if (!t)
return this;
var i = "", s = this.length;
for (var r = 0; r < s; ++r)
e.indexOf(this.charAt(r))!==-1 && (i += "\\"), i += this.charAt(r);
return i
}, String.prototype.escapeForRegExp = function() {
return this.escapeCharacters("^[]{}()\\.$*+?|")
}, ReaderArticleFinder = function(e) {
this.contentDocument = e, this.didSearchForArticleNode=!1, this.article = null, this.didSearchForExtraArticleNode=!1, this.extraArticle = null, this.leadingImage = null, this._cachedScrollY = 0, this._cachedScrollX = 0, this._elementsWithCachedBoundingRects = [], this._cachedContentTextStyle = null, this.pageNumber = 1, this.prefixWithDateForNextPageURL = null, this._elementsEvaluatedForTextContent = [], this.previouslyDiscoveredPageURLStrings = []
}, ReaderArticleFinder.prototype = {
isReaderModeAvailable: function() {
return this.canRunReaderDetection() ? this.findArticleBySearchingWhitelist()?!0 : (this.cacheWindowScrollPosition(), this.article = this.findArticleByVisualExamination(), this.article && this.articleIsLTR(), !!this.article) : null
},
prepareToTransitionToReader: function() {
this.adoptableArticle(!0), this.nextPageURL(), this.articleIsLTR()
},
nextPageURL: function() {
if (!this._nextPageURL) {
var t = this.nextPageURLString();
typeof ReaderArticleFinderJSController != "undefined" && t && (t = ReaderArticleFinderJSController.substituteURLForNextPageURL(t)), this._nextPageURL = t
}
return this._nextPageURL
},
containerElementsForMultiPageContent: function() {
const e = /(.*page.*)(\d{1,2})(.*)/i, t = 3;
var n = [], r = this.articleNode(), i, s = 0;
for (; ;) {
i = e.exec(r.getAttribute("id"));
if (i)
break;
r = r.parentElement;
if (!r || s++===t)
return []
}
var o = childrenOfParentElement(r), u = o.length;
for (var a = 0; a < u; ++a) {
var f = o[a];
if (f === r)
continue;
var l = e.exec(f.getAttribute("id"));
if (!l || l[1] !== i[1] || l[3] !== i[3])
continue;
if (isElementVisible(f)&&!isElementPositionedOffScreen(f))
continue;
n.push(f)
}
return n
},
adoptableMultiPageContentElements: function() {
return this.containerElementsForMultiPageContent().map(function(e) {
return this.cleanArticleNode(e, e.cloneNode(!0), !1)
}, this)
},
classNameIsSignificantInRouteComputation: function(t) {
return t?!(t.toLowerCase()in StylisticClassNames) : !1
},
shouldIgnoreInRouteComputation: function(t) {
return t.tagName === "SCRIPT" || t.tagName === "LINK" || t.tagName === "STYLE"?!0 : t.tagName !== "TR"?!1 : t.offsetHeight?!1 : !0
},
routeToArticleNode: function() {
var t = [], n = this.articleNode();
while (n) {
var r = {};
r.tagName = n.tagName;
var i = n.getAttribute("id");
i && (r.id = i), this.classNameIsSignificantInRouteComputation(n.className) && (r.className = n.className), r.index = 1;
for (var s = n.previousElementSibling; s; s = s.previousElementSibling)
this.shouldIgnoreInRouteComputation(s) || r.index++;
t.unshift(r), n = n.parentElement
}
return t
},
adjustArticleNode: function() {
if (!this.article)
return;
var t;
for (t = this.article.element; t; t = t.parentElement)
if (VeryPositiveClassNameRegEx.test(t.className)) {
this.article.element = t;
return
}
t = this.article.element;
if (t.tagName === "SECTION" && t.parentElement && t.parentElement.getAttribute("itemprop") === "articleBody") {
this.article.element = t.parentElement;
return
}
t = this.article.element;
if (t.getAttribute("id") ||!t.className)
return;
var n = t.tagName, r = t.className, i = t.parentElement, s = i.children;
for (var o = 0, u = s.length; o < u; ++o) {
var a = s[o];
if (a === t)
continue;
if (a.tagName !== n || a.className !== r)
continue;
var f = CandidateElement.candidateIfElementIsViable(a, this.contentDocument, !0);
if (!f || f.finalScore() < ReaderMinimumScore)
continue;
this.article.element = i;
return
}
},
findArticleBySearchingWhitelist: function() {
var t = ListOfHostnameAndTrustedArticleNodeSelectorPairs.length;
for (var n = 0; n < t; ++n) {
var r = ListOfHostnameAndTrustedArticleNodeSelectorPairs[n], i = r[0];
if (!i.test(this.contentDocument.location.hostname))
continue;
var s = r[1], o = this.contentDocument.querySelectorAll(s);
if (o.length === 1)
return new CandidateElement(o[0], this.contentDocument)
}
return null
},
articleNode: function(t) {
return this.didSearchForArticleNode || (this.article = this.findArticleBySearchingWhitelist(), this.article || (this.article = this.findArticleBySearchingAllElements()), this.article || (this.article = this.findArticleByVisualExamination()), !this.article && t && (this.article = this.findArticleBySearchingAllElements(!0)), this.adjustArticleNode(), this.didSearchForArticleNode=!0, 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 : (this._cachedContentTextStyle = contentTextStyleForNode(this.contentDocument, this.articleNode()), this._cachedContentTextStyle || (this._cachedContentTextStyle = getComputedStyle(this.articleNode())), this._cachedContentTextStyle)
},
commaCountIsLessThan: function(t, n) {
var r = 0, i = t.textContent, s =- 1;
while (r < n && (s = i.indexOf(",", s + 1)) >= 0)
r++;
return r < n
},
calculateLinkDensity: function(t) {
var n = removeWhitespace(t.textContent).length;
if (!n)
return 0;
var r = t.getElementsByTagName("a"), i = 0, s = r.length;
for (var o = 0; o < s; ++o)
i += removeWhitespace(r[o].textContent).length;
return i / n
},
shouldPruneElement: function(t, n) {
const r = .33, i = .5, s = .2, o = 25, u = 4e4;
var a = t.tagName;
if (!t.parentElement)
return !1;
if (a === "IFRAME")
return shouldPruneIframe(t, this.contentDocument);
if (a !== "OBJECT" && a !== "EMBED" && a !== "CANVAS") {
var f=!1, l = t.childNodes.length;
for (var c = 0; c < l; ++c) {
var h = t.childNodes[c], p = h.nodeType;
if (p === Node.ELEMENT_NODE || p === Node.TEXT_NODE&&!isNodeWhitespace(h)) {
f=!0;
break
}
}
if (!f) {
if (a === "P") {
var d = t.previousSibling, v = t.nextSibling;
if (d && d.nodeType === Node.TEXT_NODE&&!isNodeWhitespace(d) && v && v.nodeType === Node.TEXT_NODE&&!isNodeWhitespace(v))
return !1
}
return !0
}
if (a === "P")
return !1
}
if (a === "CANVAS")
return t.parentNode.tagName === "CUFON";
var m = 0;
if (n) {
if (VeryNegativeClassNameRegEx.test(n.className))
return !0;
var g = n.className, y = n.getAttribute("id");
PositiveRegEx.test(g) && m++, PositiveRegEx.test(y) && m++, NegativeRegEx.test(g) && m--, NegativeRegEx.test(y) && m--
}
if (m < 0)
return !0;
if (t.querySelector(".tweet-wrapper"))
return !1;
if (a === "UL" || a === "OL") {
if (n.querySelector("iframe") && n.querySelector("script"))
return !0;
var b = n.children, w = b.length;
if (!w)
return !0;
var E = 0, S = 0;
for (var c = 0; c < w; ++c)
SharingRegex.test(b[c].className) && E++, NegativeRegEx.test(b[c].className) && S++;
return E / w >= MinimumRatioOfListItemsBeingRelatedToSharingToPruneEntireList?!0 : S / w >= MinimumRatioOfListItemsBeingRelatedToSharingToPruneEntireList?!0 : !1
}
if (a === "OBJECT") {
var x = t.querySelector("embed[src]"), T = x ? anchorForURL(x.src, this.contentDocument): null;
if (T && HostnamesKnownToContainEmbeddableMediaRegex.test(T.hostname))
return !1;
var N = t.getAttribute("data");
return T = N ? anchorForURL(N, this.contentDocument) : null, T && HostnamesKnownToContainEmbeddableMediaRegex.test(T.hostname)?!1 : !0
}
if (t.childElementCount === 1) {
var C = t.firstElementChild;
if (C.tagName === "A")
return !1;
if (C.tagName === "SPAN" && C.className === "converted-anchor" && nearestAncestorElementWithTagName(C, "TABLE"))
return !1
}
var k = t.getElementsByTagName("img"), L = k.length;
if (L) {
var A = 0;
for (var c = 0; c < L; ++c) {
var O = k[c].originalElement;
if (!isElementVisible(O))
continue;
var M = cachedElementBoundingRect(O);
A += M.width / L * (M.height / L)
}
if (A > u)
return !1
}
if (!this.commaCountIsLessThan(t, 10))
return !1;
var _ = t.getElementsByTagName("p").length, D = t.getElementsByTagName("br").length, P = _ + Math.floor(D / 2);
if (L > P)
return !0;
if (t.getElementsByTagName("li").length > P)
return !0;
if (t.getElementsByTagName("input").length / P > r)
return !0;
if (t.textContent.length < o && L !== 1)
return !0;
if (t.querySelector("embed"))
return !0;
var H = this.calculateLinkDensity(t);
if (m >= 1 && H > i)
return !0;
if (m < 1 && H > s)
return !0;
if (a === "TABLE") {
var B = removeWhitespace(t.innerText).length, j = removeWhitespace(n.innerText).length;
if (B <= j * .5)
return !0
}
return !1
},
wordCountIsLessThan: function(t, n) {
var r = 0, i = t.textContent, s =- 1;
while ((s = i.indexOf(" ", s + 1)) >= 0 && r < n)
r++;
return r < n
},
leadingImageIsAppropriateWidth: function(t) {
return !this.article ||!t?!1 : t.getBoundingClientRect().width >= this.article.element.getBoundingClientRect().width - ToleranceForLeadingImageWidthToArticleWidthForFullWidthPresentation
},
newDivFromNode: function(t) {
var n = this.contentDocument.createElement("div");
return t && (n.innerHTML = t.innerHTML), n
},
adoptableLeadingImage: function() {
const t = 5, n = /credit/, r = /caption/, i = /src|alt/;
if (!this.article ||!this.leadingImage ||!this.leadingImageIsAppropriateWidth(this.leadingImage))
return null;
var s = this.leadingImage.parentNode, o = null, u = null, a = s.children.length;
if (s.tagName === "DIV" && a > 1 && a < t) {
var f = s.cloneNode(!0).querySelectorAll("p, div"), l = f.length;
for (var c = 0; c < l; ++c) {
var h = f[c];
n.test(h.className) ? o = h.cloneNode(!0) : r.test(h.className) && (u = h.cloneNode(!0))
}
}
var p = this.leadingImage.cloneNode(!1), d = p.attributes;
for (var c = 0; c < d.length; ++c) {
var v = d[c].nodeName;
i.test(v) || (p.removeAttribute(v), c--)
}
var m = this.contentDocument.createElement("div");
m.className = "leading-image", m.appendChild(p);
if (o) {
var g = this.newDivFromNode(o);
g.className = "credit", m.appendChild(g)
}
if (u) {
var y = this.newDivFromNode(u);
y.className = "caption", m.appendChild(y)
}
return m
},
adoptableArticle: function(t) {
if (this._adoptableArticle)
return this._adoptableArticle.cloneNode(!0);
clearCachedElementBoundingRects(), this.cacheWindowScrollPosition();
var n = this.articleNode(t);
this._adoptableArticle = n ? n.cloneNode(!0) : null;
if (!this._adoptableArticle)
return this._adoptableArticle;
this._articleBoundingRect = cachedElementBoundingRect(this.article.element), this._adoptableArticle = this.cleanArticleNode(n, this._adoptableArticle, !1);
if (this._adoptableArticle.tagName === "P") {
var r = document.createElement("div");
r.appendChild(this._adoptableArticle), this._adoptableArticle = r
}
var i = this.extraArticleNode();
if (i) {
var s = this.cleanArticleNode(i, i.cloneNode(!0), !0);
s && (this.extraArticle.isPrepended ? this._adoptableArticle.insertBefore(s, this._adoptableArticle.firstChild) : this._adoptableArticle.appendChild(s));
var o = cachedElementBoundingRect(this.article.element), u = cachedElementBoundingRect(this.extraArticle.element), a = {
top: Math.min(o.top, u.top),
right: Math.max(o.right, u.right),
bottom: Math.max(o.bottom, u.bottom),
left: Math.min(o.left, u.left)
};
a.width = a.right - a.left, a.height = a.bottom - a.top, this._articleBoundingRect = a
}
this._articleTextContent = this._adoptableArticle.innerText;
var f = this.adoptableLeadingImage();
return f && this._adoptableArticle.insertBefore(f, this._adoptableArticle.firstChild), this._adoptableArticle
},
elementPinToEdge: function(t) {
const n = {
AREA: 1,
BR: 1,
CANVAS: 1,
EMBED: 1,
FRAME: 1,
HR: 1,
IMG: 1,
INPUT: 1
}, r = 120;
if (window.scrollY < r)
return null;
var i = cachedElementBoundingRect(t), s = t.ownerDocument.elementFromPoint((i.left + i.right) / 2, 0);
s && s.tagName in n && (s = s.parentElement);
var o = s;
while (o && o !== t)
o = o.parentNode;
return o ? s : null
},
dominantContentSelectorAndDepth: function(e) {
const t = 2;
var n = {}, r = {};
walkElementSubtree
(e, t, function(e, t) {
if (!isElementVisible(e))
return;
var i = selectorForElement(e) + " | " + t;
r[i] ? r[i] += 1 : (r[i] = 1, n[i] = e)
});
var i, s = arrayOfKeysAndValuesOfObjectSortedByValueDescending(r);
switch (s.length) {
case 0:
break;
case 1:
i = s[0].key;
break;
default:
var o = s[0];
o.value > s[1].value && (i = o.key)
}
if (!i)
return null;
var u = n[i];
return {
selector: selectorForElement(u),
depth: depthOfElementWithinElement(u, e)
}
},
functionToPreventPruningElementDueToInvisibility: function() {
const e = [[/nytimes.com/, function(e, t) {
var n = e;
if (!t)
return !1;
while (n && n !== t) {
if (n.classList.contains("hidden"))
return !0;
n = n.parentElement
}
return !1
}
]];
var t = e.length;
for (var n = 0; n < t; ++n) {
var r = e[n], i = r[0];
if (i.test(this.contentDocument.location.hostname))
return r[1]
}
return function() {
return !1
}
},
cleanArticleNode: function(t, n, r) {
function S(e) {
f += e, l && (l += e), c && (c += e), h && (h += e), p && (p += e)
}
function x() {
l === 1 && (l = 0), c === 1 && (c = 0), h === 1 && (h = 0), p === 1 && (p = 0)
}
function T() {
const e = .8;
var n = cachedElementBoundingRect(t);
if (n.width === 0 || n.height === 0)
return !0;
var r = childrenWithParallelStructure(t), i = r.length, s;
if (i) {
s = [];
for (var o = 0; o < i; ++o) {
var u = r[o];
if (getComputedStyle(u).float === "none") {
var a = u.children, f = a.length;
for (var l = 0; l < f; ++l)
s.push(a[l])
} else
s.push(u)
}
} else
s = t.children;
var c = s.length, h = 0;
for (var o = 0; o < c; ++o) {
var p = s[o];
getComputedStyle(p).float !== "none" && (h += p.innerText.length)
}
var d = t.innerText.length, v = h / d;
return v > e
}
function N(e) {
const n = 50;
if (cachedElementBoundingRect(e).height > n)
return !1;
const r = {
UL: 1,
LI: 1,
NAV: 1
};
return r[e.tagName]?!0 : e.parentElement === t&&!e.nextElementSibling?!0 : !1
}
const i = {
FORM: 1,
SCRIPT: 1,
STYLE: 1,
LINK: 1
}, s = {
DIV: 1,
TABLE: 1,
OBJECT: 1,
UL: 1,
CANVAS: 1,
P: 1,
IFRAME: 1,
ASIDE: 1,
SECTION: 1,
FOOTER: 1,
NAV: 1,
OL: 1
}, o = {
I: 1,
EM: 1
}, u = {
B: 1,
STRONG: 1,
H1: 1,
H2: 1,
H3: 1,
H4: 1,
H5: 1,
H6: 1
};
var a = [], f = 0, l = 0, c = 0, h = 0, p = 0, d = t, v = d.ownerDocument.defaultView, m = n, g = this.articleTitle(), y = this._articleTitleElement, b = this.elementPinToEdge(t), w = null, E = isElementVisible(t), C = this.dominantContentSelectorAndDepth(t), k = T(), L = new Set;
this.previouslyDiscoveredPageURLStrings.forEach(function(e) {
L.add(e)
});
var A = this.nextPageURL();
A && L.add(A);
var O = null;
this._articleTitleElement && (O = cachedElementBoundingRect(this._articleTitleElement));
var M = this.functionToPreventPruningElementDueToInvisibility();
while (d) {
var _ = null, D = m.tagName;
m.originalElement = d, d === b && (w = m), D in i && (_ = m), !_ && d === y && (_ = m);
if (!_ && (D === "H1" || D === "H2")) {
var P = d.offsetTop - t.offsetTop;
if (P < HeaderMinimumDistanceFromArticleTop) {
var H = innerTextOrTextContent(d), B = H.length * HeaderLevenshteinDistanceToLengthRatio;
levenshteinDistance(g, H) <= B && (_ = m)
}
}
_ || this.isMediaWikiPage() && /editsection/.test(d.className) && (_ = m);
var j;
_ || (j = getComputedStyle(d));
if (!_ && D === "DIV" && m.parentNode) {
var F = d.querySelectorAll("a, blockquote, dl, div, img, ol, p, pre, table, ul"), I = l || j["float"] !== "none";
if (!I&&!F.length) {
var q = m.parentNode, R = this.contentDocument.createElement("p");
while (m.firstChild) {
var U = m.firstChild;
R.appendChild(U)
}
q.replaceChild(R, m), w === m && (w = R), m = R, m.originalElement = d, D = m.tagName
}
}
!_ && m.parentNode && D in s && a.push(m);
if (!_) {
if (E) {
var z = j.display === "none" || j.visibility !== "visible" || computedStyleIndicatesElementIsInvisibleDueToClipping(j);
if (z) {
var W = C ? f === C.depth && selectorForElement(d) === C.selector: !1;
!W&&!M(d, t) && (_ = m)
}
}
isElementPositionedOffScreen(d) ? _ = m : d !== t&&!l && j["float"] !== "none"&&!k && (cachedElementBoundingRect(d).height >= FloatMinimumHeight || d.childElementCount > 1) && (l = 1)
}
if (!_) {
var X = m.attributes;
for (var V = 0; V < X.length; ++V) {
var $ = X[V].nodeName;
AttributesToRemoveRegEx.test($) && (m.removeAttribute($), V--)
}
j.clear === "both" && m.classList.add("clear");
if ((D === "UL" || D === "OL") && j["list-style-type"] === "none" && j["background-image"] === "none") {
var J = d.children, K = J.length, Q=!0;
for (var V = 0; V < K; ++V) {
var G = getComputedStyle(J[V]);
if (G["list-style-type"] !== "none" || parseInt(G["-webkit-padding-start"]) !== 0) {
Q=!1;
break
}
}
Q && m.classList.add("list-style-type-none")
}
!h && j.fontStyle !== "normal" && (D in o || (m.style.fontStyle = j.fontStyle), h = 1), !p && j.fontWeight !== "normal" && (D in u || (m.style.fontWeight = j.fontWeight), p = 1);
if (l) {
l === 1 && (cachedElementBoundingRect(d).width <= MaximumFloatWidth ? m.setAttribute("class", "auxiliary float " + j["float"]) : m.classList.add("auxiliary"));
var Y = d.style.getPropertyValue("width");
if (Y)
m.style.width = Y;
else {
var Z = v.getMatchedCSSRules(d, "", !0);
if (Z) {
var et = Z.length;
for (var V = et - 1; V >= 0; --V) {
Y = Z[V].style.getPropertyValue("width");
if (Y) {
m.style.width = Y;
break
}
}
}
}
l === 1&&!Y && (m.style.width = cachedElementBoundingRect(d).width + "px");
var tt = m.parentNode === n ? 36: 12, nt = m.style.width;
nt && parseInt(nt) >= screen.width - tt && m.setAttribute("class", "large-element")
}
if (D === "TABLE")
c || (c = 1);
else if (D === "VIDEO") {
var rt = cachedElementBoundingRect(d);
const it = 36;
rt.width > screen.width - it && m.setAttribute("class", "large-element")
} else if (D === "IMG") {
var st=!1, ot = X.length;
for (var V = 0; V < ot; ++V) {
var $ = X[V].nodeName;
if (KnownImageLazyLoadingAttributes[$.toLowerCase()]) {
m.setAttribute("src", m.getAttribute($)), st=!0;
break
}
}
m.removeAttribute("border"), m.removeAttribute("hspace"), m.removeAttribute("vspace");
var ut = m.getAttribute("align");
m.removeAttribute("align");
if (ut === "left" || ut === "right")
m.classList.add("float"), m.classList.add(ut);
if (!l&&!st) {
var at = cachedElementBoundingRect(d), ft = at.width, lt = at.height;
ft === 1 && lt === 1 ? _ = m : O && lt < MinimumHeightForImagesAboveTheArticleTitle && at.bottom < O.top ? _ = m : ft < ImageSizeTiny && lt < ImageSizeTiny && m.setAttribute("class", "reader-image-tiny")
}
} else if (D === "FONT")
m.removeAttribute("size"), m.removeAttribute("face"), m.removeAttribute("color");
else if (D === "A" && m.parentNode) {
var ct = m.getAttribute("href");
if (ct && ct.length && (ct[0] === "#" || ct.substring(0, 11) === "javascript:")) {
if (!c&&!m.childElementCount && m.parentElement.childElementCount === 1 && m.parentElement.tagName !== "LI") {
var ht = this.contentDocument.evaluate("text()", m.parentElement, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
ht.snapshotLength || (_ = m)
}
if (!_) {
var R = this.contentDocument.createElement("span");
if (m.childElementCount === 1 && m.firstElementChild.tagName === "IMG") {
var pt = m.firstElementChild;
pt.width > AnchorImageMinimumWidth && pt.height > AnchorImageMinimumHeight && R.setAttribute("class", "converted-image-anchor")
}
R.className || R.setAttribute("class", "converted-anchor");
while (m.firstChild)
R.appendChild(m.firstChild);
m.parentNode.replaceChild(R, m), m = R, w === m && (w = R)
}
}
}
}
!_ && elementIsCommentBlock(d) && (_ = m);
if (!_ && D === "A" && L.has(d.href)) {
var dt = d, vt = m, mt, gt;
while ((dt = dt.parentElement) && (vt = vt.parentElement)) {
const yt = 10;
if (cachedElementBoundingRect(dt).top - cachedElementBoundingRect(d).top > yt)
break;
if (dt === t)
break;
N(dt) && (mt = dt, gt = vt)
}
mt && (_ = gt, d = mt, m = gt, m.originalElement = d, D = m.tagName), dt = null, vt = null, mt = null, gt = null
}
var bt = _ ? null: d.firstElementChild;
if (bt)
d = bt, m = m.firstElementChild, S(1);
else {
var wt;
while (d !== t&&!(wt = d.nextElementSibling))
d = d.parentElement, m = m.parentElement, S( - 1);
if (d === t) {
if (_)
if (_.parentElement)
_.remove();
else if (r)
return null;
break
}
d = wt, m = m.nextElementSibling, x()
}
if (_)
if (_.parentElement)
_.remove();
else if (r)
return null
}
var Et = n.querySelectorAll("iframe"), St = Et.length;
for (var V = 0; V < St; ++V) {
var xt = Et[V];
if (elementLooksLikeEmbeddedTweet(xt.originalElement)) {
var Tt = this.adoptableSimpleTweetFromTwitterIframe(xt);
Tt && xt.parentElement.replaceChild(Tt, xt)
}
}
for (var V = a.length - 1; V >= 0; --V) {
var Nt = a[V];
Nt.parentNode && this.shouldPruneElement(Nt, Nt.originalElement) && (w === Nt && ((w = Nt.nextElementSibling) || (w = Nt.parentElement)), Nt.remove())
}
var Ct = n.querySelectorAll(".float");
for (var V = 0; V < Ct.length; ++V) {
var kt=!1, Lt = Ct[V];
if (!kt) {
var At = Lt.querySelectorAll("a, span.converted-image-anchor"), Ot = Lt.querySelectorAll("span.converted-anchor");
kt = Lt.parentNode && Ot.length > At.length
}
if (!kt) {
var Mt = Lt.querySelectorAll("embed, object").length, _t = Lt.originalElement.querySelectorAll("embed, object").length;
!Mt && _t && (kt=!0)
}
if (!kt) {
var Dt = Lt.originalElement.getElementsByTagName("img"), Pt = Dt.length, Ht = 0;
for (var Bt = 0; Bt < Pt; ++Bt) {
E && isElementVisible(Dt[Bt]) && Ht++;
if (Ht > 1)
break
}
if (Ht === 1) {
var jt = Lt.getElementsByTagName("img").length;
jt || (kt=!0)
}
}
kt && (w === Lt && ((w = Lt.nextElementSibling) || (w = Lt.parentElement)), Lt.remove())
}
if (r&&!removeWhitespace(n.innerText).length)
return null;
if (w) {
var Ft = document.createElement("div"), It = w.originalElement.getBoundingClientRect(), qt = It.height > 0 ? It.top * 100 / It.height: 0;
Ft.style.position = "relative", Ft.style.top = Math.round( - qt) + "%", Ft.setAttribute("id", "safari-reader-element-marker"), w.insertBefore(Ft, w.firstChild)
}
return n
},
adoptableSimpleTweetFromTwitterIframe: function(t) {
var n = t.originalElement.contentDocument.documentElement, r = n.querySelector("[data-tweet-id].expanded");
if (!r)
return null;
var i = this.contentDocument.createElement("div");
i.classList.add("tweet-wrapper");
var s = this.contentDocument.createElement("blockquote");
s.classList.add("simple-tweet"), i.appendChild(s);
var o = r.getAttribute("data-tweet-id");
i.setAttribute("data-reader-tweet-id", o);
var u = r.querySelector(".dateline"), a = r.querySelector('[data-scribe="element:screen_name"]'), f = r.querySelector('[data-scribe="element:name"]'), l = r.querySelector(".e-entry-title");
if (!u ||!a ||!f ||!l)
return i;
var c = "&mdash; " + f.innerText + " (" + a.innerText + ")", h = this.contentDocument.createElement("p");
h.innerHTML = l.innerHTML, s.appendChild(h), s.insertAdjacentHTML("beforeend", c);
var p = this.contentDocument.createElement("span");
p.innerHTML = u.innerHTML, s.appendChild(p);
var d = s.querySelectorAll("img.twitter-emoji"), v = d.length;
for (var m = 0; m < v; ++m) {
var g = d[m], y = g.getAttribute("alt");
if (y && y.length > 0) {
var b = this.contentDocument.createElement("span");
b.innerText = y, g.parentNode.replaceChild(b, g)
}
}
return i
},
leadingImageNode: function() {
const t = 250, n = .5, r = 3;
if (!this.article ||!this.article.element)
return null;
var i = this.article.element;
for (var s = 0; s < r; ++s) {
if (!i.parentNode)
break;
i = i.parentNode;
var o = i.getElementsByTagName("img")[0];
if (o) {
var u = cachedElementBoundingRect(o);
if (u.height >= t && u.width >= this._articleWidth * n) {
var a = this.article.element.compareDocumentPosition(o);
if (!(a & DocumentPositionPreceding) || a & DocumentPositionContainedBy)
continue;
a = this.extraArticle ? this.extraArticle.element.compareDocumentPosition(o) : null;
if (a && (!(a & DocumentPositionPreceding) || a & DocumentPositionContainedBy))
continue;
return o
}
}
}
return null
},
mainImageNode: function() {
var t = this.leadingImageNode();
if (t)
return t;
if (this.article && this.article.element) {
var n = this.article.element.querySelectorAll("img"), r = n.length;
for (var i = 0; i < r; ++i) {
var s = n[i], o = s._cachedElementBoundingRect;
o || (o = s.getBoundingClientRect());
if (o.width >= MainImageMinimumWidthAndHeight && o.height >= MainImageMinimumWidthAndHeight)
return s
}
}
return null
},
articleTitle: function() {
function m(e, t) {
var n = e ? t.indexOf(e): - 1;
return n!==-1 && (n === 0 || n + e.length === t.length)
}
function g(e, t) {
return e.host === t.host && e.pathname === t.pathname
}
if (!this.articleNode())
return;
if (this._articleTitle)
return this._articleTitle;
const t = 500, n = 20, r = 8, i = 1.1, s = 1.25, o = /header|title|headline|instapaper_title/i, u = 1.5, a = 1.8, f = 1.5, l = .6, c = 3, h = 1.5, p = 9, d = 1.5, v = /byline|author/i;
var y = function(e) {
var t = this.contentDocument.querySelector(e), n = t && t.attributes.length === 2 ? t.content: null;
if (n) {
var r = this.articleTitleAndSiteNameFromTitleString(n);
r && (n = r.articleTitle)
}
return n
}.bind(this), b = this.contentDocument.title, w = y("head meta[property='og:title']"), E = y("head meta[name='twitter:title']"), S = cachedElementBoundingRect(this.articleNode());
this.extraArticleNode() && this.extraArticle.isPrepended && (S = cachedElementBoundingRect(this.extraArticleNode()));
var x = S.left + S.width / 2, T = S.top, N = T;
this._articleWidth = S.width, this.leadingImage = this.leadingImageNode();
if (this.leadingImage) {
var C = cachedElementBoundingRect(this.leadingImage);
N = (C.top + T) / 2
}
var k = "h1, h2, h3, h4, h5, .headline, .article_title, #hn-headline, .inside-head, .instapaper_title", L = this.article.element.tagName;
if (L === "DL" || L === "DD")
k += ", dt";
var A = this.contentDocument.querySelectorAll(k);
A = Array.prototype.slice.call(A, 0);
var O = this.contentDocument.location, M = this.article.element.getElementsByTagName("a");
for (var _ = 0; _ < M.length; _++) {
var D = M[_];
if (D.offsetTop > this.articleNode().offsetTop + n)
break;
if (g(D, O)) {
A.push(D);
break
}
}
var P, H = A.map(innerTextOrTextContent), B = A.length, j = 0, F = [], I = [], q = [];
for (var _ = 0; _ < B; ++_) {
var R = A[_], U = H[_], z = stringSimilarity(b, U);
if (w) {
var W = stringSimilarity(w, U);
z += W, W > StringSimilarityToDeclareStringsNearlyIdentical && I.push(R)
}
if (E) {
var X = stringSimilarity(E, U);
z += X, X > StringSimilarityToDeclareStringsNearlyIdentical && q.push(R)
}
z === j ? F.push(R) : z > j && (j = z, F = [R])
}
I.length === 1 ? (P = I[0], P.headerText = innerTextOrTextContent(P)) : q.length === 1 && (P = q[0], P.headerText = innerTextOrTextContent(P));
if (!P)
for (var _ = 0; _ < B; ++_) {
var R = A[_];
if (!isElementVisible(R))
continue;
var V = cachedElementBoundingRect(R), $ = V.left + V.width / 2, J = V.top + V.height / 2, K = $ - x, Q = J - N, G = I.indexOf(R)!==-1, Y = q.indexOf(R)!==-1, Z = R.classList.contains("instapaper_title"), et = R.getAttribute("itemprop") === "headline", tt = G || Y || Z || et, nt = Math.sqrt(K * K + Q * Q), rt = tt ? t: Math.max(t - nt, 0), U = H[_], it = R.getAttribute("property");
if (it) {
var st = /dc.title/i.exec(it);
if (st && st[0]) {
var ot = this.contentDocument.querySelectorAll('*[property~="' + st[0] + '"]');
if (ot.length === 1) {
P = R, P.headerText = U;
break
}
}
}
if (v.test(R.className))
continue;
if (!tt) {
if (nt > t)
continue;
if ($ < S.left || $ > S.right)
continue
}
if (b && stringsAreNearlyIdentical(U, b))
rt*=c;
else if (m(U, b))
rt*=h;
else if (U.length < r)
continue;
var ut=!1, at = nearestAncestorElementWithTagName(R, "A");
at || (at = R.querySelector("a"));
if (at) {
var ft = at.host === O.host, lt = at.pathname === O.pathname;
if (ft && lt)
rt*=f;
else {
if (ft && nearestAncestorElementWithTagName(R, "LI"))
continue;
rt*=l, ut=!0
}
}
var ct = fontSizeFromComputedStyle(getComputedStyle(R));
ut || (rt*=ct / BaseFontSize), rt*=1 + TitleCandidateDepthScoreMultiplier * elementDepth(R);
var ht = parseInt(this.contentTextStyle().fontSize);
parseInt(ct) > ht * i && (rt*=s);
if (o.test(R.className) || o.test(R.getAttribute("id")))
rt*=u;
var pt = R.parentElement;
pt && (o.test(pt.className) || o.test(pt.getAttribute("id"))) && (rt*=u), F.indexOf(R)!==-1 && (rt*=a);
if (!P || rt > P.headerScore)
P = R, P.headerScore = rt, P.headerText = U
}
P && domDistance(P, this.articleNode(), p + 1) > p && parseInt(getComputedStyle(P).fontSize) < d * ht && (P = null);
if (P) {
this._articleTitleElement = P;
var dt = P.headerText.trim();
w && m(w, dt) ? this._articleTitle = w : b && m(b, dt) ? this._articleTitle = b : this._articleTitle = dt
}
return this._articleTitle || (w && m(w, b) ? this._articleTitle = w : this._articleTitle = b), this._articleTitle
},
articleIsLTR: function() {
if (!this._articleIsLTR) {
var t = getComputedStyle(this.article.element);
this._articleIsLTR = t ? t.direction === "ltr" : !0
}
return this._articleIsLTR
},
findSuggestedCandidate: function() {
var t = this.suggestedRouteToArticle;
if (!t ||!t.length)
return null;
var n, r;
for (r = t.length - 1; r >= 0; --r)
if (t[r].id) {
n = this.contentDocument.getElementById(t[r].id);
if (n)
break
}
r++, n || (n = this.contentDocument);
while (r < t.length) {
var i = t[r], s = n.nodeType === Node.DOCUMENT_NODE ? n.documentElement: n.firstElementChild;
for (var o = 1; s && o < i.index; s = s.nextElementSibling)
this.shouldIgnoreInRouteComputation(s) || o++;
if (!s)
return null;
if (s.tagName !== i.tagName)
return null;
if (i.className && s.className !== i.className)
return null;
n = s, r++
}
return isElementVisible(n) ? new CandidateElement(n, this.contentDocument) : null
},
canRunReaderDetection: function() {
var e = this.contentDocument.location.hostname, t = this.contentDocument.location.pathname;
for (var n in BlacklistedHostsAllowedPathRegexMap) {
var r = new RegExp(n.escapeForRegExp());
if (!r.test(e))
continue;
var i = BlacklistedHostsAllowedPathRegexMap[n];
return i instanceof RegExp ? i.test(t) : !1
}
return !0
},
findArticleBySearchingAllElements: function(t) {
var n = this.findSuggestedCandidate(), r = this.findCandidateElements();
if (!r ||!r.length)
return n;
if (n && n.basicScore() >= ReaderMinimumScore)
return n;
var i = this.highestScoringCandidateFromCandidates(r);
for (var s = i.element; s !== this.contentDocument; s = s.parentNode)
if (s.tagName === "BLOCKQUOTE") {
var o = s.parentNode, u = r.length;
for (var a = 0; a < u; ++a) {
var f = r[a];
if (f.element === o) {
i = f;
break
}
}
break
}
if (n && i.finalScore() < ReaderMinimumScore)
return n;
if (!t) {
if (i.shouldDisqualifyDueToScoreDensity())
return null;
if (i.shouldDisqualifyDueToHorizontalRuleDensity())
return null;
if (i.shouldDisqualifyDueToHeaderDensity())
return null;
if (i.shouldDisqualifyDueToSimilarElements(r))
return null
}
return i
},
findExtraArticle: function() {
if (!this.article)
return null;
for (var t = 0, n = this.article.element; t < 3 && n; ++t, n = n.parentNode) {
var r = this.findExtraArticleCandidateElements(n);
if (!r ||!r.length)
continue;
var i = this.sortCandidateElementsInDescendingScoreOrder(r), s;
for (var o = 0; o < i.length; o++) {
s = i[o];
if (!s ||!s.basicScore())
break;
if (s.shouldDisqualifyDueToScoreDensity())
continue;
if (s.shouldDisqualifyDueToHorizontalRuleDensity())
continue;
if (s.shouldDisqualifyDueToHeaderDensity())
continue;
if (cachedElementBoundingRect(s.element).height < PrependedArticleCandidateMinimumHeight && cachedElementBoundingRect(this.article.element).width !== cachedElementBoundingRect(s.element).width)
continue;
var u = contentTextStyleForNode(this.contentDocument, s.element);
if (!u)
continue;
if (u.fontFamily !== this.contentTextStyle().fontFamily || u.fontSize !== this.contentTextStyle().fontSize)
continue;
if (s)
return s
}
}
return null
},
highestScoringCandidateFromCandidates: function(t) {
var n = 0, r = null, i = t.length;
for (var s = 0; s < i; ++s) {
var o = t[s], u = o.basicScore();
u >= n && (n = u, r = o)
}
return r
},
sortCandidateElementsInDescendingScoreOrder: function(t) {
function n(e, t) {
return e.basicScore() !== t.basicScore() ? t.basicScore() - e.basicScore() : t.depth() - e.depth()
}
return t.sort(n)
},
findCandidateElements: function() {
const t = 1e3;
var n = Date.now() + t, r = this.contentDocument.getElementsByTagName("*"), i = r.length, s = [];
for (var o = 0; o < i; ++o) {
var u = r[o];
if (CandidateTagNamesToIgnore[u.tagName])
continue;
var a = CandidateElement.candidateIfElementIsViable(u, this.contentDocument);
a && s.push(a);
if (Date.now() > n) {
s = [];
break
}
}
var f = s.length;
for (var o = 0; o < f; ++o)
s[o].element.candidateElement = s[o];
for (var o = 0; o < f; ++o) {
var l = s[o];
if (l.element.tagName !== "BLOCKQUOTE")
continue;
var c = l.element.parentElement.candidateElement;
if (!c)
continue;
c.addTextNodesFromCandidateElement(l)
}
for (var o = 0; o < f; ++o)
s[o].element.candidateElement = null;
return s
},
findExtraArticleCandidateElements: function(t) {
if (!this.article)
return [];
t || (t = this.article.element);
var n = "preceding-sibling::*/descendant-or-self::*", r = this.contentDocument.evaluate(n, t, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null), i = r.snapshotLength, s = [];
for (var o = 0; o < i; ++o) {
var u = r.snapshotItem(o);
if (CandidateTagNamesToIgnore[u.tagName])
continue;
var a = CandidateElement.extraArticleCandidateIfElementIsViable(u, this.article, this.contentDocument, !0);
a && s.push(a)
}
n = "following-sibling::*/descendant-or-self::*", r = this.contentDocument.evaluate(n, t, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null), i = r.snapshotLength;
for (var o = 0; o < i; ++o) {
var u = r.snapshotItem(o);
if (CandidateTagNamesToIgnore[u.tagName])
continue;
var a = CandidateElement.extraArticleCandidateIfElementIsViable(u, this.article, this.contentDocument, !1);
a && s.push(a)
}
return s
},
isGeneratedBy: function(t) {
var n = this.contentDocument.head ? this.contentDocument.head.querySelector("meta[name=generator]"): null;
if (!n)
return !1;
var r = n.content;
return r ? t.test(r) : !1
},
isMediaWikiPage: function() {
return this.isGeneratedBy(/^MediaWiki /)
},
isWordPressSite: function() {
return this.isGeneratedBy(/^WordPress/)
},
nextPageURLString: function() {
if (!this.article)
return null;
if (this.isMediaWikiPage())
return null;
var t, n = 0, r = this.article.element;
r.parentNode && getComputedStyle(r).display === "inline" && (r = r.parentNode);
var i = r, s = cachedElementBoundingRect(r).bottom + LinkMaxVerticalDistanceFromArticle;
while (isElementNode(i) && cachedElementBoundingRect(i).bottom <= s)
i = i.parentNode;
i !== r && (i === this.contentDocument || isElementNode(i)) && (r = i);
var o = this.contentDocument.evaluate(LinkCandidateXPathQuery, r, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null), u = o.snapshotLength;
if (this.pageNumber <= 2&&!this.prefixWithDateForNextPageURL) {
var a = this.contentDocument.location.pathname, f = a.match(LinkDateRegex);
f && (f = f[0], this.prefixWithDateForNextPageURL = a.substring(0, a.indexOf(f) + f.length))
}
for (var l = 0; l < u; ++l) {
var c = o.snapshotItem(l), h = this.scoreNextPageLinkCandidate(c);
h > n && (t = c, n = h)
}
return t ? t.href : null
},
scoreNextPageLinkCandidate: function(t) {
function n(e, t, n, r) {
t.substring(0, e.length) === e && (t = t.substring(e.length), e = "");
var i = t.lastInteger();
if (isNaN(i))
return !1;
var s = e ? e.lastInteger(): NaN;
if (isNaN(s) || s >= MaximumExactIntegralValue)
s = r;
return i === s ? n.lastInteger() === s + 1 : i === s + 1
}
function r(e) {
var t = {}, n = e.substring(1).split("&"), r = n.length;
for (var i = 0; i < r; ++i) {
var s = n[i], o = s.indexOf("=");
o===-1 ? t[s] = null : t[s.substring(0, o)] = s.substring(o + 1)
}
return t
}
var i = this.contentDocument.location;
if (t.host !== i.host)
return 0;
if (t.pathname === i.pathname && t.search === i.search)
return 0;
if (t.toString().indexOf("#")!==-1)
return 0;
if (anchorLinksToAttachment(t) || anchorLinksToTagOrCategoryPage(t))
return 0;
if (!isElementVisible(t))
return 0;
var s = cachedElementBoundingRect(t), o = this._articleBoundingRect, u = Math.max(0, Math.max(o.top - (s.top + s.height), s.top - (o.top + o.height)));
if (s.top < o.top)
return 0;
if (u > LinkMaxVerticalDistanceFromArticle)
return 0;
var a = Math.max(0, Math.max(o.left - (s.left + s.width), s.left - (o.left + o.width)));
if (a > 0)
return 0;
var f = i.pathname, l = t.pathname;
if (this.prefixWithDateForNextPageURL) {
if (t.pathname.indexOf(this.prefixWithDateForNextPageURL)===-1)
return 0;
f = f.substring(this.prefixWithDateForNextPageURL.length), l = l.substring(this.prefixWithDateForNextPageURL.length)
}
var c = l.substring(1).split("/");
c[c.length - 1] || c.pop();
var h = c.length, p = f.substring(1).split("/"), d=!1;
p[p.length - 1] || (d=!0, p.pop());
var v = p.length;
if (h < v)
return 0;
var m = 0, g = 0, y = t.textContent;
for (var b = 0; b < h; ++b) {
var w = c[b], E = b < v ? p[b]: "";
if (E !== w) {
if (b < v - 2)
return 0;
if (w.length >= E.length) {
var S = 0;
while (w[w.length - 1 - S] === E[E.length - 1 - S])
S++;
S && (w = w.substring(0, w.length - S), E = E.substring(0, E.length - S));
var x = w.indexOf(E);
x!==-1 && (w = w.substring(x))
}
n(E, w, y, this.pageNumber) ? g = Math.pow(LinkNextOrdinalValueBase, b - h + 1) : m++
}
if (m > 1)
return 0
}
var T=!1;
if (t.search) {
linkParameters = r(t.search), referenceParameters = r(i.search);
for (var N in linkParameters) {
var C = linkParameters[N], k = N in referenceParameters ? referenceParameters[N]: null;
if (k !== C) {
k === null && (k = ""), C === null && (C = "");
if (C.length < k.length)
m++;
else if (n(k, C, y, this.pageNumber)) {
if (LinkURLSearchParameterKeyMatchRegex.test(N)) {
if (f.toLowerCase() !== l.toLowerCase())
return 0;
if (this.isWordPressSite() && d)
return 0;
T=!0
}
if (LinkURLBadSearchParameterKeyMatchRegex.test(N)) {
m++;
continue
}
g = Math.max(g, 1 / LinkNextOrdinalValueBase)
} else
m++
}
}
}
if (!g)
return 0;
if (LinkURLPageSlashNumberMatchRegex.test(t.href) || LinkURLSlashDigitEndMatchRegex.test(t.href))
T=!0;
if (!T && h === v && stringSimilarity(f, l) < LinkMinimumURLSimilarityRatio)
return 0;
if (LinkURLArchiveSlashDigitEndMatchRegex.test(t))
return 0;
var L = LinkMatchWeight * (Math.pow(LinkMismatchValueBase, - m) + g) + LinkVerticalDistanceFromArticleWeight * u / LinkMaxVerticalDistanceFromArticle;
T && (L += LinkURLSemanticMatchBonus), t.parentNode.tagName === "LI" && (L += LinkListItemBonus);
var y = t.innerText;
return LinkNextMatchRegEx.test(y) && (L += LinkNextMatchBonus), LinkPageMatchRegEx.test(y) && (L += LinkPageMatchBonus), LinkContinueMatchRegEx.test(y) && (L += LinkContinueMatchBonus), L
},
elementContainsEnoughTextOfSameStyle: function(t) {
function o(e, t) {
function u(e) {
var t = e.children[0];
if (t) {
var n = t.children, r = n.length;
for (var i = 0; i < r; ++i)
if (getComputedStyle(n[i]).float !== "none")
return !1
}
return !0
}
function a(e, i) {
if (e.nodeType === Node.TEXT_NODE) {
/\S/.test(e.nodeValue) && r.push(e);
return
}
if (e.nodeType !== Node.ELEMENT_NODE)
return;
if (!isElementVisible(e))
return;
if (t&&++n > t)
return;
if (e._evaluatedForTextContent)
return;
var f = e.tagName;
if (f === "IFRAME" || f === "FORM")
return;
o[f] ? i-- : (f === "UL" || f === "OL") && u(e) && i--;
var l = i + 1;
if (l < s) {
var c = e.childNodes, h = c.length;
for (var p = 0; p < h; ++p)
a(c[p], l)
}
}
var n = 0, r = [], o = {
P: 1,
STRONG: 1,
B: 1,
EM: 1,
I: 1,
SPAN: 1
};
return i && (o.CENTER = 1, o.FONT = 1), a(e, 0), r
}
const n = 110, r = 1800;
var i = t.tagName === "BODY", s = i ? 2: 3, u = o(t, n), a = r / scoreMultiplierForElementTagNameAndAttributes(t) / languageScoreMultiplierForTextNodes(u), f = {}, l = u.length;
for (var c = 0; c < l; ++c) {
var h = u[c], p = h.length, d = h.parentElement, v = window.getComputedStyle(d), m = v.fontFamily + "|" + v.fontSize, g = Math.pow(p, TextNodeLengthPower);
if (f[m]) {
if ((f[m] += g) > a)
break
} else
f[m] = g
}
for (var m in f)
if (f[m] > a)
return !0;
return !1
},
pointsToUseForHitTesting: function() {
const t = window.innerWidth, n = t / 4, r = t / 2, i = 128, s = 320;
return [[r, 800], [r, 600], [n, 800], [r, 400], [r - i, 1100], [s, 700], [3 * n, 800], [t - s, 700], [r - i, 1300]]
},
clearVisualExaminationState: function() {
var t = this._elementsEvaluatedForTextContent.length;
for (var n = 0; n < t; ++n)
delete this._elementsEvaluatedForTextContent[n]._evaluatedForTextContent;
this._elementsEvaluatedForTextContent = []
},
findArticleByVisualExamination: function() {
this.clearVisualExaminationState();
var t = this.pointsToUseForHitTesting(), n = t.length;
for (var r = 0; r < n; r++) {
var i = t[r][0], s = t[r][1], o = elementAtPoint(i, s);
for (var u = o; u; u = u.parentElement) {
if (u._evaluatedForTextContent)
break;
if (VeryPositiveClassNameRegEx.test(u.className))
return new CandidateElement(u, this.contentDocument);
if (CandidateTagNamesToIgnore[u.tagName])
continue;
var a = u.offsetWidth, f = u.offsetHeight;
if (!a&&!f) {
var l = cachedElementBoundingRect(u);
a = l.width, f = l.height
}
if (a < CandidateMinimumWidth || f < CandidateMinimumHeight || a * f < CandidateMinimumArea)
continue;
var c = this.elementContainsEnoughTextOfSameStyle(u);
u._evaluatedForTextContent=!0, this._elementsEvaluatedForTextContent.push(u);
if (!c)
continue;
if (CandidateElement.candidateElementAdjustedHeight(u) < CandidateMinimumHeight)
continue;
var h = new CandidateElement(u, this.contentDocument);
if (h.shouldDisqualifyDueToSimilarElements())
return null;
if (h.shouldDisqualifyDueToHorizontalRuleDensity())
return null;
if (h.shouldDisqualifyDueToHeaderDensity())
return null;
if (h.shouldDisqualifyForDeepLinking())
continue;
return h
}
}
return null
},
articleTextContent: function() {
return this._articleTextContent
},
pageDescription: function() {
var t = this.contentDocument.querySelectorAll("head meta[name]"), n = t.length;
for (var r = 0; r < n; ++r) {
var i = t[r];
if (i.getAttribute("name").toLowerCase() === "description") {
var s = i.getAttribute("content");
if (s)
return s.trim()
}
}
return null
},
articleTitleAndSiteNameFromTitleString: function(e) {
const t = [" - ", " \u2013 ", " \u2014 ", ": ", " | ", " \u00bb "], n = t.length, r = .6;
var i = this.contentDocument.location.host, s = i.replace(/^(www|m)\./, ""), o = s.replace(/\.(com|info|net|org|edu)$/, "").toLowerCase(), u, a;
for (var f = 0; f < n; ++f) {
var l = e.split(t[f]);
if (l.length !== 2)
continue;
var c = l[0].trim(), h = l[1].trim(), p = c.toLowerCase(), d = h.toLowerCase(), v = Math.max(stringSimilarity(p, s), stringSimilarity(p, o)), m = Math.max(stringSimilarity(d, s), stringSimilarity(d, o)), g = Math.max(v, m);
if (!a || g > a)
a = g, v > m ? u = {
siteName: c,
articleTitle: h
} : u = {
siteName: h,
articleTitle: c
}
}
return u && a >= r ? u : null
},
readingListItemInformation: function() {
const t = 220, n = 220;
var r, i = this.pageDescription(), s=!1;
this.adoptableArticle() ? (r = this.articleTitle(), i = i || this.articleTextContent(), s=!0) : (r = this.contentDocument.title, this.contentDocument.body && (i = i || this.contentDocument.body.innerText));
var o = "", u = this.mainImageNode();
return u && (o = u.src), r || (r = userVisibleURLString(this.contentDocument.location.href)), r = r.trim().substring(0, t), i || (i = ""), i = i.trim().substring(0, n).replace(/[\s]+/g, " "), {
title: r,
previewText: i,
mainImageURL: o,
isReaderAvailable: s
}
}
};
var ReaderArticleFinderJS = new ReaderArticleFinder(document);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment