diff --git a/dist/generate-custom-parser.js b/dist/generate-custom-parser.js index 82973205..06cad172 100644 --- a/dist/generate-custom-parser.js +++ b/dist/generate-custom-parser.js @@ -2,35 +2,200 @@ function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } -var _slicedToArray = _interopDefault(require('babel-runtime/helpers/slicedToArray')); var fs = _interopDefault(require('fs')); var URL = _interopDefault(require('url')); var inquirer = _interopDefault(require('inquirer')); var ora = _interopDefault(require('ora')); -var _typeof = _interopDefault(require('babel-runtime/helpers/typeof')); var regenerator = _interopDefault(require('babel-runtime/regenerator')); var _extends = _interopDefault(require('babel-runtime/helpers/extends')); var asyncToGenerator = _interopDefault(require('babel-runtime/helpers/asyncToGenerator')); var cheerio = _interopDefault(require('cheerio')); var promise = _interopDefault(require('babel-runtime/core-js/promise')); var request = _interopDefault(require('request')); -var _Reflect$ownKeys = _interopDefault(require('babel-runtime/core-js/reflect/own-keys')); +var ownKeys = _interopDefault(require('babel-runtime/core-js/reflect/own-keys')); +var toConsumableArray = _interopDefault(require('babel-runtime/helpers/toConsumableArray')); +var slicedToArray = _interopDefault(require('babel-runtime/helpers/slicedToArray')); var stringDirection = _interopDefault(require('string-direction')); -var _getIterator = _interopDefault(require('babel-runtime/core-js/get-iterator')); +var getIterator = _interopDefault(require('babel-runtime/core-js/get-iterator')); var defineProperty = _interopDefault(require('babel-runtime/helpers/defineProperty')); +var _typeof = _interopDefault(require('babel-runtime/helpers/typeof')); var validUrl = _interopDefault(require('valid-url')); var moment = _interopDefault(require('moment')); var wuzzy = _interopDefault(require('wuzzy')); var difflib = _interopDefault(require('difflib')); var from = _interopDefault(require('babel-runtime/core-js/array/from')); var ellipsize = _interopDefault(require('ellipsize')); -var _taggedTemplateLiteral = _interopDefault(require('babel-runtime/helpers/taggedTemplateLiteral')); function createCommonjsModule(fn, module) { return module = { exports: {} }, fn(module, module.exports), module.exports; } -var mercury=createCommonjsModule(function(module){'use strict';function _interopDefault(ex){return ex&&(typeof ex==='undefined'?'undefined':_typeof(ex))==='object'&&'default'in ex?ex['default']:ex;}var _regeneratorRuntime=_interopDefault(regenerator);var _extends$$=_interopDefault(_extends);var _asyncToGenerator=_interopDefault(asyncToGenerator);var URL$$=_interopDefault(URL);var cheerio$$=_interopDefault(cheerio);var _Promise=_interopDefault(promise);var request$$=_interopDefault(request);var _Reflect$ownKeys$$=_interopDefault(_Reflect$ownKeys);var stringDirection$$=_interopDefault(stringDirection);var _getIterator$$=_interopDefault(_getIterator);var _defineProperty=_interopDefault(defineProperty);var _slicedToArray$$=_interopDefault(_slicedToArray);var _typeof$$=_interopDefault(_typeof);var validUrl$$=_interopDefault(validUrl);var moment$$=_interopDefault(moment);var wuzzy$$=_interopDefault(wuzzy);var difflib$$=_interopDefault(difflib);var _Array$from=_interopDefault(from);var ellipsize$$=_interopDefault(ellipsize);var _marked=[range].map(_regeneratorRuntime.mark);function range(){var start=arguments.length>0&&arguments[0]!==undefined?arguments[0]:1;var end=arguments.length>1&&arguments[1]!==undefined?arguments[1]:1;return _regeneratorRuntime.wrap(function range$(_context){while(1){switch(_context.prev=_context.next){case 0:if(!(start<=end)){_context.next=5;break;}_context.next=3;return start+=1;case 3:_context.next=0;break;case 5:case"end":return _context.stop();}}},_marked[0],this);}// extremely simple url validation as a first step +var _typeof$1 = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { + return typeof obj; +} : function (obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; +}; + +var asyncGenerator = function () { + function AwaitValue(value) { + this.value = value; + } + + function AsyncGenerator(gen) { + var front, back; + + function send(key, arg) { + return new Promise(function (resolve, reject) { + var request = { + key: key, + arg: arg, + resolve: resolve, + reject: reject, + next: null + }; + + if (back) { + back = back.next = request; + } else { + front = back = request; + resume(key, arg); + } + }); + } + + function resume(key, arg) { + try { + var result = gen[key](arg); + var value = result.value; + + if (value instanceof AwaitValue) { + Promise.resolve(value.value).then(function (arg) { + resume("next", arg); + }, function (arg) { + resume("throw", arg); + }); + } else { + settle(result.done ? "return" : "normal", result.value); + } + } catch (err) { + settle("throw", err); + } + } + + function settle(type, value) { + switch (type) { + case "return": + front.resolve({ + value: value, + done: true + }); + break; + + case "throw": + front.reject(value); + break; + + default: + front.resolve({ + value: value, + done: false + }); + break; + } + + front = front.next; + + if (front) { + resume(front.key, front.arg); + } else { + back = null; + } + } + + this._invoke = send; + + if (typeof gen.return !== "function") { + this.return = undefined; + } + } + + if (typeof Symbol === "function" && Symbol.asyncIterator) { + AsyncGenerator.prototype[Symbol.asyncIterator] = function () { + return this; + }; + } + + AsyncGenerator.prototype.next = function (arg) { + return this._invoke("next", arg); + }; + + AsyncGenerator.prototype.throw = function (arg) { + return this._invoke("throw", arg); + }; + + AsyncGenerator.prototype.return = function (arg) { + return this._invoke("return", arg); + }; + + return { + wrap: function (fn) { + return function () { + return new AsyncGenerator(fn.apply(this, arguments)); + }; + }, + await: function (value) { + return new AwaitValue(value); + } + }; +}(); + +var slicedToArray$1 = function () { + function sliceIterator(arr, i) { + var _arr = []; + var _n = true; + var _d = false; + var _e = undefined; + + try { + for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { + _arr.push(_s.value); + + if (i && _arr.length === i) break; + } + } catch (err) { + _d = true; + _e = err; + } finally { + try { + if (!_n && _i["return"]) _i["return"](); + } finally { + if (_d) throw _e; + } + } + + return _arr; + } + + return function (arr, i) { + if (Array.isArray(arr)) { + return arr; + } else if (Symbol.iterator in Object(arr)) { + return sliceIterator(arr, i); + } else { + throw new TypeError("Invalid attempt to destructure non-iterable instance"); + } + }; +}(); + +var taggedTemplateLiteral = function (strings, raw) { + return Object.freeze(Object.defineProperties(strings, { + raw: { + value: Object.freeze(raw) + } + })); +}; + +var mercury=createCommonjsModule(function(module){'use strict';function _interopDefault(ex){return ex&&(typeof ex==='undefined'?'undefined':_typeof$1(ex))==='object'&&'default'in ex?ex['default']:ex;}var _regeneratorRuntime=_interopDefault(regenerator);var _extends$$=_interopDefault(_extends);var _asyncToGenerator=_interopDefault(asyncToGenerator);var URL$$=_interopDefault(URL);var cheerio$$=_interopDefault(cheerio);var _Promise=_interopDefault(promise);var request$$=_interopDefault(request);var _Reflect$ownKeys=_interopDefault(ownKeys);var _toConsumableArray=_interopDefault(toConsumableArray);var _slicedToArray=_interopDefault(slicedToArray);var stringDirection$$=_interopDefault(stringDirection);var _getIterator=_interopDefault(getIterator);var _defineProperty=_interopDefault(defineProperty);var _typeof$$=_interopDefault(_typeof);var validUrl$$=_interopDefault(validUrl);var moment$$=_interopDefault(moment);var wuzzy$$=_interopDefault(wuzzy);var difflib$$=_interopDefault(difflib);var _Array$from=_interopDefault(from);var ellipsize$$=_interopDefault(ellipsize);var _marked=[range].map(_regeneratorRuntime.mark);function range(){var start=arguments.length>0&&arguments[0]!==undefined?arguments[0]:1;var end=arguments.length>1&&arguments[1]!==undefined?arguments[1]:1;return _regeneratorRuntime.wrap(function range$(_context){while(1){switch(_context.prev=_context.next){case 0:if(!(start<=end)){_context.next=5;break;}_context.next=3;return start+=1;case 3:_context.next=0;break;case 5:case"end":return _context.stop();}}},_marked[0],this);}// extremely simple url validation as a first step function validateUrl(_ref){var hostname=_ref.hostname;// If this isn't a valid url, return an error message return!!hostname;}var Errors={badUrl:{error:true,messages:'The url parameter passed does not look like a valid URL. Please check your data and try again.'}};var REQUEST_HEADERS={'User-Agent':'Readability - http://readability.com/about/'};// The number of milliseconds to attempt to fetch a resource before timing out. var FETCH_TIMEOUT=10000;// Content types that we do not extract content from @@ -64,7 +229,7 @@ function normalizeMetaTags($){$=convertMetaProp($,'content','value');$=convertMe // Many sites will have img tags with no source, or an image tag with a src // attribute that a is a placeholer. We need to be able to properly fill in // the src attribute so the images are no longer lazy loaded. -function convertLazyLoadedImages($){$('img').each(function(_,img){_Reflect$ownKeys$$(img.attribs).forEach(function(attr){var value=img.attribs[attr];if(attr!=='src'&&IS_LINK.test(value)&&IS_IMAGE.test(value)){$(img).attr('src',value);}});});return $;}function isComment(index,node){return node.type==='comment';}function cleanComments($){$.root().find('*').contents().filter(isComment).remove();return $;}function clean($){$(TAGS_TO_REMOVE).remove();$=cleanComments($);return $;}var Resource={// Create a Resource. +function convertLazyLoadedImages($){$('img').each(function(_,img){_Reflect$ownKeys(img.attribs).forEach(function(attr){var value=img.attribs[attr];if(attr!=='src'&&IS_LINK.test(value)&&IS_IMAGE.test(value)){$(img).attr('src',value);}});});return $;}function isComment(index,node){return node.type==='comment';}function cleanComments($){$.root().find('*').contents().filter(isComment).remove();return $;}function clean($){$(TAGS_TO_REMOVE).remove();$=cleanComments($);return $;}var Resource={// Create a Resource. // // :param url: The URL for the document we should retrieve. // :param response: If set, use as the response rather than @@ -72,7 +237,7 @@ function convertLazyLoadedImages($){$('img').each(function(_,img){_Reflect$ownKe // string. create:function create(url,preparedResponse,parsedUrl){var _this=this;return _asyncToGenerator(_regeneratorRuntime.mark(function _callee(){var result,validResponse;return _regeneratorRuntime.wrap(function _callee$(_context){while(1){switch(_context.prev=_context.next){case 0:result=void 0;if(!preparedResponse){_context.next=6;break;}validResponse={statusMessage:'OK',statusCode:200,headers:{'content-type':'text/html','content-length':500}};result={body:preparedResponse,response:validResponse};_context.next=9;break;case 6:_context.next=8;return fetchResource(url,parsedUrl);case 8:result=_context.sent;case 9:if(!result.error){_context.next=11;break;}return _context.abrupt('return',result);case 11:return _context.abrupt('return',_this.generateDoc(result));case 12:case'end':return _context.stop();}}},_callee,_this);}))();},generateDoc:function generateDoc(_ref){var content=_ref.body;var response=_ref.response;var contentType=response.headers['content-type'];// TODO: Implement is_text function from // https://github.com/ReadabilityHoldings/readability/blob/8dc89613241d04741ebd42fa9fa7df1b1d746303/readability/utils/text.py#L57 -if(!contentType.includes('html')&&!contentType.includes('text')){throw new Error('Content does not appear to be text.');}var $=cheerio$$.load(content,{normalizeWhitespace:true});if($.root().children().length===0){throw new Error('No children, likely a bad parse.');}$=normalizeMetaTags($);$=convertLazyLoadedImages($);$=clean($);return $;}};var NYMagExtractor={domain:'nymag.com',content:{// Order by most likely. Extractor will stop on first occurrence +if(!contentType.includes('html')&&!contentType.includes('text')){throw new Error('Content does not appear to be text.');}var $=cheerio$$.load(content,{normalizeWhitespace:true});if($.root().children().length===0){throw new Error('No children, likely a bad parse.');}$=normalizeMetaTags($);$=convertLazyLoadedImages($);$=clean($);return $;}};var merge=function merge(extractor,domains){return domains.reduce(function(acc,domain){acc[domain]=extractor;return acc;},{});};function mergeSupportedDomains(extractor){return extractor.supportedDomains?merge(extractor,[extractor.domain].concat(_toConsumableArray(extractor.supportedDomains))):merge(extractor,[extractor.domain]);}var NYMagExtractor={domain:'nymag.com',content:{// Order by most likely. Extractor will stop on first occurrence selectors:['div.article-content','section.body','article.article'],// Selectors to remove from the extracted content clean:['.ad','.single-related-story'],// Object of tranformations to make on matched elements // Each key is the selector, each value is the tag to @@ -87,7 +252,7 @@ noscript:function noscript($node){var $children=$node.children();if($children.le // in noscript selectors:['.post-content noscript'],// Selectors to remove from the extracted content clean:[],// Convert the noscript tag to a div -transforms:{noscript:'div'}},author:{selectors:['.post-author-name']},title:{selectors:['h2.title']},date_published:{selectors:['span.publishdate']}};var WikipediaExtractor={domain:'wikipedia.org',content:{selectors:['#mw-content-text'],defaultCleaner:false,// transform top infobox to an image with caption +transforms:{noscript:'div'}},author:{selectors:['.post-author-name']},title:{selectors:['.post h2.title']},date_published:{selectors:['span.publishdate']}};var WikipediaExtractor={domain:'wikipedia.org',content:{selectors:['#mw-content-text'],defaultCleaner:false,// transform top infobox to an image with caption transforms:{'.infobox img':function infoboxImg($node){var $parent=$node.parents('.infobox');// Only prepend the first image in .infobox if($parent.children('img').length===0){$parent.prepend($node);}},'.infobox caption':'figcaption','.infobox':'figure'},// Selectors to remove from the extracted content clean:['.mw-editsection','figure tr, figure td, figure tbody','#toc','.navbox']},author:'Wikipedia Contributors',title:{selectors:['h2.title']},date_published:{selectors:['#footer-info-lastmod']}};var TwitterExtractor={domain:'twitter.com',content:{transforms:{// We're transforming essentially the whole page here. @@ -96,7 +261,7 @@ clean:['.mw-editsection','figure tr, figure td, figure tbody','#toc','.navbox']} // it to fit our needs before we clean it up. '.permalink[role=main]':function permalinkRoleMain($node,$){var tweets=$node.find('.tweet');var $tweetContainer=$('
');$tweetContainer.append(tweets);$node.replaceWith($tweetContainer);},// Twitter wraps @ with s, which // renders as a strikethrough -s:'span'},selectors:['.permalink[role=main]'],defaultCleaner:false,clean:['.stream-item-footer','button','.tweet-details-fixer']},author:{selectors:['.tweet.permalink-tweet .username']},date_published:{selectors:[['.permalink-tweet ._timestamp[data-time-ms]','data-time-ms']]}};var NYTimesExtractor={title:{selectors:['.g-headline','h1.headline']},author:{selectors:['.g-byline','.byline']},content:{selectors:['div.g-blocks','article#story'],defaultCleaner:false,transforms:{'img.g-lazy':function imgGLazy($node){var src=$node.attr('src');// const widths = $node.attr('data-widths') +s:'span'},selectors:['.permalink[role=main]'],defaultCleaner:false,clean:['.stream-item-footer','button','.tweet-details-fixer']},author:{selectors:['.tweet.permalink-tweet .username']},date_published:{selectors:[['.permalink-tweet ._timestamp[data-time-ms]','data-time-ms']]}};var NYTimesExtractor={title:{selectors:['.g-headline','h1.headline']},author:{selectors:[['meta[name="author"]','value'],'.g-byline','.byline']},content:{selectors:['div.g-blocks','article#story'],defaultCleaner:false,transforms:{'img.g-lazy':function imgGLazy($node){var src=$node.attr('src');// const widths = $node.attr('data-widths') // .slice(1) // .slice(0, -1) // .split(','); @@ -181,10 +346,50 @@ transforms:[],// Is there anything that is in the result that shouldn't be? // The clean selectors will remove anything that matches from // the result clean:['figcaption']},date_published:{selectors:[['.story-main-content .timestamp time[datetime]','datetime']]},lead_image_url:{selectors:[// enter lead_image_url selectors -['meta[name="og:image"]','value']]},dek:{selectors:[['meta[name="description"]','value']]},next_page_url:null,excerpt:null};var Extractors={'nymag.com':NYMagExtractor,'blogspot.com':BloggerExtractor,'wikipedia.org':WikipediaExtractor,'twitter.com':TwitterExtractor,'www.nytimes.com':NYTimesExtractor,'www.theatlantic.com':TheAtlanticExtractor,'www.newyorker.com':NewYorkerExtractor,'www.wired.com':WiredExtractor,'www.msn.com':MSNExtractor,'www.yahoo.com':YahooExtractor,'www.buzzfeed.com':BuzzfeedExtractor,'fandom.wikia.com':WikiaExtractor,'www.littlethings.com':LittleThingsExtractor,'www.politico.com':PoliticoExtractor};// Spacer images to be removed -var SPACER_RE=new RegExp('trans|transparent|spacer|blank','i');// A list of tags to strip from the output if we encounter them. +['meta[name="og:image"]','value']]},dek:{selectors:[['meta[name="description"]','value']]},next_page_url:null,excerpt:null};var DeadspinExtractor={domain:'deadspin.com',supportedDomains:['jezebel.com','lifehacker.com','kotaku.com','gizmodo.com','jalopnik.com','kinja.com'],title:{selectors:['h1.headline']},author:{selectors:['.author']},content:{selectors:['.post-content','.entry-content'],// Is there anything in the content you selected that needs transformed +// before it's consumable content? E.g., unusual lazy loaded images +transforms:{'iframe.lazyload[data-recommend-id^="youtube://"]':function iframeLazyloadDataRecommendIdYoutube($node){var youtubeId=$node.attr('id').split('youtube-')[1];$node.attr('src','https://www.youtube.com/embed/'+youtubeId);}},// Is there anything that is in the result that shouldn't be? +// The clean selectors will remove anything that matches from +// the result +clean:[]},date_published:{selectors:[['time.updated[datetime]','datetime']]},lead_image_url:{selectors:[['meta[name="og:image"]','value']]},dek:{selectors:[// enter selectors +]},next_page_url:{selectors:[// enter selectors +]},excerpt:{selectors:[// enter selectors +]}};// Rename CustomExtractor +// to fit your publication +// (e.g., NYTimesExtractor) +var BroadwayWorldExtractor={domain:'www.broadwayworld.com',title:{selectors:['h1.article-title']},author:{selectors:['span[itemprop=author]']},content:{selectors:['div[itemprop=articlebody]'],// Is there anything in the content you selected that needs transformed +// before it's consumable content? E.g., unusual lazy loaded images +transforms:{},// Is there anything that is in the result that shouldn't be? +// The clean selectors will remove anything that matches from +// the result +clean:[]},date_published:{selectors:[['meta[itemprop=datePublished]','value']]},lead_image_url:{selectors:[['meta[name="og:image"]','value']]},dek:{selectors:[['meta[name="og:description"]','value']]},next_page_url:{selectors:[// enter selectors +]},excerpt:{selectors:[// enter selectors +]}};// Rename CustomExtractor +// to fit your publication +// (e.g., NYTimesExtractor) +var ApartmentTherapyExtractor={domain:'www.apartmenttherapy.com',title:{selectors:['h1.headline']},author:{selectors:['.PostByline__name']},content:{selectors:['div.post__content'],// Is there anything in the content you selected that needs transformed +// before it's consumable content? E.g., unusual lazy loaded images +transforms:{'div[data-render-react-id="images/LazyPicture"]':function divDataRenderReactIdImagesLazyPicture($node,$){var data=JSON.parse($node.attr('data-props'));var src=data.sources[0].src;var $img=$('').attr('src',src);$node.replaceWith($img);}},// Is there anything that is in the result that shouldn't be? +// The clean selectors will remove anything that matches from +// the result +clean:[]},date_published:{selectors:[['.PostByline__timestamp[datetime]','datetime']]},lead_image_url:{selectors:[['meta[name="og:image"]','value']]},dek:{selectors:[['meta[name=description]','value']]},next_page_url:{selectors:[// enter selectors +]},excerpt:{selectors:[// enter selectors +]}};var MediumExtractor={domain:'medium.com',supportedDomains:['trackchanges.postlight.com'],title:{selectors:['h1']},author:{selectors:[['meta[name="author"]','value']]},content:{selectors:['.section-content'],// Is there anything in the content you selected that needs transformed +// before it's consumable content? E.g., unusual lazy loaded images +transforms:{// Re-write lazy-loaded youtube videos +iframe:function iframe($node){var ytRe=/https:\/\/i.embed.ly\/.+url=https:\/\/i\.ytimg\.com\/vi\/(\w+)\//;var thumb=decodeURIComponent($node.attr('data-thumbnail'));if(ytRe.test(thumb)){var _thumb$match=thumb.match(ytRe);var _thumb$match2=_slicedToArray(_thumb$match,2);var _=_thumb$match2[0];var youtubeId=_thumb$match2[1];// eslint-disable-line +$node.attr('src','https://www.youtube.com/embed/'+youtubeId);var $parent=$node.parents('figure');$parent.prepend($node.clone());$node.remove();}}},// Is there anything that is in the result that shouldn't be? +// The clean selectors will remove anything that matches from +// the result +clean:[]},date_published:{selectors:[['time[datetime]','datetime']]},lead_image_url:{selectors:[['meta[name="og:image"]','value']]},dek:{selectors:[// enter selectors +]},next_page_url:{selectors:[// enter selectors +]},excerpt:{selectors:[// enter selectors +]}};var Extractors=_extends$$({'nymag.com':NYMagExtractor,'blogspot.com':BloggerExtractor,'wikipedia.org':WikipediaExtractor,'twitter.com':TwitterExtractor,'www.nytimes.com':NYTimesExtractor,'www.theatlantic.com':TheAtlanticExtractor,'www.newyorker.com':NewYorkerExtractor,'www.wired.com':WiredExtractor,'www.msn.com':MSNExtractor,'www.yahoo.com':YahooExtractor,'www.buzzfeed.com':BuzzfeedExtractor,'fandom.wikia.com':WikiaExtractor,'www.littlethings.com':LittleThingsExtractor,'www.politico.com':PoliticoExtractor},mergeSupportedDomains(DeadspinExtractor),{'www.broadwayworld.com':BroadwayWorldExtractor,'www.apartmenttherapy.com':ApartmentTherapyExtractor},mergeSupportedDomains(MediumExtractor));// Spacer images to be removed +var SPACER_RE=new RegExp('trans|transparent|spacer|blank','i');// The class we will use to mark elements we want to keep +// but would normally remove +var KEEP_CLASS='mercury-parser-keep';var KEEP_SELECTORS=['iframe[src^="https://www.youtube.com"]','iframe[src^="http://www.youtube.com"]','iframe[src^="https://player.vimeo"]','iframe[src^="http://player.vimeo"]'];// A list of tags to strip from the output if we encounter them. var STRIP_OUTPUT_TAGS=['title','script','noscript','link','style','hr','embed','iframe','object'];// cleanAttributes -var REMOVE_ATTRS=['style','align'];var REMOVE_ATTR_SELECTORS=REMOVE_ATTRS.map(function(selector){return'['+selector+']';});var REMOVE_ATTR_LIST=REMOVE_ATTRS.join(',');var WHITELIST_ATTRS=['src','srcset','href','class','id','alt','score'];var WHITELIST_ATTRS_RE=new RegExp('^('+WHITELIST_ATTRS.join('|')+')$','i');// removeEmpty +var REMOVE_ATTRS=['style','align'];var REMOVE_ATTR_SELECTORS=REMOVE_ATTRS.map(function(selector){return'['+selector+']';});var REMOVE_ATTR_LIST=REMOVE_ATTRS.join(',');var WHITELIST_ATTRS=['src','srcset','href','class','id','alt'];var WHITELIST_ATTRS_RE=new RegExp('^('+WHITELIST_ATTRS.join('|')+')$','i');// removeEmpty var REMOVE_EMPTY_TAGS=['p'];var REMOVE_EMPTY_SELECTORS=REMOVE_EMPTY_TAGS.map(function(tag){return tag+':empty';}).join(',');// cleanTags var CLEAN_CONDITIONALLY_TAGS=['ul','ol','table','div','button','form'].join(',');// cleanHeaders var HEADER_TAGS=['h2','h3','h4','h5','h6'];var HEADER_TAG_LIST=HEADER_TAGS.join(',');// // CONTENT FETCHING CONSTANTS //// @@ -279,7 +484,7 @@ while(sibling&&!(sibling.tagName&&BLOCK_LEVEL_TAGS_RE.test(sibling.tagName))){va // :param $: A cheerio object to search // :return cheerio object with new p elements // (By-reference mutation, though. Returned just for convenience.) -function convertToParagraphs($){$=brsToPs($);$=convertDivs($);$=convertSpans($);return $;}function convertNodeTo($node,$){var tag=arguments.length>2&&arguments[2]!==undefined?arguments[2]:'p';var node=$node.get(0);if(!node){return $;}var _$node$get=$node.get(0);var attribs=_$node$get.attribs;var attribString=_Reflect$ownKeys$$(attribs).map(function(key){return key+'='+attribs[key];}).join(' ');$node.replaceWith('<'+tag+' '+attribString+'>'+$node.contents()+'');return $;}function cleanForHeight($img,$){var height=parseInt($img.attr('height'),10);var width=parseInt($img.attr('width'),10)||20;// Remove images that explicitly have very small heights or +function convertToParagraphs($){$=brsToPs($);$=convertDivs($);$=convertSpans($);return $;}function convertNodeTo($node,$){var tag=arguments.length>2&&arguments[2]!==undefined?arguments[2]:'p';var node=$node.get(0);if(!node){return $;}var _$node$get=$node.get(0);var attribs=_$node$get.attribs;var attribString=_Reflect$ownKeys(attribs).map(function(key){return key+'='+attribs[key];}).join(' ');$node.replaceWith('<'+tag+' '+attribString+'>'+$node.contents()+'');return $;}function cleanForHeight($img,$){var height=parseInt($img.attr('height'),10);var width=parseInt($img.attr('width'),10)||20;// Remove images that explicitly have very small heights or // widths, because they are most likely shims or icons, // which aren't very useful for reading. if((height||20)<10||width<10){$img.remove();}else if(height){// Don't ever specify a height on images, so that we can @@ -287,17 +492,22 @@ if((height||20)<10||width<10){$img.remove();}else if(height){// Don't ever speci // aspect ratio. $img.removeAttr('height');}return $;}// Cleans out images where the source string matches transparent/spacer/etc // TODO This seems very aggressive - AP -function removeSpacers($img,$){if(SPACER_RE.test($img.attr('src'))){$img.remove();}return $;}function cleanImages($article,$){$article.find('img').each(function(index,img){var $img=$(img);cleanForHeight($img,$);removeSpacers($img,$);});return $;}function stripJunkTags(article,$){var tags=arguments.length>2&&arguments[2]!==undefined?arguments[2]:[];if(tags.length===0){tags=STRIP_OUTPUT_TAGS;}$(tags.join(','),article).remove();return $;}// H1 tags are typically the article title, which should be extracted +function removeSpacers($img,$){if(SPACER_RE.test($img.attr('src'))){$img.remove();}return $;}function cleanImages($article,$){$article.find('img').each(function(index,img){var $img=$(img);cleanForHeight($img,$);removeSpacers($img,$);});return $;}function markToKeep(article,$,url){var tags=arguments.length>3&&arguments[3]!==undefined?arguments[3]:[];if(tags.length===0){tags=KEEP_SELECTORS;}if(url){var _URL$parse=URL$$.parse(url);var protocol=_URL$parse.protocol;var hostname=_URL$parse.hostname;tags=[].concat(_toConsumableArray(tags),['iframe[src^="'+protocol+'//'+hostname+'"]']);}$(tags.join(','),article).addClass(KEEP_CLASS);return $;}function stripJunkTags(article,$){var tags=arguments.length>2&&arguments[2]!==undefined?arguments[2]:[];if(tags.length===0){tags=STRIP_OUTPUT_TAGS;}// Remove matching elements, but ignore +// any element with a class of mercury-parser-keep +$(tags.join(','),article).not('.'+KEEP_CLASS).remove();// Remove the mercury-parser-keep class from result +$('.'+KEEP_CLASS,article).removeClass(KEEP_CLASS);return $;}// H1 tags are typically the article title, which should be extracted // by the title extractor instead. If there's less than 3 of them (<3), // strip them. Otherwise, turn 'em into H2s. -function cleanHOnes(article,$){var $hOnes=$('h1',article);if($hOnes.length<3){$hOnes.each(function(index,node){return $(node).remove();});}else{$hOnes.each(function(index,node){convertNodeTo($(node),$,'h2');});}return $;}function removeAllButWhitelist($article){// $('*', article).each((index, node) => { -$article.find('*').each(function(index,node){node.attribs=_Reflect$ownKeys$$(node.attribs).reduce(function(acc,attr){if(WHITELIST_ATTRS_RE.test(attr)){return _extends$$({},acc,_defineProperty({},attr,node.attribs[attr]));}return acc;},{});});}// function removeAttrs(article, $) { +function cleanHOnes(article,$){var $hOnes=$('h1',article);if($hOnes.length<3){$hOnes.each(function(index,node){return $(node).remove();});}else{$hOnes.each(function(index,node){convertNodeTo($(node),$,'h2');});}return $;}function removeAllButWhitelist($article){$article.find('*').each(function(index,node){node.attribs=_Reflect$ownKeys(node.attribs).reduce(function(acc,attr){if(WHITELIST_ATTRS_RE.test(attr)){return _extends$$({},acc,_defineProperty({},attr,node.attribs[attr]));}return acc;},{});});return $article;}// function removeAttrs(article, $) { // REMOVE_ATTRS.forEach((attr) => { // $(`[${attr}]`, article).removeAttr(attr); // }); // } // Remove attributes like style or align -function cleanAttributes($article){removeAllButWhitelist($article);return $article;}function removeEmpty($article,$){$article.find('p').each(function(index,p){var $p=$(p);if($p.text().trim()==='')$p.remove();});return $;}// // CONTENT FETCHING CONSTANTS //// +function cleanAttributes($article){// Grabbing the parent because at this point +// $article will be wrapped in a div which will +// have a score set on it. +return removeAllButWhitelist($article.parent().length?$article.parent():$article);}function removeEmpty($article,$){$article.find('p').each(function(index,p){var $p=$(p);if($p.find('iframe, img').length===0&&$p.text().trim()==='')$p.remove();});return $;}// // CONTENT FETCHING CONSTANTS //// // A list of strings that can be considered unlikely candidates when // extracting content from a resource. These strings are joined together // and then tested for existence using re:test, so may contain simple, @@ -397,7 +607,7 @@ addScoreTo($parent.parent(),$,rawScore/2,weightNodes);}});return $;}// score con // content score, grandparents half function scoreContent($){var weightNodes=arguments.length>1&&arguments[1]!==undefined?arguments[1]:true;// First, look for special hNews based selectors and give them a big // boost, if they exist -HNEWS_CONTENT_SELECTORS$1.forEach(function(_ref){var _ref2=_slicedToArray$$(_ref,2);var parentSelector=_ref2[0];var childSelector=_ref2[1];$(parentSelector+' '+childSelector).each(function(index,node){addScore($(node).parent(parentSelector),$,80);});});// Doubling this again +HNEWS_CONTENT_SELECTORS$1.forEach(function(_ref){var _ref2=_slicedToArray(_ref,2);var parentSelector=_ref2[0];var childSelector=_ref2[1];$(parentSelector+' '+childSelector).each(function(index,node){addScore($(node).parent(parentSelector),$,80);});});// Doubling this again // Previous solution caused a bug // in which parents weren't retaining // scores. This is not ideal, and @@ -435,7 +645,7 @@ if(index<2&&segment.length<3&&!firstSegmentHasLetters){goodSegment=false;}return // pagination data exists in it. Useful for comparing to other links // that might have pagination data within them. function articleBaseUrl(url,parsed){var parsedUrl=parsed||URL$$.parse(url);var protocol=parsedUrl.protocol;var host=parsedUrl.host;var path=parsedUrl.path;var firstSegmentHasLetters=false;var cleanedSegments=path.split('/').reverse().reduce(function(acc,rawSegment,index){var segment=rawSegment;// Split off and save anything that looks like a file type. -if(segment.includes('.')){var _segment$split=segment.split('.');var _segment$split2=_slicedToArray$$(_segment$split,2);var possibleSegment=_segment$split2[0];var fileExt=_segment$split2[1];if(IS_ALPHA_RE.test(fileExt)){segment=possibleSegment;}}// If our first or second segment has anything looking like a page +if(segment.includes('.')){var _segment$split=segment.split('.');var _segment$split2=_slicedToArray(_segment$split,2);var possibleSegment=_segment$split2[0];var fileExt=_segment$split2[1];if(IS_ALPHA_RE.test(fileExt)){segment=possibleSegment;}}// If our first or second segment has anything looking like a page // number, remove it. if(PAGE_IN_HREF_RE.test(segment)&&index<2){segment=segment.replace(PAGE_IN_HREF_RE,'');}// If we're on the first segment, check to see if we have any // characters in it. The first segment is actually the last bit of @@ -512,14 +722,14 @@ var values=nodes.map(function(index,node){return $(node).attr(value);}).toArray( // also. if(values.length===1){var metaValue=void 0;// Meta values that contain HTML should be stripped, as they // weren't subject to cleaning previously. -if(cleanTags){metaValue=stripTags(values[0],$);}else{metaValue=values[0];}return{v:metaValue};}};for(var _iterator=_getIterator$$(foundNames),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var _ret=_loop();if((typeof _ret==='undefined'?'undefined':_typeof$$(_ret))==="object")return _ret.v;}// If nothing is found, return null +if(cleanTags){metaValue=stripTags(values[0],$);}else{metaValue=values[0];}return{v:metaValue};}};for(var _iterator=_getIterator(foundNames),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var _ret=_loop();if((typeof _ret==='undefined'?'undefined':_typeof$$(_ret))==="object")return _ret.v;}// If nothing is found, return null }catch(err){_didIteratorError=true;_iteratorError=err;}finally{try{if(!_iteratorNormalCompletion&&_iterator.return){_iterator.return();}}finally{if(_didIteratorError){throw _iteratorError;}}}return null;}function isGoodNode($node,maxChildren){// If it has a number of children, it's more likely a container // element. Skip it. if($node.children().length>maxChildren){return false;}// If it looks to be within a comment, skip it. if(withinComment($node)){return false;}return true;}// Given a a list of selectors find content that may // be extractable from the document. This is for flat // meta-information, like author, title, date published, etc. -function extractFromSelectors($,selectors){var maxChildren=arguments.length>2&&arguments[2]!==undefined?arguments[2]:1;var textOnly=arguments.length>3&&arguments[3]!==undefined?arguments[3]:true;var _iteratorNormalCompletion=true;var _didIteratorError=false;var _iteratorError=undefined;try{for(var _iterator=_getIterator$$(selectors),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var selector=_step.value;var nodes=$(selector);// If we didn't get exactly one of this selector, this may be +function extractFromSelectors($,selectors){var maxChildren=arguments.length>2&&arguments[2]!==undefined?arguments[2]:1;var textOnly=arguments.length>3&&arguments[3]!==undefined?arguments[3]:true;var _iteratorNormalCompletion=true;var _didIteratorError=false;var _iteratorError=undefined;try{for(var _iterator=_getIterator(selectors),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var selector=_step.value;var nodes=$(selector);// If we didn't get exactly one of this selector, this may be // a list of articles or comments. Skip it. if(nodes.length===1){var $node=$(nodes[0]);if(isGoodNode($node,maxChildren)){var content=void 0;if(textOnly){content=$node.text();}else{content=$node.html();}if(content){return content;}}}}}catch(err){_didIteratorError=true;_iteratorError=err;}finally{try{if(!_iteratorNormalCompletion&&_iterator.return){_iterator.return();}}finally{if(_didIteratorError){throw _iteratorError;}}}return null;}// strips all tags from a string of text function stripTags(text,$){// Wrapping text in html element prevents errors when text @@ -554,20 +764,23 @@ function extractCleanNode(article,_ref){var $=_ref.$;var _ref$cleanConditional=_ rewriteTopLevel(article,$);// Drop small images and spacer images // Only do this is defaultCleaner is set to true; // this can sometimes be too aggressive. -if(defaultCleaner)cleanImages(article,$);// Drop certain tags like , etc +if(defaultCleaner)cleanImages(article,$);// Mark elements to keep that would normally be removed. +// E.g., stripJunkTags will remove iframes, so we're going to mark +// YouTube/Vimeo videos as elements we want to keep. +markToKeep(article,$,url);// Drop certain tags like <title>, etc // This is -mostly- for cleanliness, not security. stripJunkTags(article,$);// H1 tags are typically the article title, which should be extracted // by the title extractor instead. If there's less than 3 of them (<3), // strip them. Otherwise, turn 'em into H2s. cleanHOnes(article,$);// Clean headers cleanHeaders(article,$,title);// Make links absolute -makeLinksAbsolute(article,$,url);// Remove unnecessary attributes -cleanAttributes(article);// We used to clean UL's and OL's here, but it was leading to +makeLinksAbsolute(article,$,url);// We used to clean UL's and OL's here, but it was leading to // too many in-article lists being removed. Consider a better // way to detect menus particularly and remove them. // Also optionally running, since it can be overly aggressive. if(defaultCleaner)cleanTags(article,$,cleanConditionally);// Remove empty paragraph nodes -removeEmpty(article,$);return article;}function cleanTitle(title,_ref){var url=_ref.url;var $=_ref.$;// If title has |, :, or - in it, see if +removeEmpty(article,$);// Remove unnecessary attributes +cleanAttributes(article,$);return article;}function cleanTitle(title,_ref){var url=_ref.url;var $=_ref.$;// If title has |, :, or - in it, see if // we can clean it up. if(TITLE_SPLITTERS_RE.test(title)){title=resolveSplitTitle(title,url);}// Final sanity check that we didn't get a crazy title. // if (title.length > 150 || title.length < 15) { @@ -579,7 +792,7 @@ return stripTags(title,$).trim();}function extractBreadcrumbTitle(splitTitle,tex if(splitTitle.length>=6){var _ret=function(){// Look to see if we can find a breadcrumb splitter that happens // more than once. If we can, we'll be able to better pull out // the title. -var termCounts=splitTitle.reduce(function(acc,titleText){acc[titleText]=acc[titleText]?acc[titleText]+1:1;return acc;},{});var _Reflect$ownKeys$redu=_Reflect$ownKeys$$(termCounts).reduce(function(acc,key){if(acc[1]<termCounts[key]){return[key,termCounts[key]];}return acc;},[0,0]);var _Reflect$ownKeys$redu2=_slicedToArray$$(_Reflect$ownKeys$redu,2);var maxTerm=_Reflect$ownKeys$redu2[0];var termCount=_Reflect$ownKeys$redu2[1];// We found a splitter that was used more than once, so it +var termCounts=splitTitle.reduce(function(acc,titleText){acc[titleText]=acc[titleText]?acc[titleText]+1:1;return acc;},{});var _Reflect$ownKeys$redu=_Reflect$ownKeys(termCounts).reduce(function(acc,key){if(acc[1]<termCounts[key]){return[key,termCounts[key]];}return acc;},[0,0]);var _Reflect$ownKeys$redu2=_slicedToArray(_Reflect$ownKeys$redu,2);var maxTerm=_Reflect$ownKeys$redu2[0];var termCount=_Reflect$ownKeys$redu2[1];// We found a splitter that was used more than once, so it // is probably the breadcrumber. Split our title on that instead. // Note: max_term should be <= 4 characters, so that " >> " // will match, but nothing longer than that. @@ -633,7 +846,7 @@ extract:function extract(_ref,opts){var $=_ref.$;var html=_ref.html;var title=_r // turning them off as we try to extract content. var node=this.getContentNode($,title,url,opts);if(nodeIsSufficient(node)){return this.cleanAndReturnNode(node,$);}// We didn't succeed on first pass, one by one disable our // extraction opts and try again. -var _iteratorNormalCompletion=true;var _didIteratorError=false;var _iteratorError=undefined;try{for(var _iterator=_getIterator$$(_Reflect$ownKeys$$(opts).filter(function(k){return opts[k]===true;})),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var key=_step.value;opts[key]=false;$=cheerio$$.load(html);node=this.getContentNode($,title,url,opts);if(nodeIsSufficient(node)){break;}}}catch(err){_didIteratorError=true;_iteratorError=err;}finally{try{if(!_iteratorNormalCompletion&&_iterator.return){_iterator.return();}}finally{if(_didIteratorError){throw _iteratorError;}}}return this.cleanAndReturnNode(node,$);},// Get node given current options +var _iteratorNormalCompletion=true;var _didIteratorError=false;var _iteratorError=undefined;try{for(var _iterator=_getIterator(_Reflect$ownKeys(opts).filter(function(k){return opts[k]===true;})),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var key=_step.value;opts[key]=false;$=cheerio$$.load(html);node=this.getContentNode($,title,url,opts);if(nodeIsSufficient(node)){break;}}}catch(err){_didIteratorError=true;_iteratorError=err;}finally{try{if(!_iteratorNormalCompletion&&_iterator.return){_iterator.return();}}finally{if(_didIteratorError){throw _iteratorError;}}}return this.cleanAndReturnNode(node,$);},// Get node given current options getContentNode:function getContentNode($,title,url,opts){return extractCleanNode(extractBestNode($,opts),{$:$,cleanConditionally:opts.cleanConditionally,title:title,url:url});},// Once we got here, either we're at our last-resort node, or // we broke early. Make sure we at least have -something- before we // move forward. @@ -683,7 +896,7 @@ var bylineRe=/^[\n\s]*By/i;var BYLINE_SELECTORS_RE=[['#byline',bylineRe],['.byli author=extractFromMeta($,AUTHOR_META_TAGS,metaCache);if(author&&author.length<AUTHOR_MAX_LENGTH){return cleanAuthor(author);}// Second, look through our selectors looking for potential authors. author=extractFromSelectors($,AUTHOR_SELECTORS,2);if(author&&author.length<AUTHOR_MAX_LENGTH){return cleanAuthor(author);}// Last, use our looser regular-expression based selectors for // potential authors. -var _iteratorNormalCompletion=true;var _didIteratorError=false;var _iteratorError=undefined;try{for(var _iterator=_getIterator$$(BYLINE_SELECTORS_RE),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var _ref4=_step.value;var _ref3=_slicedToArray$$(_ref4,2);var selector=_ref3[0];var regex=_ref3[1];var node=$(selector);if(node.length===1){var text=node.text();if(regex.test(text)){return cleanAuthor(text);}}}}catch(err){_didIteratorError=true;_iteratorError=err;}finally{try{if(!_iteratorNormalCompletion&&_iterator.return){_iterator.return();}}finally{if(_didIteratorError){throw _iteratorError;}}}return null;}};// An ordered list of meta tag names that denote +var _iteratorNormalCompletion=true;var _didIteratorError=false;var _iteratorError=undefined;try{for(var _iterator=_getIterator(BYLINE_SELECTORS_RE),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var _ref4=_step.value;var _ref3=_slicedToArray(_ref4,2);var selector=_ref3[0];var regex=_ref3[1];var node=$(selector);if(node.length===1){var text=node.text();if(regex.test(text)){return cleanAuthor(text);}}}}catch(err){_didIteratorError=true;_iteratorError=err;}finally{try{if(!_iteratorNormalCompletion&&_iterator.return){_iterator.return();}}finally{if(_didIteratorError){throw _iteratorError;}}}return null;}};// An ordered list of meta tag names that denote // likely date published dates. All attributes // should be lowercase for faster case-insensitive matching. // From most distinct to least distinct. @@ -749,9 +962,9 @@ var GenericLeadImageUrlExtractor={extract:function extract(_ref){var $=_ref.$;va var imageUrl=extractFromMeta($,LEAD_IMAGE_URL_META_TAGS,metaCache,false);if(imageUrl){cleanUrl=clean$1(imageUrl);if(cleanUrl)return cleanUrl;}// Next, try to find the "best" image via the content. // We'd rather not have to fetch each image and check dimensions, // so try to do some analysis and determine them instead. -var imgs=$('img',content).toArray();var imgScores={};imgs.forEach(function(img,index){var $img=$(img);var src=$img.attr('src');if(!src)return;var score=scoreImageUrl(src);score+=scoreAttr($img);score+=scoreByParents($img);score+=scoreBySibling($img);score+=scoreByDimensions($img);score+=scoreByPosition(imgs,index);imgScores[src]=score;});var _Reflect$ownKeys$redu=_Reflect$ownKeys$$(imgScores).reduce(function(acc,key){return imgScores[key]>acc[1]?[key,imgScores[key]]:acc;},[null,0]);var _Reflect$ownKeys$redu2=_slicedToArray$$(_Reflect$ownKeys$redu,2);var topUrl=_Reflect$ownKeys$redu2[0];var topScore=_Reflect$ownKeys$redu2[1];if(topScore>0){cleanUrl=clean$1(topUrl);if(cleanUrl)return cleanUrl;}// If nothing else worked, check to see if there are any really +var imgs=$('img',content).toArray();var imgScores={};imgs.forEach(function(img,index){var $img=$(img);var src=$img.attr('src');if(!src)return;var score=scoreImageUrl(src);score+=scoreAttr($img);score+=scoreByParents($img);score+=scoreBySibling($img);score+=scoreByDimensions($img);score+=scoreByPosition(imgs,index);imgScores[src]=score;});var _Reflect$ownKeys$redu=_Reflect$ownKeys(imgScores).reduce(function(acc,key){return imgScores[key]>acc[1]?[key,imgScores[key]]:acc;},[null,0]);var _Reflect$ownKeys$redu2=_slicedToArray(_Reflect$ownKeys$redu,2);var topUrl=_Reflect$ownKeys$redu2[0];var topScore=_Reflect$ownKeys$redu2[1];if(topScore>0){cleanUrl=clean$1(topUrl);if(cleanUrl)return cleanUrl;}// If nothing else worked, check to see if there are any really // probable nodes in the doc, like <link rel="image_src" />. -var _iteratorNormalCompletion=true;var _didIteratorError=false;var _iteratorError=undefined;try{for(var _iterator=_getIterator$$(LEAD_IMAGE_URL_SELECTORS),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var selector=_step.value;var $node=$(selector).first();var src=$node.attr('src');if(src){cleanUrl=clean$1(src);if(cleanUrl)return cleanUrl;}var href=$node.attr('href');if(href){cleanUrl=clean$1(href);if(cleanUrl)return cleanUrl;}var value=$node.attr('value');if(value){cleanUrl=clean$1(value);if(cleanUrl)return cleanUrl;}}}catch(err){_didIteratorError=true;_iteratorError=err;}finally{try{if(!_iteratorNormalCompletion&&_iterator.return){_iterator.return();}}finally{if(_didIteratorError){throw _iteratorError;}}}return null;}};function scoreSimilarity(score,articleUrl,href){// Do this last and only if we have a real candidate, because it's +var _iteratorNormalCompletion=true;var _didIteratorError=false;var _iteratorError=undefined;try{for(var _iterator=_getIterator(LEAD_IMAGE_URL_SELECTORS),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var selector=_step.value;var $node=$(selector).first();var src=$node.attr('src');if(src){cleanUrl=clean$1(src);if(cleanUrl)return cleanUrl;}var href=$node.attr('href');if(href){cleanUrl=clean$1(href);if(cleanUrl)return cleanUrl;}var value=$node.attr('value');if(value){cleanUrl=clean$1(value);if(cleanUrl)return cleanUrl;}}}catch(err){_didIteratorError=true;_iteratorError=err;}finally{try{if(!_iteratorNormalCompletion&&_iterator.return){_iterator.return();}}finally{if(_didIteratorError){throw _iteratorError;}}}return null;}};function scoreSimilarity(score,articleUrl,href){// Do this last and only if we have a real candidate, because it's // potentially expensive computationally. Compare the link to this // URL using difflib to get the % similarity of these URLs. On a // sliding scale, subtract points from this link based on @@ -825,21 +1038,21 @@ var scoredPages=links.reduce(function(possiblePages,link){// Remove any anchor d // standardizing URLs (it's hard), we're going to do // some checking with and without a trailing slash var href=removeAnchor(link.attribs.href);var $link=$(link);var linkText=$link.text();if(!shouldScore(href,articleUrl,baseUrl,parsedUrl,linkText,previousUrls)){return possiblePages;}// ## PASSED THE FIRST-PASS TESTS. Start scoring. ## -if(!possiblePages[href]){possiblePages[href]={score:0,linkText:linkText,href:href};}else{possiblePages[href].linkText=possiblePages[href].linkText+'|'+linkText;}var possiblePage=possiblePages[href];var linkData=makeSig($link,linkText);var pageNum=pageNumFromUrl(href);var score=scoreBaseUrl(href,baseRegex);score+=scoreNextLinkText(linkData);score+=scoreCapLinks(linkData);score+=scorePrevLink(linkData);score+=scoreByParents$1($link);score+=scoreExtraneousLinks(href);score+=scorePageInLink(pageNum,isWp);score+=scoreLinkText(linkText,pageNum);score+=scoreSimilarity(score,articleUrl,href);possiblePage.score=score;return possiblePages;},{});return _Reflect$ownKeys$$(scoredPages).length===0?null:scoredPages;}// Looks for and returns next page url +if(!possiblePages[href]){possiblePages[href]={score:0,linkText:linkText,href:href};}else{possiblePages[href].linkText=possiblePages[href].linkText+'|'+linkText;}var possiblePage=possiblePages[href];var linkData=makeSig($link,linkText);var pageNum=pageNumFromUrl(href);var score=scoreBaseUrl(href,baseRegex);score+=scoreNextLinkText(linkData);score+=scoreCapLinks(linkData);score+=scorePrevLink(linkData);score+=scoreByParents$1($link);score+=scoreExtraneousLinks(href);score+=scorePageInLink(pageNum,isWp);score+=scoreLinkText(linkText,pageNum);score+=scoreSimilarity(score,articleUrl,href);possiblePage.score=score;return possiblePages;},{});return _Reflect$ownKeys(scoredPages).length===0?null:scoredPages;}// Looks for and returns next page url // for multi-page articles var GenericNextPageUrlExtractor={extract:function extract(_ref){var $=_ref.$;var url=_ref.url;var parsedUrl=_ref.parsedUrl;var _ref$previousUrls=_ref.previousUrls;var previousUrls=_ref$previousUrls===undefined?[]:_ref$previousUrls;parsedUrl=parsedUrl||URL$$.parse(url);var articleUrl=removeAnchor(url);var baseUrl=articleBaseUrl(url,parsedUrl);var links=$('a[href]').toArray();var scoredLinks=scoreLinks({links:links,articleUrl:articleUrl,baseUrl:baseUrl,parsedUrl:parsedUrl,$:$,previousUrls:previousUrls});// If no links were scored, return null if(!scoredLinks)return null;// now that we've scored all possible pages, // find the biggest one. -var topPage=_Reflect$ownKeys$$(scoredLinks).reduce(function(acc,link){var scoredLink=scoredLinks[link];return scoredLink.score>acc.score?scoredLink:acc;},{score:-100});// If the score is less than 50, we're not confident enough to use it, +var topPage=_Reflect$ownKeys(scoredLinks).reduce(function(acc,link){var scoredLink=scoredLinks[link];return scoredLink.score>acc.score?scoredLink:acc;},{score:-100});// If the score is less than 50, we're not confident enough to use it, // so we fail. if(topPage.score>=50){return topPage.href;}return null;}};var CANONICAL_META_SELECTORS=['og:url'];function parseDomain(url){var parsedUrl=URL$$.parse(url);var hostname=parsedUrl.hostname;return hostname;}function result(url){return{url:url,domain:parseDomain(url)};}var GenericUrlExtractor={extract:function extract(_ref){var $=_ref.$;var url=_ref.url;var metaCache=_ref.metaCache;var $canonical=$('link[rel=canonical]');if($canonical.length!==0){var href=$canonical.attr('href');if(href){return result(href);}}var metaUrl=extractFromMeta($,CANONICAL_META_SELECTORS,metaCache);if(metaUrl){return result(metaUrl);}return result(url);}};var EXCERPT_META_SELECTORS=['og:description','twitter:description'];function clean$2(content,$){var maxLength=arguments.length>2&&arguments[2]!==undefined?arguments[2]:200;content=content.replace(/[\s\n]+/g,' ').trim();return ellipsize$$(content,maxLength,{ellipse:'…'});}var GenericExcerptExtractor={extract:function extract(_ref){var $=_ref.$;var content=_ref.content;var metaCache=_ref.metaCache;var excerpt=extractFromMeta($,EXCERPT_META_SELECTORS,metaCache);if(excerpt){return clean$2(stripTags(excerpt,$));}// Fall back to excerpting from the extracted content var maxLength=200;var shortContent=content.slice(0,maxLength*5);return clean$2($(shortContent).text(),$,maxLength);}};var GenericWordCountExtractor={extract:function extract(_ref){var content=_ref.content;var $=cheerio$$.load(content);var text=normalizeSpaces($('div').first().text());return text.split(/\s/).length;}};var GenericExtractor={// This extractor is the default for all domains domain:'*',title:GenericTitleExtractor.extract,date_published:GenericDatePublishedExtractor.extract,author:GenericAuthorExtractor.extract,content:GenericContentExtractor.extract.bind(GenericContentExtractor),lead_image_url:GenericLeadImageUrlExtractor.extract,dek:GenericDekExtractor.extract,next_page_url:GenericNextPageUrlExtractor.extract,url_and_domain:GenericUrlExtractor.extract,excerpt:GenericExcerptExtractor.extract,word_count:GenericWordCountExtractor.extract,direction:function direction(_ref){var title=_ref.title;return stringDirection$$.getDirection(title);},extract:function extract(options){var html=options.html;if(html){var $=cheerio$$.load(html);options.$=$;}var title=this.title(options);var date_published=this.date_published(options);var author=this.author(options);var content=this.content(_extends$$({},options,{title:title}));var lead_image_url=this.lead_image_url(_extends$$({},options,{content:content}));var dek=this.dek(_extends$$({},options,{content:content}));var next_page_url=this.next_page_url(options);var excerpt=this.excerpt(_extends$$({},options,{content:content}));var word_count=this.word_count(_extends$$({},options,{content:content}));var direction=this.direction({title:title});var _url_and_domain=this.url_and_domain(options);var url=_url_and_domain.url;var domain=_url_and_domain.domain;return{title:title,author:author,date_published:date_published||null,dek:dek,lead_image_url:lead_image_url,content:content,next_page_url:next_page_url,url:url,domain:domain,excerpt:excerpt,word_count:word_count,direction:direction};}};function getExtractor(url,parsedUrl){parsedUrl=parsedUrl||URL$$.parse(url);var _parsedUrl=parsedUrl;var hostname=_parsedUrl.hostname;var baseDomain=hostname.split('.').slice(-2).join('.');return Extractors[hostname]||Extractors[baseDomain]||GenericExtractor;}// Remove elements by an array of selectors function cleanBySelectors($content,$,_ref){var clean=_ref.clean;if(!clean)return $content;$(clean.join(','),$content).remove();return $content;}// Transform matching elements -function transformElements($content,$,_ref2){var transforms=_ref2.transforms;if(!transforms)return $content;_Reflect$ownKeys$$(transforms).forEach(function(key){var $matches=$(key,$content);var value=transforms[key];// If value is a string, convert directly +function transformElements($content,$,_ref2){var transforms=_ref2.transforms;if(!transforms)return $content;_Reflect$ownKeys(transforms).forEach(function(key){var $matches=$(key,$content);var value=transforms[key];// If value is a string, convert directly if(typeof value==='string'){$matches.each(function(index,node){convertNodeTo($(node),$,transforms[key]);});}else if(typeof value==='function'){// If value is function, apply function to node $matches.each(function(index,node){var result=value($(node),$);// If function returns a string, convert node to that value -if(typeof result==='string'){convertNodeTo($(node),$,result);}});}});return $content;}function findMatchingSelector($,selectors){return selectors.find(function(selector){if(Array.isArray(selector)){var _selector=_slicedToArray$$(selector,2);var s=_selector[0];var attr=_selector[1];return $(s).length===1&&$(s).attr(attr)&&$(s).attr(attr).trim()!=='';}return $(selector).length===1&&$(selector).text().trim()!=='';});}function select(opts){var $=opts.$;var type=opts.type;var extractionOpts=opts.extractionOpts;var _opts$extractHtml=opts.extractHtml;var extractHtml=_opts$extractHtml===undefined?false:_opts$extractHtml;// Skip if there's not extraction for this type +if(typeof result==='string'){convertNodeTo($(node),$,result);}});}});return $content;}function findMatchingSelector($,selectors){return selectors.find(function(selector){if(Array.isArray(selector)){var _selector=_slicedToArray(selector,2);var s=_selector[0];var attr=_selector[1];return $(s).length===1&&$(s).attr(attr)&&$(s).attr(attr).trim()!=='';}return $(selector).length===1&&$(selector).text().trim()!=='';});}function select(opts){var $=opts.$;var type=opts.type;var extractionOpts=opts.extractionOpts;var _opts$extractHtml=opts.extractHtml;var extractHtml=_opts$extractHtml===undefined?false:_opts$extractHtml;// Skip if there's not extraction for this type if(!extractionOpts)return null;// If a string is hardcoded for a type (e.g., Wikipedia // contributors), return the string if(typeof extractionOpts==='string')return extractionOpts;var selectors=extractionOpts.selectors;var _extractionOpts$defau=extractionOpts.defaultCleaner;var defaultCleaner=_extractionOpts$defau===undefined?true:_extractionOpts$defau;var matchingSelector=findMatchingSelector($,selectors);if(!matchingSelector)return null;// Declaring result; will contain either @@ -850,7 +1063,7 @@ if(typeof extractionOpts==='string')return extractionOpts;var selectors=extracti if(extractHtml){var $content=$(matchingSelector);// Wrap in div so transformation can take place on root element $content.wrap($('<div></div>'));$content=$content.parent();$content=transformElements($content,$,extractionOpts);$content=cleanBySelectors($content,$,extractionOpts);$content=Cleaners[type]($content,_extends$$({},opts,{defaultCleaner:defaultCleaner}));return $.html($content);}var result=void 0;// if selector is an array (e.g., ['img', 'src']), // extract the attr -if(Array.isArray(matchingSelector)){var _matchingSelector=_slicedToArray$$(matchingSelector,2);var selector=_matchingSelector[0];var attr=_matchingSelector[1];result=$(selector).attr(attr).trim();}else{result=$(matchingSelector).text().trim();}// Allow custom extractor to skip default cleaner +if(Array.isArray(matchingSelector)){var _matchingSelector=_slicedToArray(matchingSelector,2);var selector=_matchingSelector[0];var attr=_matchingSelector[1];result=$(selector).attr(attr).trim();}else{result=$(matchingSelector).text().trim();}// Allow custom extractor to skip default cleaner // for this type; defaults to true if(defaultCleaner){return Cleaners[type](result,opts);}return result;}function extractResult(opts){var type=opts.type;var extractor=opts.extractor;var _opts$fallback=opts.fallback;var fallback=_opts$fallback===undefined?true:_opts$fallback;var result=select(_extends$$({},opts,{extractionOpts:extractor[type]}));// If custom parser succeeds, return the result if(result){return result;}// If nothing matches the selector, and fallback is enabled, @@ -867,6 +1080,10 @@ if(!(fetchAllPages&&next_page_url)){_context.next=25;break;}_context.next=22;ret // to work with, e.g., for custom extractor generator fetchResource:function fetchResource(url){var _this2=this;return _asyncToGenerator(_regeneratorRuntime.mark(function _callee2(){return _regeneratorRuntime.wrap(function _callee2$(_context2){while(1){switch(_context2.prev=_context2.next){case 0:_context2.next=2;return Resource.create(url);case 2:return _context2.abrupt('return',_context2.sent);case 3:case'end':return _context2.stop();}}},_callee2,_this2);}))();}};module.exports=Mercury;}); +// The class we will use to mark elements we want to keep +// but would normally remove +var KEEP_CLASS = 'mercury-parser-keep'; + // A list of tags to strip from the output if we encounter them. var STRIP_OUTPUT_TAGS = ['title', 'script', 'noscript', 'link', 'style', 'hr', 'embed', 'iframe', 'object']; @@ -876,7 +1093,7 @@ var REMOVE_ATTR_SELECTORS = REMOVE_ATTRS.map(function (selector) { return '[' + selector + ']'; }); var REMOVE_ATTR_LIST = REMOVE_ATTRS.join(','); -var WHITELIST_ATTRS = ['src', 'srcset', 'href', 'class', 'id', 'alt', 'score']; +var WHITELIST_ATTRS = ['src', 'srcset', 'href', 'class', 'id', 'alt']; var WHITELIST_ATTRS_RE = new RegExp('^(' + WHITELIST_ATTRS.join('|') + ')$', 'i'); // removeEmpty @@ -980,7 +1197,12 @@ function stripJunkTags(article, $) { tags = STRIP_OUTPUT_TAGS; } - $(tags.join(','), article).remove(); + // Remove matching elements, but ignore + // any element with a class of mercury-parser-keep + $(tags.join(','), article).not('.' + KEEP_CLASS).remove(); + + // Remove the mercury-parser-keep class from result + $('.' + KEEP_CLASS, article).removeClass(KEEP_CLASS); return $; } @@ -1110,7 +1332,7 @@ function template(strings) { var _ref = compiled.match(bodyPattern) || []; - var _ref2 = _slicedToArray(_ref, 1); + var _ref2 = slicedToArray$1(_ref, 1); var body = _ref2[0]; @@ -1132,14 +1354,14 @@ function template(strings) { }).join('\n'); } -var _templateObject = _taggedTemplateLiteral(['\n // Rename CustomExtractor\n // to fit your publication\n // (e.g., NYTimesExtractor)\n export const CustomExtractor = {\n domain: \'', '\',\n title: {\n selectors: [\n // enter title selectors\n ],\n },\n\n author: {\n selectors: [\n // enter author selectors\n ],\n },\n\n content: {\n selectors: [\n // enter content selectors\n ],\n\n // Is there anything in the content you selected that needs transformed\n // before it\'s consumable content? E.g., unusual lazy loaded images\n transforms: {\n },\n\n // Is there anything that is in the result that shouldn\'t be?\n // The clean selectors will remove anything that matches from\n // the result\n clean: [\n\n ]\n },\n\n date_published: {\n selectors: [\n // enter selectors\n ],\n },\n\n lead_image_url: {\n selectors: [\n // enter selectors\n ],\n },\n\n dek: {\n selectors: [\n // enter selectors\n ],\n },\n\n next_page_url: {\n selectors: [\n // enter selectors\n ],\n },\n\n excerpt: {\n selectors: [\n // enter selectors\n ],\n },\n }\n '], ['\n // Rename CustomExtractor\n // to fit your publication\n // (e.g., NYTimesExtractor)\n export const CustomExtractor = {\n domain: \'', '\',\n title: {\n selectors: [\n // enter title selectors\n ],\n },\n\n author: {\n selectors: [\n // enter author selectors\n ],\n },\n\n content: {\n selectors: [\n // enter content selectors\n ],\n\n // Is there anything in the content you selected that needs transformed\n // before it\'s consumable content? E.g., unusual lazy loaded images\n transforms: {\n },\n\n // Is there anything that is in the result that shouldn\'t be?\n // The clean selectors will remove anything that matches from\n // the result\n clean: [\n\n ]\n },\n\n date_published: {\n selectors: [\n // enter selectors\n ],\n },\n\n lead_image_url: {\n selectors: [\n // enter selectors\n ],\n },\n\n dek: {\n selectors: [\n // enter selectors\n ],\n },\n\n next_page_url: {\n selectors: [\n // enter selectors\n ],\n },\n\n excerpt: {\n selectors: [\n // enter selectors\n ],\n },\n }\n ']); +var _templateObject = taggedTemplateLiteral(['\n // Rename CustomExtractor\n // to fit your publication\n // (e.g., NYTimesExtractor)\n export const CustomExtractor = {\n domain: \'', '\',\n\n title: {\n selectors: [\n // enter title selectors\n ],\n },\n\n author: {\n selectors: [\n // enter author selectors\n ],\n },\n\n date_published: {\n selectors: [\n // enter selectors\n ],\n },\n\n dek: {\n selectors: [\n // enter selectors\n ],\n },\n\n lead_image_url: {\n selectors: [\n // enter selectors\n ],\n },\n\n content: {\n selectors: [\n // enter content selectors\n ],\n\n // Is there anything in the content you selected that needs transformed\n // before it\'s consumable content? E.g., unusual lazy loaded images\n transforms: {\n },\n\n // Is there anything that is in the result that shouldn\'t be?\n // The clean selectors will remove anything that matches from\n // the result\n clean: [\n\n ]\n },\n }\n '], ['\n // Rename CustomExtractor\n // to fit your publication\n // (e.g., NYTimesExtractor)\n export const CustomExtractor = {\n domain: \'', '\',\n\n title: {\n selectors: [\n // enter title selectors\n ],\n },\n\n author: {\n selectors: [\n // enter author selectors\n ],\n },\n\n date_published: {\n selectors: [\n // enter selectors\n ],\n },\n\n dek: {\n selectors: [\n // enter selectors\n ],\n },\n\n lead_image_url: {\n selectors: [\n // enter selectors\n ],\n },\n\n content: {\n selectors: [\n // enter content selectors\n ],\n\n // Is there anything in the content you selected that needs transformed\n // before it\'s consumable content? E.g., unusual lazy loaded images\n transforms: {\n },\n\n // Is there anything that is in the result that shouldn\'t be?\n // The clean selectors will remove anything that matches from\n // the result\n clean: [\n\n ]\n },\n }\n ']); function extractorTemplate (hostname) { return template(_templateObject, hostname); } -var _templateObject$1 = _taggedTemplateLiteral(['\n it(\'returns the ', '\', async () => {\n // To pass this test, fill out the ', ' selector\n // in ', '/index.js.\n const html =\n fs.readFileSync(\'', '\');\n const articleUrl =\n \'', '\';\n\n const { ', ' } =\n await Mercury.parse(articleUrl, html, { fallback: false });\n\n // Update these values with the expected values from\n // the article.\n assert.equal(', ', ', ')\n });\n '], ['\n it(\'returns the ', '\', async () => {\n // To pass this test, fill out the ', ' selector\n // in ', '/index.js.\n const html =\n fs.readFileSync(\'', '\');\n const articleUrl =\n \'', '\';\n\n const { ', ' } =\n await Mercury.parse(articleUrl, html, { fallback: false });\n\n // Update these values with the expected values from\n // the article.\n assert.equal(', ', ', ')\n });\n ']); -var _templateObject2 = _taggedTemplateLiteral(['\n import assert from \'assert\';\n import fs from \'fs\';\n import URL from \'url\';\n import cheerio from \'cheerio\';\n\n import Mercury from \'mercury\';\n import getExtractor from \'extractors/get-extractor\';\n import { excerptContent } from \'utils/text\';\n\n // Rename CustomExtractor\n describe(\'CustomExtractor\', () => {\n it(\'is selected properly\', () => {\n // To pass this test, rename your extractor in\n // ', '/index.js\n // (e.g., CustomExtractor => NYTimesExtractor)\n // then add your new extractor to\n // src/extractors/all.js\n const url =\n \'', '\';\n const extractor = getExtractor(url);\n assert.equal(extractor.domain, URL.parse(url).hostname)\n })\n\n ', '\n\n it(\'returns the content\', async () => {\n // To pass this test, fill out the content selector\n // in ', '/index.js.\n // You may also want to make use of the clean and transform\n // options.\n const html =\n fs.readFileSync(\'', '\');\n const url =\n \'', '\';\n\n const { content } =\n await Mercury.parse(url, html, { fallback: false });\n\n const $ = cheerio.load(content || \'\');\n\n const first13 = excerptContent($(\'*\').first().text(), 13)\n\n // Update these values with the expected values from\n // the article.\n assert.equal(first13, null);\n });\n });\n '], ['\n import assert from \'assert\';\n import fs from \'fs\';\n import URL from \'url\';\n import cheerio from \'cheerio\';\n\n import Mercury from \'mercury\';\n import getExtractor from \'extractors/get-extractor\';\n import { excerptContent } from \'utils/text\';\n\n // Rename CustomExtractor\n describe(\'CustomExtractor\', () => {\n it(\'is selected properly\', () => {\n // To pass this test, rename your extractor in\n // ', '/index.js\n // (e.g., CustomExtractor => NYTimesExtractor)\n // then add your new extractor to\n // src/extractors/all.js\n const url =\n \'', '\';\n const extractor = getExtractor(url);\n assert.equal(extractor.domain, URL.parse(url).hostname)\n })\n\n ', '\n\n it(\'returns the content\', async () => {\n // To pass this test, fill out the content selector\n // in ', '/index.js.\n // You may also want to make use of the clean and transform\n // options.\n const html =\n fs.readFileSync(\'', '\');\n const url =\n \'', '\';\n\n const { content } =\n await Mercury.parse(url, html, { fallback: false });\n\n const $ = cheerio.load(content || \'\');\n\n const first13 = excerptContent($(\'*\').first().text(), 13)\n\n // Update these values with the expected values from\n // the article.\n assert.equal(first13, null);\n });\n });\n ']); +var _templateObject$1 = taggedTemplateLiteral(['\n it(\'returns the ', '\', async () => {\n // To pass this test, fill out the ', ' selector\n // in ', '/index.js.\n const html =\n fs.readFileSync(\'', '\');\n const articleUrl =\n \'', '\';\n\n const { ', ' } =\n await Mercury.parse(articleUrl, html, { fallback: false });\n\n // Update these values with the expected values from\n // the article.\n assert.equal(', ', ', ')\n });\n '], ['\n it(\'returns the ', '\', async () => {\n // To pass this test, fill out the ', ' selector\n // in ', '/index.js.\n const html =\n fs.readFileSync(\'', '\');\n const articleUrl =\n \'', '\';\n\n const { ', ' } =\n await Mercury.parse(articleUrl, html, { fallback: false });\n\n // Update these values with the expected values from\n // the article.\n assert.equal(', ', ', ')\n });\n ']); +var _templateObject2 = taggedTemplateLiteral(['\n import assert from \'assert\';\n import fs from \'fs\';\n import URL from \'url\';\n import cheerio from \'cheerio\';\n\n import Mercury from \'mercury\';\n import getExtractor from \'extractors/get-extractor\';\n import { excerptContent } from \'utils/text\';\n\n // Rename CustomExtractor\n // to fit your publication\n // (e.g., NYTimesExtractor)\n describe(\'CustomExtractor\', () => {\n it(\'is selected properly\', () => {\n // This test should be passing by default.\n // It sanity checks that the correct parser\n // is being selected for URLs from this domain\n const url =\n \'', '\';\n const extractor = getExtractor(url);\n assert.equal(extractor.domain, URL.parse(url).hostname)\n })\n\n ', '\n\n it(\'returns the content\', async () => {\n // To pass this test, fill out the content selector\n // in ', '/index.js.\n // You may also want to make use of the clean and transform\n // options.\n const html =\n fs.readFileSync(\'', '\');\n const url =\n \'', '\';\n\n const { content } =\n await Mercury.parse(url, html, { fallback: false });\n\n const $ = cheerio.load(content || \'\');\n\n const first13 = excerptContent($(\'*\').first().text(), 13)\n\n // Update these values with the expected values from\n // the article.\n assert.equal(first13, \'Add the first 13 words of the article here\');\n });\n });\n '], ['\n import assert from \'assert\';\n import fs from \'fs\';\n import URL from \'url\';\n import cheerio from \'cheerio\';\n\n import Mercury from \'mercury\';\n import getExtractor from \'extractors/get-extractor\';\n import { excerptContent } from \'utils/text\';\n\n // Rename CustomExtractor\n // to fit your publication\n // (e.g., NYTimesExtractor)\n describe(\'CustomExtractor\', () => {\n it(\'is selected properly\', () => {\n // This test should be passing by default.\n // It sanity checks that the correct parser\n // is being selected for URLs from this domain\n const url =\n \'', '\';\n const extractor = getExtractor(url);\n assert.equal(extractor.domain, URL.parse(url).hostname)\n })\n\n ', '\n\n it(\'returns the content\', async () => {\n // To pass this test, fill out the content selector\n // in ', '/index.js.\n // You may also want to make use of the clean and transform\n // options.\n const html =\n fs.readFileSync(\'', '\');\n const url =\n \'', '\';\n\n const { content } =\n await Mercury.parse(url, html, { fallback: false });\n\n const $ = cheerio.load(content || \'\');\n\n const first13 = excerptContent($(\'*\').first().text(), 13)\n\n // Update these values with the expected values from\n // the article.\n assert.equal(first13, \'Add the first 13 words of the article here\');\n });\n });\n ']); var IGNORE = ['url', 'domain', 'content', 'word_count', 'next_page_url', 'excerpt', 'direction', 'total_pages', 'rendered_pages']; function testFor(key, value, dir, file, url) { @@ -1147,11 +1369,11 @@ function testFor(key, value, dir, file, url) { return k === key; })) return ''; - return template(_templateObject$1, key, key, dir, file, url, key, key, value ? "'" + value + "'" : "''"); + return template(_templateObject$1, key, key, dir, file, url, key, key, value ? "`" + value + "`" : "''"); } function extractorTestTemplate (file, url, dir, result) { - return template(_templateObject2, dir, url, _Reflect$ownKeys(result).map(function (k) { + return template(_templateObject2, url, Reflect.ownKeys(result).map(function (k) { return testFor(k, result[k], dir, file, url); }).join('\n\n'), dir, file, url); } @@ -1193,7 +1415,7 @@ function confirm(fn, args, msg, newParser) { } function savePage($, _ref, newParser) { - var _ref2 = _slicedToArray(_ref, 1); + var _ref2 = slicedToArray$1(_ref, 1); var url = _ref2[0]; @@ -1239,6 +1461,15 @@ function generateScaffold(url, file, result) { fs.writeFileSync(getDir(url) + '/index.js', extractor); fs.writeFileSync(getDir(url) + '/index.test.js', extractorTest); + fs.appendFileSync('./src/extractors/custom/index.js', exportString(url)); +} + +function exportString(url) { + var _URL$parse4 = URL.parse(url); + + var hostname = _URL$parse4.hostname; + + return 'export * from \'./' + hostname + '\''; } function confirmCreateDir(dir, msg) { @@ -1250,9 +1481,9 @@ function confirmCreateDir(dir, msg) { function scaffoldCustomParser(url) { var dir = getDir(url); - var _URL$parse4 = URL.parse(url); + var _URL$parse5 = URL.parse(url); - var hostname = _URL$parse4.hostname; + var hostname = _URL$parse5.hostname; var newParser = false; @@ -1266,9 +1497,9 @@ function scaffoldCustomParser(url) { } function getDir(url) { - var _URL$parse5 = URL.parse(url); + var _URL$parse6 = URL.parse(url); - var hostname = _URL$parse5.hostname; + var hostname = _URL$parse6.hostname; return './src/extractors/custom/' + hostname; } diff --git a/dist/generate-custom-parser.js.map b/dist/generate-custom-parser.js.map index a3fc43c0..b38322b4 100644 --- a/dist/generate-custom-parser.js.map +++ b/dist/generate-custom-parser.js.map @@ -1 +1 @@ -{"version":3,"file":null,"sources":["mercury.js","../src/utils/dom/constants.js","../src/utils/dom/strip-junk-tags.js","../src/extractors/generic/content/scoring/constants.js","../src/utils/dom/make-links-absolute.js","../scripts/templates/insert-values.js","../scripts/templates/index.js","../scripts/templates/custom-extractor.js","../scripts/templates/custom-extractor-test.js","../scripts/generate-custom-parser.js"],"sourcesContent":["'use strict';\n\nfunction _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }\n\nvar _regeneratorRuntime = _interopDefault(require('babel-runtime/regenerator'));\nvar _extends = _interopDefault(require('babel-runtime/helpers/extends'));\nvar _asyncToGenerator = _interopDefault(require('babel-runtime/helpers/asyncToGenerator'));\nvar URL = _interopDefault(require('url'));\nvar cheerio = _interopDefault(require('cheerio'));\nvar _Promise = _interopDefault(require('babel-runtime/core-js/promise'));\nvar request = _interopDefault(require('request'));\nvar _Reflect$ownKeys = _interopDefault(require('babel-runtime/core-js/reflect/own-keys'));\nvar stringDirection = _interopDefault(require('string-direction'));\nvar _getIterator = _interopDefault(require('babel-runtime/core-js/get-iterator'));\nvar _defineProperty = _interopDefault(require('babel-runtime/helpers/defineProperty'));\nvar _slicedToArray = _interopDefault(require('babel-runtime/helpers/slicedToArray'));\nvar _typeof = _interopDefault(require('babel-runtime/helpers/typeof'));\nvar validUrl = _interopDefault(require('valid-url'));\nvar moment = _interopDefault(require('moment'));\nvar wuzzy = _interopDefault(require('wuzzy'));\nvar difflib = _interopDefault(require('difflib'));\nvar _Array$from = _interopDefault(require('babel-runtime/core-js/array/from'));\nvar ellipsize = _interopDefault(require('ellipsize'));\n\nvar _marked = [range].map(_regeneratorRuntime.mark);\n\nfunction range() {\n var start = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;\n var end = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;\n return _regeneratorRuntime.wrap(function range$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n if (!(start <= end)) {\n _context.next = 5;\n break;\n }\n\n _context.next = 3;\n return start += 1;\n\n case 3:\n _context.next = 0;\n break;\n\n case 5:\n case \"end\":\n return _context.stop();\n }\n }\n }, _marked[0], this);\n}\n\n// extremely simple url validation as a first step\nfunction validateUrl(_ref) {\n var hostname = _ref.hostname;\n\n // If this isn't a valid url, return an error message\n return !!hostname;\n}\n\nvar Errors = {\n badUrl: {\n error: true,\n messages: 'The url parameter passed does not look like a valid URL. Please check your data and try again.'\n }\n};\n\nvar REQUEST_HEADERS = {\n 'User-Agent': 'Readability - http://readability.com/about/'\n};\n\n// The number of milliseconds to attempt to fetch a resource before timing out.\nvar FETCH_TIMEOUT = 10000;\n\n// Content types that we do not extract content from\nvar BAD_CONTENT_TYPES = ['audio/mpeg', 'image/gif', 'image/jpeg', 'image/jpg'];\n\nvar BAD_CONTENT_TYPES_RE = new RegExp('^(' + BAD_CONTENT_TYPES.join('|') + ')$', 'i');\n\n// Use this setting as the maximum size an article can be\n// for us to attempt parsing. Defaults to 5 MB.\nvar MAX_CONTENT_LENGTH = 5242880;\n\nfunction get(options) {\n return new _Promise(function (resolve, reject) {\n request(options, function (err, response, body) {\n if (err) {\n reject(err);\n } else {\n resolve({ body: body, response: response });\n }\n });\n });\n}\n\n// Evaluate a response to ensure it's something we should be keeping.\n// This does not validate in the sense of a response being 200 level or\n// not. Validation here means that we haven't found reason to bail from\n// further processing of this url.\n\nfunction validateResponse(response) {\n var parseNon2xx = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n\n // Check if we got a valid status code\n if (response.statusMessage !== 'OK') {\n if (!response.statusCode) {\n throw new Error('Unable to fetch content. Original exception was ' + response.error);\n } else if (!parseNon2xx) {\n throw new Error('Resource returned a response status code of ' + response.statusCode + ' and resource was instructed to reject non-2xx level status codes.');\n }\n }\n\n var _response$headers = response.headers;\n var contentType = _response$headers['content-type'];\n var contentLength = _response$headers['content-length'];\n\n // Check that the content is not in BAD_CONTENT_TYPES\n\n if (BAD_CONTENT_TYPES_RE.test(contentType)) {\n throw new Error('Content-type for this resource was ' + contentType + ' and is not allowed.');\n }\n\n // Check that the content length is below maximum\n if (contentLength > MAX_CONTENT_LENGTH) {\n throw new Error('Content for this resource was too large. Maximum content length is ' + MAX_CONTENT_LENGTH + '.');\n }\n\n return true;\n}\n\n// Set our response attribute to the result of fetching our URL.\n// TODO: This should gracefully handle timeouts and raise the\n// proper exceptions on the many failure cases of HTTP.\n// TODO: Ensure we are not fetching something enormous. Always return\n// unicode content for HTML, with charset conversion.\n\nvar fetchResource = (function () {\n var _ref2 = _asyncToGenerator(_regeneratorRuntime.mark(function _callee(url, parsedUrl) {\n var options, _ref3, response, body;\n\n return _regeneratorRuntime.wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n parsedUrl = parsedUrl || URL.parse(encodeURI(url));\n\n options = {\n url: parsedUrl,\n headers: _extends({}, REQUEST_HEADERS),\n timeout: FETCH_TIMEOUT,\n // Don't set encoding; fixes issues\n // w/gzipped responses\n encoding: null,\n // Accept cookies\n jar: true,\n // Accept and decode gzip\n gzip: true,\n // Follow any redirect\n followAllRedirects: true\n };\n _context.next = 4;\n return get(options);\n\n case 4:\n _ref3 = _context.sent;\n response = _ref3.response;\n body = _ref3.body;\n _context.prev = 7;\n\n validateResponse(response);\n return _context.abrupt('return', { body: body, response: response });\n\n case 12:\n _context.prev = 12;\n _context.t0 = _context['catch'](7);\n return _context.abrupt('return', Errors.badUrl);\n\n case 15:\n case 'end':\n return _context.stop();\n }\n }\n }, _callee, this, [[7, 12]]);\n }));\n\n function fetchResource(_x2, _x3) {\n return _ref2.apply(this, arguments);\n }\n\n return fetchResource;\n})();\n\nfunction convertMetaProp($, from, to) {\n $('meta[' + from + ']').each(function (_, node) {\n var $node = $(node);\n\n var value = $node.attr(from);\n $node.attr(to, value);\n $node.removeAttr(from);\n });\n\n return $;\n}\n\n// For ease of use in extracting from meta tags,\n// replace the \"content\" attribute on meta tags with the\n// \"value\" attribute.\n//\n// In addition, normalize 'property' attributes to 'name' for ease of\n// querying later. See, e.g., og or twitter meta tags.\n\nfunction normalizeMetaTags($) {\n $ = convertMetaProp($, 'content', 'value');\n $ = convertMetaProp($, 'property', 'name');\n return $;\n}\n\nvar IS_LINK = new RegExp('https?://', 'i');\nvar IS_IMAGE = new RegExp('.(png|gif|jpe?g)', 'i');\n\nvar TAGS_TO_REMOVE = ['script', 'style', 'form'].join(',');\n\n// Convert all instances of images with potentially\n// lazy loaded images into normal images.\n// Many sites will have img tags with no source, or an image tag with a src\n// attribute that a is a placeholer. We need to be able to properly fill in\n// the src attribute so the images are no longer lazy loaded.\nfunction convertLazyLoadedImages($) {\n $('img').each(function (_, img) {\n _Reflect$ownKeys(img.attribs).forEach(function (attr) {\n var value = img.attribs[attr];\n\n if (attr !== 'src' && IS_LINK.test(value) && IS_IMAGE.test(value)) {\n $(img).attr('src', value);\n }\n });\n });\n\n return $;\n}\n\nfunction isComment(index, node) {\n return node.type === 'comment';\n}\n\nfunction cleanComments($) {\n $.root().find('*').contents().filter(isComment).remove();\n\n return $;\n}\n\nfunction clean($) {\n $(TAGS_TO_REMOVE).remove();\n\n $ = cleanComments($);\n return $;\n}\n\nvar Resource = {\n\n // Create a Resource.\n //\n // :param url: The URL for the document we should retrieve.\n // :param response: If set, use as the response rather than\n // attempting to fetch it ourselves. Expects a\n // string.\n create: function create(url, preparedResponse, parsedUrl) {\n var _this = this;\n\n return _asyncToGenerator(_regeneratorRuntime.mark(function _callee() {\n var result, validResponse;\n return _regeneratorRuntime.wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n result = void 0;\n\n if (!preparedResponse) {\n _context.next = 6;\n break;\n }\n\n validResponse = {\n statusMessage: 'OK',\n statusCode: 200,\n headers: {\n 'content-type': 'text/html',\n 'content-length': 500\n }\n };\n\n\n result = { body: preparedResponse, response: validResponse };\n _context.next = 9;\n break;\n\n case 6:\n _context.next = 8;\n return fetchResource(url, parsedUrl);\n\n case 8:\n result = _context.sent;\n\n case 9:\n if (!result.error) {\n _context.next = 11;\n break;\n }\n\n return _context.abrupt('return', result);\n\n case 11:\n return _context.abrupt('return', _this.generateDoc(result));\n\n case 12:\n case 'end':\n return _context.stop();\n }\n }\n }, _callee, _this);\n }))();\n },\n generateDoc: function generateDoc(_ref) {\n var content = _ref.body;\n var response = _ref.response;\n var contentType = response.headers['content-type'];\n\n // TODO: Implement is_text function from\n // https://github.com/ReadabilityHoldings/readability/blob/8dc89613241d04741ebd42fa9fa7df1b1d746303/readability/utils/text.py#L57\n\n if (!contentType.includes('html') && !contentType.includes('text')) {\n throw new Error('Content does not appear to be text.');\n }\n\n var $ = cheerio.load(content, { normalizeWhitespace: true });\n\n if ($.root().children().length === 0) {\n throw new Error('No children, likely a bad parse.');\n }\n\n $ = normalizeMetaTags($);\n $ = convertLazyLoadedImages($);\n $ = clean($);\n\n return $;\n }\n};\n\nvar NYMagExtractor = {\n domain: 'nymag.com',\n content: {\n // Order by most likely. Extractor will stop on first occurrence\n selectors: ['div.article-content', 'section.body', 'article.article'],\n\n // Selectors to remove from the extracted content\n clean: ['.ad', '.single-related-story'],\n\n // Object of tranformations to make on matched elements\n // Each key is the selector, each value is the tag to\n // transform to.\n // If a function is given, it should return a string\n // to convert to or nothing (in which case it will not perform\n // the transformation.\n transforms: {\n // Convert h1s to h2s\n h1: 'h2',\n\n // Convert lazy-loaded noscript images to figures\n noscript: function noscript($node) {\n var $children = $node.children();\n if ($children.length === 1 && $children.get(0).tagName === 'img') {\n return 'figure';\n }\n\n return null;\n }\n }\n },\n\n title: {\n selectors: ['h1.lede-feature-title', 'h1.headline-primary', 'h1']\n },\n\n author: {\n selectors: ['.by-authors', '.lede-feature-author']\n },\n\n dek: {\n selectors: ['.lede-feature-teaser']\n },\n\n date_published: {\n selectors: [['time.article-timestamp[datetime]', 'datetime'], 'time.article-timestamp']\n }\n};\n\nvar BloggerExtractor = {\n domain: 'blogspot.com',\n content: {\n // Blogger is insane and does not load its content\n // initially in the page, but it's all there\n // in noscript\n selectors: ['.post-content noscript'],\n\n // Selectors to remove from the extracted content\n clean: [],\n\n // Convert the noscript tag to a div\n transforms: {\n noscript: 'div'\n }\n },\n\n author: {\n selectors: ['.post-author-name']\n },\n\n title: {\n selectors: ['h2.title']\n },\n\n date_published: {\n selectors: ['span.publishdate']\n }\n};\n\nvar WikipediaExtractor = {\n domain: 'wikipedia.org',\n content: {\n selectors: ['#mw-content-text'],\n\n defaultCleaner: false,\n\n // transform top infobox to an image with caption\n transforms: {\n '.infobox img': function infoboxImg($node) {\n var $parent = $node.parents('.infobox');\n // Only prepend the first image in .infobox\n if ($parent.children('img').length === 0) {\n $parent.prepend($node);\n }\n },\n '.infobox caption': 'figcaption',\n '.infobox': 'figure'\n },\n\n // Selectors to remove from the extracted content\n clean: ['.mw-editsection', 'figure tr, figure td, figure tbody', '#toc', '.navbox']\n\n },\n\n author: 'Wikipedia Contributors',\n\n title: {\n selectors: ['h2.title']\n },\n\n date_published: {\n selectors: ['#footer-info-lastmod']\n }\n\n};\n\nvar TwitterExtractor = {\n domain: 'twitter.com',\n\n content: {\n transforms: {\n // We're transforming essentially the whole page here.\n // Twitter doesn't have nice selectors, so our initial\n // selector grabs the whole page, then we're re-writing\n // it to fit our needs before we clean it up.\n '.permalink[role=main]': function permalinkRoleMain($node, $) {\n var tweets = $node.find('.tweet');\n var $tweetContainer = $('<div id=\"TWEETS_GO_HERE\"></div>');\n $tweetContainer.append(tweets);\n $node.replaceWith($tweetContainer);\n },\n\n // Twitter wraps @ with s, which\n // renders as a strikethrough\n s: 'span'\n },\n\n selectors: ['.permalink[role=main]'],\n\n defaultCleaner: false,\n\n clean: ['.stream-item-footer', 'button', '.tweet-details-fixer']\n },\n\n author: {\n selectors: ['.tweet.permalink-tweet .username']\n },\n\n date_published: {\n selectors: [['.permalink-tweet ._timestamp[data-time-ms]', 'data-time-ms']]\n }\n\n};\n\nvar NYTimesExtractor = {\n title: {\n selectors: ['.g-headline', 'h1.headline']\n },\n\n author: {\n selectors: ['.g-byline', '.byline']\n },\n\n content: {\n selectors: ['div.g-blocks', 'article#story'],\n\n defaultCleaner: false,\n\n transforms: {\n 'img.g-lazy': function imgGLazy($node) {\n var src = $node.attr('src');\n // const widths = $node.attr('data-widths')\n // .slice(1)\n // .slice(0, -1)\n // .split(',');\n // if (widths.length) {\n // width = widths.slice(-1);\n // } else {\n // width = '900';\n // }\n var width = 640;\n\n src = src.replace('{{size}}', width);\n $node.attr('src', src);\n }\n },\n\n clean: ['.ad', 'header#story-header', '.story-body-1 .lede.video', '.visually-hidden', '#newsletter-promo', '.promo', '.comments-button', '.hidden']\n },\n\n date_published: null,\n\n lead_image_url: null,\n\n dek: null,\n\n next_page_url: null,\n\n excerpt: null\n};\n\n// Rename CustomExtractor\n// to fit your publication\nvar TheAtlanticExtractor = {\n domain: 'www.theatlantic.com',\n title: {\n selectors: ['h1.hed']\n },\n\n author: {\n selectors: ['article#article .article-cover-extra .metadata .byline a']\n },\n\n content: {\n selectors: ['.article-body'],\n\n // Is there anything in the content you selected that needs transformed\n // before it's consumable content? E.g., unusual lazy loaded images\n transforms: [],\n\n // Is there anything that is in the result that shouldn't be?\n // The clean selectors will remove anything that matches from\n // the result\n clean: []\n },\n\n date_published: null,\n\n lead_image_url: null,\n\n dek: null,\n\n next_page_url: null,\n\n excerpt: null\n};\n\n// Rename CustomExtractor\n// to fit your publication\n// (e.g., NYTimesExtractor)\nvar NewYorkerExtractor = {\n domain: 'www.newyorker.com',\n title: {\n selectors: ['h1.title']\n },\n\n author: {\n selectors: ['.contributors']\n },\n\n content: {\n selectors: ['div#articleBody', 'div.articleBody'],\n\n // Is there anything in the content you selected that needs transformed\n // before it's consumable content? E.g., unusual lazy loaded images\n transforms: [],\n\n // Is there anything that is in the result that shouldn't be?\n // The clean selectors will remove anything that matches from\n // the result\n clean: []\n },\n\n date_published: {\n selectors: [['meta[name=\"article:published_time\"]', 'value']]\n },\n\n lead_image_url: {\n selectors: [['meta[name=\"og:image\"]', 'value']]\n },\n\n dek: {\n selectors: [['meta[name=\"og:description\"]', 'value']]\n },\n\n next_page_url: null,\n\n excerpt: null\n};\n\n// Rename CustomExtractor\n// to fit your publication\n// (e.g., NYTimesExtractor)\nvar WiredExtractor = {\n domain: 'www.wired.com',\n title: {\n selectors: ['h1.post-title']\n },\n\n author: {\n selectors: ['a[rel=\"author\"]']\n },\n\n content: {\n selectors: ['article.content'],\n\n // Is there anything in the content you selected that needs transformed\n // before it's consumable content? E.g., unusual lazy loaded images\n transforms: [],\n\n // Is there anything that is in the result that shouldn't be?\n // The clean selectors will remove anything that matches from\n // the result\n clean: ['.visually-hidden']\n },\n\n date_published: {\n selectors: [['meta[itemprop=\"datePublished\"]', 'value']]\n },\n\n lead_image_url: {\n selectors: [['meta[name=\"og:image\"]', 'value']]\n },\n\n dek: {\n selectors: [['meta[name=\"og:description\"]', 'value']]\n },\n\n next_page_url: null,\n\n excerpt: null\n};\n\n// Rename CustomExtractor\n// to fit your publication\n// (e.g., NYTimesExtractor)\nvar MSNExtractor = {\n domain: 'www.msn.com',\n title: {\n selectors: ['h1']\n },\n\n author: {\n selectors: ['span.authorname-txt']\n },\n\n content: {\n selectors: ['div.richtext'],\n\n // Is there anything in the content you selected that needs transformed\n // before it's consumable content? E.g., unusual lazy loaded images\n transforms: [],\n\n // Is there anything that is in the result that shouldn't be?\n // The clean selectors will remove anything that matches from\n // the result\n clean: ['span.caption']\n },\n\n date_published: {\n selectors: ['span.time']\n },\n\n lead_image_url: {\n selectors: []\n },\n\n dek: {\n selectors: [['meta[name=\"description\"]', 'value']]\n },\n\n next_page_url: null,\n\n excerpt: null\n};\n\n// Rename CustomExtractor\n// to fit your publication\n// (e.g., NYTimesExtractor)\nvar YahooExtractor = {\n domain: 'www.yahoo.com',\n title: {\n selectors: ['header.canvas-header']\n },\n\n author: {\n selectors: ['span.provider-name']\n },\n\n content: {\n selectors: [\n // enter content selectors\n '.content-canvas'],\n\n // Is there anything in the content you selected that needs transformed\n // before it's consumable content? E.g., unusual lazy loaded images\n transforms: [],\n\n // Is there anything that is in the result that shouldn't be?\n // The clean selectors will remove anything that matches from\n // the result\n clean: ['.figure-caption']\n },\n\n date_published: {\n selectors: [['time.date[datetime]', 'datetime']]\n },\n\n lead_image_url: {\n selectors: [['meta[name=\"og:image\"]', 'value']]\n },\n\n dek: {\n selectors: [['meta[name=\"og:description\"]', 'value']]\n },\n\n next_page_url: null,\n\n excerpt: null\n};\n\n// Rename CustomExtractor\n// to fit your publication\n// (e.g., NYTimesExtractor)\nvar BuzzfeedExtractor = {\n domain: 'www.buzzfeed.com',\n title: {\n selectors: ['h1[id=\"post-title\"]']\n },\n\n author: {\n selectors: ['a[data-action=\"user/username\"]', 'byline__author']\n },\n\n content: {\n selectors: ['#buzz_sub_buzz'],\n\n defaultCleaner: false,\n\n // Is there anything in the content you selected that needs transformed\n // before it's consumable content? E.g., unusual lazy loaded images\n transforms: {\n h2: 'b'\n },\n\n // Is there anything that is in the result that shouldn't be?\n // The clean selectors will remove anything that matches from\n // the result\n clean: ['.instapaper_ignore', '.suplist_list_hide .buzz_superlist_item .buzz_superlist_number_inline', '.share-box']\n },\n\n date_published: {\n selectors: ['.buzz-datetime']\n },\n\n lead_image_url: {\n selectors: [['meta[name=\"og:image\"]', 'value']]\n },\n\n dek: {\n selectors: [['meta[name=\"description\"]', 'value']]\n },\n\n next_page_url: null,\n\n excerpt: null\n};\n\n// Rename CustomExtractor\n// to fit your publication\n// (e.g., NYTimesExtractor)\nvar WikiaExtractor = {\n domain: 'fandom.wikia.com',\n title: {\n selectors: ['h1.entry-title']\n },\n\n author: {\n selectors: ['.author vcard', '.fn']\n },\n\n content: {\n selectors: ['.grid-content', '.entry-content'],\n\n // Is there anything in the content you selected that needs transformed\n // before it's consumable content? E.g., unusual lazy loaded images\n transforms: [],\n\n // Is there anything that is in the result that shouldn't be?\n // The clean selectors will remove anything that matches from\n // the result\n clean: []\n },\n\n date_published: {\n selectors: [['meta[name=\"article:published_time\"]', 'value']]\n },\n\n lead_image_url: {\n selectors: [['meta[name=\"og:image\"]', 'value']]\n },\n\n dek: {\n selectors: [['meta[name=\"og:description\"]', 'value']]\n },\n\n next_page_url: null,\n\n excerpt: null\n};\n\n// Rename CustomExtractor\n// to fit your publication\n// (e.g., NYTimesExtractor)\nvar LittleThingsExtractor = {\n domain: 'www.littlethings.com',\n title: {\n selectors: ['h1.post-title']\n },\n\n author: {\n selectors: [['meta[name=\"author\"]', 'value']]\n },\n\n content: {\n selectors: [\n // enter content selectors\n '.mainContentIntro', '.content-wrapper'],\n\n // Is there anything in the content you selected that needs transformed\n // before it's consumable content? E.g., unusual lazy loaded images\n transforms: [],\n\n // Is there anything that is in the result that shouldn't be?\n // The clean selectors will remove anything that matches from\n // the result\n clean: []\n },\n\n lead_image_url: {\n selectors: [['meta[name=\"og:image\"]', 'value']]\n },\n\n next_page_url: null,\n\n excerpt: null\n};\n\n// Rename CustomExtractor\n// to fit your publication\n// (e.g., NYTimesExtractor)\nvar PoliticoExtractor = {\n domain: 'www.politico.com',\n title: {\n selectors: [\n // enter title selectors\n ['meta[name=\"og:title\"]', 'value']]\n },\n\n author: {\n selectors: ['.story-main-content .byline .vcard']\n },\n\n content: {\n selectors: [\n // enter content selectors\n '.story-main-content', '.content-group', '.story-core', '.story-text'],\n\n // Is there anything in the content you selected that needs transformed\n // before it's consumable content? E.g., unusual lazy loaded images\n transforms: [],\n\n // Is there anything that is in the result that shouldn't be?\n // The clean selectors will remove anything that matches from\n // the result\n clean: ['figcaption']\n },\n\n date_published: {\n selectors: [['.story-main-content .timestamp time[datetime]', 'datetime']]\n },\n\n lead_image_url: {\n selectors: [\n // enter lead_image_url selectors\n ['meta[name=\"og:image\"]', 'value']]\n },\n\n dek: {\n selectors: [['meta[name=\"description\"]', 'value']]\n },\n\n next_page_url: null,\n\n excerpt: null\n};\n\nvar Extractors = {\n 'nymag.com': NYMagExtractor,\n 'blogspot.com': BloggerExtractor,\n 'wikipedia.org': WikipediaExtractor,\n 'twitter.com': TwitterExtractor,\n 'www.nytimes.com': NYTimesExtractor,\n 'www.theatlantic.com': TheAtlanticExtractor,\n 'www.newyorker.com': NewYorkerExtractor,\n 'www.wired.com': WiredExtractor,\n 'www.msn.com': MSNExtractor,\n 'www.yahoo.com': YahooExtractor,\n 'www.buzzfeed.com': BuzzfeedExtractor,\n 'fandom.wikia.com': WikiaExtractor,\n 'www.littlethings.com': LittleThingsExtractor,\n 'www.politico.com': PoliticoExtractor\n\n};\n\n// Spacer images to be removed\nvar SPACER_RE = new RegExp('trans|transparent|spacer|blank', 'i');\n\n// A list of tags to strip from the output if we encounter them.\nvar STRIP_OUTPUT_TAGS = ['title', 'script', 'noscript', 'link', 'style', 'hr', 'embed', 'iframe', 'object'];\n\n// cleanAttributes\nvar REMOVE_ATTRS = ['style', 'align'];\nvar REMOVE_ATTR_SELECTORS = REMOVE_ATTRS.map(function (selector) {\n return '[' + selector + ']';\n});\nvar REMOVE_ATTR_LIST = REMOVE_ATTRS.join(',');\nvar WHITELIST_ATTRS = ['src', 'srcset', 'href', 'class', 'id', 'alt', 'score'];\nvar WHITELIST_ATTRS_RE = new RegExp('^(' + WHITELIST_ATTRS.join('|') + ')$', 'i');\n\n// removeEmpty\nvar REMOVE_EMPTY_TAGS = ['p'];\nvar REMOVE_EMPTY_SELECTORS = REMOVE_EMPTY_TAGS.map(function (tag) {\n return tag + ':empty';\n}).join(',');\n\n// cleanTags\nvar CLEAN_CONDITIONALLY_TAGS = ['ul', 'ol', 'table', 'div', 'button', 'form'].join(',');\n\n// cleanHeaders\nvar HEADER_TAGS = ['h2', 'h3', 'h4', 'h5', 'h6'];\nvar HEADER_TAG_LIST = HEADER_TAGS.join(',');\n\n// // CONTENT FETCHING CONSTANTS ////\n\n// A list of strings that can be considered unlikely candidates when\n// extracting content from a resource. These strings are joined together\n// and then tested for existence using re:test, so may contain simple,\n// non-pipe style regular expression queries if necessary.\nvar UNLIKELY_CANDIDATES_BLACKLIST = ['ad-break', 'adbox', 'advert', 'addthis', 'agegate', 'aux', 'blogger-labels', 'combx', 'comment', 'conversation', 'disqus', 'entry-unrelated', 'extra', 'foot',\n// 'form', // This is too generic, has too many false positives\n'header', 'hidden', 'loader', 'login', // Note: This can hit 'blogindex'.\n'menu', 'meta', 'nav', 'outbrain', 'pager', 'pagination', 'predicta', // readwriteweb inline ad box\n'presence_control_external', // lifehacker.com container full of false positives\n'popup', 'printfriendly', 'related', 'remove', 'remark', 'rss', 'share', 'shoutbox', 'sidebar', 'sociable', 'sponsor', 'taboola', 'tools'];\n\n// A list of strings that can be considered LIKELY candidates when\n// extracting content from a resource. Essentially, the inverse of the\n// blacklist above - if something matches both blacklist and whitelist,\n// it is kept. This is useful, for example, if something has a className\n// of \"rss-content entry-content\". It matched 'rss', so it would normally\n// be removed, however, it's also the entry content, so it should be left\n// alone.\n//\n// These strings are joined together and then tested for existence using\n// re:test, so may contain simple, non-pipe style regular expression queries\n// if necessary.\nvar UNLIKELY_CANDIDATES_WHITELIST = ['and', 'article', 'body', 'blogindex', 'column', 'content', 'entry-content-asset', 'format', // misuse of form\n'hfeed', 'hentry', 'hatom', 'main', 'page', 'posts', 'shadow'];\n\n// A list of tags which, if found inside, should cause a <div /> to NOT\n// be turned into a paragraph tag. Shallow div tags without these elements\n// should be turned into <p /> tags.\nvar DIV_TO_P_BLOCK_TAGS = ['a', 'blockquote', 'dl', 'div', 'img', 'p', 'pre', 'table'].join(',');\n\n// A list of tags that should be ignored when trying to find the top candidate\n// for a document.\nvar NON_TOP_CANDIDATE_TAGS = ['br', 'b', 'i', 'label', 'hr', 'area', 'base', 'basefont', 'input', 'img', 'link', 'meta'];\n\nvar NON_TOP_CANDIDATE_TAGS_RE = new RegExp('^(' + NON_TOP_CANDIDATE_TAGS.join('|') + ')$', 'i');\n\nvar PHOTO_HINTS = ['figure', 'photo', 'image', 'caption'];\nvar PHOTO_HINTS_RE = new RegExp(PHOTO_HINTS.join('|'), 'i');\n\n// A list of strings that denote a positive scoring for this content as being\n// an article container. Checked against className and id.\n//\n// TODO: Perhaps have these scale based on their odds of being quality?\nvar POSITIVE_SCORE_HINTS = ['article', 'articlecontent', 'instapaper_body', 'blog', 'body', 'content', 'entry-content-asset', 'entry', 'hentry', 'main', 'Normal', 'page', 'pagination', 'permalink', 'post', 'story', 'text', '[-_]copy', // usatoday\n'\\\\Bcopy'];\n\n// The above list, joined into a matching regular expression\nvar POSITIVE_SCORE_RE = new RegExp(POSITIVE_SCORE_HINTS.join('|'), 'i');\n\n// A list of strings that denote a negative scoring for this content as being\n// an article container. Checked against className and id.\n//\n// TODO: Perhaps have these scale based on their odds of being quality?\nvar NEGATIVE_SCORE_HINTS = ['adbox', 'advert', 'author', 'bio', 'bookmark', 'bottom', 'byline', 'clear', 'com-', 'combx', 'comment', 'comment\\\\B', 'contact', 'copy', 'credit', 'crumb', 'date', 'deck', 'excerpt', 'featured', // tnr.com has a featured_content which throws us off\n'foot', 'footer', 'footnote', 'graf', 'head', 'info', 'infotext', // newscientist.com copyright\n'instapaper_ignore', 'jump', 'linebreak', 'link', 'masthead', 'media', 'meta', 'modal', 'outbrain', // slate.com junk\n'promo', 'pr_', // autoblog - press release\n'related', 'respond', 'roundcontent', // lifehacker restricted content warning\n'scroll', 'secondary', 'share', 'shopping', 'shoutbox', 'side', 'sidebar', 'sponsor', 'stamp', 'sub', 'summary', 'tags', 'tools', 'widget'];\n// The above list, joined into a matching regular expression\nvar NEGATIVE_SCORE_RE = new RegExp(NEGATIVE_SCORE_HINTS.join('|'), 'i');\n\n// XPath to try to determine if a page is wordpress. Not always successful.\nvar IS_WP_SELECTOR = 'meta[name=generator][value^=WordPress]';\n\n// A list of words that, if found in link text or URLs, likely mean that\n// this link is not a next page link.\nvar EXTRANEOUS_LINK_HINTS = ['print', 'archive', 'comment', 'discuss', 'e-mail', 'email', 'share', 'reply', 'all', 'login', 'sign', 'single', 'adx', 'entry-unrelated'];\nvar EXTRANEOUS_LINK_HINTS_RE = new RegExp(EXTRANEOUS_LINK_HINTS.join('|'), 'i');\n\n// Match any phrase that looks like it could be page, or paging, or pagination\nvar PAGE_RE = new RegExp('pag(e|ing|inat)', 'i');\n\n// A list of all of the block level tags known in HTML5 and below. Taken from\n// http://bit.ly/qneNIT\nvar BLOCK_LEVEL_TAGS = ['article', 'aside', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'col', 'colgroup', 'dd', 'div', 'dl', 'dt', 'embed', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hgroup', 'hr', 'li', 'map', 'object', 'ol', 'output', 'p', 'pre', 'progress', 'section', 'table', 'tbody', 'textarea', 'tfoot', 'th', 'thead', 'tr', 'ul', 'video'];\nvar BLOCK_LEVEL_TAGS_RE = new RegExp('^(' + BLOCK_LEVEL_TAGS.join('|') + ')$', 'i');\n\n// The removal is implemented as a blacklist and whitelist, this test finds\n// blacklisted elements that aren't whitelisted. We do this all in one\n// expression-both because it's only one pass, and because this skips the\n// serialization for whitelisted nodes.\nvar candidatesBlacklist = UNLIKELY_CANDIDATES_BLACKLIST.join('|');\nvar CANDIDATES_BLACKLIST = new RegExp(candidatesBlacklist, 'i');\n\nvar candidatesWhitelist = UNLIKELY_CANDIDATES_WHITELIST.join('|');\nvar CANDIDATES_WHITELIST = new RegExp(candidatesWhitelist, 'i');\n\nfunction stripUnlikelyCandidates($) {\n // Loop through the provided document and remove any non-link nodes\n // that are unlikely candidates for article content.\n //\n // Links are ignored because there are very often links to content\n // that are identified as non-body-content, but may be inside\n // article-like content.\n //\n // :param $: a cheerio object to strip nodes from\n // :return $: the cleaned cheerio object\n $('*').not('a').each(function (index, node) {\n var $node = $(node);\n var classes = $node.attr('class');\n var id = $node.attr('id');\n if (!id && !classes) return;\n\n var classAndId = (classes || '') + ' ' + (id || '');\n if (CANDIDATES_WHITELIST.test(classAndId)) {\n return;\n } else if (CANDIDATES_BLACKLIST.test(classAndId)) {\n $node.remove();\n }\n });\n\n return $;\n}\n\n// ## NOTES:\n// Another good candidate for refactoring/optimizing.\n// Very imperative code, I don't love it. - AP\n\n\n// Given cheerio object, convert consecutive <br /> tags into\n// <p /> tags instead.\n//\n// :param $: A cheerio object\n\nfunction brsToPs($) {\n var collapsing = false;\n $('br').each(function (index, element) {\n var nextElement = $(element).next().get(0);\n\n if (nextElement && nextElement.tagName === 'br') {\n collapsing = true;\n $(element).remove();\n } else if (collapsing) {\n collapsing = false;\n // $(element).replaceWith('<p />')\n paragraphize(element, $, true);\n }\n });\n\n return $;\n}\n\n// Given a node, turn it into a P if it is not already a P, and\n// make sure it conforms to the constraints of a P tag (I.E. does\n// not contain any other block tags.)\n//\n// If the node is a <br />, it treats the following inline siblings\n// as if they were its children.\n//\n// :param node: The node to paragraphize; this is a raw node\n// :param $: The cheerio object to handle dom manipulation\n// :param br: Whether or not the passed node is a br\n\nfunction paragraphize(node, $) {\n var br = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n\n var $node = $(node);\n\n if (br) {\n var sibling = node.nextSibling;\n var p = $('<p></p>');\n\n // while the next node is text or not a block level element\n // append it to a new p node\n while (sibling && !(sibling.tagName && BLOCK_LEVEL_TAGS_RE.test(sibling.tagName))) {\n var nextSibling = sibling.nextSibling;\n $(sibling).appendTo(p);\n sibling = nextSibling;\n }\n\n $node.replaceWith(p);\n $node.remove();\n return $;\n }\n\n return $;\n}\n\nfunction convertDivs($) {\n $('div').each(function (index, div) {\n var $div = $(div);\n var convertable = $div.children(DIV_TO_P_BLOCK_TAGS).length === 0;\n\n if (convertable) {\n convertNodeTo($div, $, 'p');\n }\n });\n\n return $;\n}\n\nfunction convertSpans($) {\n $('span').each(function (index, span) {\n var $span = $(span);\n var convertable = $span.parents('p, div').length === 0;\n if (convertable) {\n convertNodeTo($span, $, 'p');\n }\n });\n\n return $;\n}\n\n// Loop through the provided doc, and convert any p-like elements to\n// actual paragraph tags.\n//\n// Things fitting this criteria:\n// * Multiple consecutive <br /> tags.\n// * <div /> tags without block level elements inside of them\n// * <span /> tags who are not children of <p /> or <div /> tags.\n//\n// :param $: A cheerio object to search\n// :return cheerio object with new p elements\n// (By-reference mutation, though. Returned just for convenience.)\n\nfunction convertToParagraphs($) {\n $ = brsToPs($);\n $ = convertDivs($);\n $ = convertSpans($);\n\n return $;\n}\n\nfunction convertNodeTo($node, $) {\n var tag = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'p';\n\n var node = $node.get(0);\n if (!node) {\n return $;\n }\n\n var _$node$get = $node.get(0);\n\n var attribs = _$node$get.attribs;\n\n var attribString = _Reflect$ownKeys(attribs).map(function (key) {\n return key + '=' + attribs[key];\n }).join(' ');\n\n $node.replaceWith('<' + tag + ' ' + attribString + '>' + $node.contents() + '</' + tag + '>');\n return $;\n}\n\nfunction cleanForHeight($img, $) {\n var height = parseInt($img.attr('height'), 10);\n var width = parseInt($img.attr('width'), 10) || 20;\n\n // Remove images that explicitly have very small heights or\n // widths, because they are most likely shims or icons,\n // which aren't very useful for reading.\n if ((height || 20) < 10 || width < 10) {\n $img.remove();\n } else if (height) {\n // Don't ever specify a height on images, so that we can\n // scale with respect to width without screwing up the\n // aspect ratio.\n $img.removeAttr('height');\n }\n\n return $;\n}\n\n// Cleans out images where the source string matches transparent/spacer/etc\n// TODO This seems very aggressive - AP\nfunction removeSpacers($img, $) {\n if (SPACER_RE.test($img.attr('src'))) {\n $img.remove();\n }\n\n return $;\n}\n\nfunction cleanImages($article, $) {\n $article.find('img').each(function (index, img) {\n var $img = $(img);\n\n cleanForHeight($img, $);\n removeSpacers($img, $);\n });\n\n return $;\n}\n\nfunction stripJunkTags(article, $) {\n var tags = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];\n\n if (tags.length === 0) {\n tags = STRIP_OUTPUT_TAGS;\n }\n\n $(tags.join(','), article).remove();\n\n return $;\n}\n\n// H1 tags are typically the article title, which should be extracted\n// by the title extractor instead. If there's less than 3 of them (<3),\n// strip them. Otherwise, turn 'em into H2s.\n\nfunction cleanHOnes(article, $) {\n var $hOnes = $('h1', article);\n\n if ($hOnes.length < 3) {\n $hOnes.each(function (index, node) {\n return $(node).remove();\n });\n } else {\n $hOnes.each(function (index, node) {\n convertNodeTo($(node), $, 'h2');\n });\n }\n\n return $;\n}\n\nfunction removeAllButWhitelist($article) {\n // $('*', article).each((index, node) => {\n $article.find('*').each(function (index, node) {\n node.attribs = _Reflect$ownKeys(node.attribs).reduce(function (acc, attr) {\n if (WHITELIST_ATTRS_RE.test(attr)) {\n return _extends({}, acc, _defineProperty({}, attr, node.attribs[attr]));\n }\n\n return acc;\n }, {});\n });\n}\n\n// function removeAttrs(article, $) {\n// REMOVE_ATTRS.forEach((attr) => {\n// $(`[${attr}]`, article).removeAttr(attr);\n// });\n// }\n\n// Remove attributes like style or align\nfunction cleanAttributes($article) {\n removeAllButWhitelist($article);\n\n return $article;\n}\n\nfunction removeEmpty($article, $) {\n $article.find('p').each(function (index, p) {\n var $p = $(p);\n if ($p.text().trim() === '') $p.remove();\n });\n\n return $;\n}\n\n// // CONTENT FETCHING CONSTANTS ////\n\n// A list of strings that can be considered unlikely candidates when\n// extracting content from a resource. These strings are joined together\n// and then tested for existence using re:test, so may contain simple,\n// non-pipe style regular expression queries if necessary.\nvar UNLIKELY_CANDIDATES_BLACKLIST$1 = ['ad-break', 'adbox', 'advert', 'addthis', 'agegate', 'aux', 'blogger-labels', 'combx', 'comment', 'conversation', 'disqus', 'entry-unrelated', 'extra', 'foot', 'form', 'header', 'hidden', 'loader', 'login', // Note: This can hit 'blogindex'.\n'menu', 'meta', 'nav', 'pager', 'pagination', 'predicta', // readwriteweb inline ad box\n'presence_control_external', // lifehacker.com container full of false positives\n'popup', 'printfriendly', 'related', 'remove', 'remark', 'rss', 'share', 'shoutbox', 'sidebar', 'sociable', 'sponsor', 'tools'];\n\n// A list of strings that can be considered LIKELY candidates when\n// extracting content from a resource. Essentially, the inverse of the\n// blacklist above - if something matches both blacklist and whitelist,\n// it is kept. This is useful, for example, if something has a className\n// of \"rss-content entry-content\". It matched 'rss', so it would normally\n// be removed, however, it's also the entry content, so it should be left\n// alone.\n//\n// These strings are joined together and then tested for existence using\n// re:test, so may contain simple, non-pipe style regular expression queries\n// if necessary.\nvar UNLIKELY_CANDIDATES_WHITELIST$1 = ['and', 'article', 'body', 'blogindex', 'column', 'content', 'entry-content-asset', 'format', // misuse of form\n'hfeed', 'hentry', 'hatom', 'main', 'page', 'posts', 'shadow'];\n\n// A list of tags which, if found inside, should cause a <div /> to NOT\n// be turned into a paragraph tag. Shallow div tags without these elements\n// should be turned into <p /> tags.\nvar DIV_TO_P_BLOCK_TAGS$1 = ['a', 'blockquote', 'dl', 'div', 'img', 'p', 'pre', 'table'].join(',');\n\n// A list of tags that should be ignored when trying to find the top candidate\n// for a document.\nvar NON_TOP_CANDIDATE_TAGS$1 = ['br', 'b', 'i', 'label', 'hr', 'area', 'base', 'basefont', 'input', 'img', 'link', 'meta'];\n\nvar NON_TOP_CANDIDATE_TAGS_RE$1 = new RegExp('^(' + NON_TOP_CANDIDATE_TAGS$1.join('|') + ')$', 'i');\n\n// A list of selectors that specify, very clearly, either hNews or other\n// very content-specific style content, like Blogger templates.\n// More examples here: http://microformats.org/wiki/blog-post-formats\nvar HNEWS_CONTENT_SELECTORS$1 = [['.hentry', '.entry-content'], ['entry', '.entry-content'], ['.entry', '.entry_content'], ['.post', '.postbody'], ['.post', '.post_body'], ['.post', '.post-body']];\n\nvar PHOTO_HINTS$1 = ['figure', 'photo', 'image', 'caption'];\nvar PHOTO_HINTS_RE$1 = new RegExp(PHOTO_HINTS$1.join('|'), 'i');\n\n// A list of strings that denote a positive scoring for this content as being\n// an article container. Checked against className and id.\n//\n// TODO: Perhaps have these scale based on their odds of being quality?\nvar POSITIVE_SCORE_HINTS$1 = ['article', 'articlecontent', 'instapaper_body', 'blog', 'body', 'content', 'entry-content-asset', 'entry', 'hentry', 'main', 'Normal', 'page', 'pagination', 'permalink', 'post', 'story', 'text', '[-_]copy', // usatoday\n'\\\\Bcopy'];\n\n// The above list, joined into a matching regular expression\nvar POSITIVE_SCORE_RE$1 = new RegExp(POSITIVE_SCORE_HINTS$1.join('|'), 'i');\n\n// Readability publisher-specific guidelines\nvar READABILITY_ASSET$1 = new RegExp('entry-content-asset', 'i');\n\n// A list of strings that denote a negative scoring for this content as being\n// an article container. Checked against className and id.\n//\n// TODO: Perhaps have these scale based on their odds of being quality?\nvar NEGATIVE_SCORE_HINTS$1 = ['adbox', 'advert', 'author', 'bio', 'bookmark', 'bottom', 'byline', 'clear', 'com-', 'combx', 'comment', 'comment\\\\B', 'contact', 'copy', 'credit', 'crumb', 'date', 'deck', 'excerpt', 'featured', // tnr.com has a featured_content which throws us off\n'foot', 'footer', 'footnote', 'graf', 'head', 'info', 'infotext', // newscientist.com copyright\n'instapaper_ignore', 'jump', 'linebreak', 'link', 'masthead', 'media', 'meta', 'modal', 'outbrain', // slate.com junk\n'promo', 'pr_', // autoblog - press release\n'related', 'respond', 'roundcontent', // lifehacker restricted content warning\n'scroll', 'secondary', 'share', 'shopping', 'shoutbox', 'side', 'sidebar', 'sponsor', 'stamp', 'sub', 'summary', 'tags', 'tools', 'widget'];\n// The above list, joined into a matching regular expression\nvar NEGATIVE_SCORE_RE$1 = new RegExp(NEGATIVE_SCORE_HINTS$1.join('|'), 'i');\n\n// A list of all of the block level tags known in HTML5 and below. Taken from\n// http://bit.ly/qneNIT\nvar BLOCK_LEVEL_TAGS$1 = ['article', 'aside', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'col', 'colgroup', 'dd', 'div', 'dl', 'dt', 'embed', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hgroup', 'hr', 'li', 'map', 'object', 'ol', 'output', 'p', 'pre', 'progress', 'section', 'table', 'tbody', 'textarea', 'tfoot', 'th', 'thead', 'tr', 'ul', 'video'];\nvar BLOCK_LEVEL_TAGS_RE$1 = new RegExp('^(' + BLOCK_LEVEL_TAGS$1.join('|') + ')$', 'i');\n\n// The removal is implemented as a blacklist and whitelist, this test finds\n// blacklisted elements that aren't whitelisted. We do this all in one\n// expression-both because it's only one pass, and because this skips the\n// serialization for whitelisted nodes.\nvar candidatesBlacklist$1 = UNLIKELY_CANDIDATES_BLACKLIST$1.join('|');\nvar candidatesWhitelist$1 = UNLIKELY_CANDIDATES_WHITELIST$1.join('|');\nvar PARAGRAPH_SCORE_TAGS$1 = new RegExp('^(p|li|span|pre)$', 'i');\nvar CHILD_CONTENT_TAGS$1 = new RegExp('^(td|blockquote|ol|ul|dl)$', 'i');\nvar BAD_TAGS$1 = new RegExp('^(address|form)$', 'i');\n\n// Get the score of a node based on its className and id.\nfunction getWeight(node) {\n var classes = node.attr('class');\n var id = node.attr('id');\n var score = 0;\n\n if (id) {\n // if id exists, try to score on both positive and negative\n if (POSITIVE_SCORE_RE$1.test(id)) {\n score += 25;\n }\n if (NEGATIVE_SCORE_RE$1.test(id)) {\n score -= 25;\n }\n }\n\n if (classes) {\n if (score === 0) {\n // if classes exist and id did not contribute to score\n // try to score on both positive and negative\n if (POSITIVE_SCORE_RE$1.test(classes)) {\n score += 25;\n }\n if (NEGATIVE_SCORE_RE$1.test(classes)) {\n score -= 25;\n }\n }\n\n // even if score has been set by id, add score for\n // possible photo matches\n // \"try to keep photos if we can\"\n if (PHOTO_HINTS_RE$1.test(classes)) {\n score += 10;\n }\n\n // add 25 if class matches entry-content-asset,\n // a class apparently instructed for use in the\n // Readability publisher guidelines\n // https://www.readability.com/developers/guidelines\n if (READABILITY_ASSET$1.test(classes)) {\n score += 25;\n }\n }\n\n return score;\n}\n\n// returns the score of a node based on\n// the node's score attribute\n// returns null if no score set\nfunction getScore($node) {\n return parseFloat($node.attr('score')) || null;\n}\n\n// return 1 for every comma in text\nfunction scoreCommas(text) {\n return (text.match(/,/g) || []).length;\n}\n\nvar idkRe = new RegExp('^(p|pre)$', 'i');\n\nfunction scoreLength(textLength) {\n var tagName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'p';\n\n var chunks = textLength / 50;\n\n if (chunks > 0) {\n var lengthBonus = void 0;\n\n // No idea why p or pre are being tamped down here\n // but just following the source for now\n // Not even sure why tagName is included here,\n // since this is only being called from the context\n // of scoreParagraph\n if (idkRe.test(tagName)) {\n lengthBonus = chunks - 2;\n } else {\n lengthBonus = chunks - 1.25;\n }\n\n return Math.min(Math.max(lengthBonus, 0), 3);\n }\n\n return 0;\n}\n\n// Score a paragraph using various methods. Things like number of\n// commas, etc. Higher is better.\nfunction scoreParagraph(node) {\n var score = 1;\n var text = node.text().trim();\n var textLength = text.length;\n\n // If this paragraph is less than 25 characters, don't count it.\n if (textLength < 25) {\n return 0;\n }\n\n // Add points for any commas within this paragraph\n score += scoreCommas(text);\n\n // For every 50 characters in this paragraph, add another point. Up\n // to 3 points.\n score += scoreLength(textLength);\n\n // Articles can end with short paragraphs when people are being clever\n // but they can also end with short paragraphs setting up lists of junk\n // that we strip. This negative tweaks junk setup paragraphs just below\n // the cutoff threshold.\n if (text.slice(-1) === ':') {\n score -= 1;\n }\n\n return score;\n}\n\nfunction setScore($node, $, score) {\n $node.attr('score', score);\n return $node;\n}\n\nfunction addScore($node, $, amount) {\n try {\n var score = getOrInitScore($node, $) + amount;\n setScore($node, $, score);\n } catch (e) {\n // Ignoring; error occurs in scoreNode\n }\n\n return $node;\n}\n\n// Adds 1/4 of a child's score to its parent\nfunction addToParent(node, $, score) {\n var parent = node.parent();\n if (parent) {\n addScore(parent, $, score * 0.25);\n }\n\n return node;\n}\n\n// gets and returns the score if it exists\n// if not, initializes a score based on\n// the node's tag type\nfunction getOrInitScore($node, $) {\n var weightNodes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;\n\n var score = getScore($node);\n\n if (score) {\n return score;\n }\n\n score = scoreNode($node);\n\n if (weightNodes) {\n score += getWeight($node);\n }\n\n addToParent($node, $, score);\n\n return score;\n}\n\n// Score an individual node. Has some smarts for paragraphs, otherwise\n// just scores based on tag.\nfunction scoreNode($node) {\n var _$node$get = $node.get(0);\n\n var tagName = _$node$get.tagName;\n\n // TODO: Consider ordering by most likely.\n // E.g., if divs are a more common tag on a page,\n // Could save doing that regex test on every node – AP\n\n if (PARAGRAPH_SCORE_TAGS$1.test(tagName)) {\n return scoreParagraph($node);\n } else if (tagName === 'div') {\n return 5;\n } else if (CHILD_CONTENT_TAGS$1.test(tagName)) {\n return 3;\n } else if (BAD_TAGS$1.test(tagName)) {\n return -3;\n } else if (tagName === 'th') {\n return -5;\n }\n\n return 0;\n}\n\nfunction convertSpans$1($node, $) {\n if ($node.get(0)) {\n var _$node$get = $node.get(0);\n\n var tagName = _$node$get.tagName;\n\n\n if (tagName === 'span') {\n // convert spans to divs\n convertNodeTo($node, $, 'div');\n }\n }\n}\n\nfunction addScoreTo($node, $, score) {\n if ($node) {\n convertSpans$1($node, $);\n addScore($node, $, score);\n }\n}\n\nfunction scorePs($, weightNodes) {\n $('p, pre').not('[score]').each(function (index, node) {\n // The raw score for this paragraph, before we add any parent/child\n // scores.\n var $node = $(node);\n $node = setScore($node, $, getOrInitScore($node, $, weightNodes));\n\n var $parent = $node.parent();\n var rawScore = scoreNode($node);\n\n addScoreTo($parent, $, rawScore, weightNodes);\n if ($parent) {\n // Add half of the individual content score to the\n // grandparent\n addScoreTo($parent.parent(), $, rawScore / 2, weightNodes);\n }\n });\n\n return $;\n}\n\n// score content. Parents get the full value of their children's\n// content score, grandparents half\nfunction scoreContent($) {\n var weightNodes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n\n // First, look for special hNews based selectors and give them a big\n // boost, if they exist\n HNEWS_CONTENT_SELECTORS$1.forEach(function (_ref) {\n var _ref2 = _slicedToArray(_ref, 2);\n\n var parentSelector = _ref2[0];\n var childSelector = _ref2[1];\n\n $(parentSelector + ' ' + childSelector).each(function (index, node) {\n addScore($(node).parent(parentSelector), $, 80);\n });\n });\n\n // Doubling this again\n // Previous solution caused a bug\n // in which parents weren't retaining\n // scores. This is not ideal, and\n // should be fixed.\n scorePs($, weightNodes);\n scorePs($, weightNodes);\n\n return $;\n}\n\nvar NORMALIZE_RE = /\\s{2,}/g;\n\nfunction normalizeSpaces(text) {\n return text.replace(NORMALIZE_RE, ' ').trim();\n}\n\n// Given a node type to search for, and a list of regular expressions,\n// look to see if this extraction can be found in the URL. Expects\n// that each expression in r_list will return group(1) as the proper\n// string to be cleaned.\n// Only used for date_published currently.\nfunction extractFromUrl(url, regexList) {\n var matchRe = regexList.find(function (re) {\n return re.test(url);\n });\n if (matchRe) {\n return matchRe.exec(url)[1];\n }\n\n return null;\n}\n\n// An expression that looks to try to find the page digit within a URL, if\n// it exists.\n// Matches:\n// page=1\n// pg=1\n// p=1\n// paging=12\n// pag=7\n// pagination/1\n// paging/88\n// pa/83\n// p/11\n//\n// Does not match:\n// pg=102\n// page:2\nvar PAGE_IN_HREF_RE = new RegExp('(page|paging|(p(a|g|ag)?(e|enum|ewanted|ing|ination)))?(=|/)([0-9]{1,3})', 'i');\n\nvar HAS_ALPHA_RE = /[a-z]/i;\n\nvar IS_ALPHA_RE = /^[a-z]+$/i;\nvar IS_DIGIT_RE = /^[0-9]+$/i;\n\nfunction pageNumFromUrl(url) {\n var matches = url.match(PAGE_IN_HREF_RE);\n if (!matches) return null;\n\n var pageNum = parseInt(matches[6], 10);\n\n // Return pageNum < 100, otherwise\n // return null\n return pageNum < 100 ? pageNum : null;\n}\n\nfunction removeAnchor(url) {\n return url.split('#')[0].replace(/\\/$/, '');\n}\n\nfunction isGoodSegment(segment, index, firstSegmentHasLetters) {\n var goodSegment = true;\n\n // If this is purely a number, and it's the first or second\n // url_segment, it's probably a page number. Remove it.\n if (index < 2 && IS_DIGIT_RE.test(segment) && segment.length < 3) {\n goodSegment = true;\n }\n\n // If this is the first url_segment and it's just \"index\",\n // remove it\n if (index === 0 && segment.toLowerCase() === 'index') {\n goodSegment = false;\n }\n\n // If our first or second url_segment is smaller than 3 characters,\n // and the first url_segment had no alphas, remove it.\n if (index < 2 && segment.length < 3 && !firstSegmentHasLetters) {\n goodSegment = false;\n }\n\n return goodSegment;\n}\n\n// Take a URL, and return the article base of said URL. That is, no\n// pagination data exists in it. Useful for comparing to other links\n// that might have pagination data within them.\nfunction articleBaseUrl(url, parsed) {\n var parsedUrl = parsed || URL.parse(url);\n var protocol = parsedUrl.protocol;\n var host = parsedUrl.host;\n var path = parsedUrl.path;\n\n\n var firstSegmentHasLetters = false;\n var cleanedSegments = path.split('/').reverse().reduce(function (acc, rawSegment, index) {\n var segment = rawSegment;\n\n // Split off and save anything that looks like a file type.\n if (segment.includes('.')) {\n var _segment$split = segment.split('.');\n\n var _segment$split2 = _slicedToArray(_segment$split, 2);\n\n var possibleSegment = _segment$split2[0];\n var fileExt = _segment$split2[1];\n\n if (IS_ALPHA_RE.test(fileExt)) {\n segment = possibleSegment;\n }\n }\n\n // If our first or second segment has anything looking like a page\n // number, remove it.\n if (PAGE_IN_HREF_RE.test(segment) && index < 2) {\n segment = segment.replace(PAGE_IN_HREF_RE, '');\n }\n\n // If we're on the first segment, check to see if we have any\n // characters in it. The first segment is actually the last bit of\n // the URL, and this will be helpful to determine if we're on a URL\n // segment that looks like \"/2/\" for example.\n if (index === 0) {\n firstSegmentHasLetters = HAS_ALPHA_RE.test(segment);\n }\n\n // If it's not marked for deletion, push it to cleaned_segments.\n if (isGoodSegment(segment, index, firstSegmentHasLetters)) {\n acc.push(segment);\n }\n\n return acc;\n }, []);\n\n return protocol + '//' + host + cleanedSegments.reverse().join('/');\n}\n\n// Given a string, return True if it appears to have an ending sentence\n// within it, false otherwise.\nvar SENTENCE_END_RE = new RegExp('.( |$)');\nfunction hasSentenceEnd(text) {\n return SENTENCE_END_RE.test(text);\n}\n\nfunction excerptContent(content) {\n var words = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 10;\n\n return content.trim().split(/\\s+/).slice(0, words).join(' ');\n}\n\n// Now that we have a top_candidate, look through the siblings of\n// it to see if any of them are decently scored. If they are, they\n// may be split parts of the content (Like two divs, a preamble and\n// a body.) Example:\n// http://articles.latimes.com/2009/oct/14/business/fi-bigtvs14\nfunction mergeSiblings($candidate, topScore, $) {\n if (!$candidate.parent().length) {\n return $candidate;\n }\n\n var siblingScoreThreshold = Math.max(10, topScore * 0.25);\n var wrappingDiv = $('<div></div>');\n\n $candidate.parent().children().each(function (index, sibling) {\n var $sibling = $(sibling);\n // Ignore tags like BR, HR, etc\n if (NON_TOP_CANDIDATE_TAGS_RE$1.test(sibling.tagName)) {\n return null;\n }\n\n var siblingScore = getScore($sibling);\n if (siblingScore) {\n if ($sibling === $candidate) {\n wrappingDiv.append($sibling);\n } else {\n var contentBonus = 0;\n var density = linkDensity($sibling);\n\n // If sibling has a very low link density,\n // give it a small bonus\n if (density < 0.05) {\n contentBonus += 20;\n }\n\n // If sibling has a high link density,\n // give it a penalty\n if (density >= 0.5) {\n contentBonus -= 20;\n }\n\n // If sibling node has the same class as\n // candidate, give it a bonus\n if ($sibling.attr('class') === $candidate.attr('class')) {\n contentBonus += topScore * 0.2;\n }\n\n var newScore = siblingScore + contentBonus;\n\n if (newScore >= siblingScoreThreshold) {\n return wrappingDiv.append($sibling);\n } else if (sibling.tagName === 'p') {\n var siblingContent = $sibling.text();\n var siblingContentLength = textLength(siblingContent);\n\n if (siblingContentLength > 80 && density < 0.25) {\n return wrappingDiv.append($sibling);\n } else if (siblingContentLength <= 80 && density === 0 && hasSentenceEnd(siblingContent)) {\n return wrappingDiv.append($sibling);\n }\n }\n }\n }\n\n return null;\n });\n\n return wrappingDiv;\n}\n\n// After we've calculated scores, loop through all of the possible\n// candidate nodes we found and find the one with the highest score.\nfunction findTopCandidate($) {\n var $candidate = void 0;\n var topScore = 0;\n\n $('[score]').each(function (index, node) {\n // Ignore tags like BR, HR, etc\n if (NON_TOP_CANDIDATE_TAGS_RE$1.test(node.tagName)) {\n return;\n }\n\n var $node = $(node);\n var score = getScore($node);\n\n if (score > topScore) {\n topScore = score;\n $candidate = $node;\n }\n });\n\n // If we don't have a candidate, return the body\n // or whatever the first element is\n if (!$candidate) {\n return $('body') || $('*').first();\n }\n\n $candidate = mergeSiblings($candidate, topScore, $);\n\n return $candidate;\n}\n\nfunction removeUnlessContent($node, $, weight) {\n // Explicitly save entry-content-asset tags, which are\n // noted as valuable in the Publisher guidelines. For now\n // this works everywhere. We may want to consider making\n // this less of a sure-thing later.\n if ($node.hasClass('entry-content-asset')) {\n return;\n }\n\n var content = normalizeSpaces($node.text());\n\n if (scoreCommas(content) < 10) {\n var pCount = $('p', $node).length;\n var inputCount = $('input', $node).length;\n\n // Looks like a form, too many inputs.\n if (inputCount > pCount / 3) {\n $node.remove();\n return;\n }\n\n var contentLength = content.length;\n var imgCount = $('img', $node).length;\n\n // Content is too short, and there are no images, so\n // this is probably junk content.\n if (contentLength < 25 && imgCount === 0) {\n $node.remove();\n return;\n }\n\n var density = linkDensity($node);\n\n // Too high of link density, is probably a menu or\n // something similar.\n // console.log(weight, density, contentLength)\n if (weight < 25 && density > 0.2 && contentLength > 75) {\n $node.remove();\n return;\n }\n\n // Too high of a link density, despite the score being\n // high.\n if (weight >= 25 && density > 0.5) {\n // Don't remove the node if it's a list and the\n // previous sibling starts with a colon though. That\n // means it's probably content.\n var tagName = $node.get(0).tagName;\n var nodeIsList = tagName === 'ol' || tagName === 'ul';\n if (nodeIsList) {\n var previousNode = $node.prev();\n if (previousNode && normalizeSpaces(previousNode.text()).slice(-1) === ':') {\n return;\n }\n }\n\n $node.remove();\n return;\n }\n\n var scriptCount = $('script', $node).length;\n\n // Too many script tags, not enough content.\n if (scriptCount > 0 && contentLength < 150) {\n $node.remove();\n return;\n }\n }\n}\n\n// Given an article, clean it of some superfluous content specified by\n// tags. Things like forms, ads, etc.\n//\n// Tags is an array of tag name's to search through. (like div, form,\n// etc)\n//\n// Return this same doc.\nfunction cleanTags($article, $) {\n $(CLEAN_CONDITIONALLY_TAGS, $article).each(function (index, node) {\n var $node = $(node);\n var weight = getScore($node);\n if (!weight) {\n weight = getOrInitScore($node, $);\n setScore($node, $, weight);\n }\n\n // drop node if its weight is < 0\n if (weight < 0) {\n $node.remove();\n } else {\n // deteremine if node seems like content\n removeUnlessContent($node, $, weight);\n }\n });\n\n return $;\n}\n\nfunction cleanHeaders($article, $) {\n var title = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';\n\n $(HEADER_TAG_LIST, $article).each(function (index, header) {\n var $header = $(header);\n // Remove any headers that appear before all other p tags in the\n // document. This probably means that it was part of the title, a\n // subtitle or something else extraneous like a datestamp or byline,\n // all of which should be handled by other metadata handling.\n if ($($header, $article).prevAll('p').length === 0) {\n return $header.remove();\n }\n\n // Remove any headers that match the title exactly.\n if (normalizeSpaces($(header).text()) === title) {\n return $header.remove();\n }\n\n // If this header has a negative weight, it's probably junk.\n // Get rid of it.\n if (getWeight($(header)) < 0) {\n return $header.remove();\n }\n\n return $header;\n });\n\n return $;\n}\n\n// Rewrite the tag name to div if it's a top level node like body or\n// html to avoid later complications with multiple body tags.\n\nfunction rewriteTopLevel(article, $) {\n // I'm not using context here because\n // it's problematic when converting the\n // top-level/root node - AP\n $ = convertNodeTo($('html'), $, 'div');\n $ = convertNodeTo($('body'), $, 'div');\n\n return $;\n}\n\nfunction absolutize($, rootUrl, attr, $content) {\n $('[' + attr + ']', $content).each(function (_, node) {\n var url = node.attribs[attr];\n var absoluteUrl = URL.resolve(rootUrl, url);\n\n node.attribs[attr] = absoluteUrl;\n });\n}\n\nfunction makeLinksAbsolute($content, $, url) {\n ['href', 'src'].forEach(function (attr) {\n return absolutize($, url, attr, $content);\n });\n\n return $content;\n}\n\nfunction textLength(text) {\n return text.trim().replace(/\\s+/g, ' ').length;\n}\n\n// Determines what percentage of the text\n// in a node is link text\n// Takes a node, returns a float\nfunction linkDensity($node) {\n var totalTextLength = textLength($node.text());\n\n var linkText = $node.find('a').text();\n var linkLength = textLength(linkText);\n\n if (totalTextLength > 0) {\n return linkLength / totalTextLength;\n } else if (totalTextLength === 0 && linkLength > 0) {\n return 1;\n }\n\n return 0;\n}\n\n// Given a node type to search for, and a list of meta tag names to\n// search for, find a meta tag associated.\n\nfunction extractFromMeta($, metaNames, cachedNames) {\n var cleanTags = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;\n\n var foundNames = metaNames.filter(function (name) {\n return cachedNames.indexOf(name) !== -1;\n });\n\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n var _loop = function _loop() {\n var name = _step.value;\n\n var type = 'name';\n var value = 'value';\n\n var nodes = $('meta[' + type + '=\"' + name + '\"]');\n\n // Get the unique value of every matching node, in case there\n // are two meta tags with the same name and value.\n // Remove empty values.\n var values = nodes.map(function (index, node) {\n return $(node).attr(value);\n }).toArray().filter(function (text) {\n return text !== '';\n });\n\n // If we have more than one value for the same name, we have a\n // conflict and can't trust any of them. Skip this name. If we have\n // zero, that means our meta tags had no values. Skip this name\n // also.\n if (values.length === 1) {\n var metaValue = void 0;\n // Meta values that contain HTML should be stripped, as they\n // weren't subject to cleaning previously.\n if (cleanTags) {\n metaValue = stripTags(values[0], $);\n } else {\n metaValue = values[0];\n }\n\n return {\n v: metaValue\n };\n }\n };\n\n for (var _iterator = _getIterator(foundNames), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var _ret = _loop();\n\n if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === \"object\") return _ret.v;\n }\n\n // If nothing is found, return null\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n return null;\n}\n\nfunction isGoodNode($node, maxChildren) {\n // If it has a number of children, it's more likely a container\n // element. Skip it.\n if ($node.children().length > maxChildren) {\n return false;\n }\n // If it looks to be within a comment, skip it.\n if (withinComment($node)) {\n return false;\n }\n\n return true;\n}\n\n// Given a a list of selectors find content that may\n// be extractable from the document. This is for flat\n// meta-information, like author, title, date published, etc.\nfunction extractFromSelectors($, selectors) {\n var maxChildren = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;\n var textOnly = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = _getIterator(selectors), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var selector = _step.value;\n\n var nodes = $(selector);\n\n // If we didn't get exactly one of this selector, this may be\n // a list of articles or comments. Skip it.\n if (nodes.length === 1) {\n var $node = $(nodes[0]);\n\n if (isGoodNode($node, maxChildren)) {\n var content = void 0;\n if (textOnly) {\n content = $node.text();\n } else {\n content = $node.html();\n }\n\n if (content) {\n return content;\n }\n }\n }\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n return null;\n}\n\n// strips all tags from a string of text\nfunction stripTags(text, $) {\n // Wrapping text in html element prevents errors when text\n // has no html\n var cleanText = $('<span>' + text + '</span>').text();\n return cleanText === '' ? text : cleanText;\n}\n\nfunction withinComment($node) {\n var parents = $node.parents().toArray();\n var commentParent = parents.find(function (parent) {\n var classAndId = parent.attribs.class + ' ' + parent.attribs.id;\n return classAndId.includes('comment');\n });\n\n return commentParent !== undefined;\n}\n\n// Given a node, determine if it's article-like enough to return\n// param: node (a cheerio node)\n// return: boolean\n\nfunction nodeIsSufficient($node) {\n return $node.text().trim().length >= 100;\n}\n\nfunction isWordpress($) {\n return $(IS_WP_SELECTOR).length > 0;\n}\n\n// CLEAN AUTHOR CONSTANTS\nvar CLEAN_AUTHOR_RE = /^\\s*(posted |written )?by\\s*:?\\s*(.*)/i;\n// author = re.sub(r'^\\s*(posted |written )?by\\s*:?\\s*(.*)(?i)',\n\n// CLEAN DEK CONSTANTS\nvar TEXT_LINK_RE = new RegExp('http(s)?://', 'i');\n// CLEAN DATE PUBLISHED CONSTANTS\nvar MS_DATE_STRING = /^\\d{13}$/i;\nvar SEC_DATE_STRING = /^\\d{10}$/i;\nvar CLEAN_DATE_STRING_RE = /^\\s*published\\s*:?\\s*(.*)/i;\nvar TIME_MERIDIAN_SPACE_RE = /(.*\\d)(am|pm)(.*)/i;\nvar TIME_MERIDIAN_DOTS_RE = /\\.m\\./i;\nvar months = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'];\nvar allMonths = months.join('|');\nvar timestamp1 = '[0-9]{1,2}:[0-9]{2,2}( ?[ap].?m.?)?';\nvar timestamp2 = '[0-9]{1,2}[/-][0-9]{1,2}[/-][0-9]{2,4}';\nvar SPLIT_DATE_STRING = new RegExp('(' + timestamp1 + ')|(' + timestamp2 + ')|([0-9]{1,4})|(' + allMonths + ')', 'ig');\n\n// CLEAN TITLE CONSTANTS\n// A regular expression that will match separating characters on a\n// title, that usually denote breadcrumbs or something similar.\nvar TITLE_SPLITTERS_RE = /(: | - | \\| )/g;\n\nvar DOMAIN_ENDINGS_RE = new RegExp('.com$|.net$|.org$|.co.uk$', 'g');\n\n// Take an author string (like 'By David Smith ') and clean it to\n// just the name(s): 'David Smith'.\nfunction cleanAuthor(author) {\n return author.replace(CLEAN_AUTHOR_RE, '$2').trim();\n}\n\nfunction clean$1(leadImageUrl) {\n leadImageUrl = leadImageUrl.trim();\n if (validUrl.isWebUri(leadImageUrl)) {\n return leadImageUrl;\n }\n\n return null;\n}\n\n// Take a dek HTML fragment, and return the cleaned version of it.\n// Return None if the dek wasn't good enough.\nfunction cleanDek(dek, _ref) {\n var $ = _ref.$;\n var excerpt = _ref.excerpt;\n\n // Sanity check that we didn't get too short or long of a dek.\n if (dek.length > 1000 || dek.length < 5) return null;\n\n // Check that dek isn't the same as excerpt\n if (excerpt && excerptContent(excerpt, 10) === excerptContent(dek, 10)) return null;\n\n var dekText = stripTags(dek, $);\n\n // Plain text links shouldn't exist in the dek. If we have some, it's\n // not a good dek - bail.\n if (TEXT_LINK_RE.test(dekText)) return null;\n\n return dekText.trim();\n}\n\n// Is there a compelling reason to use moment here?\n// Mostly only being used for the isValid() method,\n// but could just check for 'Invalid Date' string.\n\nfunction cleanDateString(dateString) {\n return (dateString.match(SPLIT_DATE_STRING) || []).join(' ').replace(TIME_MERIDIAN_DOTS_RE, 'm').replace(TIME_MERIDIAN_SPACE_RE, '$1 $2 $3').replace(CLEAN_DATE_STRING_RE, '$1').trim();\n}\n\n// Take a date published string, and hopefully return a date out of\n// it. Return none if we fail.\nfunction cleanDatePublished(dateString) {\n // If string is in milliseconds or seconds, convert to int\n if (MS_DATE_STRING.test(dateString) || SEC_DATE_STRING.test(dateString)) {\n dateString = parseInt(dateString, 10);\n }\n\n var date = moment(new Date(dateString));\n\n if (!date.isValid()) {\n dateString = cleanDateString(dateString);\n date = moment(new Date(dateString));\n }\n\n return date.isValid() ? date.toISOString() : null;\n}\n\n// Clean our article content, returning a new, cleaned node.\n\nfunction extractCleanNode(article, _ref) {\n var $ = _ref.$;\n var _ref$cleanConditional = _ref.cleanConditionally;\n var cleanConditionally = _ref$cleanConditional === undefined ? true : _ref$cleanConditional;\n var _ref$title = _ref.title;\n var title = _ref$title === undefined ? '' : _ref$title;\n var _ref$url = _ref.url;\n var url = _ref$url === undefined ? '' : _ref$url;\n var _ref$defaultCleaner = _ref.defaultCleaner;\n var defaultCleaner = _ref$defaultCleaner === undefined ? true : _ref$defaultCleaner;\n\n // Rewrite the tag name to div if it's a top level node like body or\n // html to avoid later complications with multiple body tags.\n rewriteTopLevel(article, $);\n\n // Drop small images and spacer images\n // Only do this is defaultCleaner is set to true;\n // this can sometimes be too aggressive.\n if (defaultCleaner) cleanImages(article, $);\n\n // Drop certain tags like <title>, etc\n // This is -mostly- for cleanliness, not security.\n stripJunkTags(article, $);\n\n // H1 tags are typically the article title, which should be extracted\n // by the title extractor instead. If there's less than 3 of them (<3),\n // strip them. Otherwise, turn 'em into H2s.\n cleanHOnes(article, $);\n\n // Clean headers\n cleanHeaders(article, $, title);\n\n // Make links absolute\n makeLinksAbsolute(article, $, url);\n\n // Remove unnecessary attributes\n cleanAttributes(article);\n\n // We used to clean UL's and OL's here, but it was leading to\n // too many in-article lists being removed. Consider a better\n // way to detect menus particularly and remove them.\n // Also optionally running, since it can be overly aggressive.\n if (defaultCleaner) cleanTags(article, $, cleanConditionally);\n\n // Remove empty paragraph nodes\n removeEmpty(article, $);\n\n return article;\n}\n\nfunction cleanTitle(title, _ref) {\n var url = _ref.url;\n var $ = _ref.$;\n\n // If title has |, :, or - in it, see if\n // we can clean it up.\n if (TITLE_SPLITTERS_RE.test(title)) {\n title = resolveSplitTitle(title, url);\n }\n\n // Final sanity check that we didn't get a crazy title.\n // if (title.length > 150 || title.length < 15) {\n if (title.length > 150) {\n // If we did, return h1 from the document if it exists\n var h1 = $('h1');\n if (h1.length === 1) {\n title = h1.text();\n }\n }\n\n // strip any html tags in the title text\n return stripTags(title, $).trim();\n}\n\nfunction extractBreadcrumbTitle(splitTitle, text) {\n // This must be a very breadcrumbed title, like:\n // The Best Gadgets on Earth : Bits : Blogs : NYTimes.com\n // NYTimes - Blogs - Bits - The Best Gadgets on Earth\n if (splitTitle.length >= 6) {\n var _ret = function () {\n // Look to see if we can find a breadcrumb splitter that happens\n // more than once. If we can, we'll be able to better pull out\n // the title.\n var termCounts = splitTitle.reduce(function (acc, titleText) {\n acc[titleText] = acc[titleText] ? acc[titleText] + 1 : 1;\n return acc;\n }, {});\n\n var _Reflect$ownKeys$redu = _Reflect$ownKeys(termCounts).reduce(function (acc, key) {\n if (acc[1] < termCounts[key]) {\n return [key, termCounts[key]];\n }\n\n return acc;\n }, [0, 0]);\n\n var _Reflect$ownKeys$redu2 = _slicedToArray(_Reflect$ownKeys$redu, 2);\n\n var maxTerm = _Reflect$ownKeys$redu2[0];\n var termCount = _Reflect$ownKeys$redu2[1];\n\n // We found a splitter that was used more than once, so it\n // is probably the breadcrumber. Split our title on that instead.\n // Note: max_term should be <= 4 characters, so that \" >> \"\n // will match, but nothing longer than that.\n\n if (termCount >= 2 && maxTerm.length <= 4) {\n splitTitle = text.split(maxTerm);\n }\n\n var splitEnds = [splitTitle[0], splitTitle.slice(-1)];\n var longestEnd = splitEnds.reduce(function (acc, end) {\n return acc.length > end.length ? acc : end;\n }, '');\n\n if (longestEnd.length > 10) {\n return {\n v: longestEnd\n };\n }\n\n return {\n v: text\n };\n }();\n\n if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === \"object\") return _ret.v;\n }\n\n return null;\n}\n\nfunction cleanDomainFromTitle(splitTitle, url) {\n // Search the ends of the title, looking for bits that fuzzy match\n // the URL too closely. If one is found, discard it and return the\n // rest.\n //\n // Strip out the big TLDs - it just makes the matching a bit more\n // accurate. Not the end of the world if it doesn't strip right.\n var _URL$parse = URL.parse(url);\n\n var host = _URL$parse.host;\n\n var nakedDomain = host.replace(DOMAIN_ENDINGS_RE, '');\n\n var startSlug = splitTitle[0].toLowerCase().replace(' ', '');\n var startSlugRatio = wuzzy.levenshtein(startSlug, nakedDomain);\n\n if (startSlugRatio > 0.4 && startSlug.length > 5) {\n return splitTitle.slice(2).join('');\n }\n\n var endSlug = splitTitle.slice(-1)[0].toLowerCase().replace(' ', '');\n var endSlugRatio = wuzzy.levenshtein(endSlug, nakedDomain);\n\n if (endSlugRatio > 0.4 && endSlug.length >= 5) {\n return splitTitle.slice(0, -2).join('');\n }\n\n return null;\n}\n\n// Given a title with separators in it (colons, dashes, etc),\n// resolve whether any of the segments should be removed.\nfunction resolveSplitTitle(title) {\n var url = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';\n\n // Splits while preserving splitters, like:\n // ['The New New York', ' - ', 'The Washington Post']\n var splitTitle = title.split(TITLE_SPLITTERS_RE);\n if (splitTitle.length === 1) {\n return title;\n }\n\n var newTitle = extractBreadcrumbTitle(splitTitle, title);\n if (newTitle) return newTitle;\n\n newTitle = cleanDomainFromTitle(splitTitle, url);\n if (newTitle) return newTitle;\n\n // Fuzzy ratio didn't find anything, so this title is probably legit.\n // Just return it all.\n return title;\n}\n\nvar Cleaners = {\n author: cleanAuthor,\n lead_image_url: clean$1,\n dek: cleanDek,\n date_published: cleanDatePublished,\n content: extractCleanNode,\n title: cleanTitle\n};\n\n// Using a variety of scoring techniques, extract the content most\n// likely to be article text.\n//\n// If strip_unlikely_candidates is True, remove any elements that\n// match certain criteria first. (Like, does this element have a\n// classname of \"comment\")\n//\n// If weight_nodes is True, use classNames and IDs to determine the\n// worthiness of nodes.\n//\n// Returns a cheerio object $\nfunction extractBestNode($, opts) {\n // clone the node so we can get back to our\n // initial parsed state if needed\n // TODO Do I need this? – AP\n // let $root = $.root().clone()\n\n\n if (opts.stripUnlikelyCandidates) {\n $ = stripUnlikelyCandidates($);\n }\n\n $ = convertToParagraphs($);\n $ = scoreContent($, opts.weightNodes);\n var $topCandidate = findTopCandidate($);\n\n return $topCandidate;\n}\n\nvar GenericContentExtractor = {\n defaultOpts: {\n stripUnlikelyCandidates: true,\n weightNodes: true,\n cleanConditionally: true\n },\n\n // Extract the content for this resource - initially, pass in our\n // most restrictive opts which will return the highest quality\n // content. On each failure, retry with slightly more lax opts.\n //\n // :param return_type: string. If \"node\", should return the content\n // as a cheerio node rather than as an HTML string.\n //\n // Opts:\n // stripUnlikelyCandidates: Remove any elements that match\n // non-article-like criteria first.(Like, does this element\n // have a classname of \"comment\")\n //\n // weightNodes: Modify an elements score based on whether it has\n // certain classNames or IDs. Examples: Subtract if a node has\n // a className of 'comment', Add if a node has an ID of\n // 'entry-content'.\n //\n // cleanConditionally: Clean the node to return of some\n // superfluous content. Things like forms, ads, etc.\n extract: function extract(_ref, opts) {\n var $ = _ref.$;\n var html = _ref.html;\n var title = _ref.title;\n var url = _ref.url;\n\n opts = _extends({}, this.defaultOpts, opts);\n\n $ = $ || cheerio.load(html);\n\n // Cascade through our extraction-specific opts in an ordered fashion,\n // turning them off as we try to extract content.\n var node = this.getContentNode($, title, url, opts);\n\n if (nodeIsSufficient(node)) {\n return this.cleanAndReturnNode(node, $);\n }\n\n // We didn't succeed on first pass, one by one disable our\n // extraction opts and try again.\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = _getIterator(_Reflect$ownKeys(opts).filter(function (k) {\n return opts[k] === true;\n })), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var key = _step.value;\n\n opts[key] = false;\n $ = cheerio.load(html);\n\n node = this.getContentNode($, title, url, opts);\n\n if (nodeIsSufficient(node)) {\n break;\n }\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n return this.cleanAndReturnNode(node, $);\n },\n\n\n // Get node given current options\n getContentNode: function getContentNode($, title, url, opts) {\n return extractCleanNode(extractBestNode($, opts), {\n $: $,\n cleanConditionally: opts.cleanConditionally,\n title: title,\n url: url\n });\n },\n\n\n // Once we got here, either we're at our last-resort node, or\n // we broke early. Make sure we at least have -something- before we\n // move forward.\n cleanAndReturnNode: function cleanAndReturnNode(node, $) {\n if (!node) {\n return null;\n }\n\n return normalizeSpaces($.html(node));\n\n // if return_type == \"html\":\n // return normalize_spaces(node_to_html(node))\n // else:\n // return node\n }\n};\n\n// TODO: It would be great if we could merge the meta and selector lists into\n// a list of objects, because we could then rank them better. For example,\n// .hentry .entry-title is far better suited than <meta title>.\n\n// An ordered list of meta tag names that denote likely article titles. All\n// attributes should be lowercase for faster case-insensitive matching. From\n// most distinct to least distinct.\nvar STRONG_TITLE_META_TAGS = ['tweetmeme-title', 'dc.title', 'rbtitle', 'headline', 'title'];\n\n// og:title is weak because it typically contains context that we don't like,\n// for example the source site's name. Gotta get that brand into facebook!\nvar WEAK_TITLE_META_TAGS = ['og:title'];\n\n// An ordered list of XPath Selectors to find likely article titles. From\n// most explicit to least explicit.\n//\n// Note - this does not use classes like CSS. This checks to see if the string\n// exists in the className, which is not as accurate as .className (which\n// splits on spaces/endlines), but for our purposes it's close enough. The\n// speed tradeoff is worth the accuracy hit.\nvar STRONG_TITLE_SELECTORS = ['.hentry .entry-title', 'h1#articleHeader', 'h1.articleHeader', 'h1.article', '.instapaper_title', '#meebo-title'];\n\nvar WEAK_TITLE_SELECTORS = ['article h1', '#entry-title', '.entry-title', '#entryTitle', '#entrytitle', '.entryTitle', '.entrytitle', '#articleTitle', '.articleTitle', 'post post-title', 'h1.title', 'h2.article', 'h1', 'html head title', 'title'];\n\nvar GenericTitleExtractor = {\n extract: function extract(_ref) {\n var $ = _ref.$;\n var url = _ref.url;\n var metaCache = _ref.metaCache;\n\n // First, check to see if we have a matching meta tag that we can make\n // use of that is strongly associated with the headline.\n var title = void 0;\n\n title = extractFromMeta($, STRONG_TITLE_META_TAGS, metaCache);\n if (title) return cleanTitle(title, { url: url, $: $ });\n\n // Second, look through our content selectors for the most likely\n // article title that is strongly associated with the headline.\n title = extractFromSelectors($, STRONG_TITLE_SELECTORS);\n if (title) return cleanTitle(title, { url: url, $: $ });\n\n // Third, check for weaker meta tags that may match.\n title = extractFromMeta($, WEAK_TITLE_META_TAGS, metaCache);\n if (title) return cleanTitle(title, { url: url, $: $ });\n\n // Last, look for weaker selector tags that may match.\n title = extractFromSelectors($, WEAK_TITLE_SELECTORS);\n if (title) return cleanTitle(title, { url: url, $: $ });\n\n // If no matches, return an empty string\n return '';\n }\n};\n\n// An ordered list of meta tag names that denote likely article authors. All\n// attributes should be lowercase for faster case-insensitive matching. From\n// most distinct to least distinct.\n//\n// Note: \"author\" is too often the -developer- of the page, so it is not\n// added here.\nvar AUTHOR_META_TAGS = ['byl', 'clmst', 'dc.author', 'dcsext.author', 'dc.creator', 'rbauthors', 'authors'];\n\nvar AUTHOR_MAX_LENGTH = 300;\n\n// An ordered list of XPath Selectors to find likely article authors. From\n// most explicit to least explicit.\n//\n// Note - this does not use classes like CSS. This checks to see if the string\n// exists in the className, which is not as accurate as .className (which\n// splits on spaces/endlines), but for our purposes it's close enough. The\n// speed tradeoff is worth the accuracy hit.\nvar AUTHOR_SELECTORS = ['.entry .entry-author', '.author.vcard .fn', '.author .vcard .fn', '.byline.vcard .fn', '.byline .vcard .fn', '.byline .by .author', '.byline .by', '.byline .author', '.post-author.vcard', '.post-author .vcard', 'a[rel=author]', '#by_author', '.by_author', '#entryAuthor', '.entryAuthor', '.byline a[href*=author]', '#author .authorname', '.author .authorname', '#author', '.author', '.articleauthor', '.ArticleAuthor', '.byline'];\n\n// An ordered list of Selectors to find likely article authors, with\n// regular expression for content.\nvar bylineRe = /^[\\n\\s]*By/i;\nvar BYLINE_SELECTORS_RE = [['#byline', bylineRe], ['.byline', bylineRe]];\n\nvar GenericAuthorExtractor = {\n extract: function extract(_ref) {\n var $ = _ref.$;\n var metaCache = _ref.metaCache;\n\n var author = void 0;\n\n // First, check to see if we have a matching\n // meta tag that we can make use of.\n author = extractFromMeta($, AUTHOR_META_TAGS, metaCache);\n if (author && author.length < AUTHOR_MAX_LENGTH) {\n return cleanAuthor(author);\n }\n\n // Second, look through our selectors looking for potential authors.\n author = extractFromSelectors($, AUTHOR_SELECTORS, 2);\n if (author && author.length < AUTHOR_MAX_LENGTH) {\n return cleanAuthor(author);\n }\n\n // Last, use our looser regular-expression based selectors for\n // potential authors.\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = _getIterator(BYLINE_SELECTORS_RE), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var _ref4 = _step.value;\n\n var _ref3 = _slicedToArray(_ref4, 2);\n\n var selector = _ref3[0];\n var regex = _ref3[1];\n\n var node = $(selector);\n if (node.length === 1) {\n var text = node.text();\n if (regex.test(text)) {\n return cleanAuthor(text);\n }\n }\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n return null;\n }\n};\n\n// An ordered list of meta tag names that denote\n// likely date published dates. All attributes\n// should be lowercase for faster case-insensitive matching.\n// From most distinct to least distinct.\nvar DATE_PUBLISHED_META_TAGS = ['article:published_time', 'displaydate', 'dc.date', 'dc.date.issued', 'rbpubdate', 'publish_date', 'pub_date', 'pagedate', 'pubdate', 'revision_date', 'doc_date', 'date_created', 'content_create_date', 'lastmodified', 'created', 'date'];\n\n// An ordered list of XPath Selectors to find\n// likely date published dates. From most explicit\n// to least explicit.\nvar DATE_PUBLISHED_SELECTORS = ['.hentry .dtstamp.published', '.hentry .published', '.hentry .dtstamp.updated', '.hentry .updated', '.single .published', '.meta .published', '.meta .postDate', '.entry-date', '.byline .date', '.postmetadata .date', '.article_datetime', '.date-header', '.story-date', '.dateStamp', '#story .datetime', '.dateline', '.pubdate'];\n\n// An ordered list of compiled regular expressions to find likely date\n// published dates from the URL. These should always have the first\n// reference be a date string that is parseable by dateutil.parser.parse\nvar abbrevMonthsStr = '(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)';\nvar DATE_PUBLISHED_URL_RES = [\n// /2012/01/27/ but not /2012/01/293\nnew RegExp('/(20\\\\d{2}/\\\\d{2}/\\\\d{2})/', 'i'),\n// 20120127 or 20120127T but not 2012012733 or 8201201733\n// /[^0-9](20\\d{2}[01]\\d[0-3]\\d)([^0-9]|$)/i,\n// 2012-01-27\nnew RegExp('(20\\\\d{2}-[01]\\\\d-[0-3]\\\\d)', 'i'),\n// /2012/jan/27/\nnew RegExp('/(20\\\\d{2}/' + abbrevMonthsStr + '/[0-3]\\\\d)/', 'i')];\n\nvar GenericDatePublishedExtractor = {\n extract: function extract(_ref) {\n var $ = _ref.$;\n var url = _ref.url;\n var metaCache = _ref.metaCache;\n\n var datePublished = void 0;\n // First, check to see if we have a matching meta tag\n // that we can make use of.\n // Don't try cleaning tags from this string\n datePublished = extractFromMeta($, DATE_PUBLISHED_META_TAGS, metaCache, false);\n if (datePublished) return cleanDatePublished(datePublished);\n\n // Second, look through our selectors looking for potential\n // date_published's.\n datePublished = extractFromSelectors($, DATE_PUBLISHED_SELECTORS);\n if (datePublished) return cleanDatePublished(datePublished);\n\n // Lastly, look to see if a dately string exists in the URL\n datePublished = extractFromUrl(url, DATE_PUBLISHED_URL_RES);\n if (datePublished) return cleanDatePublished(datePublished);\n\n return null;\n }\n};\n\n// import {\n// DEK_META_TAGS,\n// DEK_SELECTORS,\n// DEK_URL_RES,\n// } from './constants';\n\n// import { cleanDek } from 'cleaners';\n\n// import {\n// extractFromMeta,\n// extractFromSelectors,\n// } from 'utils/dom';\n\n// Currently there is only one selector for\n// deks. We should simply return null here\n// until we have a more robust generic option.\n// Below is the original source for this, for reference.\nvar GenericDekExtractor = {\n // extract({ $, content, metaCache }) {\n extract: function extract() {\n return null;\n }\n};\n\n// An ordered list of meta tag names that denote likely article leading images.\n// All attributes should be lowercase for faster case-insensitive matching.\n// From most distinct to least distinct.\nvar LEAD_IMAGE_URL_META_TAGS = ['og:image', 'twitter:image', 'image_src'];\n\nvar LEAD_IMAGE_URL_SELECTORS = ['link[rel=image_src]'];\n\nvar POSITIVE_LEAD_IMAGE_URL_HINTS = ['upload', 'wp-content', 'large', 'photo', 'wp-image'];\nvar POSITIVE_LEAD_IMAGE_URL_HINTS_RE = new RegExp(POSITIVE_LEAD_IMAGE_URL_HINTS.join('|'), 'i');\n\nvar NEGATIVE_LEAD_IMAGE_URL_HINTS = ['spacer', 'sprite', 'blank', 'throbber', 'gradient', 'tile', 'bg', 'background', 'icon', 'social', 'header', 'hdr', 'advert', 'spinner', 'loader', 'loading', 'default', 'rating', 'share', 'facebook', 'twitter', 'theme', 'promo', 'ads', 'wp-includes'];\nvar NEGATIVE_LEAD_IMAGE_URL_HINTS_RE = new RegExp(NEGATIVE_LEAD_IMAGE_URL_HINTS.join('|'), 'i');\n\nvar GIF_RE = /\\.gif(\\?.*)?$/i;\nvar JPG_RE = /\\.jpe?g(\\?.*)?$/i;\n\nfunction getSig($node) {\n return ($node.attr('class') || '') + ' ' + ($node.attr('id') || '');\n}\n\n// Scores image urls based on a variety of heuristics.\nfunction scoreImageUrl(url) {\n url = url.trim();\n var score = 0;\n\n if (POSITIVE_LEAD_IMAGE_URL_HINTS_RE.test(url)) {\n score += 20;\n }\n\n if (NEGATIVE_LEAD_IMAGE_URL_HINTS_RE.test(url)) {\n score -= 20;\n }\n\n // TODO: We might want to consider removing this as\n // gifs are much more common/popular than they once were\n if (GIF_RE.test(url)) {\n score -= 10;\n }\n\n if (JPG_RE.test(url)) {\n score += 10;\n }\n\n // PNGs are neutral.\n\n return score;\n}\n\n// Alt attribute usually means non-presentational image.\nfunction scoreAttr($img) {\n if ($img.attr('alt')) {\n return 5;\n }\n\n return 0;\n}\n\n// Look through our parent and grandparent for figure-like\n// container elements, give a bonus if we find them\nfunction scoreByParents($img) {\n var score = 0;\n var $figParent = $img.parents('figure').first();\n\n if ($figParent.length === 1) {\n score += 25;\n }\n\n var $parent = $img.parent();\n var $gParent = void 0;\n if ($parent.length === 1) {\n $gParent = $parent.parent();\n }\n\n [$parent, $gParent].forEach(function ($node) {\n if (PHOTO_HINTS_RE$1.test(getSig($node))) {\n score += 15;\n }\n });\n\n return score;\n}\n\n// Look at our immediate sibling and see if it looks like it's a\n// caption. Bonus if so.\nfunction scoreBySibling($img) {\n var score = 0;\n var $sibling = $img.next();\n var sibling = $sibling.get(0);\n\n if (sibling && sibling.tagName === 'figcaption') {\n score += 25;\n }\n\n if (PHOTO_HINTS_RE$1.test(getSig($sibling))) {\n score += 15;\n }\n\n return score;\n}\n\nfunction scoreByDimensions($img) {\n var score = 0;\n\n var width = parseFloat($img.attr('width'));\n var height = parseFloat($img.attr('height'));\n var src = $img.attr('src');\n\n // Penalty for skinny images\n if (width && width <= 50) {\n score -= 50;\n }\n\n // Penalty for short images\n if (height && height <= 50) {\n score -= 50;\n }\n\n if (width && height && !src.includes('sprite')) {\n var area = width * height;\n if (area < 5000) {\n // Smaller than 50 x 100\n score -= 100;\n } else {\n score += Math.round(area / 1000);\n }\n }\n\n return score;\n}\n\nfunction scoreByPosition($imgs, index) {\n return $imgs.length / 2 - index;\n}\n\n// Given a resource, try to find the lead image URL from within\n// it. Like content and next page extraction, uses a scoring system\n// to determine what the most likely image may be. Short circuits\n// on really probable things like og:image meta tags.\n//\n// Potential signals to still take advantage of:\n// * domain\n// * weird aspect ratio\nvar GenericLeadImageUrlExtractor = {\n extract: function extract(_ref) {\n var $ = _ref.$;\n var content = _ref.content;\n var metaCache = _ref.metaCache;\n\n var cleanUrl = void 0;\n\n // Check to see if we have a matching meta tag that we can make use of.\n // Moving this higher because common practice is now to use large\n // images on things like Open Graph or Twitter cards.\n // images usually have for things like Open Graph.\n var imageUrl = extractFromMeta($, LEAD_IMAGE_URL_META_TAGS, metaCache, false);\n\n if (imageUrl) {\n cleanUrl = clean$1(imageUrl);\n\n if (cleanUrl) return cleanUrl;\n }\n\n // Next, try to find the \"best\" image via the content.\n // We'd rather not have to fetch each image and check dimensions,\n // so try to do some analysis and determine them instead.\n var imgs = $('img', content).toArray();\n var imgScores = {};\n\n imgs.forEach(function (img, index) {\n var $img = $(img);\n var src = $img.attr('src');\n\n if (!src) return;\n\n var score = scoreImageUrl(src);\n score += scoreAttr($img);\n score += scoreByParents($img);\n score += scoreBySibling($img);\n score += scoreByDimensions($img);\n score += scoreByPosition(imgs, index);\n\n imgScores[src] = score;\n });\n\n var _Reflect$ownKeys$redu = _Reflect$ownKeys(imgScores).reduce(function (acc, key) {\n return imgScores[key] > acc[1] ? [key, imgScores[key]] : acc;\n }, [null, 0]);\n\n var _Reflect$ownKeys$redu2 = _slicedToArray(_Reflect$ownKeys$redu, 2);\n\n var topUrl = _Reflect$ownKeys$redu2[0];\n var topScore = _Reflect$ownKeys$redu2[1];\n\n\n if (topScore > 0) {\n cleanUrl = clean$1(topUrl);\n\n if (cleanUrl) return cleanUrl;\n }\n\n // If nothing else worked, check to see if there are any really\n // probable nodes in the doc, like <link rel=\"image_src\" />.\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = _getIterator(LEAD_IMAGE_URL_SELECTORS), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var selector = _step.value;\n\n var $node = $(selector).first();\n var src = $node.attr('src');\n if (src) {\n cleanUrl = clean$1(src);\n if (cleanUrl) return cleanUrl;\n }\n\n var href = $node.attr('href');\n if (href) {\n cleanUrl = clean$1(href);\n if (cleanUrl) return cleanUrl;\n }\n\n var value = $node.attr('value');\n if (value) {\n cleanUrl = clean$1(value);\n if (cleanUrl) return cleanUrl;\n }\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n return null;\n }\n};\n\nfunction scoreSimilarity(score, articleUrl, href) {\n // Do this last and only if we have a real candidate, because it's\n // potentially expensive computationally. Compare the link to this\n // URL using difflib to get the % similarity of these URLs. On a\n // sliding scale, subtract points from this link based on\n // similarity.\n if (score > 0) {\n var similarity = new difflib.SequenceMatcher(null, articleUrl, href).ratio();\n // Subtract .1 from diff_percent when calculating modifier,\n // which means that if it's less than 10% different, we give a\n // bonus instead. Ex:\n // 3% different = +17.5 points\n // 10% different = 0 points\n // 20% different = -25 points\n var diffPercent = 1.0 - similarity;\n var diffModifier = -(250 * (diffPercent - 0.2));\n return score + diffModifier;\n }\n\n return 0;\n}\n\nfunction scoreLinkText(linkText, pageNum) {\n // If the link text can be parsed as a number, give it a minor\n // bonus, with a slight bias towards lower numbered pages. This is\n // so that pages that might not have 'next' in their text can still\n // get scored, and sorted properly by score.\n var score = 0;\n\n if (IS_DIGIT_RE.test(linkText.trim())) {\n var linkTextAsNum = parseInt(linkText, 10);\n // If it's the first page, we already got it on the first call.\n // Give it a negative score. Otherwise, up to page 10, give a\n // small bonus.\n if (linkTextAsNum < 2) {\n score = -30;\n } else {\n score = Math.max(0, 10 - linkTextAsNum);\n }\n\n // If it appears that the current page number is greater than\n // this links page number, it's a very bad sign. Give it a big\n // penalty.\n if (pageNum && pageNum >= linkTextAsNum) {\n score -= 50;\n }\n }\n\n return score;\n}\n\nfunction scorePageInLink(pageNum, isWp) {\n // page in the link = bonus. Intentionally ignore wordpress because\n // their ?p=123 link style gets caught by this even though it means\n // separate documents entirely.\n if (pageNum && !isWp) {\n return 50;\n }\n\n return 0;\n}\n\nvar DIGIT_RE$2 = /\\d/;\n\n// A list of words that, if found in link text or URLs, likely mean that\n// this link is not a next page link.\nvar EXTRANEOUS_LINK_HINTS$1 = ['print', 'archive', 'comment', 'discuss', 'e-mail', 'email', 'share', 'reply', 'all', 'login', 'sign', 'single', 'adx', 'entry-unrelated'];\nvar EXTRANEOUS_LINK_HINTS_RE$1 = new RegExp(EXTRANEOUS_LINK_HINTS$1.join('|'), 'i');\n\n// Match any link text/classname/id that looks like it could mean the next\n// page. Things like: next, continue, >, >>, » but not >|, »| as those can\n// mean last page.\nvar NEXT_LINK_TEXT_RE$1 = new RegExp('(next|weiter|continue|>([^|]|$)|»([^|]|$))', 'i');\n\n// Match any link text/classname/id that looks like it is an end link: things\n// like \"first\", \"last\", \"end\", etc.\nvar CAP_LINK_TEXT_RE$1 = new RegExp('(first|last|end)', 'i');\n\n// Match any link text/classname/id that looks like it means the previous\n// page.\nvar PREV_LINK_TEXT_RE$1 = new RegExp('(prev|earl|old|new|<|«)', 'i');\n\nfunction scoreExtraneousLinks(href) {\n // If the URL itself contains extraneous values, give a penalty.\n if (EXTRANEOUS_LINK_HINTS_RE$1.test(href)) {\n return -25;\n }\n\n return 0;\n}\n\nfunction makeSig$1($link) {\n return ($link.attr('class') || '') + ' ' + ($link.attr('id') || '');\n}\n\nfunction scoreByParents$1($link) {\n // If a parent node contains paging-like classname or id, give a\n // bonus. Additionally, if a parent_node contains bad content\n // (like 'sponsor'), give a penalty.\n var $parent = $link.parent();\n var positiveMatch = false;\n var negativeMatch = false;\n var score = 0;\n\n _Array$from(range(0, 4)).forEach(function () {\n if ($parent.length === 0) {\n return;\n }\n\n var parentData = makeSig$1($parent, ' ');\n\n // If we have 'page' or 'paging' in our data, that's a good\n // sign. Add a bonus.\n if (!positiveMatch && PAGE_RE.test(parentData)) {\n positiveMatch = true;\n score += 25;\n }\n\n // If we have 'comment' or something in our data, and\n // we don't have something like 'content' as well, that's\n // a bad sign. Give a penalty.\n if (!negativeMatch && NEGATIVE_SCORE_RE.test(parentData) && EXTRANEOUS_LINK_HINTS_RE$1.test(parentData)) {\n if (!POSITIVE_SCORE_RE.test(parentData)) {\n negativeMatch = true;\n score -= 25;\n }\n }\n\n $parent = $parent.parent();\n });\n\n return score;\n}\n\nfunction scorePrevLink(linkData) {\n // If the link has something like \"previous\", its definitely\n // an old link, skip it.\n if (PREV_LINK_TEXT_RE$1.test(linkData)) {\n return -200;\n }\n\n return 0;\n}\n\nfunction shouldScore(href, articleUrl, baseUrl, parsedUrl, linkText, previousUrls) {\n // skip if we've already fetched this url\n if (previousUrls.find(function (url) {\n return href === url;\n }) !== undefined) {\n return false;\n }\n\n // If we've already parsed this URL, or the URL matches the base\n // URL, or is empty, skip it.\n if (!href || href === articleUrl || href === baseUrl) {\n return false;\n }\n\n var hostname = parsedUrl.hostname;\n\n var _URL$parse = URL.parse(href);\n\n var linkHost = _URL$parse.hostname;\n\n // Domain mismatch.\n\n if (linkHost !== hostname) {\n return false;\n }\n\n // If href doesn't contain a digit after removing the base URL,\n // it's certainly not the next page.\n var fragment = href.replace(baseUrl, '');\n if (!DIGIT_RE$2.test(fragment)) {\n return false;\n }\n\n // This link has extraneous content (like \"comment\") in its link\n // text, so we skip it.\n if (EXTRANEOUS_LINK_HINTS_RE$1.test(linkText)) {\n return false;\n }\n\n // Next page link text is never long, skip if it is too long.\n if (linkText.length > 25) {\n return false;\n }\n\n return true;\n}\n\nfunction scoreBaseUrl(href, baseRegex) {\n // If the baseUrl isn't part of this URL, penalize this\n // link. It could still be the link, but the odds are lower.\n // Example:\n // http://www.actionscript.org/resources/articles/745/1/JavaScript-and-VBScript-Injection-in-ActionScript-3/Page1.html\n if (!baseRegex.test(href)) {\n return -25;\n }\n\n return 0;\n}\n\nfunction scoreNextLinkText(linkData) {\n // Things like \"next\", \">>\", etc.\n if (NEXT_LINK_TEXT_RE$1.test(linkData)) {\n return 50;\n }\n\n return 0;\n}\n\nfunction scoreCapLinks(linkData) {\n // Cap links are links like \"last\", etc.\n if (CAP_LINK_TEXT_RE$1.test(linkData)) {\n // If we found a link like \"last\", but we've already seen that\n // this link is also \"next\", it's fine. If it's not been\n // previously marked as \"next\", then it's probably bad.\n // Penalize.\n if (NEXT_LINK_TEXT_RE$1.test(linkData)) {\n return -65;\n }\n }\n\n return 0;\n}\n\nfunction makeBaseRegex(baseUrl) {\n return new RegExp('^' + baseUrl, 'i');\n}\n\nfunction makeSig($link, linkText) {\n return (linkText || $link.text()) + ' ' + ($link.attr('class') || '') + ' ' + ($link.attr('id') || '');\n}\n\nfunction scoreLinks(_ref) {\n var links = _ref.links;\n var articleUrl = _ref.articleUrl;\n var baseUrl = _ref.baseUrl;\n var parsedUrl = _ref.parsedUrl;\n var $ = _ref.$;\n var _ref$previousUrls = _ref.previousUrls;\n var previousUrls = _ref$previousUrls === undefined ? [] : _ref$previousUrls;\n\n parsedUrl = parsedUrl || URL.parse(articleUrl);\n var baseRegex = makeBaseRegex(baseUrl);\n var isWp = isWordpress($);\n\n // Loop through all links, looking for hints that they may be next-page\n // links. Things like having \"page\" in their textContent, className or\n // id, or being a child of a node with a page-y className or id.\n //\n // After we do that, assign each page a score, and pick the one that\n // looks most like the next page link, as long as its score is strong\n // enough to have decent confidence.\n var scoredPages = links.reduce(function (possiblePages, link) {\n // Remove any anchor data since we don't do a good job\n // standardizing URLs (it's hard), we're going to do\n // some checking with and without a trailing slash\n var href = removeAnchor(link.attribs.href);\n var $link = $(link);\n var linkText = $link.text();\n\n if (!shouldScore(href, articleUrl, baseUrl, parsedUrl, linkText, previousUrls)) {\n return possiblePages;\n }\n\n // ## PASSED THE FIRST-PASS TESTS. Start scoring. ##\n if (!possiblePages[href]) {\n possiblePages[href] = {\n score: 0,\n linkText: linkText,\n href: href\n };\n } else {\n possiblePages[href].linkText = possiblePages[href].linkText + '|' + linkText;\n }\n\n var possiblePage = possiblePages[href];\n var linkData = makeSig($link, linkText);\n var pageNum = pageNumFromUrl(href);\n\n var score = scoreBaseUrl(href, baseRegex);\n score += scoreNextLinkText(linkData);\n score += scoreCapLinks(linkData);\n score += scorePrevLink(linkData);\n score += scoreByParents$1($link);\n score += scoreExtraneousLinks(href);\n score += scorePageInLink(pageNum, isWp);\n score += scoreLinkText(linkText, pageNum);\n score += scoreSimilarity(score, articleUrl, href);\n\n possiblePage.score = score;\n\n return possiblePages;\n }, {});\n\n return _Reflect$ownKeys(scoredPages).length === 0 ? null : scoredPages;\n}\n\n// Looks for and returns next page url\n// for multi-page articles\nvar GenericNextPageUrlExtractor = {\n extract: function extract(_ref) {\n var $ = _ref.$;\n var url = _ref.url;\n var parsedUrl = _ref.parsedUrl;\n var _ref$previousUrls = _ref.previousUrls;\n var previousUrls = _ref$previousUrls === undefined ? [] : _ref$previousUrls;\n\n parsedUrl = parsedUrl || URL.parse(url);\n\n var articleUrl = removeAnchor(url);\n var baseUrl = articleBaseUrl(url, parsedUrl);\n\n var links = $('a[href]').toArray();\n\n var scoredLinks = scoreLinks({\n links: links,\n articleUrl: articleUrl,\n baseUrl: baseUrl,\n parsedUrl: parsedUrl,\n $: $,\n previousUrls: previousUrls\n });\n\n // If no links were scored, return null\n if (!scoredLinks) return null;\n\n // now that we've scored all possible pages,\n // find the biggest one.\n var topPage = _Reflect$ownKeys(scoredLinks).reduce(function (acc, link) {\n var scoredLink = scoredLinks[link];\n return scoredLink.score > acc.score ? scoredLink : acc;\n }, { score: -100 });\n\n // If the score is less than 50, we're not confident enough to use it,\n // so we fail.\n if (topPage.score >= 50) {\n return topPage.href;\n }\n\n return null;\n }\n};\n\nvar CANONICAL_META_SELECTORS = ['og:url'];\n\nfunction parseDomain(url) {\n var parsedUrl = URL.parse(url);\n var hostname = parsedUrl.hostname;\n\n return hostname;\n}\n\nfunction result(url) {\n return {\n url: url,\n domain: parseDomain(url)\n };\n}\n\nvar GenericUrlExtractor = {\n extract: function extract(_ref) {\n var $ = _ref.$;\n var url = _ref.url;\n var metaCache = _ref.metaCache;\n\n var $canonical = $('link[rel=canonical]');\n if ($canonical.length !== 0) {\n var href = $canonical.attr('href');\n if (href) {\n return result(href);\n }\n }\n\n var metaUrl = extractFromMeta($, CANONICAL_META_SELECTORS, metaCache);\n if (metaUrl) {\n return result(metaUrl);\n }\n\n return result(url);\n }\n};\n\nvar EXCERPT_META_SELECTORS = ['og:description', 'twitter:description'];\n\nfunction clean$2(content, $) {\n var maxLength = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 200;\n\n content = content.replace(/[\\s\\n]+/g, ' ').trim();\n return ellipsize(content, maxLength, { ellipse: '…' });\n}\n\nvar GenericExcerptExtractor = {\n extract: function extract(_ref) {\n var $ = _ref.$;\n var content = _ref.content;\n var metaCache = _ref.metaCache;\n\n var excerpt = extractFromMeta($, EXCERPT_META_SELECTORS, metaCache);\n if (excerpt) {\n return clean$2(stripTags(excerpt, $));\n }\n // Fall back to excerpting from the extracted content\n var maxLength = 200;\n var shortContent = content.slice(0, maxLength * 5);\n return clean$2($(shortContent).text(), $, maxLength);\n }\n};\n\nvar GenericWordCountExtractor = {\n extract: function extract(_ref) {\n var content = _ref.content;\n\n var $ = cheerio.load(content);\n\n var text = normalizeSpaces($('div').first().text());\n return text.split(/\\s/).length;\n }\n};\n\nvar GenericExtractor = {\n // This extractor is the default for all domains\n domain: '*',\n title: GenericTitleExtractor.extract,\n date_published: GenericDatePublishedExtractor.extract,\n author: GenericAuthorExtractor.extract,\n content: GenericContentExtractor.extract.bind(GenericContentExtractor),\n lead_image_url: GenericLeadImageUrlExtractor.extract,\n dek: GenericDekExtractor.extract,\n next_page_url: GenericNextPageUrlExtractor.extract,\n url_and_domain: GenericUrlExtractor.extract,\n excerpt: GenericExcerptExtractor.extract,\n word_count: GenericWordCountExtractor.extract,\n direction: function direction(_ref) {\n var title = _ref.title;\n return stringDirection.getDirection(title);\n },\n\n extract: function extract(options) {\n var html = options.html;\n\n\n if (html) {\n var $ = cheerio.load(html);\n options.$ = $;\n }\n\n var title = this.title(options);\n var date_published = this.date_published(options);\n var author = this.author(options);\n var content = this.content(_extends({}, options, { title: title }));\n var lead_image_url = this.lead_image_url(_extends({}, options, { content: content }));\n var dek = this.dek(_extends({}, options, { content: content }));\n var next_page_url = this.next_page_url(options);\n var excerpt = this.excerpt(_extends({}, options, { content: content }));\n var word_count = this.word_count(_extends({}, options, { content: content }));\n var direction = this.direction({ title: title });\n\n var _url_and_domain = this.url_and_domain(options);\n\n var url = _url_and_domain.url;\n var domain = _url_and_domain.domain;\n\n\n return {\n title: title,\n author: author,\n date_published: date_published || null,\n dek: dek,\n lead_image_url: lead_image_url,\n content: content,\n next_page_url: next_page_url,\n url: url,\n domain: domain,\n excerpt: excerpt,\n word_count: word_count,\n direction: direction\n };\n }\n};\n\nfunction getExtractor(url, parsedUrl) {\n parsedUrl = parsedUrl || URL.parse(url);\n var _parsedUrl = parsedUrl;\n var hostname = _parsedUrl.hostname;\n\n var baseDomain = hostname.split('.').slice(-2).join('.');\n\n return Extractors[hostname] || Extractors[baseDomain] || GenericExtractor;\n}\n\n// Remove elements by an array of selectors\nfunction cleanBySelectors($content, $, _ref) {\n var clean = _ref.clean;\n\n if (!clean) return $content;\n\n $(clean.join(','), $content).remove();\n\n return $content;\n}\n\n// Transform matching elements\nfunction transformElements($content, $, _ref2) {\n var transforms = _ref2.transforms;\n\n if (!transforms) return $content;\n\n _Reflect$ownKeys(transforms).forEach(function (key) {\n var $matches = $(key, $content);\n var value = transforms[key];\n\n // If value is a string, convert directly\n if (typeof value === 'string') {\n $matches.each(function (index, node) {\n convertNodeTo($(node), $, transforms[key]);\n });\n } else if (typeof value === 'function') {\n // If value is function, apply function to node\n $matches.each(function (index, node) {\n var result = value($(node), $);\n // If function returns a string, convert node to that value\n if (typeof result === 'string') {\n convertNodeTo($(node), $, result);\n }\n });\n }\n });\n\n return $content;\n}\n\nfunction findMatchingSelector($, selectors) {\n return selectors.find(function (selector) {\n if (Array.isArray(selector)) {\n var _selector = _slicedToArray(selector, 2);\n\n var s = _selector[0];\n var attr = _selector[1];\n\n return $(s).length === 1 && $(s).attr(attr) && $(s).attr(attr).trim() !== '';\n }\n\n return $(selector).length === 1 && $(selector).text().trim() !== '';\n });\n}\n\nfunction select(opts) {\n var $ = opts.$;\n var type = opts.type;\n var extractionOpts = opts.extractionOpts;\n var _opts$extractHtml = opts.extractHtml;\n var extractHtml = _opts$extractHtml === undefined ? false : _opts$extractHtml;\n // Skip if there's not extraction for this type\n\n if (!extractionOpts) return null;\n\n // If a string is hardcoded for a type (e.g., Wikipedia\n // contributors), return the string\n if (typeof extractionOpts === 'string') return extractionOpts;\n\n var selectors = extractionOpts.selectors;\n var _extractionOpts$defau = extractionOpts.defaultCleaner;\n var defaultCleaner = _extractionOpts$defau === undefined ? true : _extractionOpts$defau;\n\n\n var matchingSelector = findMatchingSelector($, selectors);\n\n if (!matchingSelector) return null;\n\n // Declaring result; will contain either\n // text or html, which will be cleaned\n // by the appropriate cleaner type\n\n // If the selector type requests html as its return type\n // transform and clean the element with provided selectors\n if (extractHtml) {\n var $content = $(matchingSelector);\n\n // Wrap in div so transformation can take place on root element\n $content.wrap($('<div></div>'));\n $content = $content.parent();\n\n $content = transformElements($content, $, extractionOpts);\n $content = cleanBySelectors($content, $, extractionOpts);\n\n $content = Cleaners[type]($content, _extends({}, opts, { defaultCleaner: defaultCleaner }));\n\n return $.html($content);\n }\n\n var result = void 0;\n\n // if selector is an array (e.g., ['img', 'src']),\n // extract the attr\n if (Array.isArray(matchingSelector)) {\n var _matchingSelector = _slicedToArray(matchingSelector, 2);\n\n var selector = _matchingSelector[0];\n var attr = _matchingSelector[1];\n\n result = $(selector).attr(attr).trim();\n } else {\n result = $(matchingSelector).text().trim();\n }\n\n // Allow custom extractor to skip default cleaner\n // for this type; defaults to true\n if (defaultCleaner) {\n return Cleaners[type](result, opts);\n }\n\n return result;\n}\n\nfunction extractResult(opts) {\n var type = opts.type;\n var extractor = opts.extractor;\n var _opts$fallback = opts.fallback;\n var fallback = _opts$fallback === undefined ? true : _opts$fallback;\n\n\n var result = select(_extends({}, opts, { extractionOpts: extractor[type] }));\n\n // If custom parser succeeds, return the result\n if (result) {\n return result;\n }\n\n // If nothing matches the selector, and fallback is enabled,\n // run the Generic extraction\n if (fallback) return GenericExtractor[type](opts);\n\n return null;\n}\n\nvar RootExtractor = {\n extract: function extract() {\n var extractor = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : GenericExtractor;\n var opts = arguments[1];\n var _opts = opts;\n var contentOnly = _opts.contentOnly;\n var extractedTitle = _opts.extractedTitle;\n // This is the generic extractor. Run its extract method\n\n if (extractor.domain === '*') return extractor.extract(opts);\n\n opts = _extends({}, opts, {\n extractor: extractor\n });\n\n if (contentOnly) {\n var _content = extractResult(_extends({}, opts, { type: 'content', extractHtml: true, title: extractedTitle\n }));\n return {\n content: _content\n };\n }\n var title = extractResult(_extends({}, opts, { type: 'title' }));\n var date_published = extractResult(_extends({}, opts, { type: 'date_published' }));\n var author = extractResult(_extends({}, opts, { type: 'author' }));\n var next_page_url = extractResult(_extends({}, opts, { type: 'next_page_url' }));\n var content = extractResult(_extends({}, opts, { type: 'content', extractHtml: true, title: title\n }));\n var lead_image_url = extractResult(_extends({}, opts, { type: 'lead_image_url', content: content }));\n var excerpt = extractResult(_extends({}, opts, { type: 'excerpt', content: content }));\n var dek = extractResult(_extends({}, opts, { type: 'dek', content: content, excerpt: excerpt }));\n var word_count = extractResult(_extends({}, opts, { type: 'word_count', content: content }));\n var direction = extractResult(_extends({}, opts, { type: 'direction', title: title }));\n\n var _ref3 = extractResult(_extends({}, opts, { type: 'url_and_domain' })) || { url: null, domain: null };\n\n var url = _ref3.url;\n var domain = _ref3.domain;\n\n\n return {\n title: title,\n content: content,\n author: author,\n date_published: date_published,\n lead_image_url: lead_image_url,\n dek: dek,\n next_page_url: next_page_url,\n url: url,\n domain: domain,\n excerpt: excerpt,\n word_count: word_count,\n direction: direction\n };\n }\n};\n\nvar collectAllPages = (function () {\n var _ref = _asyncToGenerator(_regeneratorRuntime.mark(function _callee(_ref2) {\n var next_page_url = _ref2.next_page_url;\n var html = _ref2.html;\n var $ = _ref2.$;\n var metaCache = _ref2.metaCache;\n var result = _ref2.result;\n var Extractor = _ref2.Extractor;\n var title = _ref2.title;\n var url = _ref2.url;\n var pages, previousUrls, extractorOpts, nextPageResult, word_count;\n return _regeneratorRuntime.wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n // At this point, we've fetched just the first page\n pages = 1;\n previousUrls = [removeAnchor(url)];\n\n // If we've gone over 26 pages, something has\n // likely gone wrong.\n\n case 2:\n if (!(next_page_url && pages < 26)) {\n _context.next = 15;\n break;\n }\n\n pages += 1;\n _context.next = 6;\n return Resource.create(next_page_url);\n\n case 6:\n $ = _context.sent;\n\n html = $.html();\n\n extractorOpts = {\n url: next_page_url,\n html: html,\n $: $,\n metaCache: metaCache,\n contentOnly: true,\n extractedTitle: title,\n previousUrls: previousUrls\n };\n nextPageResult = RootExtractor.extract(Extractor, extractorOpts);\n\n\n previousUrls.push(next_page_url);\n result = _extends({}, result, {\n content: '\\n ' + result.content + '\\n <hr>\\n <h4>Page ' + pages + '</h4>\\n ' + nextPageResult.content + '\\n '\n });\n\n next_page_url = nextPageResult.next_page_url;\n _context.next = 2;\n break;\n\n case 15:\n word_count = GenericExtractor.word_count({ content: '<div>' + result.content + '</div>' });\n return _context.abrupt('return', _extends({}, result, {\n total_pages: pages,\n pages_rendered: pages,\n word_count: word_count\n }));\n\n case 17:\n case 'end':\n return _context.stop();\n }\n }\n }, _callee, this);\n }));\n\n function collectAllPages(_x) {\n return _ref.apply(this, arguments);\n }\n\n return collectAllPages;\n})();\n\nvar Mercury = {\n parse: function parse(url, html) {\n var _this = this;\n\n var opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n return _asyncToGenerator(_regeneratorRuntime.mark(function _callee() {\n var _opts$fetchAllPages, fetchAllPages, _opts$fallback, fallback, parsedUrl, Extractor, $, metaCache, result, _result, title, next_page_url;\n\n return _regeneratorRuntime.wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n _opts$fetchAllPages = opts.fetchAllPages;\n fetchAllPages = _opts$fetchAllPages === undefined ? true : _opts$fetchAllPages;\n _opts$fallback = opts.fallback;\n fallback = _opts$fallback === undefined ? true : _opts$fallback;\n parsedUrl = URL.parse(url);\n\n if (validateUrl(parsedUrl)) {\n _context.next = 7;\n break;\n }\n\n return _context.abrupt('return', Errors.badUrl);\n\n case 7:\n Extractor = getExtractor(url, parsedUrl);\n // console.log(`Using extractor for ${Extractor.domain}`);\n\n _context.next = 10;\n return Resource.create(url, html, parsedUrl);\n\n case 10:\n $ = _context.sent;\n\n if (!$.error) {\n _context.next = 13;\n break;\n }\n\n return _context.abrupt('return', $);\n\n case 13:\n\n html = $.html();\n\n // Cached value of every meta name in our document.\n // Used when extracting title/author/date_published/dek\n metaCache = $('meta').map(function (_, node) {\n return $(node).attr('name');\n }).toArray();\n result = RootExtractor.extract(Extractor, { url: url, html: html, $: $, metaCache: metaCache, parsedUrl: parsedUrl, fallback: fallback });\n _result = result;\n title = _result.title;\n next_page_url = _result.next_page_url;\n\n // Fetch more pages if next_page_url found\n\n if (!(fetchAllPages && next_page_url)) {\n _context.next = 25;\n break;\n }\n\n _context.next = 22;\n return collectAllPages({\n Extractor: Extractor,\n next_page_url: next_page_url,\n html: html,\n $: $,\n metaCache: metaCache,\n result: result,\n title: title,\n url: url\n });\n\n case 22:\n result = _context.sent;\n _context.next = 26;\n break;\n\n case 25:\n result = _extends({}, result, {\n total_pages: 1,\n rendered_pages: 1\n });\n\n case 26:\n return _context.abrupt('return', result);\n\n case 27:\n case 'end':\n return _context.stop();\n }\n }\n }, _callee, _this);\n }))();\n },\n\n\n // A convenience method for getting a resource\n // to work with, e.g., for custom extractor generator\n fetchResource: function fetchResource(url) {\n var _this2 = this;\n\n return _asyncToGenerator(_regeneratorRuntime.mark(function _callee2() {\n return _regeneratorRuntime.wrap(function _callee2$(_context2) {\n while (1) {\n switch (_context2.prev = _context2.next) {\n case 0:\n _context2.next = 2;\n return Resource.create(url);\n\n case 2:\n return _context2.abrupt('return', _context2.sent);\n\n case 3:\n case 'end':\n return _context2.stop();\n }\n }\n }, _callee2, _this2);\n }))();\n }\n};\n\nmodule.exports = Mercury;\n//# sourceMappingURL=mercury.js.map\n","// Spacer images to be removed\nexport const SPACER_RE = new RegExp('trans|transparent|spacer|blank', 'i');\n\n// A list of tags to strip from the output if we encounter them.\nexport const STRIP_OUTPUT_TAGS = [\n 'title',\n 'script',\n 'noscript',\n 'link',\n 'style',\n 'hr',\n 'embed',\n 'iframe',\n 'object',\n];\n\n// cleanAttributes\nexport const REMOVE_ATTRS = ['style', 'align'];\nexport const REMOVE_ATTR_SELECTORS = REMOVE_ATTRS.map(selector => `[${selector}]`);\nexport const REMOVE_ATTR_LIST = REMOVE_ATTRS.join(',');\nexport const WHITELIST_ATTRS = ['src', 'srcset', 'href', 'class', 'id', 'alt', 'score'];\nexport const WHITELIST_ATTRS_RE = new RegExp(`^(${WHITELIST_ATTRS.join('|')})$`, 'i');\n\n// removeEmpty\nexport const REMOVE_EMPTY_TAGS = ['p'];\nexport const REMOVE_EMPTY_SELECTORS = REMOVE_EMPTY_TAGS.map(tag => `${tag}:empty`).join(',');\n\n// cleanTags\nexport const CLEAN_CONDITIONALLY_TAGS = ['ul', 'ol', 'table', 'div', 'button', 'form'].join(',');\n\n// cleanHeaders\nconst HEADER_TAGS = ['h2', 'h3', 'h4', 'h5', 'h6'];\nexport const HEADER_TAG_LIST = HEADER_TAGS.join(',');\n\n\n// // CONTENT FETCHING CONSTANTS ////\n\n// A list of strings that can be considered unlikely candidates when\n// extracting content from a resource. These strings are joined together\n// and then tested for existence using re:test, so may contain simple,\n// non-pipe style regular expression queries if necessary.\nexport const UNLIKELY_CANDIDATES_BLACKLIST = [\n 'ad-break',\n 'adbox',\n 'advert',\n 'addthis',\n 'agegate',\n 'aux',\n 'blogger-labels',\n 'combx',\n 'comment',\n 'conversation',\n 'disqus',\n 'entry-unrelated',\n 'extra',\n 'foot',\n // 'form', // This is too generic, has too many false positives\n 'header',\n 'hidden',\n 'loader',\n 'login', // Note: This can hit 'blogindex'.\n 'menu',\n 'meta',\n 'nav',\n 'outbrain',\n 'pager',\n 'pagination',\n 'predicta', // readwriteweb inline ad box\n 'presence_control_external', // lifehacker.com container full of false positives\n 'popup',\n 'printfriendly',\n 'related',\n 'remove',\n 'remark',\n 'rss',\n 'share',\n 'shoutbox',\n 'sidebar',\n 'sociable',\n 'sponsor',\n 'taboola',\n 'tools',\n];\n\n// A list of strings that can be considered LIKELY candidates when\n// extracting content from a resource. Essentially, the inverse of the\n// blacklist above - if something matches both blacklist and whitelist,\n// it is kept. This is useful, for example, if something has a className\n// of \"rss-content entry-content\". It matched 'rss', so it would normally\n// be removed, however, it's also the entry content, so it should be left\n// alone.\n//\n// These strings are joined together and then tested for existence using\n// re:test, so may contain simple, non-pipe style regular expression queries\n// if necessary.\nexport const UNLIKELY_CANDIDATES_WHITELIST = [\n 'and',\n 'article',\n 'body',\n 'blogindex',\n 'column',\n 'content',\n 'entry-content-asset',\n 'format', // misuse of form\n 'hfeed',\n 'hentry',\n 'hatom',\n 'main',\n 'page',\n 'posts',\n 'shadow',\n];\n\n// A list of tags which, if found inside, should cause a <div /> to NOT\n// be turned into a paragraph tag. Shallow div tags without these elements\n// should be turned into <p /> tags.\nexport const DIV_TO_P_BLOCK_TAGS = [\n 'a',\n 'blockquote',\n 'dl',\n 'div',\n 'img',\n 'p',\n 'pre',\n 'table',\n].join(',');\n\n// A list of tags that should be ignored when trying to find the top candidate\n// for a document.\nexport const NON_TOP_CANDIDATE_TAGS = [\n 'br',\n 'b',\n 'i',\n 'label',\n 'hr',\n 'area',\n 'base',\n 'basefont',\n 'input',\n 'img',\n 'link',\n 'meta',\n];\n\nexport const NON_TOP_CANDIDATE_TAGS_RE =\n new RegExp(`^(${NON_TOP_CANDIDATE_TAGS.join('|')})$`, 'i');\n\n// A list of selectors that specify, very clearly, either hNews or other\n// very content-specific style content, like Blogger templates.\n// More examples here: http://microformats.org/wiki/blog-post-formats\nexport const HNEWS_CONTENT_SELECTORS = [\n ['.hentry', '.entry-content'],\n ['entry', '.entry-content'],\n ['.entry', '.entry_content'],\n ['.post', '.postbody'],\n ['.post', '.post_body'],\n ['.post', '.post-body'],\n];\n\nexport const PHOTO_HINTS = [\n 'figure',\n 'photo',\n 'image',\n 'caption',\n];\nexport const PHOTO_HINTS_RE = new RegExp(PHOTO_HINTS.join('|'), 'i');\n\n\n// A list of strings that denote a positive scoring for this content as being\n// an article container. Checked against className and id.\n//\n// TODO: Perhaps have these scale based on their odds of being quality?\nexport const POSITIVE_SCORE_HINTS = [\n 'article',\n 'articlecontent',\n 'instapaper_body',\n 'blog',\n 'body',\n 'content',\n 'entry-content-asset',\n 'entry',\n 'hentry',\n 'main',\n 'Normal',\n 'page',\n 'pagination',\n 'permalink',\n 'post',\n 'story',\n 'text',\n '[-_]copy', // usatoday\n '\\\\Bcopy',\n];\n\n// The above list, joined into a matching regular expression\nexport const POSITIVE_SCORE_RE = new RegExp(POSITIVE_SCORE_HINTS.join('|'), 'i');\n\n// Readability publisher-specific guidelines\nexport const READABILITY_ASSET = new RegExp('entry-content-asset', 'i');\n\n// A list of strings that denote a negative scoring for this content as being\n// an article container. Checked against className and id.\n//\n// TODO: Perhaps have these scale based on their odds of being quality?\nexport const NEGATIVE_SCORE_HINTS = [\n 'adbox',\n 'advert',\n 'author',\n 'bio',\n 'bookmark',\n 'bottom',\n 'byline',\n 'clear',\n 'com-',\n 'combx',\n 'comment',\n 'comment\\\\B',\n 'contact',\n 'copy',\n 'credit',\n 'crumb',\n 'date',\n 'deck',\n 'excerpt',\n 'featured', // tnr.com has a featured_content which throws us off\n 'foot',\n 'footer',\n 'footnote',\n 'graf',\n 'head',\n 'info',\n 'infotext', // newscientist.com copyright\n 'instapaper_ignore',\n 'jump',\n 'linebreak',\n 'link',\n 'masthead',\n 'media',\n 'meta',\n 'modal',\n 'outbrain', // slate.com junk\n 'promo',\n 'pr_', // autoblog - press release\n 'related',\n 'respond',\n 'roundcontent', // lifehacker restricted content warning\n 'scroll',\n 'secondary',\n 'share',\n 'shopping',\n 'shoutbox',\n 'side',\n 'sidebar',\n 'sponsor',\n 'stamp',\n 'sub',\n 'summary',\n 'tags',\n 'tools',\n 'widget',\n];\n// The above list, joined into a matching regular expression\nexport const NEGATIVE_SCORE_RE = new RegExp(NEGATIVE_SCORE_HINTS.join('|'), 'i');\n\n// XPath to try to determine if a page is wordpress. Not always successful.\nexport const IS_WP_SELECTOR = 'meta[name=generator][value^=WordPress]';\n\n// Match a digit. Pretty clear.\nexport const DIGIT_RE = new RegExp('[0-9]');\n\n// A list of words that, if found in link text or URLs, likely mean that\n// this link is not a next page link.\nexport const EXTRANEOUS_LINK_HINTS = [\n 'print',\n 'archive',\n 'comment',\n 'discuss',\n 'e-mail',\n 'email',\n 'share',\n 'reply',\n 'all',\n 'login',\n 'sign',\n 'single',\n 'adx',\n 'entry-unrelated',\n];\nexport const EXTRANEOUS_LINK_HINTS_RE = new RegExp(EXTRANEOUS_LINK_HINTS.join('|'), 'i');\n\n// Match any phrase that looks like it could be page, or paging, or pagination\nexport const PAGE_RE = new RegExp('pag(e|ing|inat)', 'i');\n\n// Match any link text/classname/id that looks like it could mean the next\n// page. Things like: next, continue, >, >>, » but not >|, »| as those can\n// mean last page.\n// export const NEXT_LINK_TEXT_RE = new RegExp('(next|weiter|continue|>([^\\|]|$)|»([^\\|]|$))', 'i');\nexport const NEXT_LINK_TEXT_RE = /(next|weiter|continue|>([^\\|]|$)|»([^\\|]|$))/i;\n\n// Match any link text/classname/id that looks like it is an end link: things\n// like \"first\", \"last\", \"end\", etc.\nexport const CAP_LINK_TEXT_RE = new RegExp('(first|last|end)', 'i');\n\n// Match any link text/classname/id that looks like it means the previous\n// page.\nexport const PREV_LINK_TEXT_RE = new RegExp('(prev|earl|old|new|<|«)', 'i');\n\n// Match 2 or more consecutive <br> tags\nexport const BR_TAGS_RE = new RegExp('(<br[^>]*>[ \\n\\r\\t]*){2,}', 'i');\n\n// Match 1 BR tag.\nexport const BR_TAG_RE = new RegExp('<br[^>]*>', 'i');\n\n// A list of all of the block level tags known in HTML5 and below. Taken from\n// http://bit.ly/qneNIT\nexport const BLOCK_LEVEL_TAGS = [\n 'article',\n 'aside',\n 'blockquote',\n 'body',\n 'br',\n 'button',\n 'canvas',\n 'caption',\n 'col',\n 'colgroup',\n 'dd',\n 'div',\n 'dl',\n 'dt',\n 'embed',\n 'fieldset',\n 'figcaption',\n 'figure',\n 'footer',\n 'form',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'header',\n 'hgroup',\n 'hr',\n 'li',\n 'map',\n 'object',\n 'ol',\n 'output',\n 'p',\n 'pre',\n 'progress',\n 'section',\n 'table',\n 'tbody',\n 'textarea',\n 'tfoot',\n 'th',\n 'thead',\n 'tr',\n 'ul',\n 'video',\n];\nexport const BLOCK_LEVEL_TAGS_RE = new RegExp(`^(${BLOCK_LEVEL_TAGS.join('|')})$`, 'i');\n\n\n// The removal is implemented as a blacklist and whitelist, this test finds\n// blacklisted elements that aren't whitelisted. We do this all in one\n// expression-both because it's only one pass, and because this skips the\n// serialization for whitelisted nodes.\nconst candidatesBlacklist = UNLIKELY_CANDIDATES_BLACKLIST.join('|');\nexport const CANDIDATES_BLACKLIST = new RegExp(candidatesBlacklist, 'i');\n\nconst candidatesWhitelist = UNLIKELY_CANDIDATES_WHITELIST.join('|');\nexport const CANDIDATES_WHITELIST = new RegExp(candidatesWhitelist, 'i');\n\nexport const UNLIKELY_RE = new RegExp(`!(${candidatesWhitelist})|(${candidatesBlacklist})`, 'i');\n\n\nexport const PARAGRAPH_SCORE_TAGS = new RegExp('^(p|li|span|pre)$', 'i');\nexport const CHILD_CONTENT_TAGS = new RegExp('^(td|blockquote|ol|ul|dl)$', 'i');\nexport const BAD_TAGS = new RegExp('^(address|form)$', 'i');\n\nexport const HTML_OR_BODY_RE = new RegExp('^(html|body)$', 'i');\n","import {\n STRIP_OUTPUT_TAGS,\n} from './constants';\n\nexport default function stripJunkTags(article, $, tags = []) {\n if (tags.length === 0) {\n tags = STRIP_OUTPUT_TAGS;\n }\n\n $(tags.join(','), article).remove();\n\n return $;\n}\n","// // CONTENT FETCHING CONSTANTS ////\n\n// A list of strings that can be considered unlikely candidates when\n// extracting content from a resource. These strings are joined together\n// and then tested for existence using re:test, so may contain simple,\n// non-pipe style regular expression queries if necessary.\nexport const UNLIKELY_CANDIDATES_BLACKLIST = [\n 'ad-break',\n 'adbox',\n 'advert',\n 'addthis',\n 'agegate',\n 'aux',\n 'blogger-labels',\n 'combx',\n 'comment',\n 'conversation',\n 'disqus',\n 'entry-unrelated',\n 'extra',\n 'foot',\n 'form',\n 'header',\n 'hidden',\n 'loader',\n 'login', // Note: This can hit 'blogindex'.\n 'menu',\n 'meta',\n 'nav',\n 'pager',\n 'pagination',\n 'predicta', // readwriteweb inline ad box\n 'presence_control_external', // lifehacker.com container full of false positives\n 'popup',\n 'printfriendly',\n 'related',\n 'remove',\n 'remark',\n 'rss',\n 'share',\n 'shoutbox',\n 'sidebar',\n 'sociable',\n 'sponsor',\n 'tools',\n];\n\n// A list of strings that can be considered LIKELY candidates when\n// extracting content from a resource. Essentially, the inverse of the\n// blacklist above - if something matches both blacklist and whitelist,\n// it is kept. This is useful, for example, if something has a className\n// of \"rss-content entry-content\". It matched 'rss', so it would normally\n// be removed, however, it's also the entry content, so it should be left\n// alone.\n//\n// These strings are joined together and then tested for existence using\n// re:test, so may contain simple, non-pipe style regular expression queries\n// if necessary.\nexport const UNLIKELY_CANDIDATES_WHITELIST = [\n 'and',\n 'article',\n 'body',\n 'blogindex',\n 'column',\n 'content',\n 'entry-content-asset',\n 'format', // misuse of form\n 'hfeed',\n 'hentry',\n 'hatom',\n 'main',\n 'page',\n 'posts',\n 'shadow',\n];\n\n// A list of tags which, if found inside, should cause a <div /> to NOT\n// be turned into a paragraph tag. Shallow div tags without these elements\n// should be turned into <p /> tags.\nexport const DIV_TO_P_BLOCK_TAGS = [\n 'a',\n 'blockquote',\n 'dl',\n 'div',\n 'img',\n 'p',\n 'pre',\n 'table',\n].join(',');\n\n// A list of tags that should be ignored when trying to find the top candidate\n// for a document.\nexport const NON_TOP_CANDIDATE_TAGS = [\n 'br',\n 'b',\n 'i',\n 'label',\n 'hr',\n 'area',\n 'base',\n 'basefont',\n 'input',\n 'img',\n 'link',\n 'meta',\n];\n\nexport const NON_TOP_CANDIDATE_TAGS_RE =\n new RegExp(`^(${NON_TOP_CANDIDATE_TAGS.join('|')})$`, 'i');\n\n// A list of selectors that specify, very clearly, either hNews or other\n// very content-specific style content, like Blogger templates.\n// More examples here: http://microformats.org/wiki/blog-post-formats\nexport const HNEWS_CONTENT_SELECTORS = [\n ['.hentry', '.entry-content'],\n ['entry', '.entry-content'],\n ['.entry', '.entry_content'],\n ['.post', '.postbody'],\n ['.post', '.post_body'],\n ['.post', '.post-body'],\n];\n\nexport const PHOTO_HINTS = [\n 'figure',\n 'photo',\n 'image',\n 'caption',\n];\nexport const PHOTO_HINTS_RE = new RegExp(PHOTO_HINTS.join('|'), 'i');\n\n\n// A list of strings that denote a positive scoring for this content as being\n// an article container. Checked against className and id.\n//\n// TODO: Perhaps have these scale based on their odds of being quality?\nexport const POSITIVE_SCORE_HINTS = [\n 'article',\n 'articlecontent',\n 'instapaper_body',\n 'blog',\n 'body',\n 'content',\n 'entry-content-asset',\n 'entry',\n 'hentry',\n 'main',\n 'Normal',\n 'page',\n 'pagination',\n 'permalink',\n 'post',\n 'story',\n 'text',\n '[-_]copy', // usatoday\n '\\\\Bcopy',\n];\n\n// The above list, joined into a matching regular expression\nexport const POSITIVE_SCORE_RE = new RegExp(POSITIVE_SCORE_HINTS.join('|'), 'i');\n\n// Readability publisher-specific guidelines\nexport const READABILITY_ASSET = new RegExp('entry-content-asset', 'i');\n\n// A list of strings that denote a negative scoring for this content as being\n// an article container. Checked against className and id.\n//\n// TODO: Perhaps have these scale based on their odds of being quality?\nexport const NEGATIVE_SCORE_HINTS = [\n 'adbox',\n 'advert',\n 'author',\n 'bio',\n 'bookmark',\n 'bottom',\n 'byline',\n 'clear',\n 'com-',\n 'combx',\n 'comment',\n 'comment\\\\B',\n 'contact',\n 'copy',\n 'credit',\n 'crumb',\n 'date',\n 'deck',\n 'excerpt',\n 'featured', // tnr.com has a featured_content which throws us off\n 'foot',\n 'footer',\n 'footnote',\n 'graf',\n 'head',\n 'info',\n 'infotext', // newscientist.com copyright\n 'instapaper_ignore',\n 'jump',\n 'linebreak',\n 'link',\n 'masthead',\n 'media',\n 'meta',\n 'modal',\n 'outbrain', // slate.com junk\n 'promo',\n 'pr_', // autoblog - press release\n 'related',\n 'respond',\n 'roundcontent', // lifehacker restricted content warning\n 'scroll',\n 'secondary',\n 'share',\n 'shopping',\n 'shoutbox',\n 'side',\n 'sidebar',\n 'sponsor',\n 'stamp',\n 'sub',\n 'summary',\n 'tags',\n 'tools',\n 'widget',\n];\n// The above list, joined into a matching regular expression\nexport const NEGATIVE_SCORE_RE = new RegExp(NEGATIVE_SCORE_HINTS.join('|'), 'i');\n\n// Match a digit. Pretty clear.\nexport const DIGIT_RE = new RegExp('[0-9]');\n\n// Match 2 or more consecutive <br> tags\nexport const BR_TAGS_RE = new RegExp('(<br[^>]*>[ \\n\\r\\t]*){2,}', 'i');\n\n// Match 1 BR tag.\nexport const BR_TAG_RE = new RegExp('<br[^>]*>', 'i');\n\n// A list of all of the block level tags known in HTML5 and below. Taken from\n// http://bit.ly/qneNIT\nexport const BLOCK_LEVEL_TAGS = [\n 'article',\n 'aside',\n 'blockquote',\n 'body',\n 'br',\n 'button',\n 'canvas',\n 'caption',\n 'col',\n 'colgroup',\n 'dd',\n 'div',\n 'dl',\n 'dt',\n 'embed',\n 'fieldset',\n 'figcaption',\n 'figure',\n 'footer',\n 'form',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'header',\n 'hgroup',\n 'hr',\n 'li',\n 'map',\n 'object',\n 'ol',\n 'output',\n 'p',\n 'pre',\n 'progress',\n 'section',\n 'table',\n 'tbody',\n 'textarea',\n 'tfoot',\n 'th',\n 'thead',\n 'tr',\n 'ul',\n 'video',\n];\nexport const BLOCK_LEVEL_TAGS_RE = new RegExp(`^(${BLOCK_LEVEL_TAGS.join('|')})$`, 'i');\n\n\n// The removal is implemented as a blacklist and whitelist, this test finds\n// blacklisted elements that aren't whitelisted. We do this all in one\n// expression-both because it's only one pass, and because this skips the\n// serialization for whitelisted nodes.\nconst candidatesBlacklist = UNLIKELY_CANDIDATES_BLACKLIST.join('|');\nexport const CANDIDATES_BLACKLIST = new RegExp(candidatesBlacklist, 'i');\n\nconst candidatesWhitelist = UNLIKELY_CANDIDATES_WHITELIST.join('|');\nexport const CANDIDATES_WHITELIST = new RegExp(candidatesWhitelist, 'i');\n\nexport const UNLIKELY_RE = new RegExp(`!(${candidatesWhitelist})|(${candidatesBlacklist})`, 'i');\n\n\nexport const PARAGRAPH_SCORE_TAGS = new RegExp('^(p|li|span|pre)$', 'i');\nexport const CHILD_CONTENT_TAGS = new RegExp('^(td|blockquote|ol|ul|dl)$', 'i');\nexport const BAD_TAGS = new RegExp('^(address|form)$', 'i');\n\nexport const HTML_OR_BODY_RE = new RegExp('^(html|body)$', 'i');\n","import URL from 'url';\n\nfunction absolutize($, rootUrl, attr, $content) {\n $(`[${attr}]`, $content).each((_, node) => {\n const url = node.attribs[attr];\n const absoluteUrl = URL.resolve(rootUrl, url);\n\n node.attribs[attr] = absoluteUrl;\n });\n}\n\nexport default function makeLinksAbsolute($content, $, url) {\n ['href', 'src'].forEach(attr => absolutize($, url, attr, $content));\n\n return $content;\n}\n","export default function insertValues(strings, ...values) {\n if (values.length) {\n return strings.reduce((result, part, idx) => {\n let value = values[idx];\n\n if (value && typeof value.toString === 'function') {\n value = value.toString();\n } else {\n value = '';\n }\n\n return result + part + value;\n }, '');\n }\n\n return strings.join('');\n}\n","import insertValues from './insert-values'\n\nconst bodyPattern = /^\\n([\\s\\S]+)\\s{2}$/gm;\nconst trailingWhitespace = /\\s+$/;\n\nexport default function template(strings, ...values) {\n const compiled = insertValues(strings, ...values);\n let [body] = compiled.match(bodyPattern) || [];\n let indentLevel = /^\\s{0,4}(.+)$/g;\n\n if (!body) {\n body = compiled;\n indentLevel = /^\\s{0,2}(.+)$/g;\n }\n\n return body.split('\\n')\n .slice(1)\n .map((line) => {\n line = line.replace(indentLevel, '$1');\n\n if (trailingWhitespace.test(line)) {\n line = line.replace(trailingWhitespace, '');\n }\n\n return line;\n })\n .join('\\n');\n}\n","import template from './index';\n\nexport default function (hostname) {\n return template`\n // Rename CustomExtractor\n // to fit your publication\n // (e.g., NYTimesExtractor)\n export const CustomExtractor = {\n domain: '${hostname}',\n title: {\n selectors: [\n // enter title selectors\n ],\n },\n\n author: {\n selectors: [\n // enter author selectors\n ],\n },\n\n content: {\n selectors: [\n // enter content selectors\n ],\n\n // Is there anything in the content you selected that needs transformed\n // before it's consumable content? E.g., unusual lazy loaded images\n transforms: {\n },\n\n // Is there anything that is in the result that shouldn't be?\n // The clean selectors will remove anything that matches from\n // the result\n clean: [\n\n ]\n },\n\n date_published: {\n selectors: [\n // enter selectors\n ],\n },\n\n lead_image_url: {\n selectors: [\n // enter selectors\n ],\n },\n\n dek: {\n selectors: [\n // enter selectors\n ],\n },\n\n next_page_url: {\n selectors: [\n // enter selectors\n ],\n },\n\n excerpt: {\n selectors: [\n // enter selectors\n ],\n },\n }\n `;\n}\n","import template from './index';\n\nconst IGNORE = [\n 'url',\n 'domain',\n 'content',\n 'word_count',\n 'next_page_url',\n 'excerpt',\n 'direction',\n 'total_pages',\n 'rendered_pages',\n]\n\nfunction testFor(key, value, dir, file, url) {\n if (IGNORE.find(k => k === key)) return ''\n\n return template`\n it('returns the ${key}', async () => {\n // To pass this test, fill out the ${key} selector\n // in ${dir}/index.js.\n const html =\n fs.readFileSync('${file}');\n const articleUrl =\n '${url}';\n\n const { ${key} } =\n await Mercury.parse(articleUrl, html, { fallback: false });\n\n // Update these values with the expected values from\n // the article.\n assert.equal(${key}, ${value ? \"'\" + value + \"'\" : \"''\"})\n });\n `;\n}\n\nexport default function (file, url, dir, result) {\n return template`\n import assert from 'assert';\n import fs from 'fs';\n import URL from 'url';\n import cheerio from 'cheerio';\n\n import Mercury from 'mercury';\n import getExtractor from 'extractors/get-extractor';\n import { excerptContent } from 'utils/text';\n\n // Rename CustomExtractor\n describe('CustomExtractor', () => {\n it('is selected properly', () => {\n // To pass this test, rename your extractor in\n // ${dir}/index.js\n // (e.g., CustomExtractor => NYTimesExtractor)\n // then add your new extractor to\n // src/extractors/all.js\n const url =\n '${url}';\n const extractor = getExtractor(url);\n assert.equal(extractor.domain, URL.parse(url).hostname)\n })\n\n ${Reflect.ownKeys(result).map(k => testFor(k, result[k], dir, file, url)).join('\\n\\n')}\n\n it('returns the content', async () => {\n // To pass this test, fill out the content selector\n // in ${dir}/index.js.\n // You may also want to make use of the clean and transform\n // options.\n const html =\n fs.readFileSync('${file}');\n const url =\n '${url}';\n\n const { content } =\n await Mercury.parse(url, html, { fallback: false });\n\n const $ = cheerio.load(content || '');\n\n const first13 = excerptContent($('*').first().text(), 13)\n\n // Update these values with the expected values from\n // the article.\n assert.equal(first13, null);\n });\n });\n `;\n}\n","import fs from 'fs'\nimport URL from 'url'\nimport inquirer from 'inquirer'\nimport ora from 'ora'\n\nimport Mercury from '../dist/mercury'\nimport {\n stripJunkTags,\n makeLinksAbsolute,\n} from 'utils/dom'\nimport extractorTemplate from './templates/custom-extractor'\nimport extractorTestTemplate from './templates/custom-extractor-test'\n\nconst questions = [\n {\n type: 'input',\n name: 'website',\n message: 'Paste a url to an article you\\'d like to create or extend a parser for:',\n validate(value) {\n const { hostname } = URL.parse(value);\n if (hostname) return true;\n\n return false;\n },\n },\n];\n\ninquirer.prompt(questions).then((answers) => {\n scaffoldCustomParser(answers.website);\n});\n\nlet spinner;\nfunction confirm(fn, args, msg, newParser) {\n spinner = ora({ text: msg });\n spinner.start();\n const result = fn.apply(null, args);\n\n if (result && result.then) {\n result.then(r => savePage(r, args, newParser));\n } else {\n spinner.succeed();\n }\n\n return result;\n}\n\nfunction savePage($, [url], newParser) {\n const { hostname } = URL.parse(url);\n\n spinner.succeed();\n\n const filename = new Date().getTime();\n const file = `./fixtures/${hostname}/${filename}.html`;\n // fix http(s) relative links:\n makeLinksAbsolute($('*').first(), $, url)\n $('[src], [href]').each((index, node) => {\n const $node = $(node)\n const link = $node.attr('src')\n if (link && link.slice(0, 2) === '//') {\n $node.attr('src', `http:${link}`)\n }\n })\n const html = stripJunkTags($('*').first(), $, ['script']).html();\n\n fs.writeFileSync(file, html);\n\n const result = Mercury.parse(url, html).then((result) => {\n if (newParser) {\n confirm(generateScaffold, [url, file, result], 'Generating parser and tests');\n console.log(`Your custom site extractor has been set up. To get started building it, run\n npm run watch:test -- ${hostname}`)\n } else {\n console.log(`\n It looks like you already have a custom parser for this url.\n The page you linked to has been added to ${file}. Copy and paste\n the following code to use that page in your tests:\n const html = fs.readFileSync('${file}');`)\n }\n })\n}\n\nfunction generateScaffold(url, file, result) {\n const { hostname } = URL.parse(url);\n const extractor = extractorTemplate(hostname)\n const extractorTest = extractorTestTemplate(file, url, getDir(url), result)\n\n fs.writeFileSync(`${getDir(url)}/index.js`, extractor)\n fs.writeFileSync(`${getDir(url)}/index.test.js`, extractorTest)\n}\n\nfunction confirmCreateDir(dir, msg) {\n if (!fs.existsSync(dir)) {\n confirm(fs.mkdirSync, [dir], msg);\n }\n}\n\nfunction scaffoldCustomParser(url) {\n const dir = getDir(url);\n const { hostname } = URL.parse(url);\n let newParser = false\n\n if (!fs.existsSync(dir)) {\n newParser = true\n confirmCreateDir(dir, `Creating ${hostname} directory`);\n confirmCreateDir(`./fixtures/${hostname}`, 'Creating fixtures directory');\n }\n\n confirm(Mercury.fetchResource, [url], 'Fetching fixture', newParser);\n}\n\nfunction getDir(url) {\n const { hostname } = URL.parse(url);\n return `./src/extractors/custom/${hostname}`;\n}\n"],"names":["ex","_interopDefault","require$$18","require$$17","require$$16","require$$15","require$$14","require$$13","require$$12","require$$11","require$$10","require$$9","require$$8","require$$7","require$$6","require$$5","require$$4","require$$3","require$$2","require$$1","require$$0","range","map","_regeneratorRuntime","mark","arguments","length","undefined","wrap","_context","prev","next","start","end","stop","_marked","_ref","hostname","badUrl","error","messages","BAD_CONTENT_TYPES","join","options","resolve","reject","request","err","response","body","statusMessage","statusCode","parseNon2xx","headers","_response$headers","BAD_CONTENT_TYPES_RE","test","contentType","contentLength","MAX_CONTENT_LENGTH","_asyncToGenerator","url","parsedUrl","_ref3","URL","parse","encodeURI","_extends","REQUEST_HEADERS","timeout","FETCH_TIMEOUT","encoding","jar","gzip","followAllRedirects","sent","validateResponse","abrupt","t0","Errors","_callee","_x2","_x3","apply","$","from","to","each","_","node","$node","attr","value","removeAttr","convertMetaProp","img","_Reflect$ownKeys","attribs","forEach","IS_LINK","IS_IMAGE","index","type","root","find","contents","filter","isComment","remove","TAGS_TO_REMOVE","cleanComments","create","preparedResponse","validResponse","result","_this","generateDoc","includes","cheerio","load","content","normalizeWhitespace","children","normalizeMetaTags","convertLazyLoadedImages","clean","domain","selectors","transforms","h1","noscript","$children","get","tagName","title","author","dek","date_published","defaultCleaner","parents","$parent","prepend","$tweetContainer","append","tweets","replaceWith","s","src","replace","width","lead_image_url","next_page_url","excerpt","h2","NYMagExtractor","BloggerExtractor","WikipediaExtractor","TwitterExtractor","NYTimesExtractor","TheAtlanticExtractor","NewYorkerExtractor","WiredExtractor","MSNExtractor","YahooExtractor","BuzzfeedExtractor","WikiaExtractor","LittleThingsExtractor","PoliticoExtractor","REMOVE_ATTRS","selector","WHITELIST_ATTRS","REMOVE_EMPTY_TAGS","tag","HEADER_TAGS","NON_TOP_CANDIDATE_TAGS","PHOTO_HINTS","POSITIVE_SCORE_HINTS","NEGATIVE_SCORE_HINTS","EXTRANEOUS_LINK_HINTS","BLOCK_LEVEL_TAGS","UNLIKELY_CANDIDATES_BLACKLIST","candidatesBlacklist","UNLIKELY_CANDIDATES_WHITELIST","candidatesWhitelist","not","id","classes","CANDIDATES_WHITELIST","classAndId","CANDIDATES_BLACKLIST","element","nextElement","collapsing","paragraphize","br","nextSibling","sibling","BLOCK_LEVEL_TAGS_RE","appendTo","p","div","$div","DIV_TO_P_BLOCK_TAGS","convertable","convertNodeTo","span","$span","brsToPs","convertDivs","convertSpans","_$node$get","key","attribString","$img","parseInt","height","SPACER_RE","$article","cleanForHeight","removeSpacers","article","tags","STRIP_OUTPUT_TAGS","$hOnes","reduce","acc","WHITELIST_ATTRS_RE","_defineProperty","removeAllButWhitelist","$p","text","trim","NON_TOP_CANDIDATE_TAGS$1","PHOTO_HINTS$1","POSITIVE_SCORE_HINTS$1","NEGATIVE_SCORE_HINTS$1","BLOCK_LEVEL_TAGS$1","UNLIKELY_CANDIDATES_BLACKLIST$1","UNLIKELY_CANDIDATES_WHITELIST$1","POSITIVE_SCORE_RE$1","score","NEGATIVE_SCORE_RE$1","PHOTO_HINTS_RE$1","READABILITY_ASSET$1","match","textLength","chunks","idkRe","lengthBonus","min","Math","max","scoreCommas","scoreLength","slice","amount","getOrInitScore","setScore","e","parent","addScore","getScore","scoreNode","weightNodes","getWeight","addToParent","PARAGRAPH_SCORE_TAGS$1","CHILD_CONTENT_TAGS$1","BAD_TAGS$1","convertSpans$1","addScoreTo","rawScore","HNEWS_CONTENT_SELECTORS$1","_slicedToArray","_ref2","parentSelector","childSelector","scorePs","NORMALIZE_RE","regexList","re","matchRe","exec","PAGE_IN_HREF_RE","matches","pageNum","split","segment","firstSegmentHasLetters","IS_DIGIT_RE","goodSegment","toLowerCase","parsed","protocol","host","path","reverse","rawSegment","_segment$split","_segment$split2","IS_ALPHA_RE","fileExt","possibleSegment","HAS_ALPHA_RE","isGoodSegment","push","cleanedSegments","words","$candidate","topScore","NON_TOP_CANDIDATE_TAGS_RE$1","$sibling","siblingScore","wrappingDiv","linkDensity","density","contentBonus","newScore","siblingScoreThreshold","siblingContent","siblingContentLength","hasSentenceEnd","first","mergeSiblings","weight","hasClass","normalizeSpaces","inputCount","pCount","imgCount","nodeIsList","previousNode","scriptCount","CLEAN_CONDITIONALLY_TAGS","removeUnlessContent","HEADER_TAG_LIST","header","$header","prevAll","rootUrl","$content","absoluteUrl","linkText","totalTextLength","linkLength","metaNames","cachedNames","name","indexOf","_step","nodes","toArray","values","cleanTags","metaValue","stripTags","v","_getIterator","foundNames","_iteratorNormalCompletion","_iterator","done","_loop","_typeof","_ret","_didIteratorError","_iteratorError","return","maxChildren","withinComment","isGoodNode","textOnly","html","cleanText","class","IS_WP_SELECTOR","months","timestamp1","timestamp2","allMonths","CLEAN_AUTHOR_RE","leadImageUrl","validUrl","isWebUri","excerptContent","TEXT_LINK_RE","dekText","dateString","SPLIT_DATE_STRING","TIME_MERIDIAN_DOTS_RE","TIME_MERIDIAN_SPACE_RE","CLEAN_DATE_STRING_RE","MS_DATE_STRING","SEC_DATE_STRING","moment","date","isValid","cleanDateString","toISOString","cleanConditionally","_ref$cleanConditional","_ref$title","_ref$url","_ref$defaultCleaner","rewriteTopLevel","cleanImages","stripJunkTags","cleanHOnes","cleanHeaders","makeLinksAbsolute","cleanAttributes","removeEmpty","TITLE_SPLITTERS_RE","resolveSplitTitle","splitTitle","titleText","termCounts","_Reflect$ownKeys$redu","_Reflect$ownKeys$redu2","termCount","maxTerm","splitEnds","longestEnd","_URL$parse","DOMAIN_ENDINGS_RE","wuzzy","levenshtein","startSlug","nakedDomain","startSlugRatio","endSlug","endSlugRatio","extractBreadcrumbTitle","newTitle","cleanDomainFromTitle","cleanAuthor","clean$1","cleanDek","cleanDatePublished","extractCleanNode","cleanTitle","opts","stripUnlikelyCandidates","convertToParagraphs","scoreContent","findTopCandidate","defaultOpts","extract","getContentNode","nodeIsSufficient","cleanAndReturnNode","k","extractBestNode","metaCache","extractFromMeta","STRONG_TITLE_META_TAGS","extractFromSelectors","STRONG_TITLE_SELECTORS","WEAK_TITLE_META_TAGS","WEAK_TITLE_SELECTORS","bylineRe","AUTHOR_META_TAGS","AUTHOR_MAX_LENGTH","AUTHOR_SELECTORS","BYLINE_SELECTORS_RE","_ref4","regex","abbrevMonthsStr","datePublished","DATE_PUBLISHED_META_TAGS","DATE_PUBLISHED_SELECTORS","extractFromUrl","DATE_PUBLISHED_URL_RES","POSITIVE_LEAD_IMAGE_URL_HINTS","NEGATIVE_LEAD_IMAGE_URL_HINTS","POSITIVE_LEAD_IMAGE_URL_HINTS_RE","NEGATIVE_LEAD_IMAGE_URL_HINTS_RE","GIF_RE","JPG_RE","$figParent","$gParent","getSig","parseFloat","area","round","$imgs","LEAD_IMAGE_URL_META_TAGS","imageUrl","cleanUrl","imgs","scoreImageUrl","scoreAttr","scoreByParents","scoreBySibling","scoreByDimensions","scoreByPosition","imgScores","topUrl","LEAD_IMAGE_URL_SELECTORS","href","articleUrl","SequenceMatcher","ratio","similarity","diffPercent","diffModifier","linkTextAsNum","isWp","EXTRANEOUS_LINK_HINTS$1","EXTRANEOUS_LINK_HINTS_RE$1","$link","_Array$from","makeSig$1","positiveMatch","PAGE_RE","parentData","negativeMatch","NEGATIVE_SCORE_RE","POSITIVE_SCORE_RE","linkData","PREV_LINK_TEXT_RE$1","baseUrl","previousUrls","linkHost","DIGIT_RE$2","fragment","baseRegex","NEXT_LINK_TEXT_RE$1","CAP_LINK_TEXT_RE$1","links","_ref$previousUrls","makeBaseRegex","isWordpress","possiblePages","link","removeAnchor","shouldScore","makeSig","pageNumFromUrl","scoreBaseUrl","scoreNextLinkText","scoreCapLinks","scorePrevLink","scoreByParents$1","scoreExtraneousLinks","scorePageInLink","scoreLinkText","scoreSimilarity","possiblePage","scoredPages","articleBaseUrl","scoreLinks","scoredLinks","scoredLink","topPage","parseDomain","$canonical","CANONICAL_META_SELECTORS","metaUrl","maxLength","ellipse","EXCERPT_META_SELECTORS","shortContent","GenericTitleExtractor","GenericDatePublishedExtractor","GenericAuthorExtractor","GenericContentExtractor","bind","GenericLeadImageUrlExtractor","GenericDekExtractor","GenericNextPageUrlExtractor","url_and_domain","GenericUrlExtractor","GenericExcerptExtractor","word_count","GenericWordCountExtractor","direction","getDirection","_url_and_domain","_parsedUrl","Extractors","baseDomain","GenericExtractor","$matches","Array","isArray","_selector","extractionOpts","extractHtml","_opts$extractHtml","_extractionOpts$defau","findMatchingSelector","matchingSelector","transformElements","cleanBySelectors","Cleaners","_matchingSelector","extractor","fallback","_opts$fallback","select","_opts","contentOnly","extractedTitle","extractResult","_content","Extractor","extractorOpts","nextPageResult","pages","RootExtractor","total_pages","pages_rendered","_x","fetchAllPages","_result","_opts$fetchAllPages","validateUrl","getExtractor","rendered_pages","fetchResource","_context2","_callee2","_this2","module","exports","Mercury","REMOVE_ATTR_SELECTORS","REMOVE_ATTR_LIST","RegExp","REMOVE_EMPTY_SELECTORS","NON_TOP_CANDIDATE_TAGS_RE","PHOTO_HINTS_RE","EXTRANEOUS_LINK_HINTS_RE","absolutize","insertValues","strings","part","idx","toString","bodyPattern","trailingWhitespace","template","compiled","indentLevel","line","IGNORE","testFor","dir","file","questions","inquirer","prompt","then","answers","website","spinner","confirm","fn","args","msg","newParser","ora","savePage","r","succeed","filename","Date","getTime","writeFileSync","generateScaffold","log","extractorTemplate","extractorTest","extractorTestTemplate","getDir","confirmCreateDir","fs","existsSync","mkdirSync","scaffoldCustomParser"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":null,"sources":["mercury.js","../src/utils/dom/constants.js","../src/utils/dom/strip-junk-tags.js","../src/extractors/generic/content/scoring/constants.js","../src/utils/dom/make-links-absolute.js","../scripts/templates/insert-values.js","../scripts/templates/index.js","../scripts/templates/custom-extractor.js","../scripts/templates/custom-extractor-test.js","../scripts/generate-custom-parser.js"],"sourcesContent":["'use strict';\n\nfunction _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }\n\nvar _regeneratorRuntime = _interopDefault(require('babel-runtime/regenerator'));\nvar _extends = _interopDefault(require('babel-runtime/helpers/extends'));\nvar _asyncToGenerator = _interopDefault(require('babel-runtime/helpers/asyncToGenerator'));\nvar URL = _interopDefault(require('url'));\nvar cheerio = _interopDefault(require('cheerio'));\nvar _Promise = _interopDefault(require('babel-runtime/core-js/promise'));\nvar request = _interopDefault(require('request'));\nvar _Reflect$ownKeys = _interopDefault(require('babel-runtime/core-js/reflect/own-keys'));\nvar _toConsumableArray = _interopDefault(require('babel-runtime/helpers/toConsumableArray'));\nvar _slicedToArray = _interopDefault(require('babel-runtime/helpers/slicedToArray'));\nvar stringDirection = _interopDefault(require('string-direction'));\nvar _getIterator = _interopDefault(require('babel-runtime/core-js/get-iterator'));\nvar _defineProperty = _interopDefault(require('babel-runtime/helpers/defineProperty'));\nvar _typeof = _interopDefault(require('babel-runtime/helpers/typeof'));\nvar validUrl = _interopDefault(require('valid-url'));\nvar moment = _interopDefault(require('moment'));\nvar wuzzy = _interopDefault(require('wuzzy'));\nvar difflib = _interopDefault(require('difflib'));\nvar _Array$from = _interopDefault(require('babel-runtime/core-js/array/from'));\nvar ellipsize = _interopDefault(require('ellipsize'));\n\nvar _marked = [range].map(_regeneratorRuntime.mark);\n\nfunction range() {\n var start = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;\n var end = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;\n return _regeneratorRuntime.wrap(function range$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n if (!(start <= end)) {\n _context.next = 5;\n break;\n }\n\n _context.next = 3;\n return start += 1;\n\n case 3:\n _context.next = 0;\n break;\n\n case 5:\n case \"end\":\n return _context.stop();\n }\n }\n }, _marked[0], this);\n}\n\n// extremely simple url validation as a first step\nfunction validateUrl(_ref) {\n var hostname = _ref.hostname;\n\n // If this isn't a valid url, return an error message\n return !!hostname;\n}\n\nvar Errors = {\n badUrl: {\n error: true,\n messages: 'The url parameter passed does not look like a valid URL. Please check your data and try again.'\n }\n};\n\nvar REQUEST_HEADERS = {\n 'User-Agent': 'Readability - http://readability.com/about/'\n};\n\n// The number of milliseconds to attempt to fetch a resource before timing out.\nvar FETCH_TIMEOUT = 10000;\n\n// Content types that we do not extract content from\nvar BAD_CONTENT_TYPES = ['audio/mpeg', 'image/gif', 'image/jpeg', 'image/jpg'];\n\nvar BAD_CONTENT_TYPES_RE = new RegExp('^(' + BAD_CONTENT_TYPES.join('|') + ')$', 'i');\n\n// Use this setting as the maximum size an article can be\n// for us to attempt parsing. Defaults to 5 MB.\nvar MAX_CONTENT_LENGTH = 5242880;\n\nfunction get(options) {\n return new _Promise(function (resolve, reject) {\n request(options, function (err, response, body) {\n if (err) {\n reject(err);\n } else {\n resolve({ body: body, response: response });\n }\n });\n });\n}\n\n// Evaluate a response to ensure it's something we should be keeping.\n// This does not validate in the sense of a response being 200 level or\n// not. Validation here means that we haven't found reason to bail from\n// further processing of this url.\n\nfunction validateResponse(response) {\n var parseNon2xx = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n\n // Check if we got a valid status code\n if (response.statusMessage !== 'OK') {\n if (!response.statusCode) {\n throw new Error('Unable to fetch content. Original exception was ' + response.error);\n } else if (!parseNon2xx) {\n throw new Error('Resource returned a response status code of ' + response.statusCode + ' and resource was instructed to reject non-2xx level status codes.');\n }\n }\n\n var _response$headers = response.headers;\n var contentType = _response$headers['content-type'];\n var contentLength = _response$headers['content-length'];\n\n // Check that the content is not in BAD_CONTENT_TYPES\n\n if (BAD_CONTENT_TYPES_RE.test(contentType)) {\n throw new Error('Content-type for this resource was ' + contentType + ' and is not allowed.');\n }\n\n // Check that the content length is below maximum\n if (contentLength > MAX_CONTENT_LENGTH) {\n throw new Error('Content for this resource was too large. Maximum content length is ' + MAX_CONTENT_LENGTH + '.');\n }\n\n return true;\n}\n\n// Set our response attribute to the result of fetching our URL.\n// TODO: This should gracefully handle timeouts and raise the\n// proper exceptions on the many failure cases of HTTP.\n// TODO: Ensure we are not fetching something enormous. Always return\n// unicode content for HTML, with charset conversion.\n\nvar fetchResource = (function () {\n var _ref2 = _asyncToGenerator(_regeneratorRuntime.mark(function _callee(url, parsedUrl) {\n var options, _ref3, response, body;\n\n return _regeneratorRuntime.wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n parsedUrl = parsedUrl || URL.parse(encodeURI(url));\n\n options = {\n url: parsedUrl,\n headers: _extends({}, REQUEST_HEADERS),\n timeout: FETCH_TIMEOUT,\n // Don't set encoding; fixes issues\n // w/gzipped responses\n encoding: null,\n // Accept cookies\n jar: true,\n // Accept and decode gzip\n gzip: true,\n // Follow any redirect\n followAllRedirects: true\n };\n _context.next = 4;\n return get(options);\n\n case 4:\n _ref3 = _context.sent;\n response = _ref3.response;\n body = _ref3.body;\n _context.prev = 7;\n\n validateResponse(response);\n return _context.abrupt('return', { body: body, response: response });\n\n case 12:\n _context.prev = 12;\n _context.t0 = _context['catch'](7);\n return _context.abrupt('return', Errors.badUrl);\n\n case 15:\n case 'end':\n return _context.stop();\n }\n }\n }, _callee, this, [[7, 12]]);\n }));\n\n function fetchResource(_x2, _x3) {\n return _ref2.apply(this, arguments);\n }\n\n return fetchResource;\n})();\n\nfunction convertMetaProp($, from, to) {\n $('meta[' + from + ']').each(function (_, node) {\n var $node = $(node);\n\n var value = $node.attr(from);\n $node.attr(to, value);\n $node.removeAttr(from);\n });\n\n return $;\n}\n\n// For ease of use in extracting from meta tags,\n// replace the \"content\" attribute on meta tags with the\n// \"value\" attribute.\n//\n// In addition, normalize 'property' attributes to 'name' for ease of\n// querying later. See, e.g., og or twitter meta tags.\n\nfunction normalizeMetaTags($) {\n $ = convertMetaProp($, 'content', 'value');\n $ = convertMetaProp($, 'property', 'name');\n return $;\n}\n\nvar IS_LINK = new RegExp('https?://', 'i');\nvar IS_IMAGE = new RegExp('.(png|gif|jpe?g)', 'i');\n\nvar TAGS_TO_REMOVE = ['script', 'style', 'form'].join(',');\n\n// Convert all instances of images with potentially\n// lazy loaded images into normal images.\n// Many sites will have img tags with no source, or an image tag with a src\n// attribute that a is a placeholer. We need to be able to properly fill in\n// the src attribute so the images are no longer lazy loaded.\nfunction convertLazyLoadedImages($) {\n $('img').each(function (_, img) {\n _Reflect$ownKeys(img.attribs).forEach(function (attr) {\n var value = img.attribs[attr];\n\n if (attr !== 'src' && IS_LINK.test(value) && IS_IMAGE.test(value)) {\n $(img).attr('src', value);\n }\n });\n });\n\n return $;\n}\n\nfunction isComment(index, node) {\n return node.type === 'comment';\n}\n\nfunction cleanComments($) {\n $.root().find('*').contents().filter(isComment).remove();\n\n return $;\n}\n\nfunction clean($) {\n $(TAGS_TO_REMOVE).remove();\n\n $ = cleanComments($);\n return $;\n}\n\nvar Resource = {\n\n // Create a Resource.\n //\n // :param url: The URL for the document we should retrieve.\n // :param response: If set, use as the response rather than\n // attempting to fetch it ourselves. Expects a\n // string.\n create: function create(url, preparedResponse, parsedUrl) {\n var _this = this;\n\n return _asyncToGenerator(_regeneratorRuntime.mark(function _callee() {\n var result, validResponse;\n return _regeneratorRuntime.wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n result = void 0;\n\n if (!preparedResponse) {\n _context.next = 6;\n break;\n }\n\n validResponse = {\n statusMessage: 'OK',\n statusCode: 200,\n headers: {\n 'content-type': 'text/html',\n 'content-length': 500\n }\n };\n\n\n result = { body: preparedResponse, response: validResponse };\n _context.next = 9;\n break;\n\n case 6:\n _context.next = 8;\n return fetchResource(url, parsedUrl);\n\n case 8:\n result = _context.sent;\n\n case 9:\n if (!result.error) {\n _context.next = 11;\n break;\n }\n\n return _context.abrupt('return', result);\n\n case 11:\n return _context.abrupt('return', _this.generateDoc(result));\n\n case 12:\n case 'end':\n return _context.stop();\n }\n }\n }, _callee, _this);\n }))();\n },\n generateDoc: function generateDoc(_ref) {\n var content = _ref.body;\n var response = _ref.response;\n var contentType = response.headers['content-type'];\n\n // TODO: Implement is_text function from\n // https://github.com/ReadabilityHoldings/readability/blob/8dc89613241d04741ebd42fa9fa7df1b1d746303/readability/utils/text.py#L57\n\n if (!contentType.includes('html') && !contentType.includes('text')) {\n throw new Error('Content does not appear to be text.');\n }\n\n var $ = cheerio.load(content, { normalizeWhitespace: true });\n\n if ($.root().children().length === 0) {\n throw new Error('No children, likely a bad parse.');\n }\n\n $ = normalizeMetaTags($);\n $ = convertLazyLoadedImages($);\n $ = clean($);\n\n return $;\n }\n};\n\nvar merge = function merge(extractor, domains) {\n return domains.reduce(function (acc, domain) {\n acc[domain] = extractor;\n return acc;\n }, {});\n};\n\nfunction mergeSupportedDomains(extractor) {\n return extractor.supportedDomains ? merge(extractor, [extractor.domain].concat(_toConsumableArray(extractor.supportedDomains))) : merge(extractor, [extractor.domain]);\n}\n\nvar NYMagExtractor = {\n domain: 'nymag.com',\n content: {\n // Order by most likely. Extractor will stop on first occurrence\n selectors: ['div.article-content', 'section.body', 'article.article'],\n\n // Selectors to remove from the extracted content\n clean: ['.ad', '.single-related-story'],\n\n // Object of tranformations to make on matched elements\n // Each key is the selector, each value is the tag to\n // transform to.\n // If a function is given, it should return a string\n // to convert to or nothing (in which case it will not perform\n // the transformation.\n transforms: {\n // Convert h1s to h2s\n h1: 'h2',\n\n // Convert lazy-loaded noscript images to figures\n noscript: function noscript($node) {\n var $children = $node.children();\n if ($children.length === 1 && $children.get(0).tagName === 'img') {\n return 'figure';\n }\n\n return null;\n }\n }\n },\n\n title: {\n selectors: ['h1.lede-feature-title', 'h1.headline-primary', 'h1']\n },\n\n author: {\n selectors: ['.by-authors', '.lede-feature-author']\n },\n\n dek: {\n selectors: ['.lede-feature-teaser']\n },\n\n date_published: {\n selectors: [['time.article-timestamp[datetime]', 'datetime'], 'time.article-timestamp']\n }\n};\n\nvar BloggerExtractor = {\n domain: 'blogspot.com',\n content: {\n // Blogger is insane and does not load its content\n // initially in the page, but it's all there\n // in noscript\n selectors: ['.post-content noscript'],\n\n // Selectors to remove from the extracted content\n clean: [],\n\n // Convert the noscript tag to a div\n transforms: {\n noscript: 'div'\n }\n },\n\n author: {\n selectors: ['.post-author-name']\n },\n\n title: {\n selectors: ['.post h2.title']\n },\n\n date_published: {\n selectors: ['span.publishdate']\n }\n};\n\nvar WikipediaExtractor = {\n domain: 'wikipedia.org',\n content: {\n selectors: ['#mw-content-text'],\n\n defaultCleaner: false,\n\n // transform top infobox to an image with caption\n transforms: {\n '.infobox img': function infoboxImg($node) {\n var $parent = $node.parents('.infobox');\n // Only prepend the first image in .infobox\n if ($parent.children('img').length === 0) {\n $parent.prepend($node);\n }\n },\n '.infobox caption': 'figcaption',\n '.infobox': 'figure'\n },\n\n // Selectors to remove from the extracted content\n clean: ['.mw-editsection', 'figure tr, figure td, figure tbody', '#toc', '.navbox']\n\n },\n\n author: 'Wikipedia Contributors',\n\n title: {\n selectors: ['h2.title']\n },\n\n date_published: {\n selectors: ['#footer-info-lastmod']\n }\n\n};\n\nvar TwitterExtractor = {\n domain: 'twitter.com',\n\n content: {\n transforms: {\n // We're transforming essentially the whole page here.\n // Twitter doesn't have nice selectors, so our initial\n // selector grabs the whole page, then we're re-writing\n // it to fit our needs before we clean it up.\n '.permalink[role=main]': function permalinkRoleMain($node, $) {\n var tweets = $node.find('.tweet');\n var $tweetContainer = $('<div id=\"TWEETS_GO_HERE\"></div>');\n $tweetContainer.append(tweets);\n $node.replaceWith($tweetContainer);\n },\n\n // Twitter wraps @ with s, which\n // renders as a strikethrough\n s: 'span'\n },\n\n selectors: ['.permalink[role=main]'],\n\n defaultCleaner: false,\n\n clean: ['.stream-item-footer', 'button', '.tweet-details-fixer']\n },\n\n author: {\n selectors: ['.tweet.permalink-tweet .username']\n },\n\n date_published: {\n selectors: [['.permalink-tweet ._timestamp[data-time-ms]', 'data-time-ms']]\n }\n\n};\n\nvar NYTimesExtractor = {\n title: {\n selectors: ['.g-headline', 'h1.headline']\n },\n\n author: {\n selectors: [['meta[name=\"author\"]', 'value'], '.g-byline', '.byline']\n },\n\n content: {\n selectors: ['div.g-blocks', 'article#story'],\n\n defaultCleaner: false,\n\n transforms: {\n 'img.g-lazy': function imgGLazy($node) {\n var src = $node.attr('src');\n // const widths = $node.attr('data-widths')\n // .slice(1)\n // .slice(0, -1)\n // .split(',');\n // if (widths.length) {\n // width = widths.slice(-1);\n // } else {\n // width = '900';\n // }\n var width = 640;\n\n src = src.replace('{{size}}', width);\n $node.attr('src', src);\n }\n },\n\n clean: ['.ad', 'header#story-header', '.story-body-1 .lede.video', '.visually-hidden', '#newsletter-promo', '.promo', '.comments-button', '.hidden']\n },\n\n date_published: null,\n\n lead_image_url: null,\n\n dek: null,\n\n next_page_url: null,\n\n excerpt: null\n};\n\n// Rename CustomExtractor\n// to fit your publication\nvar TheAtlanticExtractor = {\n domain: 'www.theatlantic.com',\n title: {\n selectors: ['h1.hed']\n },\n\n author: {\n selectors: ['article#article .article-cover-extra .metadata .byline a']\n },\n\n content: {\n selectors: ['.article-body'],\n\n // Is there anything in the content you selected that needs transformed\n // before it's consumable content? E.g., unusual lazy loaded images\n transforms: [],\n\n // Is there anything that is in the result that shouldn't be?\n // The clean selectors will remove anything that matches from\n // the result\n clean: []\n },\n\n date_published: null,\n\n lead_image_url: null,\n\n dek: null,\n\n next_page_url: null,\n\n excerpt: null\n};\n\n// Rename CustomExtractor\n// to fit your publication\n// (e.g., NYTimesExtractor)\nvar NewYorkerExtractor = {\n domain: 'www.newyorker.com',\n title: {\n selectors: ['h1.title']\n },\n\n author: {\n selectors: ['.contributors']\n },\n\n content: {\n selectors: ['div#articleBody', 'div.articleBody'],\n\n // Is there anything in the content you selected that needs transformed\n // before it's consumable content? E.g., unusual lazy loaded images\n transforms: [],\n\n // Is there anything that is in the result that shouldn't be?\n // The clean selectors will remove anything that matches from\n // the result\n clean: []\n },\n\n date_published: {\n selectors: [['meta[name=\"article:published_time\"]', 'value']]\n },\n\n lead_image_url: {\n selectors: [['meta[name=\"og:image\"]', 'value']]\n },\n\n dek: {\n selectors: [['meta[name=\"og:description\"]', 'value']]\n },\n\n next_page_url: null,\n\n excerpt: null\n};\n\n// Rename CustomExtractor\n// to fit your publication\n// (e.g., NYTimesExtractor)\nvar WiredExtractor = {\n domain: 'www.wired.com',\n title: {\n selectors: ['h1.post-title']\n },\n\n author: {\n selectors: ['a[rel=\"author\"]']\n },\n\n content: {\n selectors: ['article.content'],\n\n // Is there anything in the content you selected that needs transformed\n // before it's consumable content? E.g., unusual lazy loaded images\n transforms: [],\n\n // Is there anything that is in the result that shouldn't be?\n // The clean selectors will remove anything that matches from\n // the result\n clean: ['.visually-hidden']\n },\n\n date_published: {\n selectors: [['meta[itemprop=\"datePublished\"]', 'value']]\n },\n\n lead_image_url: {\n selectors: [['meta[name=\"og:image\"]', 'value']]\n },\n\n dek: {\n selectors: [['meta[name=\"og:description\"]', 'value']]\n },\n\n next_page_url: null,\n\n excerpt: null\n};\n\n// Rename CustomExtractor\n// to fit your publication\n// (e.g., NYTimesExtractor)\nvar MSNExtractor = {\n domain: 'www.msn.com',\n title: {\n selectors: ['h1']\n },\n\n author: {\n selectors: ['span.authorname-txt']\n },\n\n content: {\n selectors: ['div.richtext'],\n\n // Is there anything in the content you selected that needs transformed\n // before it's consumable content? E.g., unusual lazy loaded images\n transforms: [],\n\n // Is there anything that is in the result that shouldn't be?\n // The clean selectors will remove anything that matches from\n // the result\n clean: ['span.caption']\n },\n\n date_published: {\n selectors: ['span.time']\n },\n\n lead_image_url: {\n selectors: []\n },\n\n dek: {\n selectors: [['meta[name=\"description\"]', 'value']]\n },\n\n next_page_url: null,\n\n excerpt: null\n};\n\n// Rename CustomExtractor\n// to fit your publication\n// (e.g., NYTimesExtractor)\nvar YahooExtractor = {\n domain: 'www.yahoo.com',\n title: {\n selectors: ['header.canvas-header']\n },\n\n author: {\n selectors: ['span.provider-name']\n },\n\n content: {\n selectors: [\n // enter content selectors\n '.content-canvas'],\n\n // Is there anything in the content you selected that needs transformed\n // before it's consumable content? E.g., unusual lazy loaded images\n transforms: [],\n\n // Is there anything that is in the result that shouldn't be?\n // The clean selectors will remove anything that matches from\n // the result\n clean: ['.figure-caption']\n },\n\n date_published: {\n selectors: [['time.date[datetime]', 'datetime']]\n },\n\n lead_image_url: {\n selectors: [['meta[name=\"og:image\"]', 'value']]\n },\n\n dek: {\n selectors: [['meta[name=\"og:description\"]', 'value']]\n },\n\n next_page_url: null,\n\n excerpt: null\n};\n\n// Rename CustomExtractor\n// to fit your publication\n// (e.g., NYTimesExtractor)\nvar BuzzfeedExtractor = {\n domain: 'www.buzzfeed.com',\n title: {\n selectors: ['h1[id=\"post-title\"]']\n },\n\n author: {\n selectors: ['a[data-action=\"user/username\"]', 'byline__author']\n },\n\n content: {\n selectors: ['#buzz_sub_buzz'],\n\n defaultCleaner: false,\n\n // Is there anything in the content you selected that needs transformed\n // before it's consumable content? E.g., unusual lazy loaded images\n transforms: {\n h2: 'b'\n },\n\n // Is there anything that is in the result that shouldn't be?\n // The clean selectors will remove anything that matches from\n // the result\n clean: ['.instapaper_ignore', '.suplist_list_hide .buzz_superlist_item .buzz_superlist_number_inline', '.share-box']\n },\n\n date_published: {\n selectors: ['.buzz-datetime']\n },\n\n lead_image_url: {\n selectors: [['meta[name=\"og:image\"]', 'value']]\n },\n\n dek: {\n selectors: [['meta[name=\"description\"]', 'value']]\n },\n\n next_page_url: null,\n\n excerpt: null\n};\n\n// Rename CustomExtractor\n// to fit your publication\n// (e.g., NYTimesExtractor)\nvar WikiaExtractor = {\n domain: 'fandom.wikia.com',\n title: {\n selectors: ['h1.entry-title']\n },\n\n author: {\n selectors: ['.author vcard', '.fn']\n },\n\n content: {\n selectors: ['.grid-content', '.entry-content'],\n\n // Is there anything in the content you selected that needs transformed\n // before it's consumable content? E.g., unusual lazy loaded images\n transforms: [],\n\n // Is there anything that is in the result that shouldn't be?\n // The clean selectors will remove anything that matches from\n // the result\n clean: []\n },\n\n date_published: {\n selectors: [['meta[name=\"article:published_time\"]', 'value']]\n },\n\n lead_image_url: {\n selectors: [['meta[name=\"og:image\"]', 'value']]\n },\n\n dek: {\n selectors: [['meta[name=\"og:description\"]', 'value']]\n },\n\n next_page_url: null,\n\n excerpt: null\n};\n\n// Rename CustomExtractor\n// to fit your publication\n// (e.g., NYTimesExtractor)\nvar LittleThingsExtractor = {\n domain: 'www.littlethings.com',\n title: {\n selectors: ['h1.post-title']\n },\n\n author: {\n selectors: [['meta[name=\"author\"]', 'value']]\n },\n\n content: {\n selectors: [\n // enter content selectors\n '.mainContentIntro', '.content-wrapper'],\n\n // Is there anything in the content you selected that needs transformed\n // before it's consumable content? E.g., unusual lazy loaded images\n transforms: [],\n\n // Is there anything that is in the result that shouldn't be?\n // The clean selectors will remove anything that matches from\n // the result\n clean: []\n },\n\n lead_image_url: {\n selectors: [['meta[name=\"og:image\"]', 'value']]\n },\n\n next_page_url: null,\n\n excerpt: null\n};\n\n// Rename CustomExtractor\n// to fit your publication\n// (e.g., NYTimesExtractor)\nvar PoliticoExtractor = {\n domain: 'www.politico.com',\n title: {\n selectors: [\n // enter title selectors\n ['meta[name=\"og:title\"]', 'value']]\n },\n\n author: {\n selectors: ['.story-main-content .byline .vcard']\n },\n\n content: {\n selectors: [\n // enter content selectors\n '.story-main-content', '.content-group', '.story-core', '.story-text'],\n\n // Is there anything in the content you selected that needs transformed\n // before it's consumable content? E.g., unusual lazy loaded images\n transforms: [],\n\n // Is there anything that is in the result that shouldn't be?\n // The clean selectors will remove anything that matches from\n // the result\n clean: ['figcaption']\n },\n\n date_published: {\n selectors: [['.story-main-content .timestamp time[datetime]', 'datetime']]\n },\n\n lead_image_url: {\n selectors: [\n // enter lead_image_url selectors\n ['meta[name=\"og:image\"]', 'value']]\n },\n\n dek: {\n selectors: [['meta[name=\"description\"]', 'value']]\n },\n\n next_page_url: null,\n\n excerpt: null\n};\n\nvar DeadspinExtractor = {\n domain: 'deadspin.com',\n\n supportedDomains: ['jezebel.com', 'lifehacker.com', 'kotaku.com', 'gizmodo.com', 'jalopnik.com', 'kinja.com'],\n\n title: {\n selectors: ['h1.headline']\n },\n\n author: {\n selectors: ['.author']\n },\n\n content: {\n selectors: ['.post-content', '.entry-content'],\n\n // Is there anything in the content you selected that needs transformed\n // before it's consumable content? E.g., unusual lazy loaded images\n transforms: {\n 'iframe.lazyload[data-recommend-id^=\"youtube://\"]': function iframeLazyloadDataRecommendIdYoutube($node) {\n var youtubeId = $node.attr('id').split('youtube-')[1];\n $node.attr('src', 'https://www.youtube.com/embed/' + youtubeId);\n }\n },\n\n // Is there anything that is in the result that shouldn't be?\n // The clean selectors will remove anything that matches from\n // the result\n clean: []\n },\n\n date_published: {\n selectors: [['time.updated[datetime]', 'datetime']]\n },\n\n lead_image_url: {\n selectors: [['meta[name=\"og:image\"]', 'value']]\n },\n\n dek: {\n selectors: [\n // enter selectors\n ]\n },\n\n next_page_url: {\n selectors: [\n // enter selectors\n ]\n },\n\n excerpt: {\n selectors: [\n // enter selectors\n ]\n }\n};\n\n// Rename CustomExtractor\n// to fit your publication\n// (e.g., NYTimesExtractor)\nvar BroadwayWorldExtractor = {\n domain: 'www.broadwayworld.com',\n title: {\n selectors: ['h1.article-title']\n },\n\n author: {\n selectors: ['span[itemprop=author]']\n },\n\n content: {\n selectors: ['div[itemprop=articlebody]'],\n\n // Is there anything in the content you selected that needs transformed\n // before it's consumable content? E.g., unusual lazy loaded images\n transforms: {},\n\n // Is there anything that is in the result that shouldn't be?\n // The clean selectors will remove anything that matches from\n // the result\n clean: []\n },\n\n date_published: {\n selectors: [['meta[itemprop=datePublished]', 'value']]\n },\n\n lead_image_url: {\n selectors: [['meta[name=\"og:image\"]', 'value']]\n },\n\n dek: {\n selectors: [['meta[name=\"og:description\"]', 'value']]\n },\n\n next_page_url: {\n selectors: [\n // enter selectors\n ]\n },\n\n excerpt: {\n selectors: [\n // enter selectors\n ]\n }\n};\n\n// Rename CustomExtractor\n// to fit your publication\n// (e.g., NYTimesExtractor)\nvar ApartmentTherapyExtractor = {\n domain: 'www.apartmenttherapy.com',\n title: {\n selectors: ['h1.headline']\n },\n\n author: {\n selectors: ['.PostByline__name']\n },\n\n content: {\n selectors: ['div.post__content'],\n\n // Is there anything in the content you selected that needs transformed\n // before it's consumable content? E.g., unusual lazy loaded images\n transforms: {\n 'div[data-render-react-id=\"images/LazyPicture\"]': function divDataRenderReactIdImagesLazyPicture($node, $) {\n var data = JSON.parse($node.attr('data-props'));\n var src = data.sources[0].src;\n\n var $img = $('<img />').attr('src', src);\n $node.replaceWith($img);\n }\n },\n\n // Is there anything that is in the result that shouldn't be?\n // The clean selectors will remove anything that matches from\n // the result\n clean: []\n },\n\n date_published: {\n selectors: [['.PostByline__timestamp[datetime]', 'datetime']]\n },\n\n lead_image_url: {\n selectors: [['meta[name=\"og:image\"]', 'value']]\n },\n\n dek: {\n selectors: [['meta[name=description]', 'value']]\n },\n\n next_page_url: {\n selectors: [\n // enter selectors\n ]\n },\n\n excerpt: {\n selectors: [\n // enter selectors\n ]\n }\n};\n\nvar MediumExtractor = {\n domain: 'medium.com',\n\n supportedDomains: ['trackchanges.postlight.com'],\n\n title: {\n selectors: ['h1']\n },\n\n author: {\n selectors: [['meta[name=\"author\"]', 'value']]\n },\n\n content: {\n selectors: ['.section-content'],\n\n // Is there anything in the content you selected that needs transformed\n // before it's consumable content? E.g., unusual lazy loaded images\n transforms: {\n // Re-write lazy-loaded youtube videos\n iframe: function iframe($node) {\n var ytRe = /https:\\/\\/i.embed.ly\\/.+url=https:\\/\\/i\\.ytimg\\.com\\/vi\\/(\\w+)\\//;\n var thumb = decodeURIComponent($node.attr('data-thumbnail'));\n\n if (ytRe.test(thumb)) {\n var _thumb$match = thumb.match(ytRe);\n\n var _thumb$match2 = _slicedToArray(_thumb$match, 2);\n\n var _ = _thumb$match2[0];\n var youtubeId = _thumb$match2[1]; // eslint-disable-line\n\n $node.attr('src', 'https://www.youtube.com/embed/' + youtubeId);\n var $parent = $node.parents('figure');\n $parent.prepend($node.clone());\n $node.remove();\n }\n }\n },\n\n // Is there anything that is in the result that shouldn't be?\n // The clean selectors will remove anything that matches from\n // the result\n clean: []\n },\n\n date_published: {\n selectors: [['time[datetime]', 'datetime']]\n },\n\n lead_image_url: {\n selectors: [['meta[name=\"og:image\"]', 'value']]\n },\n\n dek: {\n selectors: [\n // enter selectors\n ]\n },\n\n next_page_url: {\n selectors: [\n // enter selectors\n ]\n },\n\n excerpt: {\n selectors: [\n // enter selectors\n ]\n }\n};\n\nvar Extractors = _extends({\n 'nymag.com': NYMagExtractor,\n 'blogspot.com': BloggerExtractor,\n 'wikipedia.org': WikipediaExtractor,\n 'twitter.com': TwitterExtractor,\n 'www.nytimes.com': NYTimesExtractor,\n 'www.theatlantic.com': TheAtlanticExtractor,\n 'www.newyorker.com': NewYorkerExtractor,\n 'www.wired.com': WiredExtractor,\n 'www.msn.com': MSNExtractor,\n 'www.yahoo.com': YahooExtractor,\n 'www.buzzfeed.com': BuzzfeedExtractor,\n 'fandom.wikia.com': WikiaExtractor,\n 'www.littlethings.com': LittleThingsExtractor,\n 'www.politico.com': PoliticoExtractor\n}, mergeSupportedDomains(DeadspinExtractor), {\n 'www.broadwayworld.com': BroadwayWorldExtractor,\n 'www.apartmenttherapy.com': ApartmentTherapyExtractor\n}, mergeSupportedDomains(MediumExtractor));\n\n// Spacer images to be removed\nvar SPACER_RE = new RegExp('trans|transparent|spacer|blank', 'i');\n\n// The class we will use to mark elements we want to keep\n// but would normally remove\nvar KEEP_CLASS = 'mercury-parser-keep';\n\nvar KEEP_SELECTORS = ['iframe[src^=\"https://www.youtube.com\"]', 'iframe[src^=\"http://www.youtube.com\"]', 'iframe[src^=\"https://player.vimeo\"]', 'iframe[src^=\"http://player.vimeo\"]'];\n\n// A list of tags to strip from the output if we encounter them.\nvar STRIP_OUTPUT_TAGS = ['title', 'script', 'noscript', 'link', 'style', 'hr', 'embed', 'iframe', 'object'];\n\n// cleanAttributes\nvar REMOVE_ATTRS = ['style', 'align'];\nvar REMOVE_ATTR_SELECTORS = REMOVE_ATTRS.map(function (selector) {\n return '[' + selector + ']';\n});\nvar REMOVE_ATTR_LIST = REMOVE_ATTRS.join(',');\nvar WHITELIST_ATTRS = ['src', 'srcset', 'href', 'class', 'id', 'alt'];\nvar WHITELIST_ATTRS_RE = new RegExp('^(' + WHITELIST_ATTRS.join('|') + ')$', 'i');\n\n// removeEmpty\nvar REMOVE_EMPTY_TAGS = ['p'];\nvar REMOVE_EMPTY_SELECTORS = REMOVE_EMPTY_TAGS.map(function (tag) {\n return tag + ':empty';\n}).join(',');\n\n// cleanTags\nvar CLEAN_CONDITIONALLY_TAGS = ['ul', 'ol', 'table', 'div', 'button', 'form'].join(',');\n\n// cleanHeaders\nvar HEADER_TAGS = ['h2', 'h3', 'h4', 'h5', 'h6'];\nvar HEADER_TAG_LIST = HEADER_TAGS.join(',');\n\n// // CONTENT FETCHING CONSTANTS ////\n\n// A list of strings that can be considered unlikely candidates when\n// extracting content from a resource. These strings are joined together\n// and then tested for existence using re:test, so may contain simple,\n// non-pipe style regular expression queries if necessary.\nvar UNLIKELY_CANDIDATES_BLACKLIST = ['ad-break', 'adbox', 'advert', 'addthis', 'agegate', 'aux', 'blogger-labels', 'combx', 'comment', 'conversation', 'disqus', 'entry-unrelated', 'extra', 'foot',\n// 'form', // This is too generic, has too many false positives\n'header', 'hidden', 'loader', 'login', // Note: This can hit 'blogindex'.\n'menu', 'meta', 'nav', 'outbrain', 'pager', 'pagination', 'predicta', // readwriteweb inline ad box\n'presence_control_external', // lifehacker.com container full of false positives\n'popup', 'printfriendly', 'related', 'remove', 'remark', 'rss', 'share', 'shoutbox', 'sidebar', 'sociable', 'sponsor', 'taboola', 'tools'];\n\n// A list of strings that can be considered LIKELY candidates when\n// extracting content from a resource. Essentially, the inverse of the\n// blacklist above - if something matches both blacklist and whitelist,\n// it is kept. This is useful, for example, if something has a className\n// of \"rss-content entry-content\". It matched 'rss', so it would normally\n// be removed, however, it's also the entry content, so it should be left\n// alone.\n//\n// These strings are joined together and then tested for existence using\n// re:test, so may contain simple, non-pipe style regular expression queries\n// if necessary.\nvar UNLIKELY_CANDIDATES_WHITELIST = ['and', 'article', 'body', 'blogindex', 'column', 'content', 'entry-content-asset', 'format', // misuse of form\n'hfeed', 'hentry', 'hatom', 'main', 'page', 'posts', 'shadow'];\n\n// A list of tags which, if found inside, should cause a <div /> to NOT\n// be turned into a paragraph tag. Shallow div tags without these elements\n// should be turned into <p /> tags.\nvar DIV_TO_P_BLOCK_TAGS = ['a', 'blockquote', 'dl', 'div', 'img', 'p', 'pre', 'table'].join(',');\n\n// A list of tags that should be ignored when trying to find the top candidate\n// for a document.\nvar NON_TOP_CANDIDATE_TAGS = ['br', 'b', 'i', 'label', 'hr', 'area', 'base', 'basefont', 'input', 'img', 'link', 'meta'];\n\nvar NON_TOP_CANDIDATE_TAGS_RE = new RegExp('^(' + NON_TOP_CANDIDATE_TAGS.join('|') + ')$', 'i');\n\nvar PHOTO_HINTS = ['figure', 'photo', 'image', 'caption'];\nvar PHOTO_HINTS_RE = new RegExp(PHOTO_HINTS.join('|'), 'i');\n\n// A list of strings that denote a positive scoring for this content as being\n// an article container. Checked against className and id.\n//\n// TODO: Perhaps have these scale based on their odds of being quality?\nvar POSITIVE_SCORE_HINTS = ['article', 'articlecontent', 'instapaper_body', 'blog', 'body', 'content', 'entry-content-asset', 'entry', 'hentry', 'main', 'Normal', 'page', 'pagination', 'permalink', 'post', 'story', 'text', '[-_]copy', // usatoday\n'\\\\Bcopy'];\n\n// The above list, joined into a matching regular expression\nvar POSITIVE_SCORE_RE = new RegExp(POSITIVE_SCORE_HINTS.join('|'), 'i');\n\n// A list of strings that denote a negative scoring for this content as being\n// an article container. Checked against className and id.\n//\n// TODO: Perhaps have these scale based on their odds of being quality?\nvar NEGATIVE_SCORE_HINTS = ['adbox', 'advert', 'author', 'bio', 'bookmark', 'bottom', 'byline', 'clear', 'com-', 'combx', 'comment', 'comment\\\\B', 'contact', 'copy', 'credit', 'crumb', 'date', 'deck', 'excerpt', 'featured', // tnr.com has a featured_content which throws us off\n'foot', 'footer', 'footnote', 'graf', 'head', 'info', 'infotext', // newscientist.com copyright\n'instapaper_ignore', 'jump', 'linebreak', 'link', 'masthead', 'media', 'meta', 'modal', 'outbrain', // slate.com junk\n'promo', 'pr_', // autoblog - press release\n'related', 'respond', 'roundcontent', // lifehacker restricted content warning\n'scroll', 'secondary', 'share', 'shopping', 'shoutbox', 'side', 'sidebar', 'sponsor', 'stamp', 'sub', 'summary', 'tags', 'tools', 'widget'];\n// The above list, joined into a matching regular expression\nvar NEGATIVE_SCORE_RE = new RegExp(NEGATIVE_SCORE_HINTS.join('|'), 'i');\n\n// XPath to try to determine if a page is wordpress. Not always successful.\nvar IS_WP_SELECTOR = 'meta[name=generator][value^=WordPress]';\n\n// A list of words that, if found in link text or URLs, likely mean that\n// this link is not a next page link.\nvar EXTRANEOUS_LINK_HINTS = ['print', 'archive', 'comment', 'discuss', 'e-mail', 'email', 'share', 'reply', 'all', 'login', 'sign', 'single', 'adx', 'entry-unrelated'];\nvar EXTRANEOUS_LINK_HINTS_RE = new RegExp(EXTRANEOUS_LINK_HINTS.join('|'), 'i');\n\n// Match any phrase that looks like it could be page, or paging, or pagination\nvar PAGE_RE = new RegExp('pag(e|ing|inat)', 'i');\n\n// A list of all of the block level tags known in HTML5 and below. Taken from\n// http://bit.ly/qneNIT\nvar BLOCK_LEVEL_TAGS = ['article', 'aside', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'col', 'colgroup', 'dd', 'div', 'dl', 'dt', 'embed', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hgroup', 'hr', 'li', 'map', 'object', 'ol', 'output', 'p', 'pre', 'progress', 'section', 'table', 'tbody', 'textarea', 'tfoot', 'th', 'thead', 'tr', 'ul', 'video'];\nvar BLOCK_LEVEL_TAGS_RE = new RegExp('^(' + BLOCK_LEVEL_TAGS.join('|') + ')$', 'i');\n\n// The removal is implemented as a blacklist and whitelist, this test finds\n// blacklisted elements that aren't whitelisted. We do this all in one\n// expression-both because it's only one pass, and because this skips the\n// serialization for whitelisted nodes.\nvar candidatesBlacklist = UNLIKELY_CANDIDATES_BLACKLIST.join('|');\nvar CANDIDATES_BLACKLIST = new RegExp(candidatesBlacklist, 'i');\n\nvar candidatesWhitelist = UNLIKELY_CANDIDATES_WHITELIST.join('|');\nvar CANDIDATES_WHITELIST = new RegExp(candidatesWhitelist, 'i');\n\nfunction stripUnlikelyCandidates($) {\n // Loop through the provided document and remove any non-link nodes\n // that are unlikely candidates for article content.\n //\n // Links are ignored because there are very often links to content\n // that are identified as non-body-content, but may be inside\n // article-like content.\n //\n // :param $: a cheerio object to strip nodes from\n // :return $: the cleaned cheerio object\n $('*').not('a').each(function (index, node) {\n var $node = $(node);\n var classes = $node.attr('class');\n var id = $node.attr('id');\n if (!id && !classes) return;\n\n var classAndId = (classes || '') + ' ' + (id || '');\n if (CANDIDATES_WHITELIST.test(classAndId)) {\n return;\n } else if (CANDIDATES_BLACKLIST.test(classAndId)) {\n $node.remove();\n }\n });\n\n return $;\n}\n\n// ## NOTES:\n// Another good candidate for refactoring/optimizing.\n// Very imperative code, I don't love it. - AP\n\n\n// Given cheerio object, convert consecutive <br /> tags into\n// <p /> tags instead.\n//\n// :param $: A cheerio object\n\nfunction brsToPs($) {\n var collapsing = false;\n $('br').each(function (index, element) {\n var nextElement = $(element).next().get(0);\n\n if (nextElement && nextElement.tagName === 'br') {\n collapsing = true;\n $(element).remove();\n } else if (collapsing) {\n collapsing = false;\n // $(element).replaceWith('<p />')\n paragraphize(element, $, true);\n }\n });\n\n return $;\n}\n\n// Given a node, turn it into a P if it is not already a P, and\n// make sure it conforms to the constraints of a P tag (I.E. does\n// not contain any other block tags.)\n//\n// If the node is a <br />, it treats the following inline siblings\n// as if they were its children.\n//\n// :param node: The node to paragraphize; this is a raw node\n// :param $: The cheerio object to handle dom manipulation\n// :param br: Whether or not the passed node is a br\n\nfunction paragraphize(node, $) {\n var br = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n\n var $node = $(node);\n\n if (br) {\n var sibling = node.nextSibling;\n var p = $('<p></p>');\n\n // while the next node is text or not a block level element\n // append it to a new p node\n while (sibling && !(sibling.tagName && BLOCK_LEVEL_TAGS_RE.test(sibling.tagName))) {\n var nextSibling = sibling.nextSibling;\n $(sibling).appendTo(p);\n sibling = nextSibling;\n }\n\n $node.replaceWith(p);\n $node.remove();\n return $;\n }\n\n return $;\n}\n\nfunction convertDivs($) {\n $('div').each(function (index, div) {\n var $div = $(div);\n var convertable = $div.children(DIV_TO_P_BLOCK_TAGS).length === 0;\n\n if (convertable) {\n convertNodeTo($div, $, 'p');\n }\n });\n\n return $;\n}\n\nfunction convertSpans($) {\n $('span').each(function (index, span) {\n var $span = $(span);\n var convertable = $span.parents('p, div').length === 0;\n if (convertable) {\n convertNodeTo($span, $, 'p');\n }\n });\n\n return $;\n}\n\n// Loop through the provided doc, and convert any p-like elements to\n// actual paragraph tags.\n//\n// Things fitting this criteria:\n// * Multiple consecutive <br /> tags.\n// * <div /> tags without block level elements inside of them\n// * <span /> tags who are not children of <p /> or <div /> tags.\n//\n// :param $: A cheerio object to search\n// :return cheerio object with new p elements\n// (By-reference mutation, though. Returned just for convenience.)\n\nfunction convertToParagraphs($) {\n $ = brsToPs($);\n $ = convertDivs($);\n $ = convertSpans($);\n\n return $;\n}\n\nfunction convertNodeTo($node, $) {\n var tag = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'p';\n\n var node = $node.get(0);\n if (!node) {\n return $;\n }\n\n var _$node$get = $node.get(0);\n\n var attribs = _$node$get.attribs;\n\n var attribString = _Reflect$ownKeys(attribs).map(function (key) {\n return key + '=' + attribs[key];\n }).join(' ');\n\n $node.replaceWith('<' + tag + ' ' + attribString + '>' + $node.contents() + '</' + tag + '>');\n return $;\n}\n\nfunction cleanForHeight($img, $) {\n var height = parseInt($img.attr('height'), 10);\n var width = parseInt($img.attr('width'), 10) || 20;\n\n // Remove images that explicitly have very small heights or\n // widths, because they are most likely shims or icons,\n // which aren't very useful for reading.\n if ((height || 20) < 10 || width < 10) {\n $img.remove();\n } else if (height) {\n // Don't ever specify a height on images, so that we can\n // scale with respect to width without screwing up the\n // aspect ratio.\n $img.removeAttr('height');\n }\n\n return $;\n}\n\n// Cleans out images where the source string matches transparent/spacer/etc\n// TODO This seems very aggressive - AP\nfunction removeSpacers($img, $) {\n if (SPACER_RE.test($img.attr('src'))) {\n $img.remove();\n }\n\n return $;\n}\n\nfunction cleanImages($article, $) {\n $article.find('img').each(function (index, img) {\n var $img = $(img);\n\n cleanForHeight($img, $);\n removeSpacers($img, $);\n });\n\n return $;\n}\n\nfunction markToKeep(article, $, url) {\n var tags = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];\n\n if (tags.length === 0) {\n tags = KEEP_SELECTORS;\n }\n\n if (url) {\n var _URL$parse = URL.parse(url);\n\n var protocol = _URL$parse.protocol;\n var hostname = _URL$parse.hostname;\n\n tags = [].concat(_toConsumableArray(tags), ['iframe[src^=\"' + protocol + '//' + hostname + '\"]']);\n }\n\n $(tags.join(','), article).addClass(KEEP_CLASS);\n\n return $;\n}\n\nfunction stripJunkTags(article, $) {\n var tags = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];\n\n if (tags.length === 0) {\n tags = STRIP_OUTPUT_TAGS;\n }\n\n // Remove matching elements, but ignore\n // any element with a class of mercury-parser-keep\n $(tags.join(','), article).not('.' + KEEP_CLASS).remove();\n\n // Remove the mercury-parser-keep class from result\n $('.' + KEEP_CLASS, article).removeClass(KEEP_CLASS);\n\n return $;\n}\n\n// H1 tags are typically the article title, which should be extracted\n// by the title extractor instead. If there's less than 3 of them (<3),\n// strip them. Otherwise, turn 'em into H2s.\n\nfunction cleanHOnes(article, $) {\n var $hOnes = $('h1', article);\n\n if ($hOnes.length < 3) {\n $hOnes.each(function (index, node) {\n return $(node).remove();\n });\n } else {\n $hOnes.each(function (index, node) {\n convertNodeTo($(node), $, 'h2');\n });\n }\n\n return $;\n}\n\nfunction removeAllButWhitelist($article) {\n $article.find('*').each(function (index, node) {\n node.attribs = _Reflect$ownKeys(node.attribs).reduce(function (acc, attr) {\n if (WHITELIST_ATTRS_RE.test(attr)) {\n return _extends({}, acc, _defineProperty({}, attr, node.attribs[attr]));\n }\n\n return acc;\n }, {});\n });\n\n return $article;\n}\n\n// function removeAttrs(article, $) {\n// REMOVE_ATTRS.forEach((attr) => {\n// $(`[${attr}]`, article).removeAttr(attr);\n// });\n// }\n\n// Remove attributes like style or align\nfunction cleanAttributes($article) {\n // Grabbing the parent because at this point\n // $article will be wrapped in a div which will\n // have a score set on it.\n return removeAllButWhitelist($article.parent().length ? $article.parent() : $article);\n}\n\nfunction removeEmpty($article, $) {\n $article.find('p').each(function (index, p) {\n var $p = $(p);\n if ($p.find('iframe, img').length === 0 && $p.text().trim() === '') $p.remove();\n });\n\n return $;\n}\n\n// // CONTENT FETCHING CONSTANTS ////\n\n// A list of strings that can be considered unlikely candidates when\n// extracting content from a resource. These strings are joined together\n// and then tested for existence using re:test, so may contain simple,\n// non-pipe style regular expression queries if necessary.\nvar UNLIKELY_CANDIDATES_BLACKLIST$1 = ['ad-break', 'adbox', 'advert', 'addthis', 'agegate', 'aux', 'blogger-labels', 'combx', 'comment', 'conversation', 'disqus', 'entry-unrelated', 'extra', 'foot', 'form', 'header', 'hidden', 'loader', 'login', // Note: This can hit 'blogindex'.\n'menu', 'meta', 'nav', 'pager', 'pagination', 'predicta', // readwriteweb inline ad box\n'presence_control_external', // lifehacker.com container full of false positives\n'popup', 'printfriendly', 'related', 'remove', 'remark', 'rss', 'share', 'shoutbox', 'sidebar', 'sociable', 'sponsor', 'tools'];\n\n// A list of strings that can be considered LIKELY candidates when\n// extracting content from a resource. Essentially, the inverse of the\n// blacklist above - if something matches both blacklist and whitelist,\n// it is kept. This is useful, for example, if something has a className\n// of \"rss-content entry-content\". It matched 'rss', so it would normally\n// be removed, however, it's also the entry content, so it should be left\n// alone.\n//\n// These strings are joined together and then tested for existence using\n// re:test, so may contain simple, non-pipe style regular expression queries\n// if necessary.\nvar UNLIKELY_CANDIDATES_WHITELIST$1 = ['and', 'article', 'body', 'blogindex', 'column', 'content', 'entry-content-asset', 'format', // misuse of form\n'hfeed', 'hentry', 'hatom', 'main', 'page', 'posts', 'shadow'];\n\n// A list of tags which, if found inside, should cause a <div /> to NOT\n// be turned into a paragraph tag. Shallow div tags without these elements\n// should be turned into <p /> tags.\nvar DIV_TO_P_BLOCK_TAGS$1 = ['a', 'blockquote', 'dl', 'div', 'img', 'p', 'pre', 'table'].join(',');\n\n// A list of tags that should be ignored when trying to find the top candidate\n// for a document.\nvar NON_TOP_CANDIDATE_TAGS$1 = ['br', 'b', 'i', 'label', 'hr', 'area', 'base', 'basefont', 'input', 'img', 'link', 'meta'];\n\nvar NON_TOP_CANDIDATE_TAGS_RE$1 = new RegExp('^(' + NON_TOP_CANDIDATE_TAGS$1.join('|') + ')$', 'i');\n\n// A list of selectors that specify, very clearly, either hNews or other\n// very content-specific style content, like Blogger templates.\n// More examples here: http://microformats.org/wiki/blog-post-formats\nvar HNEWS_CONTENT_SELECTORS$1 = [['.hentry', '.entry-content'], ['entry', '.entry-content'], ['.entry', '.entry_content'], ['.post', '.postbody'], ['.post', '.post_body'], ['.post', '.post-body']];\n\nvar PHOTO_HINTS$1 = ['figure', 'photo', 'image', 'caption'];\nvar PHOTO_HINTS_RE$1 = new RegExp(PHOTO_HINTS$1.join('|'), 'i');\n\n// A list of strings that denote a positive scoring for this content as being\n// an article container. Checked against className and id.\n//\n// TODO: Perhaps have these scale based on their odds of being quality?\nvar POSITIVE_SCORE_HINTS$1 = ['article', 'articlecontent', 'instapaper_body', 'blog', 'body', 'content', 'entry-content-asset', 'entry', 'hentry', 'main', 'Normal', 'page', 'pagination', 'permalink', 'post', 'story', 'text', '[-_]copy', // usatoday\n'\\\\Bcopy'];\n\n// The above list, joined into a matching regular expression\nvar POSITIVE_SCORE_RE$1 = new RegExp(POSITIVE_SCORE_HINTS$1.join('|'), 'i');\n\n// Readability publisher-specific guidelines\nvar READABILITY_ASSET$1 = new RegExp('entry-content-asset', 'i');\n\n// A list of strings that denote a negative scoring for this content as being\n// an article container. Checked against className and id.\n//\n// TODO: Perhaps have these scale based on their odds of being quality?\nvar NEGATIVE_SCORE_HINTS$1 = ['adbox', 'advert', 'author', 'bio', 'bookmark', 'bottom', 'byline', 'clear', 'com-', 'combx', 'comment', 'comment\\\\B', 'contact', 'copy', 'credit', 'crumb', 'date', 'deck', 'excerpt', 'featured', // tnr.com has a featured_content which throws us off\n'foot', 'footer', 'footnote', 'graf', 'head', 'info', 'infotext', // newscientist.com copyright\n'instapaper_ignore', 'jump', 'linebreak', 'link', 'masthead', 'media', 'meta', 'modal', 'outbrain', // slate.com junk\n'promo', 'pr_', // autoblog - press release\n'related', 'respond', 'roundcontent', // lifehacker restricted content warning\n'scroll', 'secondary', 'share', 'shopping', 'shoutbox', 'side', 'sidebar', 'sponsor', 'stamp', 'sub', 'summary', 'tags', 'tools', 'widget'];\n// The above list, joined into a matching regular expression\nvar NEGATIVE_SCORE_RE$1 = new RegExp(NEGATIVE_SCORE_HINTS$1.join('|'), 'i');\n\n// A list of all of the block level tags known in HTML5 and below. Taken from\n// http://bit.ly/qneNIT\nvar BLOCK_LEVEL_TAGS$1 = ['article', 'aside', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'col', 'colgroup', 'dd', 'div', 'dl', 'dt', 'embed', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hgroup', 'hr', 'li', 'map', 'object', 'ol', 'output', 'p', 'pre', 'progress', 'section', 'table', 'tbody', 'textarea', 'tfoot', 'th', 'thead', 'tr', 'ul', 'video'];\nvar BLOCK_LEVEL_TAGS_RE$1 = new RegExp('^(' + BLOCK_LEVEL_TAGS$1.join('|') + ')$', 'i');\n\n// The removal is implemented as a blacklist and whitelist, this test finds\n// blacklisted elements that aren't whitelisted. We do this all in one\n// expression-both because it's only one pass, and because this skips the\n// serialization for whitelisted nodes.\nvar candidatesBlacklist$1 = UNLIKELY_CANDIDATES_BLACKLIST$1.join('|');\nvar candidatesWhitelist$1 = UNLIKELY_CANDIDATES_WHITELIST$1.join('|');\nvar PARAGRAPH_SCORE_TAGS$1 = new RegExp('^(p|li|span|pre)$', 'i');\nvar CHILD_CONTENT_TAGS$1 = new RegExp('^(td|blockquote|ol|ul|dl)$', 'i');\nvar BAD_TAGS$1 = new RegExp('^(address|form)$', 'i');\n\n// Get the score of a node based on its className and id.\nfunction getWeight(node) {\n var classes = node.attr('class');\n var id = node.attr('id');\n var score = 0;\n\n if (id) {\n // if id exists, try to score on both positive and negative\n if (POSITIVE_SCORE_RE$1.test(id)) {\n score += 25;\n }\n if (NEGATIVE_SCORE_RE$1.test(id)) {\n score -= 25;\n }\n }\n\n if (classes) {\n if (score === 0) {\n // if classes exist and id did not contribute to score\n // try to score on both positive and negative\n if (POSITIVE_SCORE_RE$1.test(classes)) {\n score += 25;\n }\n if (NEGATIVE_SCORE_RE$1.test(classes)) {\n score -= 25;\n }\n }\n\n // even if score has been set by id, add score for\n // possible photo matches\n // \"try to keep photos if we can\"\n if (PHOTO_HINTS_RE$1.test(classes)) {\n score += 10;\n }\n\n // add 25 if class matches entry-content-asset,\n // a class apparently instructed for use in the\n // Readability publisher guidelines\n // https://www.readability.com/developers/guidelines\n if (READABILITY_ASSET$1.test(classes)) {\n score += 25;\n }\n }\n\n return score;\n}\n\n// returns the score of a node based on\n// the node's score attribute\n// returns null if no score set\nfunction getScore($node) {\n return parseFloat($node.attr('score')) || null;\n}\n\n// return 1 for every comma in text\nfunction scoreCommas(text) {\n return (text.match(/,/g) || []).length;\n}\n\nvar idkRe = new RegExp('^(p|pre)$', 'i');\n\nfunction scoreLength(textLength) {\n var tagName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'p';\n\n var chunks = textLength / 50;\n\n if (chunks > 0) {\n var lengthBonus = void 0;\n\n // No idea why p or pre are being tamped down here\n // but just following the source for now\n // Not even sure why tagName is included here,\n // since this is only being called from the context\n // of scoreParagraph\n if (idkRe.test(tagName)) {\n lengthBonus = chunks - 2;\n } else {\n lengthBonus = chunks - 1.25;\n }\n\n return Math.min(Math.max(lengthBonus, 0), 3);\n }\n\n return 0;\n}\n\n// Score a paragraph using various methods. Things like number of\n// commas, etc. Higher is better.\nfunction scoreParagraph(node) {\n var score = 1;\n var text = node.text().trim();\n var textLength = text.length;\n\n // If this paragraph is less than 25 characters, don't count it.\n if (textLength < 25) {\n return 0;\n }\n\n // Add points for any commas within this paragraph\n score += scoreCommas(text);\n\n // For every 50 characters in this paragraph, add another point. Up\n // to 3 points.\n score += scoreLength(textLength);\n\n // Articles can end with short paragraphs when people are being clever\n // but they can also end with short paragraphs setting up lists of junk\n // that we strip. This negative tweaks junk setup paragraphs just below\n // the cutoff threshold.\n if (text.slice(-1) === ':') {\n score -= 1;\n }\n\n return score;\n}\n\nfunction setScore($node, $, score) {\n $node.attr('score', score);\n return $node;\n}\n\nfunction addScore($node, $, amount) {\n try {\n var score = getOrInitScore($node, $) + amount;\n setScore($node, $, score);\n } catch (e) {\n // Ignoring; error occurs in scoreNode\n }\n\n return $node;\n}\n\n// Adds 1/4 of a child's score to its parent\nfunction addToParent(node, $, score) {\n var parent = node.parent();\n if (parent) {\n addScore(parent, $, score * 0.25);\n }\n\n return node;\n}\n\n// gets and returns the score if it exists\n// if not, initializes a score based on\n// the node's tag type\nfunction getOrInitScore($node, $) {\n var weightNodes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;\n\n var score = getScore($node);\n\n if (score) {\n return score;\n }\n\n score = scoreNode($node);\n\n if (weightNodes) {\n score += getWeight($node);\n }\n\n addToParent($node, $, score);\n\n return score;\n}\n\n// Score an individual node. Has some smarts for paragraphs, otherwise\n// just scores based on tag.\nfunction scoreNode($node) {\n var _$node$get = $node.get(0);\n\n var tagName = _$node$get.tagName;\n\n // TODO: Consider ordering by most likely.\n // E.g., if divs are a more common tag on a page,\n // Could save doing that regex test on every node – AP\n\n if (PARAGRAPH_SCORE_TAGS$1.test(tagName)) {\n return scoreParagraph($node);\n } else if (tagName === 'div') {\n return 5;\n } else if (CHILD_CONTENT_TAGS$1.test(tagName)) {\n return 3;\n } else if (BAD_TAGS$1.test(tagName)) {\n return -3;\n } else if (tagName === 'th') {\n return -5;\n }\n\n return 0;\n}\n\nfunction convertSpans$1($node, $) {\n if ($node.get(0)) {\n var _$node$get = $node.get(0);\n\n var tagName = _$node$get.tagName;\n\n\n if (tagName === 'span') {\n // convert spans to divs\n convertNodeTo($node, $, 'div');\n }\n }\n}\n\nfunction addScoreTo($node, $, score) {\n if ($node) {\n convertSpans$1($node, $);\n addScore($node, $, score);\n }\n}\n\nfunction scorePs($, weightNodes) {\n $('p, pre').not('[score]').each(function (index, node) {\n // The raw score for this paragraph, before we add any parent/child\n // scores.\n var $node = $(node);\n $node = setScore($node, $, getOrInitScore($node, $, weightNodes));\n\n var $parent = $node.parent();\n var rawScore = scoreNode($node);\n\n addScoreTo($parent, $, rawScore, weightNodes);\n if ($parent) {\n // Add half of the individual content score to the\n // grandparent\n addScoreTo($parent.parent(), $, rawScore / 2, weightNodes);\n }\n });\n\n return $;\n}\n\n// score content. Parents get the full value of their children's\n// content score, grandparents half\nfunction scoreContent($) {\n var weightNodes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n\n // First, look for special hNews based selectors and give them a big\n // boost, if they exist\n HNEWS_CONTENT_SELECTORS$1.forEach(function (_ref) {\n var _ref2 = _slicedToArray(_ref, 2);\n\n var parentSelector = _ref2[0];\n var childSelector = _ref2[1];\n\n $(parentSelector + ' ' + childSelector).each(function (index, node) {\n addScore($(node).parent(parentSelector), $, 80);\n });\n });\n\n // Doubling this again\n // Previous solution caused a bug\n // in which parents weren't retaining\n // scores. This is not ideal, and\n // should be fixed.\n scorePs($, weightNodes);\n scorePs($, weightNodes);\n\n return $;\n}\n\nvar NORMALIZE_RE = /\\s{2,}/g;\n\nfunction normalizeSpaces(text) {\n return text.replace(NORMALIZE_RE, ' ').trim();\n}\n\n// Given a node type to search for, and a list of regular expressions,\n// look to see if this extraction can be found in the URL. Expects\n// that each expression in r_list will return group(1) as the proper\n// string to be cleaned.\n// Only used for date_published currently.\nfunction extractFromUrl(url, regexList) {\n var matchRe = regexList.find(function (re) {\n return re.test(url);\n });\n if (matchRe) {\n return matchRe.exec(url)[1];\n }\n\n return null;\n}\n\n// An expression that looks to try to find the page digit within a URL, if\n// it exists.\n// Matches:\n// page=1\n// pg=1\n// p=1\n// paging=12\n// pag=7\n// pagination/1\n// paging/88\n// pa/83\n// p/11\n//\n// Does not match:\n// pg=102\n// page:2\nvar PAGE_IN_HREF_RE = new RegExp('(page|paging|(p(a|g|ag)?(e|enum|ewanted|ing|ination)))?(=|/)([0-9]{1,3})', 'i');\n\nvar HAS_ALPHA_RE = /[a-z]/i;\n\nvar IS_ALPHA_RE = /^[a-z]+$/i;\nvar IS_DIGIT_RE = /^[0-9]+$/i;\n\nfunction pageNumFromUrl(url) {\n var matches = url.match(PAGE_IN_HREF_RE);\n if (!matches) return null;\n\n var pageNum = parseInt(matches[6], 10);\n\n // Return pageNum < 100, otherwise\n // return null\n return pageNum < 100 ? pageNum : null;\n}\n\nfunction removeAnchor(url) {\n return url.split('#')[0].replace(/\\/$/, '');\n}\n\nfunction isGoodSegment(segment, index, firstSegmentHasLetters) {\n var goodSegment = true;\n\n // If this is purely a number, and it's the first or second\n // url_segment, it's probably a page number. Remove it.\n if (index < 2 && IS_DIGIT_RE.test(segment) && segment.length < 3) {\n goodSegment = true;\n }\n\n // If this is the first url_segment and it's just \"index\",\n // remove it\n if (index === 0 && segment.toLowerCase() === 'index') {\n goodSegment = false;\n }\n\n // If our first or second url_segment is smaller than 3 characters,\n // and the first url_segment had no alphas, remove it.\n if (index < 2 && segment.length < 3 && !firstSegmentHasLetters) {\n goodSegment = false;\n }\n\n return goodSegment;\n}\n\n// Take a URL, and return the article base of said URL. That is, no\n// pagination data exists in it. Useful for comparing to other links\n// that might have pagination data within them.\nfunction articleBaseUrl(url, parsed) {\n var parsedUrl = parsed || URL.parse(url);\n var protocol = parsedUrl.protocol;\n var host = parsedUrl.host;\n var path = parsedUrl.path;\n\n\n var firstSegmentHasLetters = false;\n var cleanedSegments = path.split('/').reverse().reduce(function (acc, rawSegment, index) {\n var segment = rawSegment;\n\n // Split off and save anything that looks like a file type.\n if (segment.includes('.')) {\n var _segment$split = segment.split('.');\n\n var _segment$split2 = _slicedToArray(_segment$split, 2);\n\n var possibleSegment = _segment$split2[0];\n var fileExt = _segment$split2[1];\n\n if (IS_ALPHA_RE.test(fileExt)) {\n segment = possibleSegment;\n }\n }\n\n // If our first or second segment has anything looking like a page\n // number, remove it.\n if (PAGE_IN_HREF_RE.test(segment) && index < 2) {\n segment = segment.replace(PAGE_IN_HREF_RE, '');\n }\n\n // If we're on the first segment, check to see if we have any\n // characters in it. The first segment is actually the last bit of\n // the URL, and this will be helpful to determine if we're on a URL\n // segment that looks like \"/2/\" for example.\n if (index === 0) {\n firstSegmentHasLetters = HAS_ALPHA_RE.test(segment);\n }\n\n // If it's not marked for deletion, push it to cleaned_segments.\n if (isGoodSegment(segment, index, firstSegmentHasLetters)) {\n acc.push(segment);\n }\n\n return acc;\n }, []);\n\n return protocol + '//' + host + cleanedSegments.reverse().join('/');\n}\n\n// Given a string, return True if it appears to have an ending sentence\n// within it, false otherwise.\nvar SENTENCE_END_RE = new RegExp('.( |$)');\nfunction hasSentenceEnd(text) {\n return SENTENCE_END_RE.test(text);\n}\n\nfunction excerptContent(content) {\n var words = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 10;\n\n return content.trim().split(/\\s+/).slice(0, words).join(' ');\n}\n\n// Now that we have a top_candidate, look through the siblings of\n// it to see if any of them are decently scored. If they are, they\n// may be split parts of the content (Like two divs, a preamble and\n// a body.) Example:\n// http://articles.latimes.com/2009/oct/14/business/fi-bigtvs14\nfunction mergeSiblings($candidate, topScore, $) {\n if (!$candidate.parent().length) {\n return $candidate;\n }\n\n var siblingScoreThreshold = Math.max(10, topScore * 0.25);\n var wrappingDiv = $('<div></div>');\n\n $candidate.parent().children().each(function (index, sibling) {\n var $sibling = $(sibling);\n // Ignore tags like BR, HR, etc\n if (NON_TOP_CANDIDATE_TAGS_RE$1.test(sibling.tagName)) {\n return null;\n }\n\n var siblingScore = getScore($sibling);\n if (siblingScore) {\n if ($sibling === $candidate) {\n wrappingDiv.append($sibling);\n } else {\n var contentBonus = 0;\n var density = linkDensity($sibling);\n\n // If sibling has a very low link density,\n // give it a small bonus\n if (density < 0.05) {\n contentBonus += 20;\n }\n\n // If sibling has a high link density,\n // give it a penalty\n if (density >= 0.5) {\n contentBonus -= 20;\n }\n\n // If sibling node has the same class as\n // candidate, give it a bonus\n if ($sibling.attr('class') === $candidate.attr('class')) {\n contentBonus += topScore * 0.2;\n }\n\n var newScore = siblingScore + contentBonus;\n\n if (newScore >= siblingScoreThreshold) {\n return wrappingDiv.append($sibling);\n } else if (sibling.tagName === 'p') {\n var siblingContent = $sibling.text();\n var siblingContentLength = textLength(siblingContent);\n\n if (siblingContentLength > 80 && density < 0.25) {\n return wrappingDiv.append($sibling);\n } else if (siblingContentLength <= 80 && density === 0 && hasSentenceEnd(siblingContent)) {\n return wrappingDiv.append($sibling);\n }\n }\n }\n }\n\n return null;\n });\n\n return wrappingDiv;\n}\n\n// After we've calculated scores, loop through all of the possible\n// candidate nodes we found and find the one with the highest score.\nfunction findTopCandidate($) {\n var $candidate = void 0;\n var topScore = 0;\n\n $('[score]').each(function (index, node) {\n // Ignore tags like BR, HR, etc\n if (NON_TOP_CANDIDATE_TAGS_RE$1.test(node.tagName)) {\n return;\n }\n\n var $node = $(node);\n var score = getScore($node);\n\n if (score > topScore) {\n topScore = score;\n $candidate = $node;\n }\n });\n\n // If we don't have a candidate, return the body\n // or whatever the first element is\n if (!$candidate) {\n return $('body') || $('*').first();\n }\n\n $candidate = mergeSiblings($candidate, topScore, $);\n\n return $candidate;\n}\n\nfunction removeUnlessContent($node, $, weight) {\n // Explicitly save entry-content-asset tags, which are\n // noted as valuable in the Publisher guidelines. For now\n // this works everywhere. We may want to consider making\n // this less of a sure-thing later.\n if ($node.hasClass('entry-content-asset')) {\n return;\n }\n\n var content = normalizeSpaces($node.text());\n\n if (scoreCommas(content) < 10) {\n var pCount = $('p', $node).length;\n var inputCount = $('input', $node).length;\n\n // Looks like a form, too many inputs.\n if (inputCount > pCount / 3) {\n $node.remove();\n return;\n }\n\n var contentLength = content.length;\n var imgCount = $('img', $node).length;\n\n // Content is too short, and there are no images, so\n // this is probably junk content.\n if (contentLength < 25 && imgCount === 0) {\n $node.remove();\n return;\n }\n\n var density = linkDensity($node);\n\n // Too high of link density, is probably a menu or\n // something similar.\n // console.log(weight, density, contentLength)\n if (weight < 25 && density > 0.2 && contentLength > 75) {\n $node.remove();\n return;\n }\n\n // Too high of a link density, despite the score being\n // high.\n if (weight >= 25 && density > 0.5) {\n // Don't remove the node if it's a list and the\n // previous sibling starts with a colon though. That\n // means it's probably content.\n var tagName = $node.get(0).tagName;\n var nodeIsList = tagName === 'ol' || tagName === 'ul';\n if (nodeIsList) {\n var previousNode = $node.prev();\n if (previousNode && normalizeSpaces(previousNode.text()).slice(-1) === ':') {\n return;\n }\n }\n\n $node.remove();\n return;\n }\n\n var scriptCount = $('script', $node).length;\n\n // Too many script tags, not enough content.\n if (scriptCount > 0 && contentLength < 150) {\n $node.remove();\n return;\n }\n }\n}\n\n// Given an article, clean it of some superfluous content specified by\n// tags. Things like forms, ads, etc.\n//\n// Tags is an array of tag name's to search through. (like div, form,\n// etc)\n//\n// Return this same doc.\nfunction cleanTags($article, $) {\n $(CLEAN_CONDITIONALLY_TAGS, $article).each(function (index, node) {\n var $node = $(node);\n var weight = getScore($node);\n if (!weight) {\n weight = getOrInitScore($node, $);\n setScore($node, $, weight);\n }\n\n // drop node if its weight is < 0\n if (weight < 0) {\n $node.remove();\n } else {\n // deteremine if node seems like content\n removeUnlessContent($node, $, weight);\n }\n });\n\n return $;\n}\n\nfunction cleanHeaders($article, $) {\n var title = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';\n\n $(HEADER_TAG_LIST, $article).each(function (index, header) {\n var $header = $(header);\n // Remove any headers that appear before all other p tags in the\n // document. This probably means that it was part of the title, a\n // subtitle or something else extraneous like a datestamp or byline,\n // all of which should be handled by other metadata handling.\n if ($($header, $article).prevAll('p').length === 0) {\n return $header.remove();\n }\n\n // Remove any headers that match the title exactly.\n if (normalizeSpaces($(header).text()) === title) {\n return $header.remove();\n }\n\n // If this header has a negative weight, it's probably junk.\n // Get rid of it.\n if (getWeight($(header)) < 0) {\n return $header.remove();\n }\n\n return $header;\n });\n\n return $;\n}\n\n// Rewrite the tag name to div if it's a top level node like body or\n// html to avoid later complications with multiple body tags.\n\nfunction rewriteTopLevel(article, $) {\n // I'm not using context here because\n // it's problematic when converting the\n // top-level/root node - AP\n $ = convertNodeTo($('html'), $, 'div');\n $ = convertNodeTo($('body'), $, 'div');\n\n return $;\n}\n\nfunction absolutize($, rootUrl, attr, $content) {\n $('[' + attr + ']', $content).each(function (_, node) {\n var url = node.attribs[attr];\n var absoluteUrl = URL.resolve(rootUrl, url);\n\n node.attribs[attr] = absoluteUrl;\n });\n}\n\nfunction makeLinksAbsolute($content, $, url) {\n ['href', 'src'].forEach(function (attr) {\n return absolutize($, url, attr, $content);\n });\n\n return $content;\n}\n\nfunction textLength(text) {\n return text.trim().replace(/\\s+/g, ' ').length;\n}\n\n// Determines what percentage of the text\n// in a node is link text\n// Takes a node, returns a float\nfunction linkDensity($node) {\n var totalTextLength = textLength($node.text());\n\n var linkText = $node.find('a').text();\n var linkLength = textLength(linkText);\n\n if (totalTextLength > 0) {\n return linkLength / totalTextLength;\n } else if (totalTextLength === 0 && linkLength > 0) {\n return 1;\n }\n\n return 0;\n}\n\n// Given a node type to search for, and a list of meta tag names to\n// search for, find a meta tag associated.\n\nfunction extractFromMeta($, metaNames, cachedNames) {\n var cleanTags = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;\n\n var foundNames = metaNames.filter(function (name) {\n return cachedNames.indexOf(name) !== -1;\n });\n\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n var _loop = function _loop() {\n var name = _step.value;\n\n var type = 'name';\n var value = 'value';\n\n var nodes = $('meta[' + type + '=\"' + name + '\"]');\n\n // Get the unique value of every matching node, in case there\n // are two meta tags with the same name and value.\n // Remove empty values.\n var values = nodes.map(function (index, node) {\n return $(node).attr(value);\n }).toArray().filter(function (text) {\n return text !== '';\n });\n\n // If we have more than one value for the same name, we have a\n // conflict and can't trust any of them. Skip this name. If we have\n // zero, that means our meta tags had no values. Skip this name\n // also.\n if (values.length === 1) {\n var metaValue = void 0;\n // Meta values that contain HTML should be stripped, as they\n // weren't subject to cleaning previously.\n if (cleanTags) {\n metaValue = stripTags(values[0], $);\n } else {\n metaValue = values[0];\n }\n\n return {\n v: metaValue\n };\n }\n };\n\n for (var _iterator = _getIterator(foundNames), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var _ret = _loop();\n\n if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === \"object\") return _ret.v;\n }\n\n // If nothing is found, return null\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n return null;\n}\n\nfunction isGoodNode($node, maxChildren) {\n // If it has a number of children, it's more likely a container\n // element. Skip it.\n if ($node.children().length > maxChildren) {\n return false;\n }\n // If it looks to be within a comment, skip it.\n if (withinComment($node)) {\n return false;\n }\n\n return true;\n}\n\n// Given a a list of selectors find content that may\n// be extractable from the document. This is for flat\n// meta-information, like author, title, date published, etc.\nfunction extractFromSelectors($, selectors) {\n var maxChildren = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;\n var textOnly = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = _getIterator(selectors), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var selector = _step.value;\n\n var nodes = $(selector);\n\n // If we didn't get exactly one of this selector, this may be\n // a list of articles or comments. Skip it.\n if (nodes.length === 1) {\n var $node = $(nodes[0]);\n\n if (isGoodNode($node, maxChildren)) {\n var content = void 0;\n if (textOnly) {\n content = $node.text();\n } else {\n content = $node.html();\n }\n\n if (content) {\n return content;\n }\n }\n }\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n return null;\n}\n\n// strips all tags from a string of text\nfunction stripTags(text, $) {\n // Wrapping text in html element prevents errors when text\n // has no html\n var cleanText = $('<span>' + text + '</span>').text();\n return cleanText === '' ? text : cleanText;\n}\n\nfunction withinComment($node) {\n var parents = $node.parents().toArray();\n var commentParent = parents.find(function (parent) {\n var classAndId = parent.attribs.class + ' ' + parent.attribs.id;\n return classAndId.includes('comment');\n });\n\n return commentParent !== undefined;\n}\n\n// Given a node, determine if it's article-like enough to return\n// param: node (a cheerio node)\n// return: boolean\n\nfunction nodeIsSufficient($node) {\n return $node.text().trim().length >= 100;\n}\n\nfunction isWordpress($) {\n return $(IS_WP_SELECTOR).length > 0;\n}\n\n// CLEAN AUTHOR CONSTANTS\nvar CLEAN_AUTHOR_RE = /^\\s*(posted |written )?by\\s*:?\\s*(.*)/i;\n// author = re.sub(r'^\\s*(posted |written )?by\\s*:?\\s*(.*)(?i)',\n\n// CLEAN DEK CONSTANTS\nvar TEXT_LINK_RE = new RegExp('http(s)?://', 'i');\n// CLEAN DATE PUBLISHED CONSTANTS\nvar MS_DATE_STRING = /^\\d{13}$/i;\nvar SEC_DATE_STRING = /^\\d{10}$/i;\nvar CLEAN_DATE_STRING_RE = /^\\s*published\\s*:?\\s*(.*)/i;\nvar TIME_MERIDIAN_SPACE_RE = /(.*\\d)(am|pm)(.*)/i;\nvar TIME_MERIDIAN_DOTS_RE = /\\.m\\./i;\nvar months = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'];\nvar allMonths = months.join('|');\nvar timestamp1 = '[0-9]{1,2}:[0-9]{2,2}( ?[ap].?m.?)?';\nvar timestamp2 = '[0-9]{1,2}[/-][0-9]{1,2}[/-][0-9]{2,4}';\nvar SPLIT_DATE_STRING = new RegExp('(' + timestamp1 + ')|(' + timestamp2 + ')|([0-9]{1,4})|(' + allMonths + ')', 'ig');\n\n// CLEAN TITLE CONSTANTS\n// A regular expression that will match separating characters on a\n// title, that usually denote breadcrumbs or something similar.\nvar TITLE_SPLITTERS_RE = /(: | - | \\| )/g;\n\nvar DOMAIN_ENDINGS_RE = new RegExp('.com$|.net$|.org$|.co.uk$', 'g');\n\n// Take an author string (like 'By David Smith ') and clean it to\n// just the name(s): 'David Smith'.\nfunction cleanAuthor(author) {\n return author.replace(CLEAN_AUTHOR_RE, '$2').trim();\n}\n\nfunction clean$1(leadImageUrl) {\n leadImageUrl = leadImageUrl.trim();\n if (validUrl.isWebUri(leadImageUrl)) {\n return leadImageUrl;\n }\n\n return null;\n}\n\n// Take a dek HTML fragment, and return the cleaned version of it.\n// Return None if the dek wasn't good enough.\nfunction cleanDek(dek, _ref) {\n var $ = _ref.$;\n var excerpt = _ref.excerpt;\n\n // Sanity check that we didn't get too short or long of a dek.\n if (dek.length > 1000 || dek.length < 5) return null;\n\n // Check that dek isn't the same as excerpt\n if (excerpt && excerptContent(excerpt, 10) === excerptContent(dek, 10)) return null;\n\n var dekText = stripTags(dek, $);\n\n // Plain text links shouldn't exist in the dek. If we have some, it's\n // not a good dek - bail.\n if (TEXT_LINK_RE.test(dekText)) return null;\n\n return dekText.trim();\n}\n\n// Is there a compelling reason to use moment here?\n// Mostly only being used for the isValid() method,\n// but could just check for 'Invalid Date' string.\n\nfunction cleanDateString(dateString) {\n return (dateString.match(SPLIT_DATE_STRING) || []).join(' ').replace(TIME_MERIDIAN_DOTS_RE, 'm').replace(TIME_MERIDIAN_SPACE_RE, '$1 $2 $3').replace(CLEAN_DATE_STRING_RE, '$1').trim();\n}\n\n// Take a date published string, and hopefully return a date out of\n// it. Return none if we fail.\nfunction cleanDatePublished(dateString) {\n // If string is in milliseconds or seconds, convert to int\n if (MS_DATE_STRING.test(dateString) || SEC_DATE_STRING.test(dateString)) {\n dateString = parseInt(dateString, 10);\n }\n\n var date = moment(new Date(dateString));\n\n if (!date.isValid()) {\n dateString = cleanDateString(dateString);\n date = moment(new Date(dateString));\n }\n\n return date.isValid() ? date.toISOString() : null;\n}\n\n// Clean our article content, returning a new, cleaned node.\n\nfunction extractCleanNode(article, _ref) {\n var $ = _ref.$;\n var _ref$cleanConditional = _ref.cleanConditionally;\n var cleanConditionally = _ref$cleanConditional === undefined ? true : _ref$cleanConditional;\n var _ref$title = _ref.title;\n var title = _ref$title === undefined ? '' : _ref$title;\n var _ref$url = _ref.url;\n var url = _ref$url === undefined ? '' : _ref$url;\n var _ref$defaultCleaner = _ref.defaultCleaner;\n var defaultCleaner = _ref$defaultCleaner === undefined ? true : _ref$defaultCleaner;\n\n // Rewrite the tag name to div if it's a top level node like body or\n // html to avoid later complications with multiple body tags.\n rewriteTopLevel(article, $);\n\n // Drop small images and spacer images\n // Only do this is defaultCleaner is set to true;\n // this can sometimes be too aggressive.\n if (defaultCleaner) cleanImages(article, $);\n\n // Mark elements to keep that would normally be removed.\n // E.g., stripJunkTags will remove iframes, so we're going to mark\n // YouTube/Vimeo videos as elements we want to keep.\n markToKeep(article, $, url);\n\n // Drop certain tags like <title>, etc\n // This is -mostly- for cleanliness, not security.\n stripJunkTags(article, $);\n\n // H1 tags are typically the article title, which should be extracted\n // by the title extractor instead. If there's less than 3 of them (<3),\n // strip them. Otherwise, turn 'em into H2s.\n cleanHOnes(article, $);\n\n // Clean headers\n cleanHeaders(article, $, title);\n\n // Make links absolute\n makeLinksAbsolute(article, $, url);\n\n // We used to clean UL's and OL's here, but it was leading to\n // too many in-article lists being removed. Consider a better\n // way to detect menus particularly and remove them.\n // Also optionally running, since it can be overly aggressive.\n if (defaultCleaner) cleanTags(article, $, cleanConditionally);\n\n // Remove empty paragraph nodes\n removeEmpty(article, $);\n\n // Remove unnecessary attributes\n cleanAttributes(article, $);\n\n return article;\n}\n\nfunction cleanTitle(title, _ref) {\n var url = _ref.url;\n var $ = _ref.$;\n\n // If title has |, :, or - in it, see if\n // we can clean it up.\n if (TITLE_SPLITTERS_RE.test(title)) {\n title = resolveSplitTitle(title, url);\n }\n\n // Final sanity check that we didn't get a crazy title.\n // if (title.length > 150 || title.length < 15) {\n if (title.length > 150) {\n // If we did, return h1 from the document if it exists\n var h1 = $('h1');\n if (h1.length === 1) {\n title = h1.text();\n }\n }\n\n // strip any html tags in the title text\n return stripTags(title, $).trim();\n}\n\nfunction extractBreadcrumbTitle(splitTitle, text) {\n // This must be a very breadcrumbed title, like:\n // The Best Gadgets on Earth : Bits : Blogs : NYTimes.com\n // NYTimes - Blogs - Bits - The Best Gadgets on Earth\n if (splitTitle.length >= 6) {\n var _ret = function () {\n // Look to see if we can find a breadcrumb splitter that happens\n // more than once. If we can, we'll be able to better pull out\n // the title.\n var termCounts = splitTitle.reduce(function (acc, titleText) {\n acc[titleText] = acc[titleText] ? acc[titleText] + 1 : 1;\n return acc;\n }, {});\n\n var _Reflect$ownKeys$redu = _Reflect$ownKeys(termCounts).reduce(function (acc, key) {\n if (acc[1] < termCounts[key]) {\n return [key, termCounts[key]];\n }\n\n return acc;\n }, [0, 0]);\n\n var _Reflect$ownKeys$redu2 = _slicedToArray(_Reflect$ownKeys$redu, 2);\n\n var maxTerm = _Reflect$ownKeys$redu2[0];\n var termCount = _Reflect$ownKeys$redu2[1];\n\n // We found a splitter that was used more than once, so it\n // is probably the breadcrumber. Split our title on that instead.\n // Note: max_term should be <= 4 characters, so that \" >> \"\n // will match, but nothing longer than that.\n\n if (termCount >= 2 && maxTerm.length <= 4) {\n splitTitle = text.split(maxTerm);\n }\n\n var splitEnds = [splitTitle[0], splitTitle.slice(-1)];\n var longestEnd = splitEnds.reduce(function (acc, end) {\n return acc.length > end.length ? acc : end;\n }, '');\n\n if (longestEnd.length > 10) {\n return {\n v: longestEnd\n };\n }\n\n return {\n v: text\n };\n }();\n\n if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === \"object\") return _ret.v;\n }\n\n return null;\n}\n\nfunction cleanDomainFromTitle(splitTitle, url) {\n // Search the ends of the title, looking for bits that fuzzy match\n // the URL too closely. If one is found, discard it and return the\n // rest.\n //\n // Strip out the big TLDs - it just makes the matching a bit more\n // accurate. Not the end of the world if it doesn't strip right.\n var _URL$parse = URL.parse(url);\n\n var host = _URL$parse.host;\n\n var nakedDomain = host.replace(DOMAIN_ENDINGS_RE, '');\n\n var startSlug = splitTitle[0].toLowerCase().replace(' ', '');\n var startSlugRatio = wuzzy.levenshtein(startSlug, nakedDomain);\n\n if (startSlugRatio > 0.4 && startSlug.length > 5) {\n return splitTitle.slice(2).join('');\n }\n\n var endSlug = splitTitle.slice(-1)[0].toLowerCase().replace(' ', '');\n var endSlugRatio = wuzzy.levenshtein(endSlug, nakedDomain);\n\n if (endSlugRatio > 0.4 && endSlug.length >= 5) {\n return splitTitle.slice(0, -2).join('');\n }\n\n return null;\n}\n\n// Given a title with separators in it (colons, dashes, etc),\n// resolve whether any of the segments should be removed.\nfunction resolveSplitTitle(title) {\n var url = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';\n\n // Splits while preserving splitters, like:\n // ['The New New York', ' - ', 'The Washington Post']\n var splitTitle = title.split(TITLE_SPLITTERS_RE);\n if (splitTitle.length === 1) {\n return title;\n }\n\n var newTitle = extractBreadcrumbTitle(splitTitle, title);\n if (newTitle) return newTitle;\n\n newTitle = cleanDomainFromTitle(splitTitle, url);\n if (newTitle) return newTitle;\n\n // Fuzzy ratio didn't find anything, so this title is probably legit.\n // Just return it all.\n return title;\n}\n\nvar Cleaners = {\n author: cleanAuthor,\n lead_image_url: clean$1,\n dek: cleanDek,\n date_published: cleanDatePublished,\n content: extractCleanNode,\n title: cleanTitle\n};\n\n// Using a variety of scoring techniques, extract the content most\n// likely to be article text.\n//\n// If strip_unlikely_candidates is True, remove any elements that\n// match certain criteria first. (Like, does this element have a\n// classname of \"comment\")\n//\n// If weight_nodes is True, use classNames and IDs to determine the\n// worthiness of nodes.\n//\n// Returns a cheerio object $\nfunction extractBestNode($, opts) {\n // clone the node so we can get back to our\n // initial parsed state if needed\n // TODO Do I need this? – AP\n // let $root = $.root().clone()\n\n\n if (opts.stripUnlikelyCandidates) {\n $ = stripUnlikelyCandidates($);\n }\n\n $ = convertToParagraphs($);\n $ = scoreContent($, opts.weightNodes);\n var $topCandidate = findTopCandidate($);\n\n return $topCandidate;\n}\n\nvar GenericContentExtractor = {\n defaultOpts: {\n stripUnlikelyCandidates: true,\n weightNodes: true,\n cleanConditionally: true\n },\n\n // Extract the content for this resource - initially, pass in our\n // most restrictive opts which will return the highest quality\n // content. On each failure, retry with slightly more lax opts.\n //\n // :param return_type: string. If \"node\", should return the content\n // as a cheerio node rather than as an HTML string.\n //\n // Opts:\n // stripUnlikelyCandidates: Remove any elements that match\n // non-article-like criteria first.(Like, does this element\n // have a classname of \"comment\")\n //\n // weightNodes: Modify an elements score based on whether it has\n // certain classNames or IDs. Examples: Subtract if a node has\n // a className of 'comment', Add if a node has an ID of\n // 'entry-content'.\n //\n // cleanConditionally: Clean the node to return of some\n // superfluous content. Things like forms, ads, etc.\n extract: function extract(_ref, opts) {\n var $ = _ref.$;\n var html = _ref.html;\n var title = _ref.title;\n var url = _ref.url;\n\n opts = _extends({}, this.defaultOpts, opts);\n\n $ = $ || cheerio.load(html);\n\n // Cascade through our extraction-specific opts in an ordered fashion,\n // turning them off as we try to extract content.\n var node = this.getContentNode($, title, url, opts);\n\n if (nodeIsSufficient(node)) {\n return this.cleanAndReturnNode(node, $);\n }\n\n // We didn't succeed on first pass, one by one disable our\n // extraction opts and try again.\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = _getIterator(_Reflect$ownKeys(opts).filter(function (k) {\n return opts[k] === true;\n })), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var key = _step.value;\n\n opts[key] = false;\n $ = cheerio.load(html);\n\n node = this.getContentNode($, title, url, opts);\n\n if (nodeIsSufficient(node)) {\n break;\n }\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n return this.cleanAndReturnNode(node, $);\n },\n\n\n // Get node given current options\n getContentNode: function getContentNode($, title, url, opts) {\n return extractCleanNode(extractBestNode($, opts), {\n $: $,\n cleanConditionally: opts.cleanConditionally,\n title: title,\n url: url\n });\n },\n\n\n // Once we got here, either we're at our last-resort node, or\n // we broke early. Make sure we at least have -something- before we\n // move forward.\n cleanAndReturnNode: function cleanAndReturnNode(node, $) {\n if (!node) {\n return null;\n }\n\n return normalizeSpaces($.html(node));\n\n // if return_type == \"html\":\n // return normalize_spaces(node_to_html(node))\n // else:\n // return node\n }\n};\n\n// TODO: It would be great if we could merge the meta and selector lists into\n// a list of objects, because we could then rank them better. For example,\n// .hentry .entry-title is far better suited than <meta title>.\n\n// An ordered list of meta tag names that denote likely article titles. All\n// attributes should be lowercase for faster case-insensitive matching. From\n// most distinct to least distinct.\nvar STRONG_TITLE_META_TAGS = ['tweetmeme-title', 'dc.title', 'rbtitle', 'headline', 'title'];\n\n// og:title is weak because it typically contains context that we don't like,\n// for example the source site's name. Gotta get that brand into facebook!\nvar WEAK_TITLE_META_TAGS = ['og:title'];\n\n// An ordered list of XPath Selectors to find likely article titles. From\n// most explicit to least explicit.\n//\n// Note - this does not use classes like CSS. This checks to see if the string\n// exists in the className, which is not as accurate as .className (which\n// splits on spaces/endlines), but for our purposes it's close enough. The\n// speed tradeoff is worth the accuracy hit.\nvar STRONG_TITLE_SELECTORS = ['.hentry .entry-title', 'h1#articleHeader', 'h1.articleHeader', 'h1.article', '.instapaper_title', '#meebo-title'];\n\nvar WEAK_TITLE_SELECTORS = ['article h1', '#entry-title', '.entry-title', '#entryTitle', '#entrytitle', '.entryTitle', '.entrytitle', '#articleTitle', '.articleTitle', 'post post-title', 'h1.title', 'h2.article', 'h1', 'html head title', 'title'];\n\nvar GenericTitleExtractor = {\n extract: function extract(_ref) {\n var $ = _ref.$;\n var url = _ref.url;\n var metaCache = _ref.metaCache;\n\n // First, check to see if we have a matching meta tag that we can make\n // use of that is strongly associated with the headline.\n var title = void 0;\n\n title = extractFromMeta($, STRONG_TITLE_META_TAGS, metaCache);\n if (title) return cleanTitle(title, { url: url, $: $ });\n\n // Second, look through our content selectors for the most likely\n // article title that is strongly associated with the headline.\n title = extractFromSelectors($, STRONG_TITLE_SELECTORS);\n if (title) return cleanTitle(title, { url: url, $: $ });\n\n // Third, check for weaker meta tags that may match.\n title = extractFromMeta($, WEAK_TITLE_META_TAGS, metaCache);\n if (title) return cleanTitle(title, { url: url, $: $ });\n\n // Last, look for weaker selector tags that may match.\n title = extractFromSelectors($, WEAK_TITLE_SELECTORS);\n if (title) return cleanTitle(title, { url: url, $: $ });\n\n // If no matches, return an empty string\n return '';\n }\n};\n\n// An ordered list of meta tag names that denote likely article authors. All\n// attributes should be lowercase for faster case-insensitive matching. From\n// most distinct to least distinct.\n//\n// Note: \"author\" is too often the -developer- of the page, so it is not\n// added here.\nvar AUTHOR_META_TAGS = ['byl', 'clmst', 'dc.author', 'dcsext.author', 'dc.creator', 'rbauthors', 'authors'];\n\nvar AUTHOR_MAX_LENGTH = 300;\n\n// An ordered list of XPath Selectors to find likely article authors. From\n// most explicit to least explicit.\n//\n// Note - this does not use classes like CSS. This checks to see if the string\n// exists in the className, which is not as accurate as .className (which\n// splits on spaces/endlines), but for our purposes it's close enough. The\n// speed tradeoff is worth the accuracy hit.\nvar AUTHOR_SELECTORS = ['.entry .entry-author', '.author.vcard .fn', '.author .vcard .fn', '.byline.vcard .fn', '.byline .vcard .fn', '.byline .by .author', '.byline .by', '.byline .author', '.post-author.vcard', '.post-author .vcard', 'a[rel=author]', '#by_author', '.by_author', '#entryAuthor', '.entryAuthor', '.byline a[href*=author]', '#author .authorname', '.author .authorname', '#author', '.author', '.articleauthor', '.ArticleAuthor', '.byline'];\n\n// An ordered list of Selectors to find likely article authors, with\n// regular expression for content.\nvar bylineRe = /^[\\n\\s]*By/i;\nvar BYLINE_SELECTORS_RE = [['#byline', bylineRe], ['.byline', bylineRe]];\n\nvar GenericAuthorExtractor = {\n extract: function extract(_ref) {\n var $ = _ref.$;\n var metaCache = _ref.metaCache;\n\n var author = void 0;\n\n // First, check to see if we have a matching\n // meta tag that we can make use of.\n author = extractFromMeta($, AUTHOR_META_TAGS, metaCache);\n if (author && author.length < AUTHOR_MAX_LENGTH) {\n return cleanAuthor(author);\n }\n\n // Second, look through our selectors looking for potential authors.\n author = extractFromSelectors($, AUTHOR_SELECTORS, 2);\n if (author && author.length < AUTHOR_MAX_LENGTH) {\n return cleanAuthor(author);\n }\n\n // Last, use our looser regular-expression based selectors for\n // potential authors.\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = _getIterator(BYLINE_SELECTORS_RE), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var _ref4 = _step.value;\n\n var _ref3 = _slicedToArray(_ref4, 2);\n\n var selector = _ref3[0];\n var regex = _ref3[1];\n\n var node = $(selector);\n if (node.length === 1) {\n var text = node.text();\n if (regex.test(text)) {\n return cleanAuthor(text);\n }\n }\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n return null;\n }\n};\n\n// An ordered list of meta tag names that denote\n// likely date published dates. All attributes\n// should be lowercase for faster case-insensitive matching.\n// From most distinct to least distinct.\nvar DATE_PUBLISHED_META_TAGS = ['article:published_time', 'displaydate', 'dc.date', 'dc.date.issued', 'rbpubdate', 'publish_date', 'pub_date', 'pagedate', 'pubdate', 'revision_date', 'doc_date', 'date_created', 'content_create_date', 'lastmodified', 'created', 'date'];\n\n// An ordered list of XPath Selectors to find\n// likely date published dates. From most explicit\n// to least explicit.\nvar DATE_PUBLISHED_SELECTORS = ['.hentry .dtstamp.published', '.hentry .published', '.hentry .dtstamp.updated', '.hentry .updated', '.single .published', '.meta .published', '.meta .postDate', '.entry-date', '.byline .date', '.postmetadata .date', '.article_datetime', '.date-header', '.story-date', '.dateStamp', '#story .datetime', '.dateline', '.pubdate'];\n\n// An ordered list of compiled regular expressions to find likely date\n// published dates from the URL. These should always have the first\n// reference be a date string that is parseable by dateutil.parser.parse\nvar abbrevMonthsStr = '(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)';\nvar DATE_PUBLISHED_URL_RES = [\n// /2012/01/27/ but not /2012/01/293\nnew RegExp('/(20\\\\d{2}/\\\\d{2}/\\\\d{2})/', 'i'),\n// 20120127 or 20120127T but not 2012012733 or 8201201733\n// /[^0-9](20\\d{2}[01]\\d[0-3]\\d)([^0-9]|$)/i,\n// 2012-01-27\nnew RegExp('(20\\\\d{2}-[01]\\\\d-[0-3]\\\\d)', 'i'),\n// /2012/jan/27/\nnew RegExp('/(20\\\\d{2}/' + abbrevMonthsStr + '/[0-3]\\\\d)/', 'i')];\n\nvar GenericDatePublishedExtractor = {\n extract: function extract(_ref) {\n var $ = _ref.$;\n var url = _ref.url;\n var metaCache = _ref.metaCache;\n\n var datePublished = void 0;\n // First, check to see if we have a matching meta tag\n // that we can make use of.\n // Don't try cleaning tags from this string\n datePublished = extractFromMeta($, DATE_PUBLISHED_META_TAGS, metaCache, false);\n if (datePublished) return cleanDatePublished(datePublished);\n\n // Second, look through our selectors looking for potential\n // date_published's.\n datePublished = extractFromSelectors($, DATE_PUBLISHED_SELECTORS);\n if (datePublished) return cleanDatePublished(datePublished);\n\n // Lastly, look to see if a dately string exists in the URL\n datePublished = extractFromUrl(url, DATE_PUBLISHED_URL_RES);\n if (datePublished) return cleanDatePublished(datePublished);\n\n return null;\n }\n};\n\n// import {\n// DEK_META_TAGS,\n// DEK_SELECTORS,\n// DEK_URL_RES,\n// } from './constants';\n\n// import { cleanDek } from 'cleaners';\n\n// import {\n// extractFromMeta,\n// extractFromSelectors,\n// } from 'utils/dom';\n\n// Currently there is only one selector for\n// deks. We should simply return null here\n// until we have a more robust generic option.\n// Below is the original source for this, for reference.\nvar GenericDekExtractor = {\n // extract({ $, content, metaCache }) {\n extract: function extract() {\n return null;\n }\n};\n\n// An ordered list of meta tag names that denote likely article leading images.\n// All attributes should be lowercase for faster case-insensitive matching.\n// From most distinct to least distinct.\nvar LEAD_IMAGE_URL_META_TAGS = ['og:image', 'twitter:image', 'image_src'];\n\nvar LEAD_IMAGE_URL_SELECTORS = ['link[rel=image_src]'];\n\nvar POSITIVE_LEAD_IMAGE_URL_HINTS = ['upload', 'wp-content', 'large', 'photo', 'wp-image'];\nvar POSITIVE_LEAD_IMAGE_URL_HINTS_RE = new RegExp(POSITIVE_LEAD_IMAGE_URL_HINTS.join('|'), 'i');\n\nvar NEGATIVE_LEAD_IMAGE_URL_HINTS = ['spacer', 'sprite', 'blank', 'throbber', 'gradient', 'tile', 'bg', 'background', 'icon', 'social', 'header', 'hdr', 'advert', 'spinner', 'loader', 'loading', 'default', 'rating', 'share', 'facebook', 'twitter', 'theme', 'promo', 'ads', 'wp-includes'];\nvar NEGATIVE_LEAD_IMAGE_URL_HINTS_RE = new RegExp(NEGATIVE_LEAD_IMAGE_URL_HINTS.join('|'), 'i');\n\nvar GIF_RE = /\\.gif(\\?.*)?$/i;\nvar JPG_RE = /\\.jpe?g(\\?.*)?$/i;\n\nfunction getSig($node) {\n return ($node.attr('class') || '') + ' ' + ($node.attr('id') || '');\n}\n\n// Scores image urls based on a variety of heuristics.\nfunction scoreImageUrl(url) {\n url = url.trim();\n var score = 0;\n\n if (POSITIVE_LEAD_IMAGE_URL_HINTS_RE.test(url)) {\n score += 20;\n }\n\n if (NEGATIVE_LEAD_IMAGE_URL_HINTS_RE.test(url)) {\n score -= 20;\n }\n\n // TODO: We might want to consider removing this as\n // gifs are much more common/popular than they once were\n if (GIF_RE.test(url)) {\n score -= 10;\n }\n\n if (JPG_RE.test(url)) {\n score += 10;\n }\n\n // PNGs are neutral.\n\n return score;\n}\n\n// Alt attribute usually means non-presentational image.\nfunction scoreAttr($img) {\n if ($img.attr('alt')) {\n return 5;\n }\n\n return 0;\n}\n\n// Look through our parent and grandparent for figure-like\n// container elements, give a bonus if we find them\nfunction scoreByParents($img) {\n var score = 0;\n var $figParent = $img.parents('figure').first();\n\n if ($figParent.length === 1) {\n score += 25;\n }\n\n var $parent = $img.parent();\n var $gParent = void 0;\n if ($parent.length === 1) {\n $gParent = $parent.parent();\n }\n\n [$parent, $gParent].forEach(function ($node) {\n if (PHOTO_HINTS_RE$1.test(getSig($node))) {\n score += 15;\n }\n });\n\n return score;\n}\n\n// Look at our immediate sibling and see if it looks like it's a\n// caption. Bonus if so.\nfunction scoreBySibling($img) {\n var score = 0;\n var $sibling = $img.next();\n var sibling = $sibling.get(0);\n\n if (sibling && sibling.tagName === 'figcaption') {\n score += 25;\n }\n\n if (PHOTO_HINTS_RE$1.test(getSig($sibling))) {\n score += 15;\n }\n\n return score;\n}\n\nfunction scoreByDimensions($img) {\n var score = 0;\n\n var width = parseFloat($img.attr('width'));\n var height = parseFloat($img.attr('height'));\n var src = $img.attr('src');\n\n // Penalty for skinny images\n if (width && width <= 50) {\n score -= 50;\n }\n\n // Penalty for short images\n if (height && height <= 50) {\n score -= 50;\n }\n\n if (width && height && !src.includes('sprite')) {\n var area = width * height;\n if (area < 5000) {\n // Smaller than 50 x 100\n score -= 100;\n } else {\n score += Math.round(area / 1000);\n }\n }\n\n return score;\n}\n\nfunction scoreByPosition($imgs, index) {\n return $imgs.length / 2 - index;\n}\n\n// Given a resource, try to find the lead image URL from within\n// it. Like content and next page extraction, uses a scoring system\n// to determine what the most likely image may be. Short circuits\n// on really probable things like og:image meta tags.\n//\n// Potential signals to still take advantage of:\n// * domain\n// * weird aspect ratio\nvar GenericLeadImageUrlExtractor = {\n extract: function extract(_ref) {\n var $ = _ref.$;\n var content = _ref.content;\n var metaCache = _ref.metaCache;\n\n var cleanUrl = void 0;\n\n // Check to see if we have a matching meta tag that we can make use of.\n // Moving this higher because common practice is now to use large\n // images on things like Open Graph or Twitter cards.\n // images usually have for things like Open Graph.\n var imageUrl = extractFromMeta($, LEAD_IMAGE_URL_META_TAGS, metaCache, false);\n\n if (imageUrl) {\n cleanUrl = clean$1(imageUrl);\n\n if (cleanUrl) return cleanUrl;\n }\n\n // Next, try to find the \"best\" image via the content.\n // We'd rather not have to fetch each image and check dimensions,\n // so try to do some analysis and determine them instead.\n var imgs = $('img', content).toArray();\n var imgScores = {};\n\n imgs.forEach(function (img, index) {\n var $img = $(img);\n var src = $img.attr('src');\n\n if (!src) return;\n\n var score = scoreImageUrl(src);\n score += scoreAttr($img);\n score += scoreByParents($img);\n score += scoreBySibling($img);\n score += scoreByDimensions($img);\n score += scoreByPosition(imgs, index);\n\n imgScores[src] = score;\n });\n\n var _Reflect$ownKeys$redu = _Reflect$ownKeys(imgScores).reduce(function (acc, key) {\n return imgScores[key] > acc[1] ? [key, imgScores[key]] : acc;\n }, [null, 0]);\n\n var _Reflect$ownKeys$redu2 = _slicedToArray(_Reflect$ownKeys$redu, 2);\n\n var topUrl = _Reflect$ownKeys$redu2[0];\n var topScore = _Reflect$ownKeys$redu2[1];\n\n\n if (topScore > 0) {\n cleanUrl = clean$1(topUrl);\n\n if (cleanUrl) return cleanUrl;\n }\n\n // If nothing else worked, check to see if there are any really\n // probable nodes in the doc, like <link rel=\"image_src\" />.\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = _getIterator(LEAD_IMAGE_URL_SELECTORS), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var selector = _step.value;\n\n var $node = $(selector).first();\n var src = $node.attr('src');\n if (src) {\n cleanUrl = clean$1(src);\n if (cleanUrl) return cleanUrl;\n }\n\n var href = $node.attr('href');\n if (href) {\n cleanUrl = clean$1(href);\n if (cleanUrl) return cleanUrl;\n }\n\n var value = $node.attr('value');\n if (value) {\n cleanUrl = clean$1(value);\n if (cleanUrl) return cleanUrl;\n }\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n return null;\n }\n};\n\nfunction scoreSimilarity(score, articleUrl, href) {\n // Do this last and only if we have a real candidate, because it's\n // potentially expensive computationally. Compare the link to this\n // URL using difflib to get the % similarity of these URLs. On a\n // sliding scale, subtract points from this link based on\n // similarity.\n if (score > 0) {\n var similarity = new difflib.SequenceMatcher(null, articleUrl, href).ratio();\n // Subtract .1 from diff_percent when calculating modifier,\n // which means that if it's less than 10% different, we give a\n // bonus instead. Ex:\n // 3% different = +17.5 points\n // 10% different = 0 points\n // 20% different = -25 points\n var diffPercent = 1.0 - similarity;\n var diffModifier = -(250 * (diffPercent - 0.2));\n return score + diffModifier;\n }\n\n return 0;\n}\n\nfunction scoreLinkText(linkText, pageNum) {\n // If the link text can be parsed as a number, give it a minor\n // bonus, with a slight bias towards lower numbered pages. This is\n // so that pages that might not have 'next' in their text can still\n // get scored, and sorted properly by score.\n var score = 0;\n\n if (IS_DIGIT_RE.test(linkText.trim())) {\n var linkTextAsNum = parseInt(linkText, 10);\n // If it's the first page, we already got it on the first call.\n // Give it a negative score. Otherwise, up to page 10, give a\n // small bonus.\n if (linkTextAsNum < 2) {\n score = -30;\n } else {\n score = Math.max(0, 10 - linkTextAsNum);\n }\n\n // If it appears that the current page number is greater than\n // this links page number, it's a very bad sign. Give it a big\n // penalty.\n if (pageNum && pageNum >= linkTextAsNum) {\n score -= 50;\n }\n }\n\n return score;\n}\n\nfunction scorePageInLink(pageNum, isWp) {\n // page in the link = bonus. Intentionally ignore wordpress because\n // their ?p=123 link style gets caught by this even though it means\n // separate documents entirely.\n if (pageNum && !isWp) {\n return 50;\n }\n\n return 0;\n}\n\nvar DIGIT_RE$2 = /\\d/;\n\n// A list of words that, if found in link text or URLs, likely mean that\n// this link is not a next page link.\nvar EXTRANEOUS_LINK_HINTS$1 = ['print', 'archive', 'comment', 'discuss', 'e-mail', 'email', 'share', 'reply', 'all', 'login', 'sign', 'single', 'adx', 'entry-unrelated'];\nvar EXTRANEOUS_LINK_HINTS_RE$1 = new RegExp(EXTRANEOUS_LINK_HINTS$1.join('|'), 'i');\n\n// Match any link text/classname/id that looks like it could mean the next\n// page. Things like: next, continue, >, >>, » but not >|, »| as those can\n// mean last page.\nvar NEXT_LINK_TEXT_RE$1 = new RegExp('(next|weiter|continue|>([^|]|$)|»([^|]|$))', 'i');\n\n// Match any link text/classname/id that looks like it is an end link: things\n// like \"first\", \"last\", \"end\", etc.\nvar CAP_LINK_TEXT_RE$1 = new RegExp('(first|last|end)', 'i');\n\n// Match any link text/classname/id that looks like it means the previous\n// page.\nvar PREV_LINK_TEXT_RE$1 = new RegExp('(prev|earl|old|new|<|«)', 'i');\n\nfunction scoreExtraneousLinks(href) {\n // If the URL itself contains extraneous values, give a penalty.\n if (EXTRANEOUS_LINK_HINTS_RE$1.test(href)) {\n return -25;\n }\n\n return 0;\n}\n\nfunction makeSig$1($link) {\n return ($link.attr('class') || '') + ' ' + ($link.attr('id') || '');\n}\n\nfunction scoreByParents$1($link) {\n // If a parent node contains paging-like classname or id, give a\n // bonus. Additionally, if a parent_node contains bad content\n // (like 'sponsor'), give a penalty.\n var $parent = $link.parent();\n var positiveMatch = false;\n var negativeMatch = false;\n var score = 0;\n\n _Array$from(range(0, 4)).forEach(function () {\n if ($parent.length === 0) {\n return;\n }\n\n var parentData = makeSig$1($parent, ' ');\n\n // If we have 'page' or 'paging' in our data, that's a good\n // sign. Add a bonus.\n if (!positiveMatch && PAGE_RE.test(parentData)) {\n positiveMatch = true;\n score += 25;\n }\n\n // If we have 'comment' or something in our data, and\n // we don't have something like 'content' as well, that's\n // a bad sign. Give a penalty.\n if (!negativeMatch && NEGATIVE_SCORE_RE.test(parentData) && EXTRANEOUS_LINK_HINTS_RE$1.test(parentData)) {\n if (!POSITIVE_SCORE_RE.test(parentData)) {\n negativeMatch = true;\n score -= 25;\n }\n }\n\n $parent = $parent.parent();\n });\n\n return score;\n}\n\nfunction scorePrevLink(linkData) {\n // If the link has something like \"previous\", its definitely\n // an old link, skip it.\n if (PREV_LINK_TEXT_RE$1.test(linkData)) {\n return -200;\n }\n\n return 0;\n}\n\nfunction shouldScore(href, articleUrl, baseUrl, parsedUrl, linkText, previousUrls) {\n // skip if we've already fetched this url\n if (previousUrls.find(function (url) {\n return href === url;\n }) !== undefined) {\n return false;\n }\n\n // If we've already parsed this URL, or the URL matches the base\n // URL, or is empty, skip it.\n if (!href || href === articleUrl || href === baseUrl) {\n return false;\n }\n\n var hostname = parsedUrl.hostname;\n\n var _URL$parse = URL.parse(href);\n\n var linkHost = _URL$parse.hostname;\n\n // Domain mismatch.\n\n if (linkHost !== hostname) {\n return false;\n }\n\n // If href doesn't contain a digit after removing the base URL,\n // it's certainly not the next page.\n var fragment = href.replace(baseUrl, '');\n if (!DIGIT_RE$2.test(fragment)) {\n return false;\n }\n\n // This link has extraneous content (like \"comment\") in its link\n // text, so we skip it.\n if (EXTRANEOUS_LINK_HINTS_RE$1.test(linkText)) {\n return false;\n }\n\n // Next page link text is never long, skip if it is too long.\n if (linkText.length > 25) {\n return false;\n }\n\n return true;\n}\n\nfunction scoreBaseUrl(href, baseRegex) {\n // If the baseUrl isn't part of this URL, penalize this\n // link. It could still be the link, but the odds are lower.\n // Example:\n // http://www.actionscript.org/resources/articles/745/1/JavaScript-and-VBScript-Injection-in-ActionScript-3/Page1.html\n if (!baseRegex.test(href)) {\n return -25;\n }\n\n return 0;\n}\n\nfunction scoreNextLinkText(linkData) {\n // Things like \"next\", \">>\", etc.\n if (NEXT_LINK_TEXT_RE$1.test(linkData)) {\n return 50;\n }\n\n return 0;\n}\n\nfunction scoreCapLinks(linkData) {\n // Cap links are links like \"last\", etc.\n if (CAP_LINK_TEXT_RE$1.test(linkData)) {\n // If we found a link like \"last\", but we've already seen that\n // this link is also \"next\", it's fine. If it's not been\n // previously marked as \"next\", then it's probably bad.\n // Penalize.\n if (NEXT_LINK_TEXT_RE$1.test(linkData)) {\n return -65;\n }\n }\n\n return 0;\n}\n\nfunction makeBaseRegex(baseUrl) {\n return new RegExp('^' + baseUrl, 'i');\n}\n\nfunction makeSig($link, linkText) {\n return (linkText || $link.text()) + ' ' + ($link.attr('class') || '') + ' ' + ($link.attr('id') || '');\n}\n\nfunction scoreLinks(_ref) {\n var links = _ref.links;\n var articleUrl = _ref.articleUrl;\n var baseUrl = _ref.baseUrl;\n var parsedUrl = _ref.parsedUrl;\n var $ = _ref.$;\n var _ref$previousUrls = _ref.previousUrls;\n var previousUrls = _ref$previousUrls === undefined ? [] : _ref$previousUrls;\n\n parsedUrl = parsedUrl || URL.parse(articleUrl);\n var baseRegex = makeBaseRegex(baseUrl);\n var isWp = isWordpress($);\n\n // Loop through all links, looking for hints that they may be next-page\n // links. Things like having \"page\" in their textContent, className or\n // id, or being a child of a node with a page-y className or id.\n //\n // After we do that, assign each page a score, and pick the one that\n // looks most like the next page link, as long as its score is strong\n // enough to have decent confidence.\n var scoredPages = links.reduce(function (possiblePages, link) {\n // Remove any anchor data since we don't do a good job\n // standardizing URLs (it's hard), we're going to do\n // some checking with and without a trailing slash\n var href = removeAnchor(link.attribs.href);\n var $link = $(link);\n var linkText = $link.text();\n\n if (!shouldScore(href, articleUrl, baseUrl, parsedUrl, linkText, previousUrls)) {\n return possiblePages;\n }\n\n // ## PASSED THE FIRST-PASS TESTS. Start scoring. ##\n if (!possiblePages[href]) {\n possiblePages[href] = {\n score: 0,\n linkText: linkText,\n href: href\n };\n } else {\n possiblePages[href].linkText = possiblePages[href].linkText + '|' + linkText;\n }\n\n var possiblePage = possiblePages[href];\n var linkData = makeSig($link, linkText);\n var pageNum = pageNumFromUrl(href);\n\n var score = scoreBaseUrl(href, baseRegex);\n score += scoreNextLinkText(linkData);\n score += scoreCapLinks(linkData);\n score += scorePrevLink(linkData);\n score += scoreByParents$1($link);\n score += scoreExtraneousLinks(href);\n score += scorePageInLink(pageNum, isWp);\n score += scoreLinkText(linkText, pageNum);\n score += scoreSimilarity(score, articleUrl, href);\n\n possiblePage.score = score;\n\n return possiblePages;\n }, {});\n\n return _Reflect$ownKeys(scoredPages).length === 0 ? null : scoredPages;\n}\n\n// Looks for and returns next page url\n// for multi-page articles\nvar GenericNextPageUrlExtractor = {\n extract: function extract(_ref) {\n var $ = _ref.$;\n var url = _ref.url;\n var parsedUrl = _ref.parsedUrl;\n var _ref$previousUrls = _ref.previousUrls;\n var previousUrls = _ref$previousUrls === undefined ? [] : _ref$previousUrls;\n\n parsedUrl = parsedUrl || URL.parse(url);\n\n var articleUrl = removeAnchor(url);\n var baseUrl = articleBaseUrl(url, parsedUrl);\n\n var links = $('a[href]').toArray();\n\n var scoredLinks = scoreLinks({\n links: links,\n articleUrl: articleUrl,\n baseUrl: baseUrl,\n parsedUrl: parsedUrl,\n $: $,\n previousUrls: previousUrls\n });\n\n // If no links were scored, return null\n if (!scoredLinks) return null;\n\n // now that we've scored all possible pages,\n // find the biggest one.\n var topPage = _Reflect$ownKeys(scoredLinks).reduce(function (acc, link) {\n var scoredLink = scoredLinks[link];\n return scoredLink.score > acc.score ? scoredLink : acc;\n }, { score: -100 });\n\n // If the score is less than 50, we're not confident enough to use it,\n // so we fail.\n if (topPage.score >= 50) {\n return topPage.href;\n }\n\n return null;\n }\n};\n\nvar CANONICAL_META_SELECTORS = ['og:url'];\n\nfunction parseDomain(url) {\n var parsedUrl = URL.parse(url);\n var hostname = parsedUrl.hostname;\n\n return hostname;\n}\n\nfunction result(url) {\n return {\n url: url,\n domain: parseDomain(url)\n };\n}\n\nvar GenericUrlExtractor = {\n extract: function extract(_ref) {\n var $ = _ref.$;\n var url = _ref.url;\n var metaCache = _ref.metaCache;\n\n var $canonical = $('link[rel=canonical]');\n if ($canonical.length !== 0) {\n var href = $canonical.attr('href');\n if (href) {\n return result(href);\n }\n }\n\n var metaUrl = extractFromMeta($, CANONICAL_META_SELECTORS, metaCache);\n if (metaUrl) {\n return result(metaUrl);\n }\n\n return result(url);\n }\n};\n\nvar EXCERPT_META_SELECTORS = ['og:description', 'twitter:description'];\n\nfunction clean$2(content, $) {\n var maxLength = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 200;\n\n content = content.replace(/[\\s\\n]+/g, ' ').trim();\n return ellipsize(content, maxLength, { ellipse: '…' });\n}\n\nvar GenericExcerptExtractor = {\n extract: function extract(_ref) {\n var $ = _ref.$;\n var content = _ref.content;\n var metaCache = _ref.metaCache;\n\n var excerpt = extractFromMeta($, EXCERPT_META_SELECTORS, metaCache);\n if (excerpt) {\n return clean$2(stripTags(excerpt, $));\n }\n // Fall back to excerpting from the extracted content\n var maxLength = 200;\n var shortContent = content.slice(0, maxLength * 5);\n return clean$2($(shortContent).text(), $, maxLength);\n }\n};\n\nvar GenericWordCountExtractor = {\n extract: function extract(_ref) {\n var content = _ref.content;\n\n var $ = cheerio.load(content);\n\n var text = normalizeSpaces($('div').first().text());\n return text.split(/\\s/).length;\n }\n};\n\nvar GenericExtractor = {\n // This extractor is the default for all domains\n domain: '*',\n title: GenericTitleExtractor.extract,\n date_published: GenericDatePublishedExtractor.extract,\n author: GenericAuthorExtractor.extract,\n content: GenericContentExtractor.extract.bind(GenericContentExtractor),\n lead_image_url: GenericLeadImageUrlExtractor.extract,\n dek: GenericDekExtractor.extract,\n next_page_url: GenericNextPageUrlExtractor.extract,\n url_and_domain: GenericUrlExtractor.extract,\n excerpt: GenericExcerptExtractor.extract,\n word_count: GenericWordCountExtractor.extract,\n direction: function direction(_ref) {\n var title = _ref.title;\n return stringDirection.getDirection(title);\n },\n\n extract: function extract(options) {\n var html = options.html;\n\n\n if (html) {\n var $ = cheerio.load(html);\n options.$ = $;\n }\n\n var title = this.title(options);\n var date_published = this.date_published(options);\n var author = this.author(options);\n var content = this.content(_extends({}, options, { title: title }));\n var lead_image_url = this.lead_image_url(_extends({}, options, { content: content }));\n var dek = this.dek(_extends({}, options, { content: content }));\n var next_page_url = this.next_page_url(options);\n var excerpt = this.excerpt(_extends({}, options, { content: content }));\n var word_count = this.word_count(_extends({}, options, { content: content }));\n var direction = this.direction({ title: title });\n\n var _url_and_domain = this.url_and_domain(options);\n\n var url = _url_and_domain.url;\n var domain = _url_and_domain.domain;\n\n\n return {\n title: title,\n author: author,\n date_published: date_published || null,\n dek: dek,\n lead_image_url: lead_image_url,\n content: content,\n next_page_url: next_page_url,\n url: url,\n domain: domain,\n excerpt: excerpt,\n word_count: word_count,\n direction: direction\n };\n }\n};\n\nfunction getExtractor(url, parsedUrl) {\n parsedUrl = parsedUrl || URL.parse(url);\n var _parsedUrl = parsedUrl;\n var hostname = _parsedUrl.hostname;\n\n var baseDomain = hostname.split('.').slice(-2).join('.');\n\n return Extractors[hostname] || Extractors[baseDomain] || GenericExtractor;\n}\n\n// Remove elements by an array of selectors\nfunction cleanBySelectors($content, $, _ref) {\n var clean = _ref.clean;\n\n if (!clean) return $content;\n\n $(clean.join(','), $content).remove();\n\n return $content;\n}\n\n// Transform matching elements\nfunction transformElements($content, $, _ref2) {\n var transforms = _ref2.transforms;\n\n if (!transforms) return $content;\n\n _Reflect$ownKeys(transforms).forEach(function (key) {\n var $matches = $(key, $content);\n var value = transforms[key];\n\n // If value is a string, convert directly\n if (typeof value === 'string') {\n $matches.each(function (index, node) {\n convertNodeTo($(node), $, transforms[key]);\n });\n } else if (typeof value === 'function') {\n // If value is function, apply function to node\n $matches.each(function (index, node) {\n var result = value($(node), $);\n // If function returns a string, convert node to that value\n if (typeof result === 'string') {\n convertNodeTo($(node), $, result);\n }\n });\n }\n });\n\n return $content;\n}\n\nfunction findMatchingSelector($, selectors) {\n return selectors.find(function (selector) {\n if (Array.isArray(selector)) {\n var _selector = _slicedToArray(selector, 2);\n\n var s = _selector[0];\n var attr = _selector[1];\n\n return $(s).length === 1 && $(s).attr(attr) && $(s).attr(attr).trim() !== '';\n }\n\n return $(selector).length === 1 && $(selector).text().trim() !== '';\n });\n}\n\nfunction select(opts) {\n var $ = opts.$;\n var type = opts.type;\n var extractionOpts = opts.extractionOpts;\n var _opts$extractHtml = opts.extractHtml;\n var extractHtml = _opts$extractHtml === undefined ? false : _opts$extractHtml;\n // Skip if there's not extraction for this type\n\n if (!extractionOpts) return null;\n\n // If a string is hardcoded for a type (e.g., Wikipedia\n // contributors), return the string\n if (typeof extractionOpts === 'string') return extractionOpts;\n\n var selectors = extractionOpts.selectors;\n var _extractionOpts$defau = extractionOpts.defaultCleaner;\n var defaultCleaner = _extractionOpts$defau === undefined ? true : _extractionOpts$defau;\n\n\n var matchingSelector = findMatchingSelector($, selectors);\n\n if (!matchingSelector) return null;\n\n // Declaring result; will contain either\n // text or html, which will be cleaned\n // by the appropriate cleaner type\n\n // If the selector type requests html as its return type\n // transform and clean the element with provided selectors\n if (extractHtml) {\n var $content = $(matchingSelector);\n\n // Wrap in div so transformation can take place on root element\n $content.wrap($('<div></div>'));\n $content = $content.parent();\n\n $content = transformElements($content, $, extractionOpts);\n $content = cleanBySelectors($content, $, extractionOpts);\n\n $content = Cleaners[type]($content, _extends({}, opts, { defaultCleaner: defaultCleaner }));\n\n return $.html($content);\n }\n\n var result = void 0;\n\n // if selector is an array (e.g., ['img', 'src']),\n // extract the attr\n if (Array.isArray(matchingSelector)) {\n var _matchingSelector = _slicedToArray(matchingSelector, 2);\n\n var selector = _matchingSelector[0];\n var attr = _matchingSelector[1];\n\n result = $(selector).attr(attr).trim();\n } else {\n result = $(matchingSelector).text().trim();\n }\n\n // Allow custom extractor to skip default cleaner\n // for this type; defaults to true\n if (defaultCleaner) {\n return Cleaners[type](result, opts);\n }\n\n return result;\n}\n\nfunction extractResult(opts) {\n var type = opts.type;\n var extractor = opts.extractor;\n var _opts$fallback = opts.fallback;\n var fallback = _opts$fallback === undefined ? true : _opts$fallback;\n\n\n var result = select(_extends({}, opts, { extractionOpts: extractor[type] }));\n\n // If custom parser succeeds, return the result\n if (result) {\n return result;\n }\n\n // If nothing matches the selector, and fallback is enabled,\n // run the Generic extraction\n if (fallback) return GenericExtractor[type](opts);\n\n return null;\n}\n\nvar RootExtractor = {\n extract: function extract() {\n var extractor = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : GenericExtractor;\n var opts = arguments[1];\n var _opts = opts;\n var contentOnly = _opts.contentOnly;\n var extractedTitle = _opts.extractedTitle;\n // This is the generic extractor. Run its extract method\n\n if (extractor.domain === '*') return extractor.extract(opts);\n\n opts = _extends({}, opts, {\n extractor: extractor\n });\n\n if (contentOnly) {\n var _content = extractResult(_extends({}, opts, { type: 'content', extractHtml: true, title: extractedTitle\n }));\n return {\n content: _content\n };\n }\n var title = extractResult(_extends({}, opts, { type: 'title' }));\n var date_published = extractResult(_extends({}, opts, { type: 'date_published' }));\n var author = extractResult(_extends({}, opts, { type: 'author' }));\n var next_page_url = extractResult(_extends({}, opts, { type: 'next_page_url' }));\n var content = extractResult(_extends({}, opts, { type: 'content', extractHtml: true, title: title\n }));\n var lead_image_url = extractResult(_extends({}, opts, { type: 'lead_image_url', content: content }));\n var excerpt = extractResult(_extends({}, opts, { type: 'excerpt', content: content }));\n var dek = extractResult(_extends({}, opts, { type: 'dek', content: content, excerpt: excerpt }));\n var word_count = extractResult(_extends({}, opts, { type: 'word_count', content: content }));\n var direction = extractResult(_extends({}, opts, { type: 'direction', title: title }));\n\n var _ref3 = extractResult(_extends({}, opts, { type: 'url_and_domain' })) || { url: null, domain: null };\n\n var url = _ref3.url;\n var domain = _ref3.domain;\n\n\n return {\n title: title,\n content: content,\n author: author,\n date_published: date_published,\n lead_image_url: lead_image_url,\n dek: dek,\n next_page_url: next_page_url,\n url: url,\n domain: domain,\n excerpt: excerpt,\n word_count: word_count,\n direction: direction\n };\n }\n};\n\nvar collectAllPages = (function () {\n var _ref = _asyncToGenerator(_regeneratorRuntime.mark(function _callee(_ref2) {\n var next_page_url = _ref2.next_page_url;\n var html = _ref2.html;\n var $ = _ref2.$;\n var metaCache = _ref2.metaCache;\n var result = _ref2.result;\n var Extractor = _ref2.Extractor;\n var title = _ref2.title;\n var url = _ref2.url;\n var pages, previousUrls, extractorOpts, nextPageResult, word_count;\n return _regeneratorRuntime.wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n // At this point, we've fetched just the first page\n pages = 1;\n previousUrls = [removeAnchor(url)];\n\n // If we've gone over 26 pages, something has\n // likely gone wrong.\n\n case 2:\n if (!(next_page_url && pages < 26)) {\n _context.next = 15;\n break;\n }\n\n pages += 1;\n _context.next = 6;\n return Resource.create(next_page_url);\n\n case 6:\n $ = _context.sent;\n\n html = $.html();\n\n extractorOpts = {\n url: next_page_url,\n html: html,\n $: $,\n metaCache: metaCache,\n contentOnly: true,\n extractedTitle: title,\n previousUrls: previousUrls\n };\n nextPageResult = RootExtractor.extract(Extractor, extractorOpts);\n\n\n previousUrls.push(next_page_url);\n result = _extends({}, result, {\n content: '\\n ' + result.content + '\\n <hr>\\n <h4>Page ' + pages + '</h4>\\n ' + nextPageResult.content + '\\n '\n });\n\n next_page_url = nextPageResult.next_page_url;\n _context.next = 2;\n break;\n\n case 15:\n word_count = GenericExtractor.word_count({ content: '<div>' + result.content + '</div>' });\n return _context.abrupt('return', _extends({}, result, {\n total_pages: pages,\n pages_rendered: pages,\n word_count: word_count\n }));\n\n case 17:\n case 'end':\n return _context.stop();\n }\n }\n }, _callee, this);\n }));\n\n function collectAllPages(_x) {\n return _ref.apply(this, arguments);\n }\n\n return collectAllPages;\n})();\n\nvar Mercury = {\n parse: function parse(url, html) {\n var _this = this;\n\n var opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n return _asyncToGenerator(_regeneratorRuntime.mark(function _callee() {\n var _opts$fetchAllPages, fetchAllPages, _opts$fallback, fallback, parsedUrl, Extractor, $, metaCache, result, _result, title, next_page_url;\n\n return _regeneratorRuntime.wrap(function _callee$(_context) {\n while (1) {\n switch (_context.prev = _context.next) {\n case 0:\n _opts$fetchAllPages = opts.fetchAllPages;\n fetchAllPages = _opts$fetchAllPages === undefined ? true : _opts$fetchAllPages;\n _opts$fallback = opts.fallback;\n fallback = _opts$fallback === undefined ? true : _opts$fallback;\n parsedUrl = URL.parse(url);\n\n if (validateUrl(parsedUrl)) {\n _context.next = 7;\n break;\n }\n\n return _context.abrupt('return', Errors.badUrl);\n\n case 7:\n Extractor = getExtractor(url, parsedUrl);\n // console.log(`Using extractor for ${Extractor.domain}`);\n\n _context.next = 10;\n return Resource.create(url, html, parsedUrl);\n\n case 10:\n $ = _context.sent;\n\n if (!$.error) {\n _context.next = 13;\n break;\n }\n\n return _context.abrupt('return', $);\n\n case 13:\n\n html = $.html();\n\n // Cached value of every meta name in our document.\n // Used when extracting title/author/date_published/dek\n metaCache = $('meta').map(function (_, node) {\n return $(node).attr('name');\n }).toArray();\n result = RootExtractor.extract(Extractor, { url: url, html: html, $: $, metaCache: metaCache, parsedUrl: parsedUrl, fallback: fallback });\n _result = result;\n title = _result.title;\n next_page_url = _result.next_page_url;\n\n // Fetch more pages if next_page_url found\n\n if (!(fetchAllPages && next_page_url)) {\n _context.next = 25;\n break;\n }\n\n _context.next = 22;\n return collectAllPages({\n Extractor: Extractor,\n next_page_url: next_page_url,\n html: html,\n $: $,\n metaCache: metaCache,\n result: result,\n title: title,\n url: url\n });\n\n case 22:\n result = _context.sent;\n _context.next = 26;\n break;\n\n case 25:\n result = _extends({}, result, {\n total_pages: 1,\n rendered_pages: 1\n });\n\n case 26:\n return _context.abrupt('return', result);\n\n case 27:\n case 'end':\n return _context.stop();\n }\n }\n }, _callee, _this);\n }))();\n },\n\n\n // A convenience method for getting a resource\n // to work with, e.g., for custom extractor generator\n fetchResource: function fetchResource(url) {\n var _this2 = this;\n\n return _asyncToGenerator(_regeneratorRuntime.mark(function _callee2() {\n return _regeneratorRuntime.wrap(function _callee2$(_context2) {\n while (1) {\n switch (_context2.prev = _context2.next) {\n case 0:\n _context2.next = 2;\n return Resource.create(url);\n\n case 2:\n return _context2.abrupt('return', _context2.sent);\n\n case 3:\n case 'end':\n return _context2.stop();\n }\n }\n }, _callee2, _this2);\n }))();\n }\n};\n\nmodule.exports = Mercury;\n//# sourceMappingURL=mercury.js.map\n","// Spacer images to be removed\nexport const SPACER_RE = new RegExp('trans|transparent|spacer|blank', 'i');\n\n// The class we will use to mark elements we want to keep\n// but would normally remove\nexport const KEEP_CLASS = 'mercury-parser-keep';\n\nexport const KEEP_SELECTORS = [\n 'iframe[src^=\"https://www.youtube.com\"]',\n 'iframe[src^=\"http://www.youtube.com\"]',\n 'iframe[src^=\"https://player.vimeo\"]',\n 'iframe[src^=\"http://player.vimeo\"]',\n];\n\n// A list of tags to strip from the output if we encounter them.\nexport const STRIP_OUTPUT_TAGS = [\n 'title',\n 'script',\n 'noscript',\n 'link',\n 'style',\n 'hr',\n 'embed',\n 'iframe',\n 'object',\n];\n\n// cleanAttributes\nexport const REMOVE_ATTRS = ['style', 'align'];\nexport const REMOVE_ATTR_SELECTORS = REMOVE_ATTRS.map(selector => `[${selector}]`);\nexport const REMOVE_ATTR_LIST = REMOVE_ATTRS.join(',');\nexport const WHITELIST_ATTRS = ['src', 'srcset', 'href', 'class', 'id', 'alt'];\nexport const WHITELIST_ATTRS_RE = new RegExp(`^(${WHITELIST_ATTRS.join('|')})$`, 'i');\n\n// removeEmpty\nexport const REMOVE_EMPTY_TAGS = ['p'];\nexport const REMOVE_EMPTY_SELECTORS = REMOVE_EMPTY_TAGS.map(tag => `${tag}:empty`).join(',');\n\n// cleanTags\nexport const CLEAN_CONDITIONALLY_TAGS = ['ul', 'ol', 'table', 'div', 'button', 'form'].join(',');\n\n// cleanHeaders\nconst HEADER_TAGS = ['h2', 'h3', 'h4', 'h5', 'h6'];\nexport const HEADER_TAG_LIST = HEADER_TAGS.join(',');\n\n\n// // CONTENT FETCHING CONSTANTS ////\n\n// A list of strings that can be considered unlikely candidates when\n// extracting content from a resource. These strings are joined together\n// and then tested for existence using re:test, so may contain simple,\n// non-pipe style regular expression queries if necessary.\nexport const UNLIKELY_CANDIDATES_BLACKLIST = [\n 'ad-break',\n 'adbox',\n 'advert',\n 'addthis',\n 'agegate',\n 'aux',\n 'blogger-labels',\n 'combx',\n 'comment',\n 'conversation',\n 'disqus',\n 'entry-unrelated',\n 'extra',\n 'foot',\n // 'form', // This is too generic, has too many false positives\n 'header',\n 'hidden',\n 'loader',\n 'login', // Note: This can hit 'blogindex'.\n 'menu',\n 'meta',\n 'nav',\n 'outbrain',\n 'pager',\n 'pagination',\n 'predicta', // readwriteweb inline ad box\n 'presence_control_external', // lifehacker.com container full of false positives\n 'popup',\n 'printfriendly',\n 'related',\n 'remove',\n 'remark',\n 'rss',\n 'share',\n 'shoutbox',\n 'sidebar',\n 'sociable',\n 'sponsor',\n 'taboola',\n 'tools',\n];\n\n// A list of strings that can be considered LIKELY candidates when\n// extracting content from a resource. Essentially, the inverse of the\n// blacklist above - if something matches both blacklist and whitelist,\n// it is kept. This is useful, for example, if something has a className\n// of \"rss-content entry-content\". It matched 'rss', so it would normally\n// be removed, however, it's also the entry content, so it should be left\n// alone.\n//\n// These strings are joined together and then tested for existence using\n// re:test, so may contain simple, non-pipe style regular expression queries\n// if necessary.\nexport const UNLIKELY_CANDIDATES_WHITELIST = [\n 'and',\n 'article',\n 'body',\n 'blogindex',\n 'column',\n 'content',\n 'entry-content-asset',\n 'format', // misuse of form\n 'hfeed',\n 'hentry',\n 'hatom',\n 'main',\n 'page',\n 'posts',\n 'shadow',\n];\n\n// A list of tags which, if found inside, should cause a <div /> to NOT\n// be turned into a paragraph tag. Shallow div tags without these elements\n// should be turned into <p /> tags.\nexport const DIV_TO_P_BLOCK_TAGS = [\n 'a',\n 'blockquote',\n 'dl',\n 'div',\n 'img',\n 'p',\n 'pre',\n 'table',\n].join(',');\n\n// A list of tags that should be ignored when trying to find the top candidate\n// for a document.\nexport const NON_TOP_CANDIDATE_TAGS = [\n 'br',\n 'b',\n 'i',\n 'label',\n 'hr',\n 'area',\n 'base',\n 'basefont',\n 'input',\n 'img',\n 'link',\n 'meta',\n];\n\nexport const NON_TOP_CANDIDATE_TAGS_RE =\n new RegExp(`^(${NON_TOP_CANDIDATE_TAGS.join('|')})$`, 'i');\n\n// A list of selectors that specify, very clearly, either hNews or other\n// very content-specific style content, like Blogger templates.\n// More examples here: http://microformats.org/wiki/blog-post-formats\nexport const HNEWS_CONTENT_SELECTORS = [\n ['.hentry', '.entry-content'],\n ['entry', '.entry-content'],\n ['.entry', '.entry_content'],\n ['.post', '.postbody'],\n ['.post', '.post_body'],\n ['.post', '.post-body'],\n];\n\nexport const PHOTO_HINTS = [\n 'figure',\n 'photo',\n 'image',\n 'caption',\n];\nexport const PHOTO_HINTS_RE = new RegExp(PHOTO_HINTS.join('|'), 'i');\n\n\n// A list of strings that denote a positive scoring for this content as being\n// an article container. Checked against className and id.\n//\n// TODO: Perhaps have these scale based on their odds of being quality?\nexport const POSITIVE_SCORE_HINTS = [\n 'article',\n 'articlecontent',\n 'instapaper_body',\n 'blog',\n 'body',\n 'content',\n 'entry-content-asset',\n 'entry',\n 'hentry',\n 'main',\n 'Normal',\n 'page',\n 'pagination',\n 'permalink',\n 'post',\n 'story',\n 'text',\n '[-_]copy', // usatoday\n '\\\\Bcopy',\n];\n\n// The above list, joined into a matching regular expression\nexport const POSITIVE_SCORE_RE = new RegExp(POSITIVE_SCORE_HINTS.join('|'), 'i');\n\n// Readability publisher-specific guidelines\nexport const READABILITY_ASSET = new RegExp('entry-content-asset', 'i');\n\n// A list of strings that denote a negative scoring for this content as being\n// an article container. Checked against className and id.\n//\n// TODO: Perhaps have these scale based on their odds of being quality?\nexport const NEGATIVE_SCORE_HINTS = [\n 'adbox',\n 'advert',\n 'author',\n 'bio',\n 'bookmark',\n 'bottom',\n 'byline',\n 'clear',\n 'com-',\n 'combx',\n 'comment',\n 'comment\\\\B',\n 'contact',\n 'copy',\n 'credit',\n 'crumb',\n 'date',\n 'deck',\n 'excerpt',\n 'featured', // tnr.com has a featured_content which throws us off\n 'foot',\n 'footer',\n 'footnote',\n 'graf',\n 'head',\n 'info',\n 'infotext', // newscientist.com copyright\n 'instapaper_ignore',\n 'jump',\n 'linebreak',\n 'link',\n 'masthead',\n 'media',\n 'meta',\n 'modal',\n 'outbrain', // slate.com junk\n 'promo',\n 'pr_', // autoblog - press release\n 'related',\n 'respond',\n 'roundcontent', // lifehacker restricted content warning\n 'scroll',\n 'secondary',\n 'share',\n 'shopping',\n 'shoutbox',\n 'side',\n 'sidebar',\n 'sponsor',\n 'stamp',\n 'sub',\n 'summary',\n 'tags',\n 'tools',\n 'widget',\n];\n// The above list, joined into a matching regular expression\nexport const NEGATIVE_SCORE_RE = new RegExp(NEGATIVE_SCORE_HINTS.join('|'), 'i');\n\n// XPath to try to determine if a page is wordpress. Not always successful.\nexport const IS_WP_SELECTOR = 'meta[name=generator][value^=WordPress]';\n\n// Match a digit. Pretty clear.\nexport const DIGIT_RE = new RegExp('[0-9]');\n\n// A list of words that, if found in link text or URLs, likely mean that\n// this link is not a next page link.\nexport const EXTRANEOUS_LINK_HINTS = [\n 'print',\n 'archive',\n 'comment',\n 'discuss',\n 'e-mail',\n 'email',\n 'share',\n 'reply',\n 'all',\n 'login',\n 'sign',\n 'single',\n 'adx',\n 'entry-unrelated',\n];\nexport const EXTRANEOUS_LINK_HINTS_RE = new RegExp(EXTRANEOUS_LINK_HINTS.join('|'), 'i');\n\n// Match any phrase that looks like it could be page, or paging, or pagination\nexport const PAGE_RE = new RegExp('pag(e|ing|inat)', 'i');\n\n// Match any link text/classname/id that looks like it could mean the next\n// page. Things like: next, continue, >, >>, » but not >|, »| as those can\n// mean last page.\n// export const NEXT_LINK_TEXT_RE = new RegExp('(next|weiter|continue|>([^\\|]|$)|»([^\\|]|$))', 'i');\nexport const NEXT_LINK_TEXT_RE = /(next|weiter|continue|>([^\\|]|$)|»([^\\|]|$))/i;\n\n// Match any link text/classname/id that looks like it is an end link: things\n// like \"first\", \"last\", \"end\", etc.\nexport const CAP_LINK_TEXT_RE = new RegExp('(first|last|end)', 'i');\n\n// Match any link text/classname/id that looks like it means the previous\n// page.\nexport const PREV_LINK_TEXT_RE = new RegExp('(prev|earl|old|new|<|«)', 'i');\n\n// Match 2 or more consecutive <br> tags\nexport const BR_TAGS_RE = new RegExp('(<br[^>]*>[ \\n\\r\\t]*){2,}', 'i');\n\n// Match 1 BR tag.\nexport const BR_TAG_RE = new RegExp('<br[^>]*>', 'i');\n\n// A list of all of the block level tags known in HTML5 and below. Taken from\n// http://bit.ly/qneNIT\nexport const BLOCK_LEVEL_TAGS = [\n 'article',\n 'aside',\n 'blockquote',\n 'body',\n 'br',\n 'button',\n 'canvas',\n 'caption',\n 'col',\n 'colgroup',\n 'dd',\n 'div',\n 'dl',\n 'dt',\n 'embed',\n 'fieldset',\n 'figcaption',\n 'figure',\n 'footer',\n 'form',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'header',\n 'hgroup',\n 'hr',\n 'li',\n 'map',\n 'object',\n 'ol',\n 'output',\n 'p',\n 'pre',\n 'progress',\n 'section',\n 'table',\n 'tbody',\n 'textarea',\n 'tfoot',\n 'th',\n 'thead',\n 'tr',\n 'ul',\n 'video',\n];\nexport const BLOCK_LEVEL_TAGS_RE = new RegExp(`^(${BLOCK_LEVEL_TAGS.join('|')})$`, 'i');\n\n\n// The removal is implemented as a blacklist and whitelist, this test finds\n// blacklisted elements that aren't whitelisted. We do this all in one\n// expression-both because it's only one pass, and because this skips the\n// serialization for whitelisted nodes.\nconst candidatesBlacklist = UNLIKELY_CANDIDATES_BLACKLIST.join('|');\nexport const CANDIDATES_BLACKLIST = new RegExp(candidatesBlacklist, 'i');\n\nconst candidatesWhitelist = UNLIKELY_CANDIDATES_WHITELIST.join('|');\nexport const CANDIDATES_WHITELIST = new RegExp(candidatesWhitelist, 'i');\n\nexport const UNLIKELY_RE = new RegExp(`!(${candidatesWhitelist})|(${candidatesBlacklist})`, 'i');\n\n\nexport const PARAGRAPH_SCORE_TAGS = new RegExp('^(p|li|span|pre)$', 'i');\nexport const CHILD_CONTENT_TAGS = new RegExp('^(td|blockquote|ol|ul|dl)$', 'i');\nexport const BAD_TAGS = new RegExp('^(address|form)$', 'i');\n\nexport const HTML_OR_BODY_RE = new RegExp('^(html|body)$', 'i');\n","import {\n STRIP_OUTPUT_TAGS,\n KEEP_CLASS,\n} from './constants';\n\nexport default function stripJunkTags(article, $, tags = []) {\n if (tags.length === 0) {\n tags = STRIP_OUTPUT_TAGS;\n }\n\n // Remove matching elements, but ignore\n // any element with a class of mercury-parser-keep\n $(tags.join(','), article).not(`.${KEEP_CLASS}`).remove();\n\n // Remove the mercury-parser-keep class from result\n $(`.${KEEP_CLASS}`, article).removeClass(KEEP_CLASS);\n\n return $;\n}\n","// // CONTENT FETCHING CONSTANTS ////\n\n// A list of strings that can be considered unlikely candidates when\n// extracting content from a resource. These strings are joined together\n// and then tested for existence using re:test, so may contain simple,\n// non-pipe style regular expression queries if necessary.\nexport const UNLIKELY_CANDIDATES_BLACKLIST = [\n 'ad-break',\n 'adbox',\n 'advert',\n 'addthis',\n 'agegate',\n 'aux',\n 'blogger-labels',\n 'combx',\n 'comment',\n 'conversation',\n 'disqus',\n 'entry-unrelated',\n 'extra',\n 'foot',\n 'form',\n 'header',\n 'hidden',\n 'loader',\n 'login', // Note: This can hit 'blogindex'.\n 'menu',\n 'meta',\n 'nav',\n 'pager',\n 'pagination',\n 'predicta', // readwriteweb inline ad box\n 'presence_control_external', // lifehacker.com container full of false positives\n 'popup',\n 'printfriendly',\n 'related',\n 'remove',\n 'remark',\n 'rss',\n 'share',\n 'shoutbox',\n 'sidebar',\n 'sociable',\n 'sponsor',\n 'tools',\n];\n\n// A list of strings that can be considered LIKELY candidates when\n// extracting content from a resource. Essentially, the inverse of the\n// blacklist above - if something matches both blacklist and whitelist,\n// it is kept. This is useful, for example, if something has a className\n// of \"rss-content entry-content\". It matched 'rss', so it would normally\n// be removed, however, it's also the entry content, so it should be left\n// alone.\n//\n// These strings are joined together and then tested for existence using\n// re:test, so may contain simple, non-pipe style regular expression queries\n// if necessary.\nexport const UNLIKELY_CANDIDATES_WHITELIST = [\n 'and',\n 'article',\n 'body',\n 'blogindex',\n 'column',\n 'content',\n 'entry-content-asset',\n 'format', // misuse of form\n 'hfeed',\n 'hentry',\n 'hatom',\n 'main',\n 'page',\n 'posts',\n 'shadow',\n];\n\n// A list of tags which, if found inside, should cause a <div /> to NOT\n// be turned into a paragraph tag. Shallow div tags without these elements\n// should be turned into <p /> tags.\nexport const DIV_TO_P_BLOCK_TAGS = [\n 'a',\n 'blockquote',\n 'dl',\n 'div',\n 'img',\n 'p',\n 'pre',\n 'table',\n].join(',');\n\n// A list of tags that should be ignored when trying to find the top candidate\n// for a document.\nexport const NON_TOP_CANDIDATE_TAGS = [\n 'br',\n 'b',\n 'i',\n 'label',\n 'hr',\n 'area',\n 'base',\n 'basefont',\n 'input',\n 'img',\n 'link',\n 'meta',\n];\n\nexport const NON_TOP_CANDIDATE_TAGS_RE =\n new RegExp(`^(${NON_TOP_CANDIDATE_TAGS.join('|')})$`, 'i');\n\n// A list of selectors that specify, very clearly, either hNews or other\n// very content-specific style content, like Blogger templates.\n// More examples here: http://microformats.org/wiki/blog-post-formats\nexport const HNEWS_CONTENT_SELECTORS = [\n ['.hentry', '.entry-content'],\n ['entry', '.entry-content'],\n ['.entry', '.entry_content'],\n ['.post', '.postbody'],\n ['.post', '.post_body'],\n ['.post', '.post-body'],\n];\n\nexport const PHOTO_HINTS = [\n 'figure',\n 'photo',\n 'image',\n 'caption',\n];\nexport const PHOTO_HINTS_RE = new RegExp(PHOTO_HINTS.join('|'), 'i');\n\n\n// A list of strings that denote a positive scoring for this content as being\n// an article container. Checked against className and id.\n//\n// TODO: Perhaps have these scale based on their odds of being quality?\nexport const POSITIVE_SCORE_HINTS = [\n 'article',\n 'articlecontent',\n 'instapaper_body',\n 'blog',\n 'body',\n 'content',\n 'entry-content-asset',\n 'entry',\n 'hentry',\n 'main',\n 'Normal',\n 'page',\n 'pagination',\n 'permalink',\n 'post',\n 'story',\n 'text',\n '[-_]copy', // usatoday\n '\\\\Bcopy',\n];\n\n// The above list, joined into a matching regular expression\nexport const POSITIVE_SCORE_RE = new RegExp(POSITIVE_SCORE_HINTS.join('|'), 'i');\n\n// Readability publisher-specific guidelines\nexport const READABILITY_ASSET = new RegExp('entry-content-asset', 'i');\n\n// A list of strings that denote a negative scoring for this content as being\n// an article container. Checked against className and id.\n//\n// TODO: Perhaps have these scale based on their odds of being quality?\nexport const NEGATIVE_SCORE_HINTS = [\n 'adbox',\n 'advert',\n 'author',\n 'bio',\n 'bookmark',\n 'bottom',\n 'byline',\n 'clear',\n 'com-',\n 'combx',\n 'comment',\n 'comment\\\\B',\n 'contact',\n 'copy',\n 'credit',\n 'crumb',\n 'date',\n 'deck',\n 'excerpt',\n 'featured', // tnr.com has a featured_content which throws us off\n 'foot',\n 'footer',\n 'footnote',\n 'graf',\n 'head',\n 'info',\n 'infotext', // newscientist.com copyright\n 'instapaper_ignore',\n 'jump',\n 'linebreak',\n 'link',\n 'masthead',\n 'media',\n 'meta',\n 'modal',\n 'outbrain', // slate.com junk\n 'promo',\n 'pr_', // autoblog - press release\n 'related',\n 'respond',\n 'roundcontent', // lifehacker restricted content warning\n 'scroll',\n 'secondary',\n 'share',\n 'shopping',\n 'shoutbox',\n 'side',\n 'sidebar',\n 'sponsor',\n 'stamp',\n 'sub',\n 'summary',\n 'tags',\n 'tools',\n 'widget',\n];\n// The above list, joined into a matching regular expression\nexport const NEGATIVE_SCORE_RE = new RegExp(NEGATIVE_SCORE_HINTS.join('|'), 'i');\n\n// Match a digit. Pretty clear.\nexport const DIGIT_RE = new RegExp('[0-9]');\n\n// Match 2 or more consecutive <br> tags\nexport const BR_TAGS_RE = new RegExp('(<br[^>]*>[ \\n\\r\\t]*){2,}', 'i');\n\n// Match 1 BR tag.\nexport const BR_TAG_RE = new RegExp('<br[^>]*>', 'i');\n\n// A list of all of the block level tags known in HTML5 and below. Taken from\n// http://bit.ly/qneNIT\nexport const BLOCK_LEVEL_TAGS = [\n 'article',\n 'aside',\n 'blockquote',\n 'body',\n 'br',\n 'button',\n 'canvas',\n 'caption',\n 'col',\n 'colgroup',\n 'dd',\n 'div',\n 'dl',\n 'dt',\n 'embed',\n 'fieldset',\n 'figcaption',\n 'figure',\n 'footer',\n 'form',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'header',\n 'hgroup',\n 'hr',\n 'li',\n 'map',\n 'object',\n 'ol',\n 'output',\n 'p',\n 'pre',\n 'progress',\n 'section',\n 'table',\n 'tbody',\n 'textarea',\n 'tfoot',\n 'th',\n 'thead',\n 'tr',\n 'ul',\n 'video',\n];\nexport const BLOCK_LEVEL_TAGS_RE = new RegExp(`^(${BLOCK_LEVEL_TAGS.join('|')})$`, 'i');\n\n\n// The removal is implemented as a blacklist and whitelist, this test finds\n// blacklisted elements that aren't whitelisted. We do this all in one\n// expression-both because it's only one pass, and because this skips the\n// serialization for whitelisted nodes.\nconst candidatesBlacklist = UNLIKELY_CANDIDATES_BLACKLIST.join('|');\nexport const CANDIDATES_BLACKLIST = new RegExp(candidatesBlacklist, 'i');\n\nconst candidatesWhitelist = UNLIKELY_CANDIDATES_WHITELIST.join('|');\nexport const CANDIDATES_WHITELIST = new RegExp(candidatesWhitelist, 'i');\n\nexport const UNLIKELY_RE = new RegExp(`!(${candidatesWhitelist})|(${candidatesBlacklist})`, 'i');\n\n\nexport const PARAGRAPH_SCORE_TAGS = new RegExp('^(p|li|span|pre)$', 'i');\nexport const CHILD_CONTENT_TAGS = new RegExp('^(td|blockquote|ol|ul|dl)$', 'i');\nexport const BAD_TAGS = new RegExp('^(address|form)$', 'i');\n\nexport const HTML_OR_BODY_RE = new RegExp('^(html|body)$', 'i');\n","import URL from 'url';\n\nfunction absolutize($, rootUrl, attr, $content) {\n $(`[${attr}]`, $content).each((_, node) => {\n const url = node.attribs[attr];\n const absoluteUrl = URL.resolve(rootUrl, url);\n\n node.attribs[attr] = absoluteUrl;\n });\n}\n\nexport default function makeLinksAbsolute($content, $, url) {\n ['href', 'src'].forEach(attr => absolutize($, url, attr, $content));\n\n return $content;\n}\n","export default function insertValues(strings, ...values) {\n if (values.length) {\n return strings.reduce((result, part, idx) => {\n let value = values[idx];\n\n if (value && typeof value.toString === 'function') {\n value = value.toString();\n } else {\n value = '';\n }\n\n return result + part + value;\n }, '');\n }\n\n return strings.join('');\n}\n","import insertValues from './insert-values'\n\nconst bodyPattern = /^\\n([\\s\\S]+)\\s{2}$/gm;\nconst trailingWhitespace = /\\s+$/;\n\nexport default function template(strings, ...values) {\n const compiled = insertValues(strings, ...values);\n let [body] = compiled.match(bodyPattern) || [];\n let indentLevel = /^\\s{0,4}(.+)$/g;\n\n if (!body) {\n body = compiled;\n indentLevel = /^\\s{0,2}(.+)$/g;\n }\n\n return body.split('\\n')\n .slice(1)\n .map((line) => {\n line = line.replace(indentLevel, '$1');\n\n if (trailingWhitespace.test(line)) {\n line = line.replace(trailingWhitespace, '');\n }\n\n return line;\n })\n .join('\\n');\n}\n","import template from './index';\n\nexport default function (hostname) {\n return template`\n // Rename CustomExtractor\n // to fit your publication\n // (e.g., NYTimesExtractor)\n export const CustomExtractor = {\n domain: '${hostname}',\n\n title: {\n selectors: [\n // enter title selectors\n ],\n },\n\n author: {\n selectors: [\n // enter author selectors\n ],\n },\n\n date_published: {\n selectors: [\n // enter selectors\n ],\n },\n\n dek: {\n selectors: [\n // enter selectors\n ],\n },\n\n lead_image_url: {\n selectors: [\n // enter selectors\n ],\n },\n\n content: {\n selectors: [\n // enter content selectors\n ],\n\n // Is there anything in the content you selected that needs transformed\n // before it's consumable content? E.g., unusual lazy loaded images\n transforms: {\n },\n\n // Is there anything that is in the result that shouldn't be?\n // The clean selectors will remove anything that matches from\n // the result\n clean: [\n\n ]\n },\n }\n `;\n}\n","import template from './index';\n\nconst IGNORE = [\n 'url',\n 'domain',\n 'content',\n 'word_count',\n 'next_page_url',\n 'excerpt',\n 'direction',\n 'total_pages',\n 'rendered_pages',\n]\n\nfunction testFor(key, value, dir, file, url) {\n if (IGNORE.find(k => k === key)) return ''\n\n return template`\n it('returns the ${key}', async () => {\n // To pass this test, fill out the ${key} selector\n // in ${dir}/index.js.\n const html =\n fs.readFileSync('${file}');\n const articleUrl =\n '${url}';\n\n const { ${key} } =\n await Mercury.parse(articleUrl, html, { fallback: false });\n\n // Update these values with the expected values from\n // the article.\n assert.equal(${key}, ${value ? \"`\" + value + \"`\" : \"''\"})\n });\n `;\n}\n\nexport default function (file, url, dir, result) {\n return template`\n import assert from 'assert';\n import fs from 'fs';\n import URL from 'url';\n import cheerio from 'cheerio';\n\n import Mercury from 'mercury';\n import getExtractor from 'extractors/get-extractor';\n import { excerptContent } from 'utils/text';\n\n // Rename CustomExtractor\n // to fit your publication\n // (e.g., NYTimesExtractor)\n describe('CustomExtractor', () => {\n it('is selected properly', () => {\n // This test should be passing by default.\n // It sanity checks that the correct parser\n // is being selected for URLs from this domain\n const url =\n '${url}';\n const extractor = getExtractor(url);\n assert.equal(extractor.domain, URL.parse(url).hostname)\n })\n\n ${Reflect.ownKeys(result).map(k => testFor(k, result[k], dir, file, url)).join('\\n\\n')}\n\n it('returns the content', async () => {\n // To pass this test, fill out the content selector\n // in ${dir}/index.js.\n // You may also want to make use of the clean and transform\n // options.\n const html =\n fs.readFileSync('${file}');\n const url =\n '${url}';\n\n const { content } =\n await Mercury.parse(url, html, { fallback: false });\n\n const $ = cheerio.load(content || '');\n\n const first13 = excerptContent($('*').first().text(), 13)\n\n // Update these values with the expected values from\n // the article.\n assert.equal(first13, 'Add the first 13 words of the article here');\n });\n });\n `;\n}\n","import fs from 'fs'\nimport URL from 'url'\nimport inquirer from 'inquirer'\nimport ora from 'ora'\n\nimport Mercury from '../dist/mercury'\nimport {\n stripJunkTags,\n makeLinksAbsolute,\n} from 'utils/dom'\nimport extractorTemplate from './templates/custom-extractor'\nimport extractorTestTemplate from './templates/custom-extractor-test'\n\nconst questions = [\n {\n type: 'input',\n name: 'website',\n message: 'Paste a url to an article you\\'d like to create or extend a parser for:',\n validate(value) {\n const { hostname } = URL.parse(value);\n if (hostname) return true;\n\n return false;\n },\n },\n];\n\ninquirer.prompt(questions).then((answers) => {\n scaffoldCustomParser(answers.website);\n});\n\nlet spinner;\nfunction confirm(fn, args, msg, newParser) {\n spinner = ora({ text: msg });\n spinner.start();\n const result = fn.apply(null, args);\n\n if (result && result.then) {\n result.then(r => savePage(r, args, newParser));\n } else {\n spinner.succeed();\n }\n\n return result;\n}\n\nfunction savePage($, [url], newParser) {\n const { hostname } = URL.parse(url);\n\n spinner.succeed();\n\n const filename = new Date().getTime();\n const file = `./fixtures/${hostname}/${filename}.html`;\n // fix http(s) relative links:\n makeLinksAbsolute($('*').first(), $, url)\n $('[src], [href]').each((index, node) => {\n const $node = $(node)\n const link = $node.attr('src')\n if (link && link.slice(0, 2) === '//') {\n $node.attr('src', `http:${link}`)\n }\n })\n const html = stripJunkTags($('*').first(), $, ['script']).html();\n\n fs.writeFileSync(file, html);\n\n const result = Mercury.parse(url, html).then((result) => {\n if (newParser) {\n confirm(generateScaffold, [url, file, result], 'Generating parser and tests');\n console.log(`Your custom site extractor has been set up. To get started building it, run\n npm run watch:test -- ${hostname}`)\n } else {\n console.log(`\n It looks like you already have a custom parser for this url.\n The page you linked to has been added to ${file}. Copy and paste\n the following code to use that page in your tests:\n const html = fs.readFileSync('${file}');`)\n }\n })\n}\n\nfunction generateScaffold(url, file, result) {\n const { hostname } = URL.parse(url);\n const extractor = extractorTemplate(hostname)\n const extractorTest = extractorTestTemplate(file, url, getDir(url), result)\n\n fs.writeFileSync(`${getDir(url)}/index.js`, extractor)\n fs.writeFileSync(`${getDir(url)}/index.test.js`, extractorTest)\n fs.appendFileSync(\n './src/extractors/custom/index.js',\n exportString(url),\n )\n}\n\nfunction exportString(url) {\n const { hostname } = URL.parse(url);\n return `export * from './${hostname}'`;\n}\n\nfunction confirmCreateDir(dir, msg) {\n if (!fs.existsSync(dir)) {\n confirm(fs.mkdirSync, [dir], msg);\n }\n}\n\nfunction scaffoldCustomParser(url) {\n const dir = getDir(url);\n const { hostname } = URL.parse(url);\n let newParser = false\n\n if (!fs.existsSync(dir)) {\n newParser = true\n confirmCreateDir(dir, `Creating ${hostname} directory`);\n confirmCreateDir(`./fixtures/${hostname}`, 'Creating fixtures directory');\n }\n\n confirm(Mercury.fetchResource, [url], 'Fetching fixture', newParser);\n}\n\nfunction getDir(url) {\n const { hostname } = URL.parse(url);\n return `./src/extractors/custom/${hostname}`;\n}\n"],"names":["ex","_interopDefault","require$$19","require$$18","require$$17","require$$16","require$$15","require$$14","require$$13","require$$12","require$$11","require$$10","require$$9","require$$8","require$$7","require$$6","require$$5","require$$4","require$$3","require$$2","require$$1","require$$0","range","map","_regeneratorRuntime","mark","arguments","length","undefined","wrap","_context","prev","next","start","end","stop","_marked","_ref","hostname","badUrl","error","messages","BAD_CONTENT_TYPES","join","options","resolve","reject","request","err","response","body","statusMessage","statusCode","parseNon2xx","headers","_response$headers","BAD_CONTENT_TYPES_RE","test","contentType","contentLength","MAX_CONTENT_LENGTH","_asyncToGenerator","url","parsedUrl","_ref3","URL","parse","encodeURI","_extends","REQUEST_HEADERS","timeout","FETCH_TIMEOUT","encoding","jar","gzip","followAllRedirects","sent","validateResponse","abrupt","t0","Errors","_callee","_x2","_x3","apply","$","from","to","each","_","node","$node","attr","value","removeAttr","convertMetaProp","img","_Reflect$ownKeys","attribs","forEach","IS_LINK","IS_IMAGE","index","type","root","find","contents","filter","isComment","remove","TAGS_TO_REMOVE","cleanComments","create","preparedResponse","validResponse","result","_this","generateDoc","includes","cheerio","load","content","normalizeWhitespace","children","normalizeMetaTags","convertLazyLoadedImages","clean","extractor","domains","reduce","acc","domain","supportedDomains","merge","concat","_toConsumableArray","selectors","transforms","h1","noscript","$children","get","tagName","title","author","dek","date_published","defaultCleaner","parents","$parent","prepend","$tweetContainer","append","tweets","replaceWith","s","src","replace","width","lead_image_url","next_page_url","excerpt","h2","split","youtubeId","JSON","data","sources","$img","iframe","decodeURIComponent","ytRe","thumb","match","_slicedToArray","_thumb$match","_thumb$match2","clone","NYMagExtractor","BloggerExtractor","WikipediaExtractor","TwitterExtractor","NYTimesExtractor","TheAtlanticExtractor","NewYorkerExtractor","WiredExtractor","MSNExtractor","YahooExtractor","BuzzfeedExtractor","WikiaExtractor","LittleThingsExtractor","PoliticoExtractor","mergeSupportedDomains","DeadspinExtractor","BroadwayWorldExtractor","ApartmentTherapyExtractor","MediumExtractor","REMOVE_ATTRS","selector","WHITELIST_ATTRS","REMOVE_EMPTY_TAGS","tag","HEADER_TAGS","NON_TOP_CANDIDATE_TAGS","PHOTO_HINTS","POSITIVE_SCORE_HINTS","NEGATIVE_SCORE_HINTS","EXTRANEOUS_LINK_HINTS","BLOCK_LEVEL_TAGS","UNLIKELY_CANDIDATES_BLACKLIST","candidatesBlacklist","UNLIKELY_CANDIDATES_WHITELIST","candidatesWhitelist","not","id","classes","CANDIDATES_WHITELIST","classAndId","CANDIDATES_BLACKLIST","element","nextElement","collapsing","paragraphize","br","nextSibling","sibling","BLOCK_LEVEL_TAGS_RE","appendTo","p","div","$div","DIV_TO_P_BLOCK_TAGS","convertable","convertNodeTo","span","$span","brsToPs","convertDivs","convertSpans","_$node$get","key","attribString","parseInt","height","SPACER_RE","$article","cleanForHeight","removeSpacers","article","tags","KEEP_SELECTORS","_URL$parse","protocol","addClass","KEEP_CLASS","STRIP_OUTPUT_TAGS","removeClass","$hOnes","WHITELIST_ATTRS_RE","_defineProperty","parent","$p","text","trim","NON_TOP_CANDIDATE_TAGS$1","PHOTO_HINTS$1","POSITIVE_SCORE_HINTS$1","NEGATIVE_SCORE_HINTS$1","BLOCK_LEVEL_TAGS$1","UNLIKELY_CANDIDATES_BLACKLIST$1","UNLIKELY_CANDIDATES_WHITELIST$1","POSITIVE_SCORE_RE$1","score","NEGATIVE_SCORE_RE$1","PHOTO_HINTS_RE$1","READABILITY_ASSET$1","textLength","chunks","idkRe","lengthBonus","min","Math","max","scoreCommas","scoreLength","slice","amount","getOrInitScore","setScore","e","addScore","getScore","scoreNode","weightNodes","getWeight","addToParent","PARAGRAPH_SCORE_TAGS$1","CHILD_CONTENT_TAGS$1","BAD_TAGS$1","convertSpans$1","addScoreTo","rawScore","HNEWS_CONTENT_SELECTORS$1","_ref2","parentSelector","childSelector","scorePs","NORMALIZE_RE","regexList","re","matchRe","exec","PAGE_IN_HREF_RE","matches","pageNum","segment","firstSegmentHasLetters","IS_DIGIT_RE","goodSegment","toLowerCase","parsed","host","path","reverse","rawSegment","_segment$split","_segment$split2","IS_ALPHA_RE","fileExt","possibleSegment","HAS_ALPHA_RE","isGoodSegment","push","cleanedSegments","words","$candidate","topScore","NON_TOP_CANDIDATE_TAGS_RE$1","$sibling","siblingScore","wrappingDiv","linkDensity","density","contentBonus","newScore","siblingScoreThreshold","siblingContent","siblingContentLength","hasSentenceEnd","first","mergeSiblings","weight","hasClass","normalizeSpaces","inputCount","pCount","imgCount","nodeIsList","previousNode","scriptCount","CLEAN_CONDITIONALLY_TAGS","removeUnlessContent","HEADER_TAG_LIST","header","$header","prevAll","rootUrl","$content","absoluteUrl","linkText","totalTextLength","linkLength","metaNames","cachedNames","name","indexOf","_step","nodes","toArray","values","cleanTags","metaValue","stripTags","v","_getIterator","foundNames","_iteratorNormalCompletion","_iterator","done","_loop","_typeof","_ret","_didIteratorError","_iteratorError","return","maxChildren","withinComment","isGoodNode","textOnly","html","cleanText","class","IS_WP_SELECTOR","months","timestamp1","timestamp2","allMonths","CLEAN_AUTHOR_RE","leadImageUrl","validUrl","isWebUri","excerptContent","TEXT_LINK_RE","dekText","dateString","SPLIT_DATE_STRING","TIME_MERIDIAN_DOTS_RE","TIME_MERIDIAN_SPACE_RE","CLEAN_DATE_STRING_RE","MS_DATE_STRING","SEC_DATE_STRING","moment","date","isValid","cleanDateString","toISOString","cleanConditionally","_ref$cleanConditional","_ref$title","_ref$url","_ref$defaultCleaner","rewriteTopLevel","cleanImages","markToKeep","stripJunkTags","cleanHOnes","cleanHeaders","makeLinksAbsolute","removeEmpty","cleanAttributes","TITLE_SPLITTERS_RE","resolveSplitTitle","splitTitle","titleText","termCounts","_Reflect$ownKeys$redu","_Reflect$ownKeys$redu2","termCount","maxTerm","splitEnds","longestEnd","DOMAIN_ENDINGS_RE","wuzzy","levenshtein","startSlug","nakedDomain","startSlugRatio","endSlug","endSlugRatio","extractBreadcrumbTitle","newTitle","cleanDomainFromTitle","cleanAuthor","clean$1","cleanDek","cleanDatePublished","extractCleanNode","cleanTitle","opts","stripUnlikelyCandidates","convertToParagraphs","scoreContent","findTopCandidate","defaultOpts","extract","getContentNode","nodeIsSufficient","cleanAndReturnNode","k","extractBestNode","metaCache","extractFromMeta","STRONG_TITLE_META_TAGS","extractFromSelectors","STRONG_TITLE_SELECTORS","WEAK_TITLE_META_TAGS","WEAK_TITLE_SELECTORS","bylineRe","AUTHOR_META_TAGS","AUTHOR_MAX_LENGTH","AUTHOR_SELECTORS","BYLINE_SELECTORS_RE","_ref4","regex","abbrevMonthsStr","datePublished","DATE_PUBLISHED_META_TAGS","DATE_PUBLISHED_SELECTORS","extractFromUrl","DATE_PUBLISHED_URL_RES","POSITIVE_LEAD_IMAGE_URL_HINTS","NEGATIVE_LEAD_IMAGE_URL_HINTS","POSITIVE_LEAD_IMAGE_URL_HINTS_RE","NEGATIVE_LEAD_IMAGE_URL_HINTS_RE","GIF_RE","JPG_RE","$figParent","$gParent","getSig","parseFloat","area","round","$imgs","LEAD_IMAGE_URL_META_TAGS","imageUrl","cleanUrl","imgs","scoreImageUrl","scoreAttr","scoreByParents","scoreBySibling","scoreByDimensions","scoreByPosition","imgScores","topUrl","LEAD_IMAGE_URL_SELECTORS","href","articleUrl","SequenceMatcher","ratio","similarity","diffPercent","diffModifier","linkTextAsNum","isWp","EXTRANEOUS_LINK_HINTS$1","EXTRANEOUS_LINK_HINTS_RE$1","$link","_Array$from","makeSig$1","positiveMatch","PAGE_RE","parentData","negativeMatch","NEGATIVE_SCORE_RE","POSITIVE_SCORE_RE","linkData","PREV_LINK_TEXT_RE$1","baseUrl","previousUrls","linkHost","DIGIT_RE$2","fragment","baseRegex","NEXT_LINK_TEXT_RE$1","CAP_LINK_TEXT_RE$1","links","_ref$previousUrls","makeBaseRegex","isWordpress","possiblePages","link","removeAnchor","shouldScore","makeSig","pageNumFromUrl","scoreBaseUrl","scoreNextLinkText","scoreCapLinks","scorePrevLink","scoreByParents$1","scoreExtraneousLinks","scorePageInLink","scoreLinkText","scoreSimilarity","possiblePage","scoredPages","articleBaseUrl","scoreLinks","scoredLinks","scoredLink","topPage","parseDomain","$canonical","CANONICAL_META_SELECTORS","metaUrl","maxLength","ellipse","EXCERPT_META_SELECTORS","shortContent","GenericTitleExtractor","GenericDatePublishedExtractor","GenericAuthorExtractor","GenericContentExtractor","bind","GenericLeadImageUrlExtractor","GenericDekExtractor","GenericNextPageUrlExtractor","url_and_domain","GenericUrlExtractor","GenericExcerptExtractor","word_count","GenericWordCountExtractor","direction","getDirection","_url_and_domain","_parsedUrl","Extractors","baseDomain","GenericExtractor","$matches","Array","isArray","_selector","extractionOpts","extractHtml","_opts$extractHtml","_extractionOpts$defau","findMatchingSelector","matchingSelector","transformElements","cleanBySelectors","Cleaners","_matchingSelector","fallback","_opts$fallback","select","_opts","contentOnly","extractedTitle","extractResult","_content","Extractor","extractorOpts","nextPageResult","pages","RootExtractor","total_pages","pages_rendered","_x","fetchAllPages","_result","_opts$fetchAllPages","validateUrl","getExtractor","rendered_pages","fetchResource","_context2","_callee2","_this2","module","exports","Mercury","REMOVE_ATTR_SELECTORS","REMOVE_ATTR_LIST","RegExp","REMOVE_EMPTY_SELECTORS","NON_TOP_CANDIDATE_TAGS_RE","PHOTO_HINTS_RE","EXTRANEOUS_LINK_HINTS_RE","absolutize","insertValues","strings","part","idx","toString","bodyPattern","trailingWhitespace","template","compiled","indentLevel","line","IGNORE","testFor","dir","file","Reflect","ownKeys","questions","inquirer","prompt","then","answers","website","spinner","confirm","fn","args","msg","newParser","ora","savePage","r","succeed","filename","Date","getTime","writeFileSync","generateScaffold","log","extractorTemplate","extractorTest","extractorTestTemplate","getDir","appendFileSync","exportString","confirmCreateDir","fs","existsSync","mkdirSync","scaffoldCustomParser"],"mappings":"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"} \ No newline at end of file diff --git a/scripts/generate-custom-parser.js b/scripts/generate-custom-parser.js index 96138014..6c9ac07e 100755 --- a/scripts/generate-custom-parser.js +++ b/scripts/generate-custom-parser.js @@ -86,6 +86,15 @@ function generateScaffold(url, file, result) { fs.writeFileSync(`${getDir(url)}/index.js`, extractor) fs.writeFileSync(`${getDir(url)}/index.test.js`, extractorTest) + fs.appendFileSync( + './src/extractors/custom/index.js', + exportString(url), + ) +} + +function exportString(url) { + const { hostname } = URL.parse(url); + return `export * from './${hostname}'`; } function confirmCreateDir(dir, msg) { diff --git a/scripts/templates/custom-extractor-test.js b/scripts/templates/custom-extractor-test.js index 1154a4ea..78e4b68e 100644 --- a/scripts/templates/custom-extractor-test.js +++ b/scripts/templates/custom-extractor-test.js @@ -29,7 +29,7 @@ function testFor(key, value, dir, file, url) { // Update these values with the expected values from // the article. - assert.equal(${key}, ${value ? "'" + value + "'" : "''"}) + assert.equal(${key}, ${value ? "`" + value + "`" : "''"}) }); `; } @@ -46,13 +46,13 @@ export default function (file, url, dir, result) { import { excerptContent } from 'utils/text'; // Rename CustomExtractor + // to fit your publication + // (e.g., NYTimesExtractor) describe('CustomExtractor', () => { it('is selected properly', () => { - // To pass this test, rename your extractor in - // ${dir}/index.js - // (e.g., CustomExtractor => NYTimesExtractor) - // then add your new extractor to - // src/extractors/all.js + // This test should be passing by default. + // It sanity checks that the correct parser + // is being selected for URLs from this domain const url = '${url}'; const extractor = getExtractor(url); @@ -80,7 +80,7 @@ export default function (file, url, dir, result) { // Update these values with the expected values from // the article. - assert.equal(first13, null); + assert.equal(first13, 'Add the first 13 words of the article here'); }); }); `; diff --git a/scripts/templates/custom-extractor.js b/scripts/templates/custom-extractor.js index 5697f9ee..41fb4b32 100644 --- a/scripts/templates/custom-extractor.js +++ b/scripts/templates/custom-extractor.js @@ -7,6 +7,7 @@ export default function (hostname) { // (e.g., NYTimesExtractor) export const CustomExtractor = { domain: '${hostname}', + title: { selectors: [ // enter title selectors @@ -19,52 +20,40 @@ export default function (hostname) { ], }, - content: { - selectors: [ - // enter content selectors - ], - - // Is there anything in the content you selected that needs transformed - // before it's consumable content? E.g., unusual lazy loaded images - transforms: { - }, - - // Is there anything that is in the result that shouldn't be? - // The clean selectors will remove anything that matches from - // the result - clean: [ - - ] - }, - date_published: { selectors: [ // enter selectors ], }, - lead_image_url: { - selectors: [ - // enter selectors - ], - }, - dek: { selectors: [ // enter selectors ], }, - next_page_url: { + lead_image_url: { selectors: [ // enter selectors ], }, - excerpt: { + content: { selectors: [ - // enter selectors + // enter content selectors ], + + // Is there anything in the content you selected that needs transformed + // before it's consumable content? E.g., unusual lazy loaded images + transforms: { + }, + + // Is there anything that is in the result that shouldn't be? + // The clean selectors will remove anything that matches from + // the result + clean: [ + + ] }, } `; diff --git a/src/extractors/all.js b/src/extractors/all.js index 5eecf704..f31da17e 100644 --- a/src/extractors/all.js +++ b/src/extractors/all.js @@ -2,9 +2,9 @@ import mergeSupportedDomains from 'utils/merge-supported-domains'; import * as CustomExtractors from './custom/index'; export default Object.keys(CustomExtractors).reduce((acc, key) => { - const extractor = CustomExtractors[key] + const extractor = CustomExtractors[key]; return { ...acc, ...mergeSupportedDomains(extractor), - } -}, {}) + }; +}, {}); diff --git a/src/extractors/custom/www.nytimes.com/index.test.js b/src/extractors/custom/www.nytimes.com/index.test.js index e35241e3..3f6d78d7 100644 --- a/src/extractors/custom/www.nytimes.com/index.test.js +++ b/src/extractors/custom/www.nytimes.com/index.test.js @@ -11,7 +11,6 @@ describe('NYTimesExtractor', () => { const url = 'http://www.nytimes.com/interactive/2016/09/15/arts/design/national-museum-of-african-american-history-and-culture.html'; const extractor = getExtractor(url); - console.log(extractor.domain, URL.parse(url).hostname) assert.equal(extractor.domain, URL.parse(url).hostname); });