site-metadata-extractor
Version:
web(site) resource metadata extractor
737 lines • 95.7 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const isEqual_1 = __importDefault(require("lodash/isEqual"));
const uniq_1 = __importDefault(require("lodash/uniq"));
const url_1 = require("url");
const formatter_1 = __importStar(require("./formatter"));
const cleaner_1 = require("./cleaner");
const stopwords_1 = __importDefault(require("./stopwords"));
function getTagName(node) {
const element = node.get(0);
return (element === null || element === void 0 ? void 0 : element.tagName) || "";
}
function addSiblings(doc, topNode, lang) {
const baselineScoreSiblingsPara = getSiblingsScore(doc, topNode, lang);
const sibs = topNode.prevAll();
sibs.each((_index, element) => {
const currentNode = doc(element);
const ps = getSiblingsContent(doc, lang, currentNode, baselineScoreSiblingsPara);
if (ps) {
ps.forEach((p) => {
topNode.prepend(`<p>${p}</p>`);
});
}
});
return topNode;
}
function biggestTitleChunk(title, splitter) {
let largeTextIndex = 0;
let largeTextLength = 0;
const titlePieces = title.split(splitter);
titlePieces.forEach((piece, index) => {
if (piece.length > largeTextLength) {
largeTextLength = piece.length;
largeTextIndex = index;
}
});
return titlePieces[largeTextIndex];
}
function cleanNull(text) {
if (text) {
return text.replace(/^null$/g, "");
}
return "";
}
function cleanText(text) {
if (text) {
return text
.replace(/[\r\n\t]/g, " ")
.replace(/\s\s+/g, " ")
.replace(/<!--.+?-->/g, "")
.replace(/�/g, "")
.trim();
}
return text;
}
function cleanTitle(title, delimiters) {
let titleText = title || "";
let usedDelimiter = false;
delimiters.forEach((char) => {
if (titleText.indexOf(char) >= 0 && !usedDelimiter) {
titleText = biggestTitleChunk(titleText, char);
usedDelimiter = true;
}
});
return cleanText(titleText);
}
function doesNodeListContainNode(list, node) {
let contains = false;
for (let i = 0; i < list.length; i++) {
const nodeToCompare = list[i];
if ((0, isEqual_1.default)(node, nodeToCompare)) {
contains = true;
}
}
return contains;
}
function getObjectTag(doc, node) {
const srcNode = node.find("param[name=movie]");
if (srcNode.length > 0) {
const src = srcNode.attr("value");
const video = getVideoAttrs(doc, node);
video.src = src;
return video;
}
return {};
}
function getSiblingsContent(doc, lang, currentSibling, baselineScoreSiblingsPara) {
if (getTagName(currentSibling) === "p" &&
currentSibling.text().length > 0) {
return [currentSibling];
}
else {
const potentialParagraphs = currentSibling.find("p");
if (potentialParagraphs === null) {
return null;
}
else {
const ps = [];
potentialParagraphs.each((_index, element) => {
const firstParagraph = doc(element);
const text = firstParagraph.text();
if (text.length > 0) {
const wordStats = (0, stopwords_1.default)(text, lang);
const paragraphScore = wordStats.stopWordCount;
const siblingBaselineScore = 0.3;
const highLinkDensity = isHighLinkDensity(doc, firstParagraph);
const score = baselineScoreSiblingsPara * siblingBaselineScore;
if (score < paragraphScore && !highLinkDensity) {
ps.push(text);
}
}
});
return ps;
}
}
}
function getSiblingsScore(doc, topNode, lang) {
const nodesToCheck = topNode.find("p");
let base = 100000;
let paragraphsNumber = 0;
let paragraphScore = 0;
nodesToCheck.each((_index, element) => {
const node = doc(element);
const textNode = node.text();
const wordStats = (0, stopwords_1.default)(textNode, lang);
const highLinkDensity = isHighLinkDensity(doc, node);
if (wordStats.stopWordCount > 2 && !highLinkDensity) {
paragraphsNumber++;
paragraphScore += wordStats.stopWordCount;
}
});
if (paragraphsNumber > 0) {
base = paragraphScore / paragraphsNumber;
}
return base;
}
function getScore(node) {
const gravityScoreString = node.attr("gravityScore");
if (!gravityScoreString) {
return 0;
}
else {
return parseInt(gravityScoreString, 10);
}
}
function getVideoAttrs(doc, node) {
const el = doc(node);
return {
height: el.attr("height"),
src: el.attr("src"),
width: el.attr("width"),
};
}
function isAbsoluteUrl(url) {
if (typeof url !== "string") {
throw new TypeError(`Expected a \`string\`, got \`${typeof url}\``);
}
// Don't match Windows paths `c:\`
if (/^[a-zA-Z]:\\/.test(url)) {
return false;
}
// Scheme: https://tools.ietf.org/html/rfc3986#section-3.1
// Absolute URL: https://tools.ietf.org/html/rfc3986#section-4.3
return /^[a-zA-Z][a-zA-Z\d+\-.]*:/.test(url);
}
function isBoostable(doc, node, lang) {
const minimumStopWordCount = 5;
const maxStepsAwayFromNode = 3;
let stepsAway = 0;
const nodes = node.prevAll();
let boostable = false;
nodes.each((_index, element) => {
const currentNode = doc(element);
const currentNodeTag = getTagName(currentNode);
if (currentNodeTag === "p") {
if (stepsAway >= maxStepsAwayFromNode) {
boostable = false;
return false;
}
const paraText = currentNode.text();
const wordStats = (0, stopwords_1.default)(paraText, lang);
if (wordStats.stopWordCount > minimumStopWordCount) {
boostable = true;
return false;
}
stepsAway++;
}
});
return boostable;
}
function isHighLinkDensity(doc, node) {
const links = node.find("a");
if (links.length > 0) {
const text = node.text();
const words = text.split(" ");
const numberOfWords = words.length;
const sb = [];
links.each((_index, element) => {
sb.push(doc(element).text());
});
const linkText = sb.join(" ");
const linkWords = linkText.split(" ");
const numberOfLinkWords = linkWords.length;
const numberofLinks = links.length;
const percentLinkWords = numberOfLinkWords / numberOfWords;
const score = percentLinkWords * numberofLinks;
if (score >= 1.0) {
return true;
}
}
return false;
}
function isNodeScoreThresholdMet(_doc, node, e) {
const topNodeScore = getScore(node);
const currentNodeScore = getScore(e);
const thresholdScore = topNodeScore * 0.08;
const elIsTdUlOlOrBlockQ = ["td", "ul", "ol", "blockquote"].includes(getTagName(e));
if (currentNodeScore < thresholdScore && !elIsTdUlOlOrBlockQ) {
return false;
}
return true;
}
function isTableAndNoParaExist(doc, e) {
const subParagraphs = e.find("p");
subParagraphs.each((_index, element) => {
const p = doc(element);
const text = p.text();
if (text.length < 25) {
doc(p).remove();
}
});
const subParagraphsTwo = e.find("p");
const elIsTdUlOrOl = ["td", "ul", "ol"].includes(getTagName(e));
if (subParagraphsTwo.length === 0 && !elIsTdUlOrOl) {
return true;
}
return false;
}
function isValidDate(d) {
const parsedDate = Date.parse(d);
return new Date(d).toString() !== "Invalid Date" && !isNaN(parsedDate);
}
function postCleanup(doc, targetNode, lang) {
const node = addSiblings(doc, targetNode, lang);
node.children().each((_index, element) => {
const el = doc(element);
const elTag = getTagName(el);
if (!["p", "a"].includes(elTag)) {
if (isHighLinkDensity(doc, el) ||
isTableAndNoParaExist(doc, el) ||
!isNodeScoreThresholdMet(doc, node, el)) {
doc(el).remove();
}
}
});
return node;
}
function rawTitle(doc) {
let gotTitle = false;
let titleText = "";
[
doc('meta[property="og:title"]').first().attr("content"),
doc('h1[class*="title"]').first().text(),
doc("title").first().text(),
doc("h1").first().text(),
doc("h2").first().text(),
].forEach((candidate) => {
if (candidate && candidate.trim() && !gotTitle) {
titleText = candidate.trim();
gotTitle = true;
}
});
return titleText;
}
function updateNodeCount(node, addToCount) {
const countString = node.attr("gravityNodes");
let currentScore = 0;
if (countString) {
currentScore = parseInt(countString, 10);
}
const newScore = currentScore + addToCount;
node.attr("gravityNodes", `${newScore}`);
}
function updateScore(node, addToScore) {
const scoreString = node.attr("gravityScore");
let currentScore = 0;
if (scoreString) {
currentScore = parseInt(scoreString, 10);
}
const newScore = currentScore + addToScore;
node.attr("gravityScore", `${newScore}`);
}
const extractor = {
author: (doc) => {
const authorCandidates = doc("meta[property='article:author'], meta[property='og:article:author'], meta[name='author'], meta[name='dcterms.creator'], meta[name='DC.creator'], meta[name='DC.Creator'], meta[name='dc.creator'], meta[name='creator']");
const authorList = [];
authorCandidates.each((_index, element) => {
const author = cleanNull(doc(element).attr("content"));
if (author) {
authorList.push(author.trim());
}
});
// fallback to a named author div
if (authorList.length === 0) {
const fallbackAuthor = doc("span[class*='author']").first().text() ||
doc("p[class*='author']").first().text() ||
doc("div[class*='author']").first().text() ||
doc("span[class*='byline']").first().text() ||
doc("p[class*='byline']").first().text() ||
doc("div[class*='byline']").first().text();
if (fallbackAuthor) {
authorList.push(cleanText(fallbackAuthor));
}
}
return authorList;
},
calculateBestNode: (doc, lang) => {
let topNode = null;
const nodesToCheck = doc("p, pre, td");
const parentNodes = [];
const nodesWithText = [];
let startingBoost = 1.0;
let cnt = 0;
let i = 0;
nodesToCheck.each((_index, element) => {
const node = doc(element);
const textNode = node.text();
const wordStats = (0, stopwords_1.default)(textNode, lang);
const highLinkDensity = isHighLinkDensity(doc, node);
if (wordStats.stopWordCount > 2 && !highLinkDensity) {
nodesWithText.push(node);
}
});
const nodesNumber = nodesWithText.length;
const bottomNegativeScoreNodes = nodesNumber * 0.25;
const negativeScoring = 0;
nodesWithText.forEach((node) => {
let boostScore = 0.0;
if (isBoostable(doc, node, lang) === true) {
if (cnt >= 0) {
boostScore = (1.0 / startingBoost) * 50;
startingBoost += 1;
}
}
if (nodesNumber > 15) {
if (nodesNumber - i <= bottomNegativeScoreNodes) {
const booster = bottomNegativeScoreNodes - (nodesNumber - i);
boostScore = -1.0 * Math.pow(booster, 2);
const negScore = Math.abs(boostScore) + negativeScoring;
if (negScore > 40) {
boostScore = 5.0;
}
}
}
const textNode = node.text();
const wordStats = (0, stopwords_1.default)(textNode, lang);
const upScore = Math.floor(wordStats.stopWordCount + boostScore);
const parentNode = node.parent();
updateScore(parentNode, upScore);
updateNodeCount(parentNode, 1);
if (!doesNodeListContainNode(parentNodes, parentNode)) {
parentNodes.push(parentNode);
}
if (parentNodes.indexOf(parentNode) === -1) {
parentNodes.push(parentNode);
}
const parentParentNode = parentNode.parent();
if (parentParentNode) {
updateScore(parentParentNode, upScore / 2);
updateNodeCount(parentParentNode, 1);
if (!doesNodeListContainNode(parentNodes, parentParentNode)) {
parentNodes.push(parentParentNode);
}
if (parentNodes.indexOf(parentParentNode[0]) === -1) {
parentNodes.push(parentParentNode[0]);
}
}
cnt += 1;
i += 1;
});
let topNodeScore = 0;
parentNodes.forEach((el) => {
const score = getScore(doc(el));
if (score > topNodeScore) {
topNode = el;
topNodeScore = score;
}
if (topNode === null) {
topNode = el;
}
});
return topNode ? doc(topNode) : doc([]);
},
// if it gets to the end without one of these links or meta tags, return the original url as canonical
canonicalLink: (doc, resourceUrl) => {
const canonicalLinkTag = doc("link[rel='canonical'], meta[property='og:url']");
if (canonicalLinkTag) {
const resourceUrlObj = new url_1.URL(resourceUrl);
// check if it is link or meta
if (canonicalLinkTag.get(0) &&
getTagName(canonicalLinkTag) === "link") {
const cleanedCanonicalLink = cleanNull(canonicalLinkTag.first().attr("href"));
// check if link is a relative url, if so, append origin
if (!isAbsoluteUrl(cleanedCanonicalLink)) {
return `${resourceUrlObj.origin}${cleanedCanonicalLink}`;
}
return cleanedCanonicalLink;
}
else if (canonicalLinkTag.get(0) &&
getTagName(canonicalLinkTag) === "meta") {
let cleanedCanonicalMeta = cleanNull(canonicalLinkTag.attr("content"));
// check if resourceUrl protocol is https? if so, use that
const urlProtocol = resourceUrlObj.protocol;
if (urlProtocol === "https:") {
cleanedCanonicalMeta = cleanedCanonicalMeta.replace(/^http:\/\//i, "https://");
return cleanedCanonicalMeta;
}
return cleanedCanonicalMeta;
}
}
// return original url
return resourceUrl;
},
copyright: (doc) => {
var _a;
const copyrightCandidates = doc("p[class*='copyright'], div[class*='copyright'], span[class*='copyright'], li[class*='copyright'], p[id*='copyright'], div[id*='copyright'], span[id*='copyright'], li[id*='copyright']");
let text = (_a = copyrightCandidates === null || copyrightCandidates === void 0 ? void 0 : copyrightCandidates.first()) === null || _a === void 0 ? void 0 : _a.text();
if (!text) {
// try to find copyright in text
text = doc("body")
.text()
.replace(/\s*[\r\n]+\s*/g, ". ");
}
if (text.indexOf("©") > -1) {
const copyright = text
.replace(/.*?©(\s*copyright)?([^,;:.|\r\n]+).*/gi, "$2")
.trim();
return cleanText(copyright);
}
return "";
},
date: (doc) => {
const dateCandidates = doc("meta[property='article:published_time'], \
meta[itemprop*='datePublished'], meta[name='dcterms.modified'], \
meta[name='dcterms.date'], \
meta[name='DC.date.issued'], meta[name='dc.date.issued'], \
meta[name='dc.date.modified'], meta[name='dc.date.created'], \
meta[name='DC.date'], \
meta[name='DC.Date'], \
meta[name='dc.date'], \
meta[name='date'], \
time[itemprop*='pubDate'], \
time[itemprop*='pubdate'], \
span[itemprop*='datePublished'], \
span[property*='datePublished'], \
p[itemprop*='datePublished'], \
p[property*='datePublished'], \
div[itemprop*='datePublished'], \
div[property*='datePublished'], \
li[itemprop*='datePublished'], \
li[property*='datePublished'], \
time, \
span[class*='date'], \
p[class*='date'], \
div[class*='date']");
let dateToReturn = "";
if (dateCandidates) {
const dateContentCandidate = cleanNull(dateCandidates.first().attr("content"));
const dateTimeCandidate = cleanNull(dateCandidates.first().attr("datetime"));
const dateTextCandidate = cleanText(dateCandidates.first().text());
if (dateContentCandidate) {
dateToReturn = dateContentCandidate.trim();
}
else if (dateTimeCandidate) {
dateToReturn = dateTimeCandidate.trim();
}
else if (dateTextCandidate) {
dateToReturn = dateTextCandidate.trim();
}
}
if (isValidDate(dateToReturn)) {
return dateToReturn;
}
// finally try jsonld date
const jsonldBlob = extractor.jsonld(doc);
if (jsonldBlob && jsonldBlob.datePublished) {
dateToReturn = jsonldBlob.datePublished;
}
return dateToReturn;
},
description: (doc) => {
const descriptionTag = doc("meta[name=description], meta[property='og:description']");
if (descriptionTag) {
const cleanedDescription = cleanNull(descriptionTag.first().attr("content"));
if (cleanedDescription) {
return (0, formatter_1.replaceCharacters)(cleanedDescription.trim(), false, true);
}
}
return "";
},
favicon: (doc, resourceUrlObj) => {
const tag = doc("link").filter((_index, el) => {
var _a, _b;
return ((_a = doc(el).attr("rel")) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === "shortcut icon" ||
((_b = doc(el).attr("rel")) === null || _b === void 0 ? void 0 : _b.toLowerCase()) === "icon";
});
const faviconLink = tag.attr("href") || "";
// ensure the url returned from favicon is absolute url
if (faviconLink && !isAbsoluteUrl(faviconLink)) {
// add the origin to the faviconLink
return `${resourceUrlObj.origin}${faviconLink}`;
}
return faviconLink;
},
image: (doc) => {
const images = doc("meta[property='og:image'], meta[property='og:image:url'], meta[itemprop=image], meta[name='twitter:image:src'], meta[name='twitter:image'], meta[name='twitter:image0']");
if (images.length > 0 && cleanNull(images.first().attr("content"))) {
const cleanedImages = cleanNull(images.first().attr("content")) || "";
return cleanedImages.trim();
}
return "";
},
jsonld: (doc) => {
const jsonldTag = doc('script[type="application/ld+json"]');
if (jsonldTag) {
let jsonldObj = jsonldTag.html() || "{}";
// Sanitize the jsonldObj string to remove extraneous HTML/XML tags
jsonldObj = (0, cleaner_1.sanitizeJsonLdString)(jsonldObj);
try {
const parsedJSON = JSON.parse(jsonldObj);
return parsedJSON;
}
catch (e) {
console.warn(`Error in jsonld parse - ${e}`);
}
}
return null;
},
keywords: (doc) => {
const keywordsTag = doc('meta[name="keywords"]');
if (keywordsTag) {
const cleansedKeywords = cleanNull(keywordsTag.attr("content"));
if (cleansedKeywords) {
return cleansedKeywords.trim();
}
}
return "";
},
lang: (doc) => {
let language = doc("html").attr("lang");
if (!language) {
const tag = doc("meta[name=lang]") || doc("meta[http-equiv=content-language]");
language = tag.attr("content");
}
if (language) {
const value = language[0] + language[1];
const regex = /^[A-Za-z]{2}$/;
if (regex.test(value)) {
return value.toLowerCase();
}
}
return "";
},
links: (doc, topNode, lang) => {
const links = [];
const gatherLinks = () => {
const nodes = topNode.find("a");
nodes.each((_index, element) => {
const href = doc(element).attr("href");
const text = doc(element).html();
if (href && text) {
links.push({
href,
text,
});
}
});
};
if (topNode) {
topNode = postCleanup(doc, topNode, lang);
gatherLinks();
}
return links;
},
locale: (doc) => {
const localeTag = doc("meta[property='og:locale']");
if (localeTag) {
const cleanedLocale = cleanNull(localeTag.first().attr("content"));
if (cleanedLocale) {
return cleanedLocale.trim();
}
}
return "";
},
publisher: (doc) => {
const publisherCandidates = doc("meta[property='og:site_name'], meta[itemprop=name], meta[name='dc.publisher'], meta[name='DC.publisher'], meta[name='DC.Publisher']");
if (publisherCandidates) {
const cleanedPublisher = cleanNull(publisherCandidates.first().attr("content"));
if (cleanedPublisher) {
return cleanedPublisher.trim();
}
}
return "";
},
siteName: (doc) => {
const siteNameTag = doc("meta[property='og:site_name'], meta[itemprop=name]");
if (siteNameTag) {
const cleanedSiteName = cleanNull(siteNameTag.first().attr("content"));
if (cleanedSiteName) {
return cleanedSiteName.trim();
}
}
return "";
},
// Grab the title with soft truncation
softTitle: (doc) => {
const titleText = rawTitle(doc);
return cleanTitle(titleText, ["|", " - ", "»"]);
},
tags: (doc) => {
let elements = doc("a[rel='tag']");
if (elements.length === 0) {
elements = doc("a[href*='/tag/'], a[href*='/tags/'], a[href*='/topic/'], a[href*='?keyword=']");
if (elements.length === 0) {
return [];
}
}
const tags = [];
elements.each((_index, element) => {
const tag = doc(element);
const tagText = tag.text().trim();
tagText.replace(/[\s\t\n]+/g, "");
if (tagText && tagText.length > 0) {
tags.push(tagText);
}
});
return (0, uniq_1.default)(tags);
},
text: (doc, topNode, lang) => {
if (topNode) {
topNode = postCleanup(doc, topNode, lang);
return (0, formatter_1.default)(doc, topNode, lang);
}
else {
return "";
}
},
// Grab the title of an html doc (excluding junk)
// Hard-truncates titles containing colon or spaced dash
title: (doc) => {
const titleText = rawTitle(doc);
const cleanedTitle = cleanTitle(titleText, ["|", " - ", "»", ":"]);
return (0, formatter_1.replaceCharacters)(cleanedTitle, false, true);
},
type: (doc) => {
const typeTag = doc("meta[property='og:type']");
if (typeTag) {
const cleanedType = cleanNull(typeTag.first().attr("content"));
if (cleanedType) {
return cleanedType.trim();
}
}
return "";
},
videos: (doc, topNode) => {
const videolist = [];
const videoCandidates = doc(topNode).find("iframe, embed, object, video");
videoCandidates.each((_index, element) => {
const candidate = doc(element);
const tag = getTagName(candidate);
if (tag === "embed") {
if (candidate.parent() &&
getTagName(candidate.parent()) === "object") {
videolist.push(getObjectTag(doc, candidate));
}
else {
videolist.push(getVideoAttrs(doc, candidate));
}
}
else if (tag === "object") {
videolist.push(getObjectTag(doc, candidate));
}
else if (tag === "iframe" || tag === "video") {
videolist.push(getVideoAttrs(doc, candidate));
}
});
const urls = [];
const results = [];
videolist.forEach((vid) => {
if (vid.src) {
if (vid && vid.height && vid.width && urls.indexOf(vid.src) === -1) {
results.push(vid);
urls.push(vid.src);
}
}
});
return results;
},
};
exports.default = extractor;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXh0cmFjdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2V4dHJhY3Rvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUdBLDZEQUFxQztBQUNyQyx1REFBK0I7QUFFL0IsNkJBQTBCO0FBQzFCLHlEQUEyRDtBQUMzRCx1Q0FBaUQ7QUFDakQsNERBQW9DO0FBRXBDLFNBQVMsVUFBVSxDQUFDLElBQXNCO0lBQ3hDLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUF3QixDQUFDO0lBQ25ELE9BQU8sQ0FBQSxPQUFPLGFBQVAsT0FBTyx1QkFBUCxPQUFPLENBQUUsT0FBTyxLQUFJLEVBQUUsQ0FBQztBQUNoQyxDQUFDO0FBeUNELFNBQVMsV0FBVyxDQUNsQixHQUFlLEVBQ2YsT0FBeUIsRUFDekIsSUFBWTtJQUVaLE1BQU0seUJBQXlCLEdBQUcsZ0JBQWdCLENBQUMsR0FBRyxFQUFFLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQztJQUN2RSxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7SUFFL0IsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLE1BQWMsRUFBRSxPQUFnQixFQUFFLEVBQUU7UUFDN0MsTUFBTSxXQUFXLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2pDLE1BQU0sRUFBRSxHQUFHLGtCQUFrQixDQUMzQixHQUFHLEVBQ0gsSUFBSSxFQUNKLFdBQVcsRUFDWCx5QkFBeUIsQ0FDMUIsQ0FBQztRQUVGLElBQUksRUFBRSxFQUFFLENBQUM7WUFDUCxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBNEIsRUFBRSxFQUFFO2dCQUMxQyxPQUFPLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNqQyxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUM7SUFDSCxDQUFDLENB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