diff --git a/src/assets/css/theme_common.css b/src/assets/css/theme_common.css index 7dcb8519..430be3b9 100644 --- a/src/assets/css/theme_common.css +++ b/src/assets/css/theme_common.css @@ -4,7 +4,7 @@ * sr-rd-title, sr-rd-desc, sr-rd-content, p, div, a, img, pre, code, sr-blockquote, ul ol */ -.simpread-theme-root { + .simpread-theme-root { font-size: 62.5%!important; } @@ -13,8 +13,13 @@ sr-rd-title, sr-rd-desc, sr-rd-content { } sr-rd-title { - text-rendering: optimizelegibility; + display: -webkit-box; margin: 1em 0px 0.5em; + overflow : hidden; + text-overflow: ellipsis; + text-rendering: optimizelegibility; + -webkit-line-clamp: 3; + -webkit-box-orient: vertical; } sr-rd-content { @@ -186,6 +191,14 @@ sr-rd-content pre code * { font-size: 1.1rem; } +sr-rd-content pre p { + margin: 0; + padding: 0; + color: inherit; + font-size: inherit; + line-height: inherit; +} + sr-rd-content li code, sr-rd-content p code { margin: 0 4px; @@ -193,6 +206,14 @@ sr-rd-content p code { font-size: 1.1rem; } +sr-rd-content mark { + margin: 0 5px; + padding: 2px; + + background: #fffdd1; + border-bottom: 1px solid #ffedce; +} + .sr-rd-content-img { width: 90%; height: auto; @@ -217,6 +238,17 @@ sr-rd-content p code { -webkit-box-orient: vertical; } +.sr-rd-content-center-small { + display: inline-flex; +} + +.sr-rd-content-center-small img { + margin: 0; + padding: 0; + border: 0; + box-shadow: none; +} + .sr-rd-content-nobeautify { margin: 0; padding: 0; @@ -257,6 +289,8 @@ sr-rd-mult sr-rd-mult-avatar { display: flex; flex-direction: column; align-items: center; + + margin: 0 15px; } sr-rd-mult sr-rd-mult-avatar span { diff --git a/src/contentscripts.js b/src/contentscripts.js index 0c5358ae..d7da686e 100644 --- a/src/contentscripts.js +++ b/src/contentscripts.js @@ -267,6 +267,8 @@ function browserAction( is_update ) { */ function pRead() { pr = new PureRead( storage.sites ); + pr.cleanup = storage.read.cleanup == undefined ? true : storage.read.cleanup; + pr.pure = storage.read.pure == undefined ? false : storage.read.pure; pr.AddPlugin( puplugin.Plugin() ); pr.Getsites(); storage.puread = pr; diff --git a/src/manifest.json b/src/manifest.json index aa4c4aff..d9de452e 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -22,7 +22,7 @@ }, "content_scripts" : [ { - "matches" : [ "http://*/*", "https://*/*", "file:///*/*.txt" ], + "matches" : [ "http://*/*", "https://*/*", "file:///*/*.txt", "file:///*/*.md" ], "exclude_matches": [ "http://localhost/*", "https://simpread.herokuapp.com/view/*" ], "js" : [ "/bundle/common.js", diff --git a/src/module/labs.jsx b/src/module/labs.jsx index cf0a02ec..3135fa37 100644 --- a/src/module/labs.jsx +++ b/src/module/labs.jsx @@ -32,6 +32,7 @@ export default class LabsOpt extends React.Component { this.props.onChange && this.props.onChange( true ); model == "read" && state == "auto" && this.exclusionState( value ); model == "read" && state == "toc" && this.tocState( value ); + model == "read" && state == "cleanup" && this.cleanupState( value ); } changeExclusion( event ) { @@ -48,6 +49,10 @@ export default class LabsOpt extends React.Component { $( this.refs.toc ).velocity( value ? "slideDown" : "slideUp" ); } + cleanupState( value ) { + $( this.refs.cleanup ).velocity( value ? "slideDown" : "slideUp" ); + } + exclusionState( value ) { $( this.refs.exclusion ).velocity( value ? "slideDown" : "slideUp" ); $( this.refs.whitelist ).velocity( !value ? "slideDown" : "slideUp" ); @@ -61,6 +66,7 @@ export default class LabsOpt extends React.Component { componentDidMount() { this.exclusionState( this.props.read.auto ); this.tocState( this.props.read.toc ); + this.cleanupState( this.props.read.cleanup == undefined ? true : this.props.read.cleanup ); } onClick( state ) { @@ -199,6 +205,22 @@ export default class LabsOpt extends React.Component { +
词法分析引擎 测试版
+
+ this.onChange(s, "read", "cleanup") } /> +
+ this.onChange(s, "read", "pure") } /> +
+
+
授权管理
diff --git a/src/read/controlbar.jsx b/src/read/controlbar.jsx index 3e4d66df..807e8c19 100644 --- a/src/read/controlbar.jsx +++ b/src/read/controlbar.jsx @@ -126,19 +126,23 @@ export default class ReadCtlbar extends React.Component { } componentWillMount() { - if ( storage.current.fap ) { - delete conf.readItems.exit; - delete conf.readItems.option.items.setting; - } - if ( this.props.type.startsWith( "txtread::" ) && this.props.type.endsWith( "::local" )) { - delete conf.readItems.download; - delete conf.readItems.readlater; - delete conf.readItems.send; - delete conf.readItems.share; - delete conf.readItems.option; - } - if ( this.props.type.startsWith( "metaread::" ) || this.props.type.startsWith( "txtread::" ) ) { - delete conf.readItems.option; + try { + if ( storage.current.fap ) { + delete conf.readItems.exit; + delete conf.readItems.option.items.setting; + } + if ( this.props.type.startsWith( "txtread::" ) && this.props.type.endsWith( "::local" )) { + delete conf.readItems.download; + delete conf.readItems.readlater; + delete conf.readItems.send; + delete conf.readItems.share; + delete conf.readItems.option; + } + if ( this.props.type.startsWith( "metaread::" ) || this.props.type.startsWith( "txtread::" ) ) { + delete conf.readItems.option; + } + } catch ( err ) { + // TO-DO } // hack code !/chrome/ig.test( navigator.userAgent ) && ( delete conf.readItems.dyslexia ); diff --git a/src/read/read.jsx b/src/read/read.jsx index 2f664c75..85d5a3b3 100644 --- a/src/read/read.jsx +++ b/src/read/read.jsx @@ -54,6 +54,7 @@ class Read extends React.Component { async componentDidMount() { if ( $root.find( "sr-rd-content-error" ).length > 0 ) { + // Puread level to III,can't work this flow. this.componentWillUnmount(); if ( ! localStorage["sr-update-site"] ) { new Notify().Render({ content: "当前页面结构改变导致不匹配阅读模式,接下来请选择?", action: "更新", cancel: "高亮", callback: type => { @@ -79,29 +80,29 @@ class Read extends React.Component { localStorage.removeItem( "sr-update-site" ); } else { $root - .addClass( "simpread-font" ) - .addClass( theme ) - .find( rdclsjq ) + .addClass( "simpread-font" ) .addClass( theme ) - .sreffect( { opacity: 1 }, { delay: 100 }) - .addClass( "simpread-read-root-show" ); + .find( rdclsjq ) + .addClass( theme ) + .sreffect( { opacity: 1 }, { delay: 100 }) + .addClass( "simpread-read-root-show" ); this.props.read.fontfamily && ss.FontFamily( this.props.read.fontfamily ); this.props.read.fontsize && ss.FontSize( this.props.read.fontsize ); this.props.read.layout && ss.Layout( this.props.read.layout ); + this.props.read.site.css && this.props.read.site.css.length > 0 + && ss.SiteCSS( this.props.read.site.css ); + !this.props.wrapper.avatar && this.props.read.toc + && toc.Render( "sr-read", $( "sr-rd-content" ), this.props.read.theme, this.props.read.toc_hide ); ss.Preview( this.props.read.custom ); - storage.pr.state == "txt" && $( "sr-rd-content" ).css({ "word-wrap": "break-word", "white-space": "pre-wrap" }); + storage.pr.state == "txt" && !location.href.endsWith( ".md" ) && $( "sr-rd-content" ).css({ "word-wrap": "break-word", "white-space": "pre-wrap" }); storage.pr.current.site.desc == "" && $( "sr-rd-desc" ).addClass( "simpread-hidden" ); excludes( $("sr-rd-content"), this.props.wrapper.exclude ); storage.pr.Beautify( $( "sr-rd-content" ) ); storage.pr.Format( rdcls ); - !this.props.wrapper.avatar && this.props.read.toc && toc.Render( "sr-read", $( "sr-rd-content" ), this.props.read.theme, this.props.read.toc_hide ); - this.props.read.site.css && this.props.read.site.css.length > 0 && - ss.SiteCSS( this.props.read.site.css ); - kbd.Render( $( "sr-rd-content" )); tooltip.Render( rdclsjq ); waves.Render({ root: rdclsjq }); @@ -109,7 +110,8 @@ class Read extends React.Component { loadPlugins( "read_complete" ); - localStorage.removeItem( "sr-update-site" ); + // Puread level to III,can't work this flow. + //localStorage.removeItem( "sr-update-site" ); } } @@ -209,14 +211,17 @@ class Read extends React.Component { /** * Render entry * + * @param {boolean} true: call mathJaxMode(); false: @see mathJaxMode */ -function Render() { +function Render( callMathjax = true ) { + callMathjax && mathJaxMode(); storage.pr.ReadMode(); if ( typeof storage.pr.html.include == "string" && storage.pr.html.include.startsWith( "" ) ) { + console.warn( '=== Adapter failed call Readability View ===' ) storage.pr.Readability(); storage.pr.ReadMode(); - } - console.log( "current puread object is ", storage.pr ) + } else console.warn( '=== Normal Read mode ===' ) + console.warn( "=== Current PuRead object is ===", storage.pr ) ReactDOM.render( , getReadRoot() ); } @@ -258,6 +263,29 @@ function Exit() { }).addClass( "simpread-read-root-hide" ); } +/** + * MathJax Mode + */ +function mathJaxMode() { + if ( storage.pr.isMathJax() && storage.pr.state == "temp" ) { + console.warn( '=== MathJax Mode ===' ) + const dom = storage.pr.MathJaxMode(); + console.log( 'current get dom is ', dom ) + if ( typeof dom == "undefined" ) { + new Notify().Render( "智能感知失败,请移动鼠标框选。" ); + Highlight().done( dom => { + storage.pr.TempMode( "read", dom ); + Render( false ); + }); + } else if ( typeof dom == "string" ) { + const html = storage.pr.GetDom( dom, "html" ); + storage.pr.Newsite( "read", html ); + } else { + storage.pr.TempMode( "read", dom[0] ); + } + } +} + /** * Get read root * diff --git a/src/vender/puread/adaptesite.js b/src/vender/puread/adaptesite.js deleted file mode 100644 index 9e446b6f..00000000 --- a/src/vender/puread/adaptesite.js +++ /dev/null @@ -1,547 +0,0 @@ -console.log( "=== PureRead: AdapteSite load ===" ) - -import * as util from './util'; - -const site = { - url : "", - target : "", - matching : [], - name : "", // only read mode - title : "", // only read mode - desc : "", // only read mode - exclude : [], - include : "", - avatar : [], - paging : [], -}; -let minimatch, rdability; - -export default class AdapteSite { - - constructor( sites = { global:[], custom:[], local:[] } ) { - this.url = util.getURI(); - this.sites = sites; // include: global, custom, local, person - this.current = {}; - this.state = "none"; // include: meta, txt, adapter, none, temp - this.origins = []; - } - - /** - * Set global minimatch - */ - SetMinimatch( value ) { - minimatch = value; - } - - /** - * Set global rdability - */ - SetRdability( value ) { - rdability = value; - } - - /** - * Not adapter usage mozilla readability and readtmpl - */ - Readability() { - try { - const location = document.location, - uri = { - spec: location.href, - host: location.host, - prePath: location.protocol + "//" + location.host, - scheme: location.protocol.substr(0, location.protocol.indexOf(":")), - pathBase: location.protocol + "//" + location.host + location.pathname.substr(0, location.pathname.lastIndexOf("/") + 1) - }, - article = new rdability.Readability( uri, document.cloneNode(true) ).parse(); - if ( article && article.content != "" ) { - console.warn( "current parse is Readability", article ) - this.Newsite( "read", article.content ); - this.dom = $(article.content)[0]; - this.state = "temp"; - } else throw "Readability error"; - } catch ( error ) { - const $dom = readtmpl(); - if ( $dom != -1 ) { - this.Newsite( "read", $dom[0].outerHTML ); - this.dom = $dom[0]; - this.state = "temp"; - } else this.current.site = util.clone( site ); - } - } - - /** - * Get site from url - * - * @param {string} include: global, custom, local - * @param {string} url - */ - Getsite( type, url ) { - return this.sites[type].find( item => item[0] == url ); - } - - /** - * Get sites from url - */ - Getsites() { - const matching = [], - meta = readmeta(); - this.current.url = this.url; - if ( meta ) { - this.current.auto = meta.auto; - this.current.url = meta.url; - delete meta.auto; - delete meta.url; - this.current.site = { ...meta }; - this.current.site.name.startsWith( "metaread::" ) && ( this.state = "meta" ); - this.current.site.name.startsWith( "txtread::" ) && ( this.state = "txt" ); - } else { - getsite( "local", new Map( this.sites.local ), this.url, matching ); - getsite( "global", new Map( this.sites.global ), this.url, matching ); - getsite( "person", new Map( this.sites.person ), this.url, matching ); - getsite( "custom", new Map( this.sites.custom ), this.url, matching ); - if ( matching.length > 0 ) { - let found; - matching.forEach( site => { - if ( site[1].active ) { - found = site; - this.current.url = found[0]; - this.current.site = this.Safesite({ ...found[1] }, found[2], found[0] ); - this.state = "adapter"; - } - }); - if ( !found ) { - const found = matching[0]; - found[1].active = true; - this.current.url = found[0]; - this.current.site = this.Safesite({ ...found[1] }, found[2], found[0] ); - this.state = "adapter"; - } - } else { - const obj = readmulti(); - if ( obj != -1 ) { - this.Newmultisite( "read", obj ); - this.state = "temp"; - } else { - this.Readability(); - } - } - } - this.current.site.matching = matching; - } - - /** - * Add new sites to this.sites.global( global sites ) - * - * @param {object} sites.[array] - * @return {int} update sites count - */ - Addsites( result ) { - let count = 0; - if ( this.sites.global.length == 0 ) { - this.sites.global = this.Formatsites( result ); - count = this.sites.global.length; - } - else { - const obj = addsites( this.Formatsites( result ), this.sites.global ); - count = obj.count; - this.sites.global = obj.newsites; - } - return count; - } - - /** - * Add new sites to this.sites.local( local sites ) - * - * @param {object} new sites - * @return {array} this.sites.local - */ - Addlocalsites( new_sites ) { - this.sites.local = [ ...new_sites ]; - return this.sites.local; - } - - /** - * Add all sites to this.sites - * - * @param {object} new sites - * @return {object} this.sites - */ - Addallsites( sites ) { - this.sites = { - global: [ ...sites.global ], - person: [ ...sites.person ], - custom: [ ...sites.custom ], - local : [ ...sites.local ], - }; - return this.sites; - } - - /** - * Add new site( read only ) - * - * @param {string} include: focus, read - * @param {string} when read html is dom.outerHTML - */ - Newsite( mode, html ) { - const new_site = { mode, url: window.location.href, site: { name: `tempread::${window.location.host}`, title: "", desc: "", include: "", exclude: [] } }; - html && ( new_site.site.html = html ); - this.current.mode = new_site.mode, - this.current.url = new_site.url; - this.current.site = this.Safesite({ ...new_site.site }, "local", new_site.url ); - console.log( "【read only】current site object is ", this.current ) - } - - /** - * Add new multi-site( read only ) - * - * @param {string} include: focus, read - * @param {object} multi-page, avator, include - */ - Newmultisite( mode, multi ) { - const new_site = { mode, url: window.location.href, site: { name: `tempread::${window.location.host}`, title: "<title>", desc: "", include: multi.include, exclude: [], avatar: multi.avatar } }; - this.current.mode = new_site.mode, - this.current.url = new_site.url; - this.current.site = this.Safesite({ ...new_site.site }, "local", new_site.url ); - console.log( "【read only】current multi-site object is ", this.current ) - } - - /** - * Update url and site from param - * - * @param {string} value is: global, custom, local - * @param {string} older url - * @param {array} [ url, new site] - */ - Updatesite( key, older, newer ) { - let idx = this.sites[key].findIndex( item => item[0] == older ); - idx == -1 && ( idx = this.sites[key].length ); - this.sites[key].splice( idx, 1, newer ); - } - - /** - * Delete site from this.sites.local - * - * @param {string} value is: global, custom, local - * @param {string} older url - * @param {func} callback - */ - Deletesite( key, older, callback ) { - let idx = this.sites[key].findIndex( item => item[0] == older ); - idx != -1 && this.sites[key].splice( idx, 1 ); - callback( idx ); - } - - /** - * Safe site, add all site props - * - * @param {object} modify site - * @param {string} target include: global custom local - * @param {string} url - * @returns {object} site - */ - Safesite( site, target, url ) { - site.url = url; - site.target = target; - site.name == "" && ( site.name = "tempread::" ); - ( !site.avatar || site.avatar.length == 0 ) && ( site.avatar = [{ name: "" }, { url: "" }]); - ( !site.paging || site.paging.length == 0 ) && ( site.paging = [{ prev: "" }, { next: "" }]); - return site; - } - - /** - * Clean useless site props - * - * @param {object} site - * @returns {object} site - */ - Cleansite( site ) { - delete site.url; - delete site.html; - delete site.target; - delete site.matching; - site.avatar && site.avatar.length > 0 && site.avatar[0].name == "" && delete site.avatar; - site.paging && site.paging.length > 0 && site.paging[0].prev == "" && delete site.paging; - return site; - } - - /** - * Format sites object from local or remote json file - * - * @param {object} sites.[array] - * @return {array} foramat e.g. [[ <url>, object ],[ <url>, object ]] - */ - Formatsites( result ) { - const format = new Map(); - for ( let site of result.sites ) { - if ( verifysite( site ) != 0 ) continue; - const url = site.url; - delete site.url; - format.set( url, site ); - } - return [ ...format ]; - } - - /** - * Clear sites - * - * @param {string} site type, only include: global, custom. local - */ - Clearsites( type ) { - type ? ( this.sites[type] = [] ) : ( this.sites = { global:[], custom:[], local:[] }); - } - - /** - * Add urls to origins - * - * @param {json} result json - */ - Origins( result ) { - let urls = result.origins.map( item => item.url ); - urls = new Set( this.origins.concat( urls ) ); - urls.forEach( item => { - if ( item.trim() == "" || !item.trim().startsWith( "http" ) || !item.trim().endsWith( ".json" ) ) urls.delete( item ); - }); - this.origins = [ ...urls ]; - return this.origins; - } - - /** - * Add new sites to this.sites.custom( custom sites ) - * - * @param {object} new sites - * @return {array} this.sites.custom - */ - Addorigins( new_sites ) { - this.sites.custom = [ ...new_sites ]; - return this.sites.custom; - } - - /** - * Clear origins - * - * @returns custom.length - */ - Clearorigins() { - const len = this.sites.custom.length; - this.sites.custom = []; - return len; - } - -} - -/** - * Get readmeta, inlcude: txtread and metaread - * - * @return {object} meata data or undefined - */ -function readmeta() { - if ( minimatch( location.href, "file://**/*.txt" ) || minimatch( location.href, "http*://**/*.txt" ) ) { - return readtxt(); - } - const reg = /<\S+ (class|id)=("|')?[\w-_=;:' ]+("|')?>?$|<[^/][-_a-zA-Z0-9]+>?$/ig, // from util.verifyHtml() - meta = { - name : $( "meta[name='simpread:name']" ).attr( "content" ), - url : $( "meta[name='simpread:url']" ).attr( "content" ), - title : $( "meta[name='simpread:title']" ).attr( "content" ), - desc : $( "meta[name='simpread:desc']" ).attr( "content" ), - include: $( "meta[name='simpread:include']" ).attr( "content" ), - exp : $( "meta[name='simpread:exclude']" ).attr( "content" ), - auto : $( "meta[name='simpread:auto']" ).attr( "content" ), - exclude: [], - }; - if ( meta.name && meta.include ) { - if ( meta.url && !minimatch( location.href, meta.url )) { - return undefined; - } - !meta.title && ( meta.title = "<title>" ); - !meta.desc && ( meta.desc = "" ); - !meta.exp && ( meta.exp = "" ); - meta.name = `metaread::${meta.name}`; - meta.auto = meta.auto == "true" ? true : false; - const idx = [ "title", "desc", "include", "exp" ].findIndex( item => meta[item] != "" && !meta[item].match( reg )); - meta.exclude.push( meta.exp ); - delete meta.exp; - console.assert( idx == -1, "meta read mode error. ", meta ) - return idx == -1 ? meta : undefined; - } else { - console.warn( "current not found meta data", meta ) - return undefined; - } -} - -/** - * Read txt, include: file and http - */ -function readtxt() { - const title = location.pathname.split( "/" ).pop(), - type = location.protocol == "file:" ? "local" : "remote", - meta = { - name : `txtread::${type}`, - title : "<title>", - desc : "", - include: "<pre>", - auto : false, - exclude: [], - }; - if ( type == "remote" ) { - meta.include = ""; - meta.html = $( "body pre" ).html().replace( /\n/ig, "<br>" ); - } - !$( "title" ).html() && $( "head" ).append( `<title>${ decodeURI(title.replace( ".txt", "" )) }` ); - return meta; -} - -/** - * Read mode template, include: - * - * - Hexo - * - WordPress - * - Common( include
) - * - * @return {jquery} jquery object - */ -function readtmpl() { - const $root = $( "body" ), - selectors = [ - ".post-content", ".entry-content", ".post-article", ".content-post", ".article-entry", ".article-content", - ".article-body", ".markdown-body", - "[itemprop='articleBody']", - "article", - ".post", ".content", - ]; - for ( const selector of selectors ) { - const $target = $root.find( selector ); - if ( $target.length > 0 ) { - console.warn( "current selector is", selector ); - return $target; - } - } - return -1; -} - -/** - * Read mode multi template, include: - * - * - Discuz - * - Discourse - * - * @return {object} true: object; false: -1 - */ -function readmulti() { - if ( location.pathname.includes( "thread" ) || location.pathname.includes( "forum.php" ) ) { - if ( $('.t_f').length > 0 && $('.favatar').find('.authi').length > 0 && $('.avatar').find('img').length > 0 ) { - return { - avatar: [ - {"name" : "[[{$('.favatar').find('.authi')}]]"}, - {"url" : "[[{$('.avatar').find('img')}]]"} - ], - include: "[[{$('.t_f')}]]" - }; - } - } else if ( /\/t\/[\w-]+\/\d+/.test( location.pathname ) && $('meta[name=generator]').attr("content").includes("discourse") ) { - return { - avatar: [ - {"name" : "[[{$('.topic-avatar').find('.a[data-user-card]')}]]"}, - {"url" : "[[{$('.topic-avatar').find('img')}]]"} - ], - include: "[[{$('.cooked')}]]" - }; - } - return -1; -} - -/** - * Add new sites to old sites - * - * @param {array} new sites from local or remote - * @param {array} current sites from this.sites.global - * @return {object} count: new sites; forced: update sites( discard, all site must be forced update) - */ -function addsites( newsites, old ) { - const oldsites = new Map( old ), - urls = [ ...oldsites.keys() ]; - let [ count, forced ] = [ 0, 0 ]; - newsites.map( site => { - if ( !urls.includes( site[0] ) ) { - count++; - } else if ( urls.includes( site[0] )) { - forced++; - } - }); - return { count, newsites }; -} - -/** - * Find site by url from sites - * - * @param {string} type, include: global, local, custom - * @param {map} sites - * @param {string} url - * @param {array} matching sites - * - * @return {array} 0: current site; 1: current url, 2: type - */ -function getsite( type, sites, url, matching = [] ) { - const domain = (names)=>{ - const arr = names.replace( "www.", "" ).match( /\.\S+\.\S+/g ); - if ( arr ) { - return arr[0].substr(1); - } else { - return names.replace( "www.", "" ); - } - }, - urls = [ ...sites.keys() ], - arr = url.match( /[.a-zA-z0-9-_]+/g ), - uri = arr[1].replace( "www.", "" ), - hostname = domain( window.location.hostname ), - isroot = ()=>window.location.pathname == "/" || /\/(default|index|portal).[0-9a-zA-Z]+$/.test(window.location.pathname); - for ( const cur of urls ) { - const name = sites.get(cur).name, - sufname= domain( name ); - if ( !isroot() && !cur.endsWith( "*" ) && cur.replace( /^http[s]?:/, "" ) == url.replace( /^http[s]?:/, "" ) ) { - matching.push( [ cur, util.clone( sites.get( cur )), type ] ); - } else if ( cur.match( /\*/g ) && cur.match( /\*/g ).length == 1 && !isroot() && cur.endsWith( "*" ) && uri.includes( sufname ) && hostname == sufname && url.includes( name ) ) { - // e.g. https://www.douban.com/* http://mp.weixin.qq.com/* - matching.push( [ cur, util.clone( sites.get( cur )), type ] ); - } else if ( minimatch( window.location.origin + window.location.pathname, cur ) ) { - matching.push( [ cur, util.clone( sites.get( cur )), type ] ); - } - } -} - -/** - * Verify site validity, include: - * - name, url, include, error is -1 - * - title include desc, error is -2 - * - paging, error is -3 ~ -6 - * - avatar, error is -7 ~ -10 - * - * @param {object} site - */ -function verifysite( site ) { - if ( !site.name || !site.url || !site.include ) return -1; - if ( util.verifyHtml( site.title )[0] == -1 || - util.verifyHtml( site.include )[0] == -1 || - util.verifyHtml( site.desc )[0] == -1 - ) { - return -2; - } - if ( site.paging ) { - if ( site.paging.length != 2 ) return -3; - if ( !site.paging[0].prev ) return -4; - if ( !site.paging[1].next ) return -5; - if ( util.verifyHtml( site.paging[0].prev )[0] == -1 || util.verifyHtml( site.paging[1].next )[0] == -1 ) { - return -6; - } - } - if ( site.avatar ) { - if ( site.avatar.length != 2 ) return -7; - if ( !site.avatar[0].name ) return -8; - if ( !site.avatar[1].url ) return -9; - if ( util.verifyHtml( site.avatar[0].name )[0] == -1 || util.verifyHtml( site.avatar[1].url )[0] == -1 ) { - return -10; - } - } - return 0; -} diff --git a/src/vender/puread/plugin.js b/src/vender/puread/plugin.js deleted file mode 100644 index fed86ef0..00000000 --- a/src/vender/puread/plugin.js +++ /dev/null @@ -1,32 +0,0 @@ -console.log( "=== PureRead: Plugin load ===" ) - -import pangu from './plugin/pangu.min'; -import minimatch from './plugin/minimatch'; -import * as be from './plugin/beautify'; -import * as ss from './plugin/stylesheet'; -import * as rda from './plugin/readability'; - -const plugins = { - pangu : pangu, - minimatch: minimatch, - beautify : be, - style : ss, - rdability: rda, -}; - -/** - * Get PureRead Plugin - * - * @param {string} plugin name, when undefined, return all plugin - * @return {object} all plugins - * {string} plgin - */ -export function Plugin( type ) { - let result; - if ( type == undefined ) { - result = plugins; - } else { - result = plugins[type]; - } - return result; -} \ No newline at end of file diff --git a/src/vender/puread/plugin/beautify.js b/src/vender/puread/plugin/beautify.js deleted file mode 100644 index 9d724536..00000000 --- a/src/vender/puread/plugin/beautify.js +++ /dev/null @@ -1,385 +0,0 @@ -console.log( "=== PureRead: Beautify load ===" ) - -/** - * Beautify html - * - * @param {string} storage.current.site.name - */ -function specbeautify( name, $target ) { - switch ( name ) { - case "sspai.com": - //TO-DO - $target.find( ".relation-apps" ).remove(); - $target.find( ".ss-app-card" ).remove(); - break; - case "post.smzdm.com": - $target.find( "img.face" ).addClass( "sr-rd-content-nobeautify" ); - $target.find( ".insert-outer img" ).addClass( "sr-rd-content-nobeautify" ); - break; - case "infoq.com": - $target.find( "img" ).map( (index, item) => { - if ( $(item).css("float") == "left" ) { - $(item).addClass( "sr-rd-content-nobeautify" ); - } - }); - $target.find( "script" ).remove(); - break; - case "appinn.com": - $target.find( ".emoji" ).addClass( "sr-rd-content-nobeautify" ); - break; - case "hacpai.com": - $target.find( ".emoji" ).addClass( "sr-rd-content-nobeautify" ); - break; - case "douban.com": - $target.find( ".review-content" ).children().unwrap(); - $target.find( "table" ).addClass( "sr-rd-content-center" ); - $target.find( "p" ).css({"white-space": "pre-wrap"}); - $target.find( ".cc" ).removeClass(); - break; - case "qdaily.com": - $target.find( "img" ).map( (index, item) => { - const $target = $(item), - height = Number.parseInt($target.css("height")); - if ( height == 0 ) $target.remove(); - }); - $target.find( ".com-insert-images" ).map( (index, item) => { - const $target = $(item), - imgs = $target.find( "img" ).map( (index, item)=>`
${item.outerHTML}
` ), - str = imgs.get().join( "" ); - $target.empty().removeAttr( "class" ).append( str ); - }); - $target.find( ".com-insert-embed" ).remove(); - break; - case "news.mtime.com": - $target.find( ".newspictool" ).map( ( index, item ) => { - const $target = $(item), - $img = $target.find( "img" ), - $label = $target.find( "p:last" ); - $target.removeAttr( "class" ).addClass( "sr-rd-content-center" ).empty().append( $img ).append( $label ); - }); - break; - case "blog.csdn.net": - $target.find( ".save_code" ).remove(); - $target.find( ".pre-numbering" ).remove(); - $target.find( "pre" ).removeAttr( "style" ).removeAttr( "class" ); - $target.find( "code" ).removeAttr( "style" ); - $target.find( ".dp-highlighter" ).map( ( index, item )=> { - $(item).find(".bar .tools").remove(); - if ( $(item).next().is( "pre" )) $(item).next().remove(); - }); - break; - case "news.sohu.com": - $target.find( ".conserve-photo" ).remove(); - $target.find( "table" ).addClass( "sr-rd-content-center" ); - break; - case "qq.com": - $target.find( ".rv-root-v2, #backqqcom" ).remove(); - break; - case "azofreeware.com": - $target.find( "iframe" ).remove(); - break; - case "apprcn.com": - $target.find( "img" ).map( ( index, item ) => { - const $target = $(item), - src = $target.attr( "src" ); - if ( src && src.includes( "Apprcn_Wechat_Small.jpeg" ) ) $target.parent().remove(); - }); - $target.find( "a" ).map( ( index, item ) => { - const $target = $(item), - text = $target.text(); - if ( text == "来自反斗软件" ) $target.parent().remove(); - }); - break; - case "tieba.baidu.com": - $target.find( ".BDE_Smiley" ).addClass( "sr-rd-content-nobeautify" ); - $target.find( ".replace_div" ).removeAttr( "class" ).removeAttr( "style" ); - $target.find( ".replace_tip" ).remove(); - $target.find( ".d_post_content, .j_d_post_content, .post_bubble_top, .post_bubble_middle, .post_bubble_bottom" ).map( ( idx, target ) => { - $( target ).removeAttr( "class" ).removeAttr( "style" ); - }); - $( "body" ).find( ".p_author_face" ).map( ( idx, target ) => { - const $target = $( target ).find( "img" ), - src = $target.attr( "data-tb-lazyload" ), - name = $target.attr( "username" ); - src && $( "sr-rd-mult-avatar" ).find( "span" ).map( ( idx, span ) => { - const $span = $( span ), - text = $span.text(); - if ( text == name ) { - $span.parent().find( "img" ).attr( "src", src ); - } - }); - }); - break; - case "jingyan.baidu.com": - $target.find( ".exp-image-wraper" ).removeAttr( "class" ).removeAttr( "href" ); - break; - case "question.zhihu.com": - $target.find( ".zu-edit-button" ).remove(); - $target.find( "a.external" ).map( ( idx, target ) => { - $( target ).removeAttr( "class" ) - .attr( "style", "border: none;" ); - }); - $target.find( ".VagueImage" ).map( ( idx, target ) => { - const $target = $( target ), - src = $target.attr( "data-src" ); - $target.replaceWith( `` ) - }); - break; - case "chiphell.com": - $target.find( "img" ).map( ( index, item ) => { - const $target = $(item), - $parent = $target.parent(), - src = $target.attr( "src" ), - smilieid= $target.attr( "smilieid" ); - if ( $parent.is( "ignore_js_op" )) $target.unwrap(); - smilieid && src && src.includes( "static/image/smiley" ) && - $target.addClass( "sr-rd-content-nobeautify" ).attr( "style", "width: 50px;" ); - }); - $target.find( ".quote" ).remove(); - break; - case "jiemian.com": - $target.find( "script" ).remove(); - break; - case "36kr.com": - $target.find( ".load-html-img" ).removeAttr( "class" ); - break; - case "cnblogs.com": - $target.find( ".cnblogs_code" ).removeClass(); - $target.find( ".cnblogs_code_hide" ).removeClass().removeAttr( "style" ); - $target.find( ".cnblogs_code_toolbar" ).remove(); - $target.find( ".code_img_opened" ).remove(); - $target.find( ".code_img_closed" ).remove(); - break; - case "news.cnblogs.com": - $target.find( ".topic_img" ).remove(); - break; - case "g-cores.com": - $target.find( ".swiper-slide-active" ).find( "img" ).map( ( index, item ) => { - const $target = $(item); - $target.parent().parent().parent().parent().parent().parent().removeAttr( "class" ).removeAttr( "style" ).html($target); - }); - break; - case "feng.com": - $target.find( "span" ).removeAttr( "style" ); - break; - case "young.ifeng.com": - $target.find( "span" ).removeAttr( "style" ); - break; - case "ftchinese.com": - $target.find( "script" ).remove(); - break; - case "segmentfault.com": - $target.find( ".widget-codetool" ).remove(); - break; - case "mp.weixin.qq.com": - $target.find( 'section[powered-by="xiumi.us"]' ).find( "img" ).map( ( index, item ) => { - const $target = $(item), - src = $target.attr( "data-src" ); - $target.addClass( "sr-rd-content-nobeautify" ).attr( "src", src ); - }); - break; - case "ruby-china.org": - $target.find( ".twemoji" ).remove(); - break; - case "w3cplus.com": - $target.find( "iframe" ).addClass( "sr-rd-content-nobeautify" ); - break; - case "zuojj.com": - $target.find( ".syntaxhighlighter .Brush" ).attr( "style", "font-size: .7em !important;" ) - break; - case "aotu.io": - $target.find( ".highlight table" ).map( ( index, item ) => { - const $target = $(item), - $pre = $target.find( "pre" ), - $table = $target.find( "table" ); - $target.html( $pre[1] ); - $table.unwrap(); - }); - $target.find( "table" ).addClass( "sr-rd-content-center" ); - break; - case "colobu.com": - $target.find( ".highlight table" ).map( ( index, item ) => { - const $target = $(item), - $pre = $target.find( "pre" ); - $target.html( $pre[1] ); - $target.unwrap(); - }); - break; - case "hao.caibaojian.com": - $target.find( ".tlink" ).map( ( index, item ) => { - const $target = $(item); - $target.html( "" ); - }); - break; - case "wkee.net": - $target.find( "script" ).remove(); - break; - case "linux.cn": - $target.find( "pre" ).attr( "style", "background-color: #161b20; background-image: none;" ); - $target.find( "code" ).attr( "style", "background-color: transparent; background-image: none;" ); - break; - case "zhuanlan.zhihu.com": - $target.find( "div[data-src]" ).map( ( index, item ) => { - const $target = $(item), - src = $target.attr( "data-src" ); - $target.replaceWith( `
` ); - }); - break; - case "jianshu.com": - $target.find( ".image-package" ).map( ( index, item ) => { - const $target = $( item ), - $div = $target.find( "img" ); - $target.html( $div ); - }); - break; - case "medium.com": - $target.find( "figure" ).map( ( index, item ) => { - const $target = $(item), - $img = $target.find( "img" ); - $target.replaceWith( `
` ); - }); - break; - case "worldcup.fifa.com": - $target.find( "iframe" ).css({ width: "790px", height: "450px" }); - $target.find( "div" ).removeClass(); - break; - } -} - -/** - * Remove spare tag - * - * @param {string} storage.current.site.name - * @param {jquery} jquery object - */ -function removeSpareTag( name, $target ) { - let [ remove, tag ] = [ false, "" ]; - if ([ "lib.csdn.net", "huxiu.com", "my.oschina.net", "caixin.com", "163.com", "steachs.com", "hacpai.com", "apprcn.com", "mp.weixin.qq.com" ].includes( name )) { - [ remove, tag ] = [ true, "p" ]; - } else if ([ "nationalgeographic.com.cn", "dgtle.com", "news.mtime.com" ].includes( name )) { - [ remove, tag ] = [ true, "div" ]; - } else if ( ["chiphell.com"].includes( name ) ) { - [ remove, tag ] = [ true, "font" ]; - } - if ( remove ) { - $target.find( tag ).map( ( index, item ) => { - const str = $(item).text().toLowerCase().trim(); - if ( $(item).find( "img" ).length == 0 && str == "" ) $(item).remove(); - }); - } -} - -/** - * Beautify html, incldue: - * - * - change all
to - * - remove useless
- * - * @param {jquery} jquery object - */ -function htmlbeautify( $target ) { - try { - $target.html( ( index, html ) => { - return html.trim() - .replace( /<\/?blockquote/g, (value) => value[1] == "/" ? "\n?
(\n?
)*/g, "
" ) - .replace( /\/(div|p)>\n*(
\n)+/g, (value) =>value.replace( "
", "" )); - }); - } catch ( error ) { - console.error( error ); - return $target.html(); - } -} - -/** - * Common Beautify html, include: - * - task: all webiste image, remove old image and create new image - * - task: all webiste sr-blockquote, remove style - * - task: all webiste iframe, embed add center style - * - task: all hr tag add simpread-hidden class - * - task: all pre/code tag remove class - * - task: all a tag remove style - * - * @param {jquery} - */ -function commbeautify( name, $target ) { - $target.find( "img:not(.sr-rd-content-nobeautify)" ).map( ( index, item ) => { - const $target = $(item), - $orgpar = $target.parent(), - $img = $( "" ), - src = $target.attr( "src" ), - lazysrc = $target.attr( "data-src" ), - zuimei = $target.attr( "data-original" ), - cnbeta = $target.attr( "original" ), - jianshu = $target.attr( "data-original-src" ), - sina = $target.attr( "real_src" ), - fixOverflowImgsize = () => { - $img.removeClass( "sr-rd-content-img-load" ); - if ( $img[0].clientWidth > 1000 ) { - $img.css( "zoom", "0.6" ); - } - else if ( $img[0].clientHeight > 620 ) { - if ( /win|mac/i.test(navigator.platform) ) { - $img.attr( "height", 620 ); - if ( $img[0].clientWidth < $("sr-rd-content").width()) $img.css({ "width":"auto" }); - } - } - if ( $img[0].clientWidth > $("sr-rd-content").width()) $img.addClass( "sr-rd-content-img" ); - }, - loaderrorHandle = () => { - $img.addClass( "simpread-hidden" ); - if ( $img.parent().hasClass( "sr-rd-content-center" )) { - $img.parent().removeAttr( "class" ).addClass( "simpread-hidden" ); - } - }; - let newsrc, - $parent = $target.parent(), - tagname = $parent[0].tagName.toLowerCase(); - - // remove current image and create new image object - newsrc = cnbeta ? cnbeta : src; - newsrc = lazysrc ? lazysrc : newsrc; - newsrc = zuimei ? zuimei : newsrc; - newsrc = jianshu ? jianshu : newsrc; - newsrc = sina ? sina : newsrc; - // hack code - location.host.includes( "infoq.com" ) && ( newsrc = src ); - !newsrc.startsWith( "http" ) && ( newsrc = newsrc.startsWith( "//" ) ? location.protocol + newsrc : location.origin + newsrc ); - $img.attr( "src", newsrc ) - .replaceAll( $target ) - .wrap( "
" ); - if ( !/win|mac/i.test(navigator.platform) ) { - $img.on( "load", ()=>fixOverflowImgsize() ) - .on( "error", ()=>loaderrorHandle() ); - } else { - $img.one( "load", ()=>fixOverflowImgsize() ) - .one( "error", ()=>loaderrorHandle() ); - } - }); - $target.find( "sr-blockquote" ).map( ( index, item ) => { - const $target = $(item), - $parent = $target.parent(); - $target.removeAttr( "style" ).removeAttr( "class" ); - if ( name == "dgtle.com" ) { - $parent.removeClass( "quote" ); - } - }); - $target.find( "iframe:not(.sr-rd-content-nobeautify), embed:not(.sr-rd-content-nobeautify)" ).map( ( index, item )=> { - $(item).wrap( "
" ); - }); - $target.find( "hr" ).map( ( index, item )=> { - $(item).addClass( "simpread-hidden" ); - }); - $target.find( "pre" ).map( ( index, item )=> { - $(item).find( "code" ).removeAttr( "class" ); - }); - $target.find( "pre" ).removeAttr( "class" ); - $target.find( "a" ).removeAttr( "style" ); -} - -export { - specbeautify, - removeSpareTag, - htmlbeautify, - commbeautify, -} \ No newline at end of file diff --git a/src/vender/puread/plugin/minimatch.js b/src/vender/puread/plugin/minimatch.js deleted file mode 100644 index 5b5f8cf4..00000000 --- a/src/vender/puread/plugin/minimatch.js +++ /dev/null @@ -1,923 +0,0 @@ -module.exports = minimatch -minimatch.Minimatch = Minimatch - -var path = { sep: '/' } -try { - path = require('path') -} catch (er) {} - -var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {} -var expand = require('brace-expansion') - -var plTypes = { - '!': { open: '(?:(?!(?:', close: '))[^/]*?)'}, - '?': { open: '(?:', close: ')?' }, - '+': { open: '(?:', close: ')+' }, - '*': { open: '(?:', close: ')*' }, - '@': { open: '(?:', close: ')' } -} - -// any single thing other than / -// don't need to escape / when using new RegExp() -var qmark = '[^/]' - -// * => any number of characters -var star = qmark + '*?' - -// ** when dots are allowed. Anything goes, except .. and . -// not (^ or / followed by one or two dots followed by $ or /), -// followed by anything, any number of times. -var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?' - -// not a ^ or / followed by a dot, -// followed by anything, any number of times. -var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?' - -// characters that need to be escaped in RegExp. -var reSpecials = charSet('().*{}+?[]^$\\!') - -// "abc" -> { a:true, b:true, c:true } -function charSet (s) { - return s.split('').reduce(function (set, c) { - set[c] = true - return set - }, {}) -} - -// normalizes slashes. -var slashSplit = /\/+/ - -minimatch.filter = filter -function filter (pattern, options) { - options = options || {} - return function (p, i, list) { - return minimatch(p, pattern, options) - } -} - -function ext (a, b) { - a = a || {} - b = b || {} - var t = {} - Object.keys(b).forEach(function (k) { - t[k] = b[k] - }) - Object.keys(a).forEach(function (k) { - t[k] = a[k] - }) - return t -} - -minimatch.defaults = function (def) { - if (!def || !Object.keys(def).length) return minimatch - - var orig = minimatch - - var m = function minimatch (p, pattern, options) { - return orig.minimatch(p, pattern, ext(def, options)) - } - - m.Minimatch = function Minimatch (pattern, options) { - return new orig.Minimatch(pattern, ext(def, options)) - } - - return m -} - -Minimatch.defaults = function (def) { - if (!def || !Object.keys(def).length) return Minimatch - return minimatch.defaults(def).Minimatch -} - -function minimatch (p, pattern, options) { - if (typeof pattern !== 'string') { - throw new TypeError('glob pattern string required') - } - - if (!options) options = {} - - // shortcut: comments match nothing. - if (!options.nocomment && pattern.charAt(0) === '#') { - return false - } - - // "" only matches "" - if (pattern.trim() === '') return p === '' - - return new Minimatch(pattern, options).match(p) -} - -function Minimatch (pattern, options) { - if (!(this instanceof Minimatch)) { - return new Minimatch(pattern, options) - } - - if (typeof pattern !== 'string') { - throw new TypeError('glob pattern string required') - } - - if (!options) options = {} - pattern = pattern.trim() - - // windows support: need to use /, not \ - if (path.sep !== '/') { - pattern = pattern.split(path.sep).join('/') - } - - this.options = options - this.set = [] - this.pattern = pattern - this.regexp = null - this.negate = false - this.comment = false - this.empty = false - - // make the set of regexps etc. - this.make() -} - -Minimatch.prototype.debug = function () {} - -Minimatch.prototype.make = make -function make () { - // don't do it more than once. - if (this._made) return - - var pattern = this.pattern - var options = this.options - - // empty patterns and comments match nothing. - if (!options.nocomment && pattern.charAt(0) === '#') { - this.comment = true - return - } - if (!pattern) { - this.empty = true - return - } - - // step 1: figure out negation, etc. - this.parseNegate() - - // step 2: expand braces - var set = this.globSet = this.braceExpand() - - if (options.debug) this.debug = console.error - - this.debug(this.pattern, set) - - // step 3: now we have a set, so turn each one into a series of path-portion - // matching patterns. - // These will be regexps, except in the case of "**", which is - // set to the GLOBSTAR object for globstar behavior, - // and will not contain any / characters - set = this.globParts = set.map(function (s) { - return s.split(slashSplit) - }) - - this.debug(this.pattern, set) - - // glob --> regexps - set = set.map(function (s, si, set) { - return s.map(this.parse, this) - }, this) - - this.debug(this.pattern, set) - - // filter out everything that didn't compile properly. - set = set.filter(function (s) { - return s.indexOf(false) === -1 - }) - - this.debug(this.pattern, set) - - this.set = set -} - -Minimatch.prototype.parseNegate = parseNegate -function parseNegate () { - var pattern = this.pattern - var negate = false - var options = this.options - var negateOffset = 0 - - if (options.nonegate) return - - for (var i = 0, l = pattern.length - ; i < l && pattern.charAt(i) === '!' - ; i++) { - negate = !negate - negateOffset++ - } - - if (negateOffset) this.pattern = pattern.substr(negateOffset) - this.negate = negate -} - -// Brace expansion: -// a{b,c}d -> abd acd -// a{b,}c -> abc ac -// a{0..3}d -> a0d a1d a2d a3d -// a{b,c{d,e}f}g -> abg acdfg acefg -// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg -// -// Invalid sets are not expanded. -// a{2..}b -> a{2..}b -// a{b}c -> a{b}c -minimatch.braceExpand = function (pattern, options) { - return braceExpand(pattern, options) -} - -Minimatch.prototype.braceExpand = braceExpand - -function braceExpand (pattern, options) { - if (!options) { - if (this instanceof Minimatch) { - options = this.options - } else { - options = {} - } - } - - pattern = typeof pattern === 'undefined' - ? this.pattern : pattern - - if (typeof pattern === 'undefined') { - throw new TypeError('undefined pattern') - } - - if (options.nobrace || - !pattern.match(/\{.*\}/)) { - // shortcut. no need to expand. - return [pattern] - } - - return expand(pattern) -} - -// parse a component of the expanded set. -// At this point, no pattern may contain "/" in it -// so we're going to return a 2d array, where each entry is the full -// pattern, split on '/', and then turned into a regular expression. -// A regexp is made at the end which joins each array with an -// escaped /, and another full one which joins each regexp with |. -// -// Following the lead of Bash 4.1, note that "**" only has special meaning -// when it is the *only* thing in a path portion. Otherwise, any series -// of * is equivalent to a single *. Globstar behavior is enabled by -// default, and can be disabled by setting options.noglobstar. -Minimatch.prototype.parse = parse -var SUBPARSE = {} -function parse (pattern, isSub) { - if (pattern.length > 1024 * 64) { - throw new TypeError('pattern is too long') - } - - var options = this.options - - // shortcuts - if (!options.noglobstar && pattern === '**') return GLOBSTAR - if (pattern === '') return '' - - var re = '' - var hasMagic = !!options.nocase - var escaping = false - // ? => one single character - var patternListStack = [] - var negativeLists = [] - var stateChar - var inClass = false - var reClassStart = -1 - var classStart = -1 - // . and .. never match anything that doesn't start with ., - // even when options.dot is set. - var patternStart = pattern.charAt(0) === '.' ? '' // anything - // not (start or / followed by . or .. followed by / or end) - : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))' - : '(?!\\.)' - var self = this - - function clearStateChar () { - if (stateChar) { - // we had some state-tracking character - // that wasn't consumed by this pass. - switch (stateChar) { - case '*': - re += star - hasMagic = true - break - case '?': - re += qmark - hasMagic = true - break - default: - re += '\\' + stateChar - break - } - self.debug('clearStateChar %j %j', stateChar, re) - stateChar = false - } - } - - for (var i = 0, len = pattern.length, c - ; (i < len) && (c = pattern.charAt(i)) - ; i++) { - this.debug('%s\t%s %s %j', pattern, i, re, c) - - // skip over any that are escaped. - if (escaping && reSpecials[c]) { - re += '\\' + c - escaping = false - continue - } - - switch (c) { - case '/': - // completely not allowed, even escaped. - // Should already be path-split by now. - return false - - case '\\': - clearStateChar() - escaping = true - continue - - // the various stateChar values - // for the "extglob" stuff. - case '?': - case '*': - case '+': - case '@': - case '!': - this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c) - - // all of those are literals inside a class, except that - // the glob [!a] means [^a] in regexp - if (inClass) { - this.debug(' in class') - if (c === '!' && i === classStart + 1) c = '^' - re += c - continue - } - - // if we already have a stateChar, then it means - // that there was something like ** or +? in there. - // Handle the stateChar, then proceed with this one. - self.debug('call clearStateChar %j', stateChar) - clearStateChar() - stateChar = c - // if extglob is disabled, then +(asdf|foo) isn't a thing. - // just clear the statechar *now*, rather than even diving into - // the patternList stuff. - if (options.noext) clearStateChar() - continue - - case '(': - if (inClass) { - re += '(' - continue - } - - if (!stateChar) { - re += '\\(' - continue - } - - patternListStack.push({ - type: stateChar, - start: i - 1, - reStart: re.length, - open: plTypes[stateChar].open, - close: plTypes[stateChar].close - }) - // negation is (?:(?!js)[^/]*) - re += stateChar === '!' ? '(?:(?!(?:' : '(?:' - this.debug('plType %j %j', stateChar, re) - stateChar = false - continue - - case ')': - if (inClass || !patternListStack.length) { - re += '\\)' - continue - } - - clearStateChar() - hasMagic = true - var pl = patternListStack.pop() - // negation is (?:(?!js)[^/]*) - // The others are (?:) - re += pl.close - if (pl.type === '!') { - negativeLists.push(pl) - } - pl.reEnd = re.length - continue - - case '|': - if (inClass || !patternListStack.length || escaping) { - re += '\\|' - escaping = false - continue - } - - clearStateChar() - re += '|' - continue - - // these are mostly the same in regexp and glob - case '[': - // swallow any state-tracking char before the [ - clearStateChar() - - if (inClass) { - re += '\\' + c - continue - } - - inClass = true - classStart = i - reClassStart = re.length - re += c - continue - - case ']': - // a right bracket shall lose its special - // meaning and represent itself in - // a bracket expression if it occurs - // first in the list. -- POSIX.2 2.8.3.2 - if (i === classStart + 1 || !inClass) { - re += '\\' + c - escaping = false - continue - } - - // handle the case where we left a class open. - // "[z-a]" is valid, equivalent to "\[z-a\]" - if (inClass) { - // split where the last [ was, make sure we don't have - // an invalid re. if so, re-walk the contents of the - // would-be class to re-translate any characters that - // were passed through as-is - // TODO: It would probably be faster to determine this - // without a try/catch and a new RegExp, but it's tricky - // to do safely. For now, this is safe and works. - var cs = pattern.substring(classStart + 1, i) - try { - RegExp('[' + cs + ']') - } catch (er) { - // not a valid class! - var sp = this.parse(cs, SUBPARSE) - re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]' - hasMagic = hasMagic || sp[1] - inClass = false - continue - } - } - - // finish up the class. - hasMagic = true - inClass = false - re += c - continue - - default: - // swallow any state char that wasn't consumed - clearStateChar() - - if (escaping) { - // no need - escaping = false - } else if (reSpecials[c] - && !(c === '^' && inClass)) { - re += '\\' - } - - re += c - - } // switch - } // for - - // handle the case where we left a class open. - // "[abc" is valid, equivalent to "\[abc" - if (inClass) { - // split where the last [ was, and escape it - // this is a huge pita. We now have to re-walk - // the contents of the would-be class to re-translate - // any characters that were passed through as-is - cs = pattern.substr(classStart + 1) - sp = this.parse(cs, SUBPARSE) - re = re.substr(0, reClassStart) + '\\[' + sp[0] - hasMagic = hasMagic || sp[1] - } - - // handle the case where we had a +( thing at the *end* - // of the pattern. - // each pattern list stack adds 3 chars, and we need to go through - // and escape any | chars that were passed through as-is for the regexp. - // Go through and escape them, taking care not to double-escape any - // | chars that were already escaped. - for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) { - var tail = re.slice(pl.reStart + pl.open.length) - this.debug('setting tail', re, pl) - // maybe some even number of \, then maybe 1 \, followed by a | - tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) { - if (!$2) { - // the | isn't already escaped, so escape it. - $2 = '\\' - } - - // need to escape all those slashes *again*, without escaping the - // one that we need for escaping the | character. As it works out, - // escaping an even number of slashes can be done by simply repeating - // it exactly after itself. That's why this trick works. - // - // I am sorry that you have to see this. - return $1 + $1 + $2 + '|' - }) - - this.debug('tail=%j\n %s', tail, tail, pl, re) - var t = pl.type === '*' ? star - : pl.type === '?' ? qmark - : '\\' + pl.type - - hasMagic = true - re = re.slice(0, pl.reStart) + t + '\\(' + tail - } - - // handle trailing things that only matter at the very end. - clearStateChar() - if (escaping) { - // trailing \\ - re += '\\\\' - } - - // only need to apply the nodot start if the re starts with - // something that could conceivably capture a dot - var addPatternStart = false - switch (re.charAt(0)) { - case '.': - case '[': - case '(': addPatternStart = true - } - - // Hack to work around lack of negative lookbehind in JS - // A pattern like: *.!(x).!(y|z) needs to ensure that a name - // like 'a.xyz.yz' doesn't match. So, the first negative - // lookahead, has to look ALL the way ahead, to the end of - // the pattern. - for (var n = negativeLists.length - 1; n > -1; n--) { - var nl = negativeLists[n] - - var nlBefore = re.slice(0, nl.reStart) - var nlFirst = re.slice(nl.reStart, nl.reEnd - 8) - var nlLast = re.slice(nl.reEnd - 8, nl.reEnd) - var nlAfter = re.slice(nl.reEnd) - - nlLast += nlAfter - - // Handle nested stuff like *(*.js|!(*.json)), where open parens - // mean that we should *not* include the ) in the bit that is considered - // "after" the negated section. - var openParensBefore = nlBefore.split('(').length - 1 - var cleanAfter = nlAfter - for (i = 0; i < openParensBefore; i++) { - cleanAfter = cleanAfter.replace(/\)[+*?]?/, '') - } - nlAfter = cleanAfter - - var dollar = '' - if (nlAfter === '' && isSub !== SUBPARSE) { - dollar = '$' - } - var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast - re = newRe - } - - // if the re is not "" at this point, then we need to make sure - // it doesn't match against an empty path part. - // Otherwise a/* will match a/, which it should not. - if (re !== '' && hasMagic) { - re = '(?=.)' + re - } - - if (addPatternStart) { - re = patternStart + re - } - - // parsing just a piece of a larger pattern. - if (isSub === SUBPARSE) { - return [re, hasMagic] - } - - // skip the regexp for non-magical patterns - // unescape anything in it, though, so that it'll be - // an exact match against a file etc. - if (!hasMagic) { - return globUnescape(pattern) - } - - var flags = options.nocase ? 'i' : '' - try { - var regExp = new RegExp('^' + re + '$', flags) - } catch (er) { - // If it was an invalid regular expression, then it can't match - // anything. This trick looks for a character after the end of - // the string, which is of course impossible, except in multi-line - // mode, but it's not a /m regex. - return new RegExp('$.') - } - - regExp._glob = pattern - regExp._src = re - - return regExp -} - -minimatch.makeRe = function (pattern, options) { - return new Minimatch(pattern, options || {}).makeRe() -} - -Minimatch.prototype.makeRe = makeRe -function makeRe () { - if (this.regexp || this.regexp === false) return this.regexp - - // at this point, this.set is a 2d array of partial - // pattern strings, or "**". - // - // It's better to use .match(). This function shouldn't - // be used, really, but it's pretty convenient sometimes, - // when you just want to work with a regex. - var set = this.set - - if (!set.length) { - this.regexp = false - return this.regexp - } - var options = this.options - - var twoStar = options.noglobstar ? star - : options.dot ? twoStarDot - : twoStarNoDot - var flags = options.nocase ? 'i' : '' - - var re = set.map(function (pattern) { - return pattern.map(function (p) { - return (p === GLOBSTAR) ? twoStar - : (typeof p === 'string') ? regExpEscape(p) - : p._src - }).join('\\\/') - }).join('|') - - // must match entire pattern - // ending in a * or ** will make it less strict. - re = '^(?:' + re + ')$' - - // can match anything, as long as it's not this. - if (this.negate) re = '^(?!' + re + ').*$' - - try { - this.regexp = new RegExp(re, flags) - } catch (ex) { - this.regexp = false - } - return this.regexp -} - -minimatch.match = function (list, pattern, options) { - options = options || {} - var mm = new Minimatch(pattern, options) - list = list.filter(function (f) { - return mm.match(f) - }) - if (mm.options.nonull && !list.length) { - list.push(pattern) - } - return list -} - -Minimatch.prototype.match = match -function match (f, partial) { - this.debug('match', f, this.pattern) - // short-circuit in the case of busted things. - // comments, etc. - if (this.comment) return false - if (this.empty) return f === '' - - if (f === '/' && partial) return true - - var options = this.options - - // windows: need to use /, not \ - if (path.sep !== '/') { - f = f.split(path.sep).join('/') - } - - // treat the test path as a set of pathparts. - f = f.split(slashSplit) - this.debug(this.pattern, 'split', f) - - // just ONE of the pattern sets in this.set needs to match - // in order for it to be valid. If negating, then just one - // match means that we have failed. - // Either way, return on the first hit. - - var set = this.set - this.debug(this.pattern, 'set', set) - - // Find the basename of the path by looking for the last non-empty segment - var filename - var i - for (i = f.length - 1; i >= 0; i--) { - filename = f[i] - if (filename) break - } - - for (i = 0; i < set.length; i++) { - var pattern = set[i] - var file = f - if (options.matchBase && pattern.length === 1) { - file = [filename] - } - var hit = this.matchOne(file, pattern, partial) - if (hit) { - if (options.flipNegate) return true - return !this.negate - } - } - - // didn't get any hits. this is success if it's a negative - // pattern, failure otherwise. - if (options.flipNegate) return false - return this.negate -} - -// set partial to true to test if, for example, -// "/a/b" matches the start of "/*/b/*/d" -// Partial means, if you run out of file before you run -// out of pattern, then that's fine, as long as all -// the parts match. -Minimatch.prototype.matchOne = function (file, pattern, partial) { - var options = this.options - - this.debug('matchOne', - { 'this': this, file: file, pattern: pattern }) - - this.debug('matchOne', file.length, pattern.length) - - for (var fi = 0, - pi = 0, - fl = file.length, - pl = pattern.length - ; (fi < fl) && (pi < pl) - ; fi++, pi++) { - this.debug('matchOne loop') - var p = pattern[pi] - var f = file[fi] - - this.debug(pattern, p, f) - - // should be impossible. - // some invalid regexp stuff in the set. - if (p === false) return false - - if (p === GLOBSTAR) { - this.debug('GLOBSTAR', [pattern, p, f]) - - // "**" - // a/**/b/**/c would match the following: - // a/b/x/y/z/c - // a/x/y/z/b/c - // a/b/x/b/x/c - // a/b/c - // To do this, take the rest of the pattern after - // the **, and see if it would match the file remainder. - // If so, return success. - // If not, the ** "swallows" a segment, and try again. - // This is recursively awful. - // - // a/**/b/**/c matching a/b/x/y/z/c - // - a matches a - // - doublestar - // - matchOne(b/x/y/z/c, b/**/c) - // - b matches b - // - doublestar - // - matchOne(x/y/z/c, c) -> no - // - matchOne(y/z/c, c) -> no - // - matchOne(z/c, c) -> no - // - matchOne(c, c) yes, hit - var fr = fi - var pr = pi + 1 - if (pr === pl) { - this.debug('** at the end') - // a ** at the end will just swallow the rest. - // We have found a match. - // however, it will not swallow /.x, unless - // options.dot is set. - // . and .. are *never* matched by **, for explosively - // exponential reasons. - for (; fi < fl; fi++) { - if (file[fi] === '.' || file[fi] === '..' || - (!options.dot && file[fi].charAt(0) === '.')) return false - } - return true - } - - // ok, let's see if we can swallow whatever we can. - while (fr < fl) { - var swallowee = file[fr] - - this.debug('\nglobstar while', file, fr, pattern, pr, swallowee) - - // XXX remove this slice. Just pass the start index. - if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { - this.debug('globstar found match!', fr, fl, swallowee) - // found a match. - return true - } else { - // can't swallow "." or ".." ever. - // can only swallow ".foo" when explicitly asked. - if (swallowee === '.' || swallowee === '..' || - (!options.dot && swallowee.charAt(0) === '.')) { - this.debug('dot detected!', file, fr, pattern, pr) - break - } - - // ** swallows a segment, and continue. - this.debug('globstar swallow a segment, and continue') - fr++ - } - } - - // no match was found. - // However, in partial mode, we can't say this is necessarily over. - // If there's more *pattern* left, then - if (partial) { - // ran out of file - this.debug('\n>>> no match, partial?', file, fr, pattern, pr) - if (fr === fl) return true - } - return false - } - - // something other than ** - // non-magic patterns just have to match exactly - // patterns with magic have been turned into regexps. - var hit - if (typeof p === 'string') { - if (options.nocase) { - hit = f.toLowerCase() === p.toLowerCase() - } else { - hit = f === p - } - this.debug('string match', p, f, hit) - } else { - hit = f.match(p) - this.debug('pattern match', p, f, hit) - } - - if (!hit) return false - } - - // Note: ending in / means that we'll get a final "" - // at the end of the pattern. This can only match a - // corresponding "" at the end of the file. - // If the file ends in /, then it can only match a - // a pattern that ends in /, unless the pattern just - // doesn't have any more for it. But, a/b/ should *not* - // match "a/b/*", even though "" matches against the - // [^/]*? pattern, except in partial mode, where it might - // simply not be reached yet. - // However, a/b/ should still satisfy a/* - - // now either we fell off the end of the pattern, or we're done. - if (fi === fl && pi === pl) { - // ran out of pattern and filename at the same time. - // an exact hit! - return true - } else if (fi === fl) { - // ran out of file, but still had pattern left. - // this is ok if we're doing the match as part of - // a glob fs traversal. - return partial - } else if (pi === pl) { - // ran out of pattern, still have file left. - // this is only acceptable if we're on the very last - // empty segment of a file with a trailing slash. - // a/* should match a/b/ - var emptyFileEnd = (fi === fl - 1) && (file[fi] === '') - return emptyFileEnd - } - - // should be unreachable. - throw new Error('wtf?') -} - -// replace stuff like \* with * -function globUnescape (s) { - return s.replace(/\\(.)/g, '$1') -} - -function regExpEscape (s) { - return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') -} diff --git a/src/vender/puread/plugin/pangu.min.js b/src/vender/puread/plugin/pangu.min.js deleted file mode 100644 index e8f4305b..00000000 --- a/src/vender/puread/plugin/pangu.min.js +++ /dev/null @@ -1,10 +0,0 @@ -/*! - * pangu.js - * -------- - * @version: 3.3.0 - * @homepage: https://github.com/vinta/pangu.js - * @license: MIT - * @author: Vinta Chen (https://github.com/vinta) - */ -!function(e,u){"object"==typeof exports&&"object"==typeof module?module.exports=u():"function"==typeof define&&define.amd?define("pangu",[],u):"object"==typeof exports?exports.pangu=u():e.pangu=u()}(this,function(){return function(e){function u(a){if(f[a])return f[a].exports;var t=f[a]={exports:{},id:a,loaded:!1};return e[a].call(t.exports,t,t.exports,u),t.loaded=!0,t.exports}var f={};return u.m=e,u.c=f,u.p="",u(0)}([function(e,u,f){"use strict";function a(e,u){if(!(e instanceof u))throw new TypeError("Cannot call a class as a function")}function t(e,u){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!u||"object"!=typeof u&&"function"!=typeof u?e:u}function n(e,u){if("function"!=typeof u&&null!==u)throw new TypeError("Super expression must either be null or a function, not "+typeof u);e.prototype=Object.create(u&&u.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),u&&(Object.setPrototypeOf?Object.setPrototypeOf(e,u):e.__proto__=u)}var i=function(){function e(e,u){for(var f=0;f=0||u.isContentEditable||"true"===u.getAttribute("g_editable"))return!0;u=u.parentNode}return!1}},{key:"isFirstTextChild",value:function(e,u){for(var f=e.childNodes,a=0;a-1;a--){var t=f[a];if(t.nodeType!==o&&t.textContent)return t===u}return!1}},{key:"spacingNodeByXPath",value:function(e,u){for(var f=document.evaluate(e,u,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null),a=void 0,t=void 0,n=f.snapshotLength-1;n>-1;--n)if(a=f.snapshotItem(n),this.canIgnoreNode(a))t=a;else{var i=this.spacing(a.data);if(a.data!==i&&(a.data=i),t){if(a.nextSibling&&a.nextSibling.nodeName.search(this.spaceLikeTags)>=0){t=a;continue}var r=a.data.toString().substr(-1)+t.data.toString().substr(0,1),o=this.spacing(r);if(o!==r){for(var s=t;s.parentNode&&s.nodeName.search(this.spaceSensitiveTags)===-1&&this.isFirstTextChild(s.parentNode,s);)s=s.parentNode;for(var c=a;c.parentNode&&c.nodeName.search(this.spaceSensitiveTags)===-1&&this.isLastTextChild(c.parentNode,c);)c=c.parentNode;if(c.nextSibling&&c.nextSibling.nodeName.search(this.spaceLikeTags)>=0){t=a;continue}if(c.nodeName.search(this.blockTags)===-1)if(s.nodeName.search(this.spaceSensitiveTags)===-1)s.nodeName.search(this.ignoreTags)===-1&&s.nodeName.search(this.blockTags)===-1&&(t.previousSibling?t.previousSibling.nodeName.search(this.spaceLikeTags)===-1&&(t.data=" "+t.data):this.canIgnoreNode(t)||(t.data=" "+t.data));else if(c.nodeName.search(this.spaceSensitiveTags)===-1)a.data=a.data+" ";else{var d=document.createElement("pangu");d.innerHTML=" ",s.previousSibling?s.previousSibling.nodeName.search(this.spaceLikeTags)===-1&&s.parentNode.insertBefore(d,s):s.parentNode.insertBefore(d,s),d.previousElementSibling||d.parentNode&&d.parentNode.removeChild(d)}}}t=a}}},{key:"spacingNode",value:function(e){var u=".//*/text()[normalize-space(.)]";this.spacingNodeByXPath(u,e)}},{key:"spacingElementById",value:function(e){var u='id("'+e+'")//text()';this.spacingNodeByXPath(u,document)}},{key:"spacingElementByClassName",value:function(e){var u='//*[contains(concat(" ", normalize-space(@class), " "), "'+e+'")]//text()';this.spacingNodeByXPath(u,document)}},{key:"spacingElementByTagName",value:function(e){var u="//"+e+"//text()";this.spacingNodeByXPath(u,document)}},{key:"spacingPageTitle",value:function(){var e="/html/head/title/text()";this.spacingNodeByXPath(e,document)}},{key:"spacingPageBody",value:function(){for(var e="/html/body//*/text()[normalize-space(.)]",u=["script","style","textarea"],f=0;f])([A-Za-z0-9])/g,p=/([A-Za-z0-9])([\+\-\*\/=&\\|<>])([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g,l=/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])([\(\[\{<\u201c]+(.*?)[\)\]\}>\u201d]+)([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g,g=/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])([\(\[\{<\u201c>])/g,h=/([\)\]\}>\u201d<])([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g,v=/([\(\[\{<\u201c]+)(\s*)(.+?)(\s*)([\)\]\}>\u201d]+)/,b=/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])([~!;:,\.\?\u2026])([A-Za-z0-9])/g,y=/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])([A-Za-z0-9`\$%\^&\*\-=\+\\\|\/@\u00a1-\u00ff\u2022\u2027\u2150-\u218f])/g,m=/([A-Za-z0-9`~\$%\^&\*\-=\+\\\|\/!;:,\.\?\u00a1-\u00ff\u2022\u2026\u2027\u2150-\u218f])([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g,$=function(){function e(){f(this,e)}return a(e,[{key:"spacing",value:function(e){var u=e;u=u.replace(t,"$1 $2"),u=u.replace(n,"$1 $2"),u=u.replace(i,"$1$3$5"),u=u.replace(r,"$1$3$4"),u=u.replace(o,"$1 $2$3$4 $5"),u=u.replace(s,"$1 $2"),u=u.replace(c,"$1 $3"),u=u.replace(d,"$1 $2 $3"),u=u.replace(p,"$1 $2 $3");var f=u,a=u.replace(l,"$1 $2 $4");return u=a,f===a&&(u=u.replace(g,"$1 $2"),u=u.replace(h,"$1 $2")),u=u.replace(v,"$1$3$5"),u=u.replace(b,"$1$2 $3"),u=u.replace(y,"$1 $2"),u=u.replace(m,"$1 $2")}},{key:"spacingText",value:function(e){var u=arguments.length<=1||void 0===arguments[1]?function(){}:arguments[1];try{var f=this.spacing(e);u(null,f)}catch(a){u(a)}}}]),e}(),N=new $;u=e.exports=N,u.Pangu=$}])}); -//# sourceMappingURL=pangu.min.js.map \ No newline at end of file diff --git a/src/vender/puread/plugin/readability.js b/src/vender/puread/plugin/readability.js deleted file mode 100644 index 3f6b9617..00000000 --- a/src/vender/puread/plugin/readability.js +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2010 Arc90 Inc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/*eslint-env es6:false*/ -/* - * Copyright (c) 2010 Arc90 Inc - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/* - * This code is heavily based on Arc90's readability.js (1.7.1) script - * available at: http://code.google.com/p/arc90labs-readability - */ -/** - * Public constructor. - * @param {HTMLDocument} doc The document to parse. - * @param {Object} options The options object. - */ -function Readability(a,b){if(b&&b.documentElement)a=b,b=arguments[2];else if(!a||!a.documentElement)throw new Error("First argument to Readability constructor should be a document object.");b=b||{},this._doc=a,this._articleTitle=null,this._articleByline=null,this._articleDir=null,this._articleSiteName=null,this._attempts=[],this._debug=!!b.debug,this._maxElemsToParse=b.maxElemsToParse||this.DEFAULT_MAX_ELEMS_TO_PARSE,this._nbTopCandidates=b.nbTopCandidates||this.DEFAULT_N_TOP_CANDIDATES,this._charThreshold=b.charThreshold||this.DEFAULT_CHAR_THRESHOLD,this._classesToPreserve=this.CLASSES_TO_PRESERVE.concat(b.classesToPreserve||[]),this._flags=this.FLAG_STRIP_UNLIKELYS|this.FLAG_WEIGHT_CLASSES|this.FLAG_CLEAN_CONDITIONALLY;var c;this._debug?(c=function(a){var c,d,b=a.nodeName+" ";return a.nodeType==a.TEXT_NODE?b+'("'+a.textContent+'")':(c=a.className&&"."+a.className.replace(/ /g,"."),d="",a.id?d="(#"+a.id+c+")":c&&(d="("+c+")"),b+d)},this.log=function(){var a,b;"undefined"!=typeof dump?(a=Array.prototype.map.call(arguments,function(a){return a&&a.nodeName?c(a):a}).join(" "),dump("Reader: (Readability) "+a+"\n")):"undefined"!=typeof console&&(b=["Reader: (Readability) "].concat(arguments),console.log.apply(console,b))}):this.log=function(){}}Readability.prototype={FLAG_STRIP_UNLIKELYS:1,FLAG_WEIGHT_CLASSES:2,FLAG_CLEAN_CONDITIONALLY:4,ELEMENT_NODE:1,TEXT_NODE:3,DEFAULT_MAX_ELEMS_TO_PARSE:0,DEFAULT_N_TOP_CANDIDATES:5,DEFAULT_TAGS_TO_SCORE:"section,h2,h3,h4,h5,h6,p,td,pre".toUpperCase().split(","),DEFAULT_CHAR_THRESHOLD:500,REGEXPS:{unlikelyCandidates:/-ad-|ai2html|banner|breadcrumbs|combx|comment|community|cover-wrap|disqus|extra|foot|gdpr|header|legends|menu|related|remark|replies|rss|shoutbox|sidebar|skyscraper|social|sponsor|supplemental|ad-break|agegate|pagination|pager|popup|yom-remote/i,okMaybeItsACandidate:/and|article|body|column|main|shadow/i,positive:/article|body|content|entry|hentry|h-entry|main|page|pagination|post|text|blog|story/i,negative:/hidden|^hid$| hid$| hid |^hid |banner|combx|comment|com-|contact|foot|footer|footnote|gdpr|masthead|media|meta|outbrain|promo|related|scroll|share|shoutbox|sidebar|skyscraper|sponsor|shopping|tags|tool|widget/i,extraneous:/print|archive|comment|discuss|e[\-]?mail|share|reply|all|login|sign|single|utility/i,byline:/byline|author|dateline|writtenby|p-author/i,replaceFonts:/<(\/?)font[^>]*>/gi,normalize:/\s{2,}/g,videos:/\/\/(www\.)?((dailymotion|youtube|youtube-nocookie|player\.vimeo|v\.qq)\.com|(archive|upload\.wikimedia)\.org|player\.twitch\.tv)/i,nextLink:/(next|weiter|continue|>([^\|]|$)|禄([^\|]|$))/i,prevLink:/(prev|earl|old|new|<|芦)/i,whitespace:/^\s*$/,hasContent:/\S$/},DIV_TO_P_ELEMS:["A","BLOCKQUOTE","DL","DIV","IMG","OL","P","PRE","TABLE","UL","SELECT"],ALTER_TO_DIV_EXCEPTIONS:["DIV","ARTICLE","SECTION","P"],PRESENTATIONAL_ATTRIBUTES:["align","background","bgcolor","border","cellpadding","cellspacing","frame","hspace","rules","style","valign","vspace"],DEPRECATED_SIZE_ATTRIBUTE_ELEMS:["TABLE","TH","TD","HR","PRE"],PHRASING_ELEMS:["ABBR","AUDIO","B","BDO","BR","BUTTON","CITE","CODE","DATA","DATALIST","DFN","EM","EMBED","I","IMG","INPUT","KBD","LABEL","MARK","MATH","METER","NOSCRIPT","OBJECT","OUTPUT","PROGRESS","Q","RUBY","SAMP","SCRIPT","SELECT","SMALL","SPAN","STRONG","SUB","SUP","TEXTAREA","TIME","VAR","WBR"],CLASSES_TO_PRESERVE:["page"],_postProcessContent:function(a){this._fixRelativeUris(a),this._cleanClasses(a)},_removeNodes:function(a,b){var c,d,e;for(c=a.length-1;c>=0;c--)d=a[c],e=d.parentNode,e&&(!b||b.call(this,d,c,a))&&e.removeChild(d)},_replaceNodeTags:function(a,b){var c,d;for(c=a.length-1;c>=0;c--)d=a[c],this._setNodeTag(d,b)},_forEachNode:function(a,b){Array.prototype.forEach.call(a,b,this)},_someNode:function(a,b){return Array.prototype.some.call(a,b,this)},_everyNode:function(a,b){return Array.prototype.every.call(a,b,this)},_concatNodeLists:function(){var a=Array.prototype.slice,b=a.call(arguments),c=b.map(function(b){return a.call(b)});return Array.prototype.concat.apply([],c)},_getAllNodesWithTag:function(a,b){return a.querySelectorAll?a.querySelectorAll(b.join(",")):[].concat.apply([],b.map(function(b){var c=a.getElementsByTagName(b);return Array.isArray(c)?c:Array.from(c)}))},_cleanClasses:function(a){var b=this._classesToPreserve,c=(a.getAttribute("class")||"").split(/\s+/).filter(function(a){return-1!=b.indexOf(a)}).join(" ");for(c?a.setAttribute("class",c):a.removeAttribute("class"),a=a.firstElementChild;a;a=a.nextElementSibling)this._cleanClasses(a)},_fixRelativeUris:function(a){function d(a){if(b==c&&"#"==a.charAt(0))return a;try{return new URL(a,b).href}catch(d){}return a}var f,b=this._doc.baseURI,c=this._doc.documentURI,e=this._getAllNodesWithTag(a,["a"]);this._forEachNode(e,function(a){var c,b=a.getAttribute("href");b&&(0===b.indexOf("javascript:")?(c=this._doc.createTextNode(a.textContent),a.parentNode.replaceChild(c,a)):a.setAttribute("href",d(b)))}),f=this._getAllNodesWithTag(a,["img"]),this._forEachNode(f,function(a){var b=a.getAttribute("src");b&&a.setAttribute("src",d(b))})},_getArticleTitle:function(){function f(a){return a.split(/\s+/).length}var e,g,h,i,j,k,a=this._doc,b="",c="";try{b=c=a.title.trim(),"string"!=typeof b&&(b=c=this._getInnerText(a.getElementsByTagName("title")[0]))}catch(d){}return e=!1,/ [\|\-\\\/>禄] /.test(b)?(e=/ [\\\/>禄] /.test(b),b=c.replace(/(.*)[\|\-\\\/>禄] .*/gi,"$1"),f(b)<3&&(b=c.replace(/[^\|\-\\\/>禄]*[\|\-\\\/>禄](.*)/gi,"$1"))):-1!==b.indexOf(": ")?(g=this._concatNodeLists(a.getElementsByTagName("h1"),a.getElementsByTagName("h2")),h=b.trim(),i=this._someNode(g,function(a){return a.textContent.trim()===h}),i||(b=c.substring(c.lastIndexOf(":")+1),f(b)<3?b=c.substring(c.indexOf(":")+1):f(c.substr(0,c.indexOf(":")))>5&&(b=c))):(b.length>150||b.length<15)&&(j=a.getElementsByTagName("h1"),1===j.length&&(b=this._getInnerText(j[0]))),b=b.trim().replace(this.REGEXPS.normalize," "),k=f(b),4>=k&&(!e||k!=f(c.replace(/[\|\-\\\/>禄]+/g,""))-1)&&(b=c),b},_prepDocument:function(){var a=this._doc;this._removeNodes(a.getElementsByTagName("style")),a.body&&this._replaceBrs(a.body),this._replaceNodeTags(a.getElementsByTagName("font"),"SPAN")},_nextElement:function(a){for(var b=a;b&&b.nodeType!=this.ELEMENT_NODE&&this.REGEXPS.whitespace.test(b.textContent);)b=b.nextSibling;return b},_replaceBrs:function(a){this._forEachNode(this._getAllNodesWithTag(a,["br"]),function(a){for(var d,e,f,g,b=a.nextSibling,c=!1;(b=this._nextElement(b))&&"BR"==b.tagName;)c=!0,d=b.nextSibling,b.parentNode.removeChild(b),b=d;if(c){for(e=this._doc.createElement("p"),a.parentNode.replaceChild(e,a),b=e.nextSibling;b&&("BR"!=b.tagName||(f=this._nextElement(b.nextSibling),!f||"BR"!=f.tagName))&&this._isPhrasingContent(b);)g=b.nextSibling,e.appendChild(b),b=g;for(;e.lastChild&&this._isWhitespace(e.lastChild);)e.removeChild(e.lastChild);"P"===e.parentNode.tagName&&this._setNodeTag(e.parentNode,"DIV")}})},_setNodeTag:function(a,b){var c,d;if(this.log("_setNodeTag",a,b),a.__JSDOMParser__)return a.localName=b.toLowerCase(),a.tagName=b.toUpperCase(),a;for(c=a.ownerDocument.createElement(b);a.firstChild;)c.appendChild(a.firstChild);for(a.parentNode.replaceChild(c,a),a.readability&&(c.readability=a.readability),d=0;d0?c[0].textContent.includes(this._articleTitle):this._articleTitle.includes(c[0].textContent),e&&this._clean(a,"h2"))),this._clean(a,"iframe"),this._clean(a,"input"),this._clean(a,"textarea"),this._clean(a,"select"),this._clean(a,"button"),this._cleanHeaders(a),this._cleanConditionally(a,"table"),this._cleanConditionally(a,"ul"),this._cleanConditionally(a,"div"),this._removeNodes(a.getElementsByTagName("p"),function(a){var b=a.getElementsByTagName("img").length,c=a.getElementsByTagName("embed").length,d=a.getElementsByTagName("object").length,e=a.getElementsByTagName("iframe").length,f=b+c+d+e;return 0===f&&!this._getInnerText(a,!1)}),this._forEachNode(this._getAllNodesWithTag(a,["br"]),function(a){var b=this._nextElement(a.nextSibling);b&&"P"==b.tagName&&a.parentNode.removeChild(a)}),this._forEachNode(this._getAllNodesWithTag(a,["table"]),function(a){var c,d,b=this._hasSingleTagInsideElement(a,"TBODY")?a.firstElementChild:a;this._hasSingleTagInsideElement(b,"TR")&&(c=b.firstElementChild,this._hasSingleTagInsideElement(c,"TD")&&(d=c.firstElementChild,d=this._setNodeTag(d,this._everyNode(d.childNodes,this._isPhrasingContent)?"P":"DIV"),a.parentNode.replaceChild(d,a)))})},_initializeNode:function(a){switch(a.readability={contentScore:0},a.tagName){case"DIV":a.readability.contentScore+=5;break;case"PRE":case"TD":case"BLOCKQUOTE":a.readability.contentScore+=3;break;case"ADDRESS":case"OL":case"UL":case"DL":case"DD":case"DT":case"LI":case"FORM":a.readability.contentScore-=3;break;case"H1":case"H2":case"H3":case"H4":case"H5":case"H6":case"TH":a.readability.contentScore-=5}a.readability.contentScore+=this._getClassWeight(a)},_removeAndGetNext:function(a){var b=this._getNextNode(a,!0);return a.parentNode.removeChild(a),b},_getNextNode:function(a,b){if(!b&&a.firstElementChild)return a.firstElementChild;if(a.nextElementSibling)return a.nextElementSibling;do a=a.parentNode;while(a&&!a.nextElementSibling);return a&&a.nextElementSibling},_checkByline:function(a,b){var c,d;return this._articleByline?!1:(void 0!==a.getAttribute&&(c=a.getAttribute("rel"),d=a.getAttribute("itemprop")),("author"===c||d&&-1!==d.indexOf("author")||this.REGEXPS.byline.test(b))&&this._isValidByline(a.textContent)?(this._articleByline=a.textContent.trim(),!0):!1)},_getNodeAncestors:function(a,b){b=b||0;for(var c=0,d=[];a.parentNode&&(d.push(a.parentNode),!b||++c!==b);)a=a.parentNode;return d},_grabArticle:function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V;if(this.log("**** grabArticle ****"),b=this._doc,c=null!==a?!0:!1,a=a?a:this._doc.body,!a)return this.log("No body found in document. Abort."),null;for(d=a.innerHTML;;){for(e=this._flagIsActive(this.FLAG_STRIP_UNLIKELYS),f=[],g=this._doc.documentElement;g;)if(h=g.className+" "+g.id,this._isProbablyVisible(g))if(this._checkByline(g,h))g=this._removeAndGetNext(g);else if(!e||!this.REGEXPS.unlikelyCandidates.test(h)||this.REGEXPS.okMaybeItsACandidate.test(h)||this._hasAncestorTag(g,"table")||"BODY"===g.tagName||"A"===g.tagName)if("DIV"!==g.tagName&&"SECTION"!==g.tagName&&"HEADER"!==g.tagName&&"H1"!==g.tagName&&"H2"!==g.tagName&&"H3"!==g.tagName&&"H4"!==g.tagName&&"H5"!==g.tagName&&"H6"!==g.tagName||!this._isElementWithoutContent(g)){if(-1!==this.DEFAULT_TAGS_TO_SCORE.indexOf(g.tagName)&&f.push(g),"DIV"===g.tagName){for(i=null,j=g.firstChild;j;){if(k=j.nextSibling,this._isPhrasingContent(j))null!==i?i.appendChild(j):this._isWhitespace(j)||(i=b.createElement("p"),g.replaceChild(i,j),i.appendChild(j));else if(null!==i){for(;i.lastChild&&this._isWhitespace(i.lastChild);)i.removeChild(i.lastChild);i=null}j=k}this._hasSingleTagInsideElement(g,"P")&&this._getLinkDensity(g)<.25?(l=g.children[0],g.parentNode.replaceChild(l,g),g=l,f.push(g)):this._hasChildBlockElement(g)||(g=this._setNodeTag(g,"P"),f.push(g))}g=this._getNextNode(g)}else g=this._removeAndGetNext(g);else this.log("Removing unlikely candidate - "+h),g=this._removeAndGetNext(g);else this.log("Removing hidden node - "+h),g=this._removeAndGetNext(g);for(m=[],this._forEachNode(f,function(a){var b,c,d;a.parentNode&&"undefined"!=typeof a.parentNode.tagName&&(b=this._getInnerText(a),b.length<25||(c=this._getNodeAncestors(a,3),0!==c.length&&(d=0,d+=1,d+=b.split(",").length,d+=Math.min(Math.floor(b.length/100),3),this._forEachNode(c,function(a,b){if(a.tagName&&a.parentNode&&"undefined"!=typeof a.parentNode.tagName){if("undefined"==typeof a.readability&&(this._initializeNode(a),m.push(a)),0===b)var c=1;else c=1===b?2:3*b;a.readability.contentScore+=d/c}}))))}),n=[],o=0,p=m.length;p>o;o+=1)for(q=m[o],r=q.readability.contentScore*(1-this._getLinkDensity(q)),q.readability.contentScore=r,this.log("Candidate:",q,"with score "+r),s=0;st.readability.contentScore){n.splice(s,0,q),n.length>this._nbTopCandidates&&n.pop();break}if(u=n[0]||null,v=!1,null===u||"BODY"===u.tagName){for(u=b.createElement("DIV"),v=!0,x=a.childNodes;x.length;)this.log("Moving child out:",x[0]),u.appendChild(x[0]);a.appendChild(u),this._initializeNode(u)}else if(u){for(y=[],z=1;z=.75&&y.push(this._getNodeAncestors(n[z]));if(A=3,y.length>=A)for(w=u.parentNode;"BODY"!==w.tagName;){for(B=0,C=0;CB;C++)B+=Number(y[C].includes(w));if(B>=A){u=w;break}w=w.parentNode}for(u.readability||this._initializeNode(u),w=u.parentNode,D=u.readability.contentScore,E=D/3;"BODY"!==w.tagName;)if(w.readability){if(F=w.readability.contentScore,E>F)break;if(F>D){u=w;break}D=w.readability.contentScore,w=w.parentNode}else w=w.parentNode;for(w=u.parentNode;"BODY"!=w.tagName&&1==w.children.length;)u=w,w=u.parentNode;u.readability||this._initializeNode(u)}for(G=b.createElement("DIV"),c&&(G.id="readability-content"),H=Math.max(10,.2*u.readability.contentScore),w=u.parentNode,I=w.children,J=0,K=I.length;K>J;J++)L=I[J],M=!1,this.log("Looking at sibling node:",L,L.readability?"with score "+L.readability.contentScore:""),this.log("Sibling has score",L.readability?L.readability.contentScore:"Unknown"),L===u?M=!0:(N=0,L.className===u.className&&""!==u.className&&(N+=.2*u.readability.contentScore),L.readability&&L.readability.contentScore+N>=H?M=!0:"P"===L.nodeName&&(O=this._getLinkDensity(L),P=this._getInnerText(L),Q=P.length,Q>80&&.25>O?M=!0:80>Q&&Q>0&&0===O&&-1!==P.search(/\.( |$)/)&&(M=!0))),M&&(this.log("Appending node:",L),-1===this.ALTER_TO_DIV_EXCEPTIONS.indexOf(L.nodeName)&&(this.log("Altering sibling:",L,"to div."),L=this._setNodeTag(L,"DIV")),G.appendChild(L),J-=1,K-=1);if(this._debug&&this.log("Article content pre-prep: "+G.innerHTML),this._prepArticle(G),this._debug&&this.log("Article content post-prep: "+G.innerHTML),v)u.id="readability-page-1",u.className="page";else{for(R=b.createElement("DIV"),R.id="readability-page-1",R.className="page",S=G.childNodes;S.length;)R.appendChild(S[0]);G.appendChild(R)}if(this._debug&&this.log("Article content after paging: "+G.innerHTML),T=!0,U=this._getInnerText(G,!0).length,U0&&a.length<100):!1},_getArticleMetadata:function(){var a={},b={},c=this._doc.getElementsByTagName("meta"),d=/\s*(dc|dcterm|og|twitter)\s*:\s*(author|creator|description|title|site_name)\s*/gi,e=/^\s*(?:(dc|dcterm|og|twitter|weibo:(article|webpage))\s*[\.:]\s*)?(author|creator|description|title|site_name)\s*$/i;return this._forEachNode(c,function(a){var h,i,j,c=a.getAttribute("name"),f=a.getAttribute("property"),g=a.getAttribute("content");if(g){if(h=null,i=null,f&&(h=f.match(d)))for(j=h.length-1;j>=0;j--)i=h[j].toLowerCase().replace(/\s/g,""),b[i]=g.trim();!h&&c&&e.test(c)&&(i=c,g&&(i=i.toLowerCase().replace(/\s/g,"").replace(/\./g,":"),b[i]=g.trim()))}}),a.title=b["dc:title"]||b["dcterm:title"]||b["og:title"]||b["weibo:article:title"]||b["weibo:webpage:title"]||b["title"]||b["twitter:title"],a.title||(a.title=this._getArticleTitle()),a.byline=b["dc:creator"]||b["dcterm:creator"]||b["author"],a.excerpt=b["dc:description"]||b["dcterm:description"]||b["og:description"]||b["weibo:article:description"]||b["weibo:webpage:description"]||b["description"]||b["twitter:description"],a.siteName=b["og:site_name"],a},_removeScripts:function(a){this._removeNodes(a.getElementsByTagName("script"),function(a){return a.nodeValue="",a.removeAttribute("src"),!0}),this._removeNodes(a.getElementsByTagName("noscript"))},_hasSingleTagInsideElement:function(a,b){return 1!=a.children.length||a.children[0].tagName!==b?!1:!this._someNode(a.childNodes,function(a){return a.nodeType===this.TEXT_NODE&&this.REGEXPS.hasContent.test(a.textContent)})},_isElementWithoutContent:function(a){return a.nodeType===this.ELEMENT_NODE&&0==a.textContent.trim().length&&(0==a.children.length||a.children.length==a.getElementsByTagName("br").length+a.getElementsByTagName("hr").length)},_hasChildBlockElement:function(a){return this._someNode(a.childNodes,function(a){return-1!==this.DIV_TO_P_ELEMS.indexOf(a.tagName)||this._hasChildBlockElement(a)})},_isPhrasingContent:function(a){return a.nodeType===this.TEXT_NODE||-1!==this.PHRASING_ELEMS.indexOf(a.tagName)||("A"===a.tagName||"DEL"===a.tagName||"INS"===a.tagName)&&this._everyNode(a.childNodes,this._isPhrasingContent)},_isWhitespace:function(a){return a.nodeType===this.TEXT_NODE&&0===a.textContent.trim().length||a.nodeType===this.ELEMENT_NODE&&"BR"===a.tagName},_getInnerText:function(a,b){b="undefined"==typeof b?!0:b;var c=a.textContent.trim();return b?c.replace(this.REGEXPS.normalize," "):c},_getCharCount:function(a,b){return b=b||",",this._getInnerText(a).split(b).length-1},_cleanStyles:function(a){var b,c;if(a&&"svg"!==a.tagName.toLowerCase()){for(b=0;b0&&e>c)return!1;if(a.parentNode.tagName===b&&(!d||d(a.parentNode)))return!0;a=a.parentNode,e++}return!1},_getRowAndColumnCount:function(a){var e,f,g,h,i,j,b=0,c=0,d=a.getElementsByTagName("tr");for(e=0;e0?d._readabilityDataTable=!0:(i=["col","colgroup","tfoot","thead","th"],j=function(a){return!!d.getElementsByTagName(a)[0]},i.some(j)?(this.log("Data table because found data-y descendant"),d._readabilityDataTable=!0):d.getElementsByTagName("table")[0]?d._readabilityDataTable=!1:(k=this._getRowAndColumnCount(d),d._readabilityDataTable=k.rows>=10||k.columns>4?!0:k.rows*k.columns>10)))):d._readabilityDataTable=!1):d._readabilityDataTable=!1},_cleanConditionally:function(a,b){if(this._flagIsActive(this.FLAG_CLEAN_CONDITIONALLY)){var c="ul"===b||"ol"===b;this._removeNodes(a.getElementsByTagName(b),function(a){var e,f,g,h,i,j,k,l,m,n,o,p,q,d=function(a){return a._readabilityDataTable};if("table"===b&&d(a))return!1;if(this._hasAncestorTag(a,"table",-1,d))return!1;if(e=this._getClassWeight(a),f=0,this.log("Cleaning Conditionally",a),0>e+f)return!0;if(this._getCharCount(a,",")<10){for(g=a.getElementsByTagName("p").length,h=a.getElementsByTagName("img").length,i=a.getElementsByTagName("li").length-100,j=a.getElementsByTagName("input").length,k=0,l=this._concatNodeLists(a.getElementsByTagName("object"),a.getElementsByTagName("embed"),a.getElementsByTagName("iframe")),m=0;m1&&.5>g/h&&!this._hasAncestorTag(a,"figure")||!c&&i>g||j>Math.floor(g/3)||!c&&25>p&&(0===h||h>2)&&!this._hasAncestorTag(a,"figure")||!c&&25>e&&o>.2||e>=25&&o>.5||1===k&&75>p||k>1}return!1})}},_cleanMatchedNodes:function(a,b){for(var c=this._getNextNode(a,!0),d=this._getNextNode(a);d&&d!=c;)d=b(d,d.className+" "+d.id)?this._removeAndGetNext(d):this._getNextNode(d)},_cleanHeaders:function(a){for(var b=1;3>b;b+=1)this._removeNodes(a.getElementsByTagName("h"+b),function(a){return this._getClassWeight(a)<0})},_flagIsActive:function(a){return(this._flags&a)>0},_removeFlag:function(a){this._flags=this._flags&~a},_isProbablyVisible:function(a){return!(a.style&&"none"==a.style.display||a.hasAttribute("hidden"))},parse:function(){var a,b,c,d,e;if(this._maxElemsToParse>0&&(a=this._doc.getElementsByTagName("*").length,a>this._maxElemsToParse))throw new Error("Aborting parsing document; "+a+" elements found");return this._removeScripts(this._doc),this._prepDocument(),b=this._getArticleMetadata(),this._articleTitle=b.title,(c=this._grabArticle())?(this.log("Grabbed: "+c.innerHTML),this._postProcessContent(c),b.excerpt||(d=c.getElementsByTagName("p"),d.length>0&&(b.excerpt=d[0].textContent.trim())),e=c.textContent,{title:this._articleTitle,byline:b.byline||this._articleByline,dir:this._articleDir,content:c.innerHTML,textContent:e,length:e.length,excerpt:b.excerpt,siteName:b.siteName||this._articleSiteName}):null}}; - -export { - Readability as Readability -} \ No newline at end of file diff --git a/src/vender/puread/plugin/stylesheet.js b/src/vender/puread/plugin/stylesheet.js deleted file mode 100644 index 970f5769..00000000 --- a/src/vender/puread/plugin/stylesheet.js +++ /dev/null @@ -1,198 +0,0 @@ -console.log( "=== PureRead: StyleSheet load ===" ) - -const [ bgcolorstyl, bgcls ] = [ "background-color", ".simpread-focus-root" ]; -let origin_read_style = "", html_style_bal = "-1"; - -/** - * Get background color value for focus mode - * - * @param {string} background-color, e.g. rgba(235, 235, 235, 0.901961) - * @return {string} e.g. 235, 235, 235 - */ -function getColor( value ) { - const arr = value ? value.match( /[0-9]+, /ig ) : []; - if ( arr.length > 0 ) { - return arr.join( "" ).replace( /, $/, "" ); - } else { - return null; - } -}; - -/** - * Set focus mode background color for focus mode - * - * @param {string} background color - * @param {number} background opacity - * @return {string} new background color - */ -function backgroundColor( bgcolor, opacity ) { - const color = getColor( bgcolor ), - newval = `rgba(${color}, ${opacity / 100})`; - $( bgcls ).css( bgcolorstyl, newval ); - return newval; -} - -/** - * Set background opacity for focus mode - * - * @param {string} opacity - * @return {string} new background color or null - */ -function opacity( opacity ) { - const bgcolor = $( bgcls ).css( bgcolorstyl ), - color = getColor( bgcolor ), - newval = `rgba(${color}, ${opacity / 100})`; - if ( color ) { - $( bgcls ).css( bgcolorstyl, newval ); - return newval; - } else { - return null; - } -} - -/** - * Set read mode font family for read mode - * - * @param {string} font family name e.g. PingFang SC; Microsoft Yahei - */ -function fontFamily( family ) { - $( "sr-read" ).css( "font-family", family == "default" ? "" : family ); -} - -/** - * Set read mode font size for read mode - * - * @param {string} font size, e.g. 70% 62.5% - */ -function fontSize( value ) { - if ( html_style_bal == "-1" ) { - html_style_bal = $( "html" ).attr( "style" ); - html_style_bal == undefined && ( html_style_bal = "" ); - } - value ? $( "html" ).attr( "style", `font-size: ${value}!important;${html_style_bal}` ) : $( "html" ).attr( "style", html_style_bal ); -} - -/** - * Set read mode layout width for read mode - * - * @param {string} layout width - */ -function layout( width ) { - $( "sr-read" ).css( "margin", width ? `20px ${width}` : "" ); -} - -/** - * Add custom css to for read mode - * - * @param {string} read.custom[type] - * @param {object} read.custom - */ -function custom( type, props ) { - const format = ( name ) => { - return name.replace( /[A-Z]/, name => { return `-${name.toLowerCase()}` } ); - }, - arr = Object.keys( props ).map( v => { - return props[v] && `${format( v )}: ${ props[v] };` - }); - let styles = arr.join( "" ); - switch ( type ) { - case "title": - styles = `sr-rd-title {${styles}}`; - break; - case "desc": - styles = `sr-rd-desc {${styles}}`; - break; - case "art": - styles = `sr-rd-content *, sr-rd-content p, sr-rd-content div {${styles}}`; - break; - case "pre": - styles = `sr-rd-content pre {${styles}}`; - break; - case "code": - styles = `sr-rd-content pre code, sr-rd-content pre code * {${styles}}`; - break; - } - - const $target = $( "head" ).find( `style#simpread-custom-${type}` ); - if ( $target.length == 0 ) { - $( "head" ).append(``); - } else { - $target.html( styles ); - } - -} - -/** - * Add css to for read mode - * - * @param {string} read.custom.css - * @param {object} read.custom.css value - */ -function css( type, styles ) { - const $target = $( "head" ).find( `style#simpread-custom-${type}` ); - if ( $target.length == 0 ) { - $( "head" ).append(``); - } else { - $target.html( styles ); - } -} - -/** - * Add/Remove current site styles( string ) to head for read mdoe - * - * @param {string} styles - */ -function siteCSS( styles ) { - styles ? $( "head" ).append(``) : - $( "#simpread-site-css" ).remove(); -} - -/** - * Add custom to .preview tag - * - * @param {object} read.custom - * @param {string} theme backgroud color - */ -function preview( styles ) { - Object.keys( styles ).forEach( v => { - v != "css" && custom( v, styles[v] ); - }); - css( "css", styles["css"] ); -} - -/** - * Verify custom is exist - * - * @param {string} verify type - * @param {object} read.custom value - */ -function vfyCustom( type, styles ) { - switch( type ) { - case "layout": - case "margin": - case "fontfamily": - case "custom": - return styles.css != ""; - case "fontsize": - return styles.title.fontSize != "" || - styles.desc.fontSize != "" || - styles.art.fontSize != "" || - styles.css != ""; - case "theme": - return styles.css.search( "simpread-theme-root" ) != -1; - } -} - -export { - getColor as GetColor, - backgroundColor as BgColor, - opacity as Opacity, - fontFamily as FontFamily, - fontSize as FontSize, - layout as Layout, - siteCSS as SiteCSS, - preview as Preview, - custom as Custom, - css as CSS, - vfyCustom as VerifyCustom, -} \ No newline at end of file diff --git a/src/vender/puread/puplugin.min.js b/src/vender/puread/puplugin.min.js new file mode 100644 index 00000000..e01ece2f --- /dev/null +++ b/src/vender/puread/puplugin.min.js @@ -0,0 +1,3424 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (factory((global.puplugin = {}))); +}(this, (function (exports) { 'use strict'; + + var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + + function createCommonjsModule(fn, module) { + return module = { exports: {} }, fn(module, module.exports), module.exports; + } + + var _typeof = 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 pangu_min = createCommonjsModule(function (module, exports) { + /*! + * pangu.js + * -------- + * @version: 3.3.0 + * @homepage: https://github.com/vinta/pangu.js + * @license: MIT + * @author: Vinta Chen (https://github.com/vinta) + */ + !function (e, u) { + module.exports = u(); + }(commonjsGlobal, function () { + return function (e) { + function u(a) { + if (f[a]) return f[a].exports;var t = f[a] = { exports: {}, id: a, loaded: !1 };return e[a].call(t.exports, t, t.exports, u), t.loaded = !0, t.exports; + }var f = {};return u.m = e, u.c = f, u.p = "", u(0); + }([function (e, u, f) { + function a(e, u) { + if (!(e instanceof u)) throw new TypeError("Cannot call a class as a function"); + }function t(e, u) { + if (!e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return !u || "object" != (typeof u === 'undefined' ? 'undefined' : _typeof(u)) && "function" != typeof u ? e : u; + }function n(e, u) { + if ("function" != typeof u && null !== u) throw new TypeError("Super expression must either be null or a function, not " + (typeof u === 'undefined' ? 'undefined' : _typeof(u)));e.prototype = Object.create(u && u.prototype, { constructor: { value: e, enumerable: !1, writable: !0, configurable: !0 } }), u && (Object.setPrototypeOf ? Object.setPrototypeOf(e, u) : e.__proto__ = u); + }var i = function () { + function e(e, u) { + for (var f = 0; f < u.length; f++) { + var a = u[f];a.enumerable = a.enumerable || !1, a.configurable = !0, "value" in a && (a.writable = !0), Object.defineProperty(e, a.key, a); + } + }return function (u, f, a) { + return f && e(u.prototype, f), a && e(u, a), u; + }; + }(), + r = f(1).Pangu, + o = 8, + s = function (e) { + function u() { + a(this, u);var e = t(this, Object.getPrototypeOf(u).call(this));return e.topTags = /^(html|head|body|#document)$/i, e.ignoreTags = /^(script|code|pre|textarea)$/i, e.spaceSensitiveTags = /^(a|del|pre|s|strike|u)$/i, e.spaceLikeTags = /^(br|hr|i|img|pangu)$/i, e.blockTags = /^(div|h1|h2|h3|h4|h5|h6|p)$/i, e; + }return n(u, e), i(u, [{ key: "canIgnoreNode", value: function value(e) { + for (var u = e.parentNode; u && u.nodeName && u.nodeName.search(this.topTags) === -1;) { + if (u.nodeName.search(this.ignoreTags) >= 0 || u.isContentEditable || "true" === u.getAttribute("g_editable")) return !0;u = u.parentNode; + }return !1; + } }, { key: "isFirstTextChild", value: function value(e, u) { + for (var f = e.childNodes, a = 0; a < f.length; a++) { + var t = f[a];if (t.nodeType !== o && t.textContent) return t === u; + }return !1; + } }, { key: "isLastTextChild", value: function value(e, u) { + for (var f = e.childNodes, a = f.length - 1; a > -1; a--) { + var t = f[a];if (t.nodeType !== o && t.textContent) return t === u; + }return !1; + } }, { key: "spacingNodeByXPath", value: function value(e, u) { + for (var f = document.evaluate(e, u, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null), a = void 0, t = void 0, n = f.snapshotLength - 1; n > -1; --n) { + if (a = f.snapshotItem(n), this.canIgnoreNode(a)) t = a;else { + var i = this.spacing(a.data);if (a.data !== i && (a.data = i), t) { + if (a.nextSibling && a.nextSibling.nodeName.search(this.spaceLikeTags) >= 0) { + t = a;continue; + }var r = a.data.toString().substr(-1) + t.data.toString().substr(0, 1), + o = this.spacing(r);if (o !== r) { + for (var s = t; s.parentNode && s.nodeName.search(this.spaceSensitiveTags) === -1 && this.isFirstTextChild(s.parentNode, s);) { + s = s.parentNode; + }for (var c = a; c.parentNode && c.nodeName.search(this.spaceSensitiveTags) === -1 && this.isLastTextChild(c.parentNode, c);) { + c = c.parentNode; + }if (c.nextSibling && c.nextSibling.nodeName.search(this.spaceLikeTags) >= 0) { + t = a;continue; + }if (c.nodeName.search(this.blockTags) === -1) if (s.nodeName.search(this.spaceSensitiveTags) === -1) s.nodeName.search(this.ignoreTags) === -1 && s.nodeName.search(this.blockTags) === -1 && (t.previousSibling ? t.previousSibling.nodeName.search(this.spaceLikeTags) === -1 && (t.data = " " + t.data) : this.canIgnoreNode(t) || (t.data = " " + t.data));else if (c.nodeName.search(this.spaceSensitiveTags) === -1) a.data = a.data + " ";else { + var d = document.createElement("pangu");d.innerHTML = " ", s.previousSibling ? s.previousSibling.nodeName.search(this.spaceLikeTags) === -1 && s.parentNode.insertBefore(d, s) : s.parentNode.insertBefore(d, s), d.previousElementSibling || d.parentNode && d.parentNode.removeChild(d); + } + } + }t = a; + } + } + } }, { key: "spacingNode", value: function value(e) { + var u = ".//*/text()[normalize-space(.)]";this.spacingNodeByXPath(u, e); + } }, { key: "spacingElementById", value: function value(e) { + var u = 'id("' + e + '")//text()';this.spacingNodeByXPath(u, document); + } }, { key: "spacingElementByClassName", value: function value(e) { + var u = '//*[contains(concat(" ", normalize-space(@class), " "), "' + e + '")]//text()';this.spacingNodeByXPath(u, document); + } }, { key: "spacingElementByTagName", value: function value(e) { + var u = "//" + e + "//text()";this.spacingNodeByXPath(u, document); + } }, { key: "spacingPageTitle", value: function value() { + var e = "/html/head/title/text()";this.spacingNodeByXPath(e, document); + } }, { key: "spacingPageBody", value: function value() { + for (var e = "/html/body//*/text()[normalize-space(.)]", u = ["script", "style", "textarea"], f = 0; f < u.length; f++) { + var a = u[f];e += '[translate(name(..),"ABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwxyz")!="' + a + '"]'; + }this.spacingNodeByXPath(e, document); + } }, { key: "spacingPage", value: function value() { + this.spacingPageTitle(), this.spacingPageBody(); + } }]), u; + }(r), + c = new s();u = e.exports = c, u.Pangu = s; + }, function (e, u) { + function f(e, u) { + if (!(e instanceof u)) throw new TypeError("Cannot call a class as a function"); + }var a = function () { + function e(e, u) { + for (var f = 0; f < u.length; f++) { + var a = u[f];a.enumerable = a.enumerable || !1, a.configurable = !0, "value" in a && (a.writable = !0), Object.defineProperty(e, a.key, a); + } + }return function (u, f, a) { + return f && e(u.prototype, f), a && e(u, a), u; + }; + }(), + t = /([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])(["])/g, + n = /(["])([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g, + i = /(["']+)(\s*)(.+?)(\s*)(["']+)/g, + r = /([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])( )(')([A-Za-z])/g, + o = /([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])(#)([A-Za-z0-9\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff]+)(#)([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g, + s = /([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])(#([^ ]))/g, + c = /(([^ ])#)([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g, + d = /([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])([\+\-\*\/=&\\|<>])([A-Za-z0-9])/g, + p = /([A-Za-z0-9])([\+\-\*\/=&\\|<>])([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g, + l = /([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])([\(\[\{<\u201c]+(.*?)[\)\]\}>\u201d]+)([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g, + g = /([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])([\(\[\{<\u201c>])/g, + h = /([\)\]\}>\u201d<])([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g, + v = /([\(\[\{<\u201c]+)(\s*)(.+?)(\s*)([\)\]\}>\u201d]+)/, + b = /([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])([~!;:,\.\?\u2026])([A-Za-z0-9])/g, + y = /([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])([A-Za-z0-9`\$%\^&\*\-=\+\\\|\/@\u00a1-\u00ff\u2022\u2027\u2150-\u218f])/g, + m = /([A-Za-z0-9`~\$%\^&\*\-=\+\\\|\/!;:,\.\?\u00a1-\u00ff\u2022\u2026\u2027\u2150-\u218f])([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g, + $ = function () { + function e() { + f(this, e); + }return a(e, [{ key: "spacing", value: function value(e) { + var u = e;u = u.replace(t, "$1 $2"), u = u.replace(n, "$1 $2"), u = u.replace(i, "$1$3$5"), u = u.replace(r, "$1$3$4"), u = u.replace(o, "$1 $2$3$4 $5"), u = u.replace(s, "$1 $2"), u = u.replace(c, "$1 $3"), u = u.replace(d, "$1 $2 $3"), u = u.replace(p, "$1 $2 $3");var f = u, + a = u.replace(l, "$1 $2 $4");return u = a, f === a && (u = u.replace(g, "$1 $2"), u = u.replace(h, "$1 $2")), u = u.replace(v, "$1$3$5"), u = u.replace(b, "$1$2 $3"), u = u.replace(y, "$1 $2"), u = u.replace(m, "$1 $2"); + } }, { key: "spacingText", value: function value(e) { + var u = arguments.length <= 1 || void 0 === arguments[1] ? function () {} : arguments[1];try { + var f = this.spacing(e);u(null, f); + } catch (a) { + u(a); + } + } }]), e; + }(), + N = new $();u = e.exports = N, u.Pangu = $; + }]); + }); + + }); + var pangu_min_1 = pangu_min.pangu; + + // Copyright Joyent, Inc. and other Node contributors. + // + // Permission is hereby granted, free of charge, to any person obtaining a + // copy of this software and associated documentation files (the + // "Software"), to deal in the Software without restriction, including + // without limitation the rights to use, copy, modify, merge, publish, + // distribute, sublicense, and/or sell copies of the Software, and to permit + // persons to whom the Software is furnished to do so, subject to the + // following conditions: + // + // The above copyright notice and this permission notice shall be included + // in all copies or substantial portions of the Software. + // + // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + // USE OR OTHER DEALINGS IN THE SOFTWARE. + + // resolves . and .. elements in a path array with directory names there + // must be no slashes, empty elements, or device names (c:\) in the array + // (so also no leading and trailing slashes - it does not distinguish + // relative and absolute paths) + function normalizeArray(parts, allowAboveRoot) { + // if the path tries to go above the root, `up` ends up > 0 + var up = 0; + for (var i = parts.length - 1; i >= 0; i--) { + var last = parts[i]; + if (last === '.') { + parts.splice(i, 1); + } else if (last === '..') { + parts.splice(i, 1); + up++; + } else if (up) { + parts.splice(i, 1); + up--; + } + } + + // if the path is allowed to go above the root, restore leading ..s + if (allowAboveRoot) { + for (; up--; up) { + parts.unshift('..'); + } + } + + return parts; + } + + // Split a filename into [root, dir, basename, ext], unix version + // 'root' is just a slash, or nothing. + var splitPathRe = + /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; + var splitPath = function(filename) { + return splitPathRe.exec(filename).slice(1); + }; + + // path.resolve([from ...], to) + // posix version + function resolve() { + var resolvedPath = '', + resolvedAbsolute = false; + + for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { + var path = (i >= 0) ? arguments[i] : '/'; + + // Skip empty and invalid entries + if (typeof path !== 'string') { + throw new TypeError('Arguments to path.resolve must be strings'); + } else if (!path) { + continue; + } + + resolvedPath = path + '/' + resolvedPath; + resolvedAbsolute = path.charAt(0) === '/'; + } + + // At this point the path should be resolved to a full absolute path, but + // handle relative paths to be safe (might happen when process.cwd() fails) + + // Normalize the path + resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) { + return !!p; + }), !resolvedAbsolute).join('/'); + + return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; + } + // path.normalize(path) + // posix version + function normalize(path) { + var isPathAbsolute = isAbsolute(path), + trailingSlash = substr(path, -1) === '/'; + + // Normalize the path + path = normalizeArray(filter(path.split('/'), function(p) { + return !!p; + }), !isPathAbsolute).join('/'); + + if (!path && !isPathAbsolute) { + path = '.'; + } + if (path && trailingSlash) { + path += '/'; + } + + return (isPathAbsolute ? '/' : '') + path; + } + // posix version + function isAbsolute(path) { + return path.charAt(0) === '/'; + } + + // posix version + function join() { + var paths = Array.prototype.slice.call(arguments, 0); + return normalize(filter(paths, function(p, index) { + if (typeof p !== 'string') { + throw new TypeError('Arguments to path.join must be strings'); + } + return p; + }).join('/')); + } + + + // path.relative(from, to) + // posix version + function relative(from, to) { + from = resolve(from).substr(1); + to = resolve(to).substr(1); + + function trim(arr) { + var start = 0; + for (; start < arr.length; start++) { + if (arr[start] !== '') break; + } + + var end = arr.length - 1; + for (; end >= 0; end--) { + if (arr[end] !== '') break; + } + + if (start > end) return []; + return arr.slice(start, end - start + 1); + } + + var fromParts = trim(from.split('/')); + var toParts = trim(to.split('/')); + + var length = Math.min(fromParts.length, toParts.length); + var samePartsLength = length; + for (var i = 0; i < length; i++) { + if (fromParts[i] !== toParts[i]) { + samePartsLength = i; + break; + } + } + + var outputParts = []; + for (var i = samePartsLength; i < fromParts.length; i++) { + outputParts.push('..'); + } + + outputParts = outputParts.concat(toParts.slice(samePartsLength)); + + return outputParts.join('/'); + } + + var sep = '/'; + var delimiter = ':'; + + function dirname(path) { + var result = splitPath(path), + root = result[0], + dir = result[1]; + + if (!root && !dir) { + // No dirname whatsoever + return '.'; + } + + if (dir) { + // It has a dirname, strip trailing slash + dir = dir.substr(0, dir.length - 1); + } + + return root + dir; + } + + function basename(path, ext) { + var f = splitPath(path)[2]; + // TODO: make this comparison case-insensitive on windows? + if (ext && f.substr(-1 * ext.length) === ext) { + f = f.substr(0, f.length - ext.length); + } + return f; + } + + + function extname(path) { + return splitPath(path)[3]; + } + var path = { + extname: extname, + basename: basename, + dirname: dirname, + sep: sep, + delimiter: delimiter, + relative: relative, + join: join, + isAbsolute: isAbsolute, + normalize: normalize, + resolve: resolve + }; + function filter (xs, f) { + if (xs.filter) return xs.filter(f); + var res = []; + for (var i = 0; i < xs.length; i++) { + if (f(xs[i], i, xs)) res.push(xs[i]); + } + return res; + } + + // String.prototype.substr - negative index don't work in IE8 + var substr = 'ab'.substr(-1) === 'b' ? + function (str, start, len) { return str.substr(start, len) } : + function (str, start, len) { + if (start < 0) start = str.length + start; + return str.substr(start, len); + } + ; + + var path$1 = /*#__PURE__*/Object.freeze({ + resolve: resolve, + normalize: normalize, + isAbsolute: isAbsolute, + join: join, + relative: relative, + sep: sep, + delimiter: delimiter, + dirname: dirname, + basename: basename, + extname: extname, + default: path + }); + + var concatMap = function (xs, fn) { + var res = []; + for (var i = 0; i < xs.length; i++) { + var x = fn(xs[i], i); + if (isArray(x)) res.push.apply(res, x); + else res.push(x); + } + return res; + }; + + var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; + }; + + var balancedMatch = balanced; + function balanced(a, b, str) { + if (a instanceof RegExp) a = maybeMatch(a, str); + if (b instanceof RegExp) b = maybeMatch(b, str); + + var r = range(a, b, str); + + return r && { + start: r[0], + end: r[1], + pre: str.slice(0, r[0]), + body: str.slice(r[0] + a.length, r[1]), + post: str.slice(r[1] + b.length) + }; + } + + function maybeMatch(reg, str) { + var m = str.match(reg); + return m ? m[0] : null; + } + + balanced.range = range; + function range(a, b, str) { + var begs, beg, left, right, result; + var ai = str.indexOf(a); + var bi = str.indexOf(b, ai + 1); + var i = ai; + + if (ai >= 0 && bi > 0) { + begs = []; + left = str.length; + + while (i >= 0 && !result) { + if (i == ai) { + begs.push(i); + ai = str.indexOf(a, i + 1); + } else if (begs.length == 1) { + result = [ begs.pop(), bi ]; + } else { + beg = begs.pop(); + if (beg < left) { + left = beg; + right = bi; + } + + bi = str.indexOf(b, i + 1); + } + + i = ai < bi && ai >= 0 ? ai : bi; + } + + if (begs.length) { + result = [ left, right ]; + } + } + + return result; + } + + var braceExpansion = expandTop; + + var escSlash = '\0SLASH'+Math.random()+'\0'; + var escOpen = '\0OPEN'+Math.random()+'\0'; + var escClose = '\0CLOSE'+Math.random()+'\0'; + var escComma = '\0COMMA'+Math.random()+'\0'; + var escPeriod = '\0PERIOD'+Math.random()+'\0'; + + function numeric(str) { + return parseInt(str, 10) == str + ? parseInt(str, 10) + : str.charCodeAt(0); + } + + function escapeBraces(str) { + return str.split('\\\\').join(escSlash) + .split('\\{').join(escOpen) + .split('\\}').join(escClose) + .split('\\,').join(escComma) + .split('\\.').join(escPeriod); + } + + function unescapeBraces(str) { + return str.split(escSlash).join('\\') + .split(escOpen).join('{') + .split(escClose).join('}') + .split(escComma).join(',') + .split(escPeriod).join('.'); + } + + + // Basically just str.split(","), but handling cases + // where we have nested braced sections, which should be + // treated as individual members, like {a,{b,c},d} + function parseCommaParts(str) { + if (!str) + return ['']; + + var parts = []; + var m = balancedMatch('{', '}', str); + + if (!m) + return str.split(','); + + var pre = m.pre; + var body = m.body; + var post = m.post; + var p = pre.split(','); + + p[p.length-1] += '{' + body + '}'; + var postParts = parseCommaParts(post); + if (post.length) { + p[p.length-1] += postParts.shift(); + p.push.apply(p, postParts); + } + + parts.push.apply(parts, p); + + return parts; + } + + function expandTop(str) { + if (!str) + return []; + + // I don't know why Bash 4.3 does this, but it does. + // Anything starting with {} will have the first two bytes preserved + // but *only* at the top level, so {},a}b will not expand to anything, + // but a{},b}c will be expanded to [a}c,abc]. + // One could argue that this is a bug in Bash, but since the goal of + // this module is to match Bash's rules, we escape a leading {} + if (str.substr(0, 2) === '{}') { + str = '\\{\\}' + str.substr(2); + } + + return expand(escapeBraces(str), true).map(unescapeBraces); + } + + function embrace(str) { + return '{' + str + '}'; + } + function isPadded(el) { + return /^-?0\d/.test(el); + } + + function lte(i, y) { + return i <= y; + } + function gte(i, y) { + return i >= y; + } + + function expand(str, isTop) { + var expansions = []; + + var m = balancedMatch('{', '}', str); + if (!m || /\$$/.test(m.pre)) return [str]; + + var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); + var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); + var isSequence = isNumericSequence || isAlphaSequence; + var isOptions = m.body.indexOf(',') >= 0; + if (!isSequence && !isOptions) { + // {a},b} + if (m.post.match(/,.*\}/)) { + str = m.pre + '{' + m.body + escClose + m.post; + return expand(str); + } + return [str]; + } + + var n; + if (isSequence) { + n = m.body.split(/\.\./); + } else { + n = parseCommaParts(m.body); + if (n.length === 1) { + // x{{a,b}}y ==> x{a}y x{b}y + n = expand(n[0], false).map(embrace); + if (n.length === 1) { + var post = m.post.length + ? expand(m.post, false) + : ['']; + return post.map(function(p) { + return m.pre + n[0] + p; + }); + } + } + } + + // at this point, n is the parts, and we know it's not a comma set + // with a single entry. + + // no need to expand pre, since it is guaranteed to be free of brace-sets + var pre = m.pre; + var post = m.post.length + ? expand(m.post, false) + : ['']; + + var N; + + if (isSequence) { + var x = numeric(n[0]); + var y = numeric(n[1]); + var width = Math.max(n[0].length, n[1].length); + var incr = n.length == 3 + ? Math.abs(numeric(n[2])) + : 1; + var test = lte; + var reverse = y < x; + if (reverse) { + incr *= -1; + test = gte; + } + var pad = n.some(isPadded); + + N = []; + + for (var i = x; test(i, y); i += incr) { + var c; + if (isAlphaSequence) { + c = String.fromCharCode(i); + if (c === '\\') + c = ''; + } else { + c = String(i); + if (pad) { + var need = width - c.length; + if (need > 0) { + var z = new Array(need + 1).join('0'); + if (i < 0) + c = '-' + z + c.slice(1); + else + c = z + c; + } + } + } + N.push(c); + } + } else { + N = concatMap(n, function(el) { return expand(el, false) }); + } + + for (var j = 0; j < N.length; j++) { + for (var k = 0; k < post.length; k++) { + var expansion = pre + N[j] + post[k]; + if (!isTop || isSequence || expansion) + expansions.push(expansion); + } + } + + return expansions; + } + + var require$$0 = ( path$1 && path ) || path$1; + + var minimatch_1 = minimatch; + minimatch.Minimatch = Minimatch; + + var path$2 = { sep: '/' }; + try { + path$2 = require$$0; + } catch (er) {} + + var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}; + + var plTypes = { + '!': { open: '(?:(?!(?:', close: '))[^/]*?)' }, + '?': { open: '(?:', close: ')?' }, + '+': { open: '(?:', close: ')+' }, + '*': { open: '(?:', close: ')*' }, + '@': { open: '(?:', close: ')' } + + // any single thing other than / + // don't need to escape / when using new RegExp() + };var qmark = '[^/]'; + + // * => any number of characters + var star = qmark + '*?'; + + // ** when dots are allowed. Anything goes, except .. and . + // not (^ or / followed by one or two dots followed by $ or /), + // followed by anything, any number of times. + var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?'; + + // not a ^ or / followed by a dot, + // followed by anything, any number of times. + var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?'; + + // characters that need to be escaped in RegExp. + var reSpecials = charSet('().*{}+?[]^$\\!'); + + // "abc" -> { a:true, b:true, c:true } + function charSet(s) { + return s.split('').reduce(function (set, c) { + set[c] = true; + return set; + }, {}); + } + + // normalizes slashes. + var slashSplit = /\/+/; + + minimatch.filter = filter$1; + function filter$1(pattern, options) { + options = options || {}; + return function (p, i, list) { + return minimatch(p, pattern, options); + }; + } + + function ext(a, b) { + a = a || {}; + b = b || {}; + var t = {}; + Object.keys(b).forEach(function (k) { + t[k] = b[k]; + }); + Object.keys(a).forEach(function (k) { + t[k] = a[k]; + }); + return t; + } + + minimatch.defaults = function (def) { + if (!def || !Object.keys(def).length) return minimatch; + + var orig = minimatch; + + var m = function minimatch(p, pattern, options) { + return orig.minimatch(p, pattern, ext(def, options)); + }; + + m.Minimatch = function Minimatch(pattern, options) { + return new orig.Minimatch(pattern, ext(def, options)); + }; + + return m; + }; + + Minimatch.defaults = function (def) { + if (!def || !Object.keys(def).length) return Minimatch; + return minimatch.defaults(def).Minimatch; + }; + + function minimatch(p, pattern, options) { + if (typeof pattern !== 'string') { + throw new TypeError('glob pattern string required'); + } + + if (!options) options = {}; + + // shortcut: comments match nothing. + if (!options.nocomment && pattern.charAt(0) === '#') { + return false; + } + + // "" only matches "" + if (pattern.trim() === '') return p === ''; + + return new Minimatch(pattern, options).match(p); + } + + function Minimatch(pattern, options) { + if (!(this instanceof Minimatch)) { + return new Minimatch(pattern, options); + } + + if (typeof pattern !== 'string') { + throw new TypeError('glob pattern string required'); + } + + if (!options) options = {}; + pattern = pattern.trim(); + + // windows support: need to use /, not \ + if (path$2.sep !== '/') { + pattern = pattern.split(path$2.sep).join('/'); + } + + this.options = options; + this.set = []; + this.pattern = pattern; + this.regexp = null; + this.negate = false; + this.comment = false; + this.empty = false; + + // make the set of regexps etc. + this.make(); + } + + Minimatch.prototype.debug = function () {}; + + Minimatch.prototype.make = make; + function make() { + // don't do it more than once. + if (this._made) return; + + var pattern = this.pattern; + var options = this.options; + + // empty patterns and comments match nothing. + if (!options.nocomment && pattern.charAt(0) === '#') { + this.comment = true; + return; + } + if (!pattern) { + this.empty = true; + return; + } + + // step 1: figure out negation, etc. + this.parseNegate(); + + // step 2: expand braces + var set = this.globSet = this.braceExpand(); + + if (options.debug) this.debug = console.error; + + this.debug(this.pattern, set); + + // step 3: now we have a set, so turn each one into a series of path-portion + // matching patterns. + // These will be regexps, except in the case of "**", which is + // set to the GLOBSTAR object for globstar behavior, + // and will not contain any / characters + set = this.globParts = set.map(function (s) { + return s.split(slashSplit); + }); + + this.debug(this.pattern, set); + + // glob --> regexps + set = set.map(function (s, si, set) { + return s.map(this.parse, this); + }, this); + + this.debug(this.pattern, set); + + // filter out everything that didn't compile properly. + set = set.filter(function (s) { + return s.indexOf(false) === -1; + }); + + this.debug(this.pattern, set); + + this.set = set; + } + + Minimatch.prototype.parseNegate = parseNegate; + function parseNegate() { + var pattern = this.pattern; + var negate = false; + var options = this.options; + var negateOffset = 0; + + if (options.nonegate) return; + + for (var i = 0, l = pattern.length; i < l && pattern.charAt(i) === '!'; i++) { + negate = !negate; + negateOffset++; + } + + if (negateOffset) this.pattern = pattern.substr(negateOffset); + this.negate = negate; + } + + // Brace expansion: + // a{b,c}d -> abd acd + // a{b,}c -> abc ac + // a{0..3}d -> a0d a1d a2d a3d + // a{b,c{d,e}f}g -> abg acdfg acefg + // a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg + // + // Invalid sets are not expanded. + // a{2..}b -> a{2..}b + // a{b}c -> a{b}c + minimatch.braceExpand = function (pattern, options) { + return braceExpand(pattern, options); + }; + + Minimatch.prototype.braceExpand = braceExpand; + + function braceExpand(pattern, options) { + if (!options) { + if (this instanceof Minimatch) { + options = this.options; + } else { + options = {}; + } + } + + pattern = typeof pattern === 'undefined' ? this.pattern : pattern; + + if (typeof pattern === 'undefined') { + throw new TypeError('undefined pattern'); + } + + if (options.nobrace || !pattern.match(/\{.*\}/)) { + // shortcut. no need to expand. + return [pattern]; + } + + return braceExpansion(pattern); + } + + // parse a component of the expanded set. + // At this point, no pattern may contain "/" in it + // so we're going to return a 2d array, where each entry is the full + // pattern, split on '/', and then turned into a regular expression. + // A regexp is made at the end which joins each array with an + // escaped /, and another full one which joins each regexp with |. + // + // Following the lead of Bash 4.1, note that "**" only has special meaning + // when it is the *only* thing in a path portion. Otherwise, any series + // of * is equivalent to a single *. Globstar behavior is enabled by + // default, and can be disabled by setting options.noglobstar. + Minimatch.prototype.parse = parse; + var SUBPARSE = {}; + function parse(pattern, isSub) { + if (pattern.length > 1024 * 64) { + throw new TypeError('pattern is too long'); + } + + var options = this.options; + + // shortcuts + if (!options.noglobstar && pattern === '**') return GLOBSTAR; + if (pattern === '') return ''; + + var re = ''; + var hasMagic = !!options.nocase; + var escaping = false; + // ? => one single character + var patternListStack = []; + var negativeLists = []; + var stateChar; + var inClass = false; + var reClassStart = -1; + var classStart = -1; + // . and .. never match anything that doesn't start with ., + // even when options.dot is set. + var patternStart = pattern.charAt(0) === '.' ? '' // anything + // not (start or / followed by . or .. followed by / or end) + : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))' : '(?!\\.)'; + var self = this; + + function clearStateChar() { + if (stateChar) { + // we had some state-tracking character + // that wasn't consumed by this pass. + switch (stateChar) { + case '*': + re += star; + hasMagic = true; + break; + case '?': + re += qmark; + hasMagic = true; + break; + default: + re += '\\' + stateChar; + break; + } + self.debug('clearStateChar %j %j', stateChar, re); + stateChar = false; + } + } + + for (var i = 0, len = pattern.length, c; i < len && (c = pattern.charAt(i)); i++) { + this.debug('%s\t%s %s %j', pattern, i, re, c); + + // skip over any that are escaped. + if (escaping && reSpecials[c]) { + re += '\\' + c; + escaping = false; + continue; + } + + switch (c) { + case '/': + // completely not allowed, even escaped. + // Should already be path-split by now. + return false; + + case '\\': + clearStateChar(); + escaping = true; + continue; + + // the various stateChar values + // for the "extglob" stuff. + case '?': + case '*': + case '+': + case '@': + case '!': + this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c); + + // all of those are literals inside a class, except that + // the glob [!a] means [^a] in regexp + if (inClass) { + this.debug(' in class'); + if (c === '!' && i === classStart + 1) c = '^'; + re += c; + continue; + } + + // if we already have a stateChar, then it means + // that there was something like ** or +? in there. + // Handle the stateChar, then proceed with this one. + self.debug('call clearStateChar %j', stateChar); + clearStateChar(); + stateChar = c; + // if extglob is disabled, then +(asdf|foo) isn't a thing. + // just clear the statechar *now*, rather than even diving into + // the patternList stuff. + if (options.noext) clearStateChar(); + continue; + + case '(': + if (inClass) { + re += '('; + continue; + } + + if (!stateChar) { + re += '\\('; + continue; + } + + patternListStack.push({ + type: stateChar, + start: i - 1, + reStart: re.length, + open: plTypes[stateChar].open, + close: plTypes[stateChar].close + }); + // negation is (?:(?!js)[^/]*) + re += stateChar === '!' ? '(?:(?!(?:' : '(?:'; + this.debug('plType %j %j', stateChar, re); + stateChar = false; + continue; + + case ')': + if (inClass || !patternListStack.length) { + re += '\\)'; + continue; + } + + clearStateChar(); + hasMagic = true; + var pl = patternListStack.pop(); + // negation is (?:(?!js)[^/]*) + // The others are (?:) + re += pl.close; + if (pl.type === '!') { + negativeLists.push(pl); + } + pl.reEnd = re.length; + continue; + + case '|': + if (inClass || !patternListStack.length || escaping) { + re += '\\|'; + escaping = false; + continue; + } + + clearStateChar(); + re += '|'; + continue; + + // these are mostly the same in regexp and glob + case '[': + // swallow any state-tracking char before the [ + clearStateChar(); + + if (inClass) { + re += '\\' + c; + continue; + } + + inClass = true; + classStart = i; + reClassStart = re.length; + re += c; + continue; + + case ']': + // a right bracket shall lose its special + // meaning and represent itself in + // a bracket expression if it occurs + // first in the list. -- POSIX.2 2.8.3.2 + if (i === classStart + 1 || !inClass) { + re += '\\' + c; + escaping = false; + continue; + } + + // handle the case where we left a class open. + // "[z-a]" is valid, equivalent to "\[z-a\]" + if (inClass) { + // split where the last [ was, make sure we don't have + // an invalid re. if so, re-walk the contents of the + // would-be class to re-translate any characters that + // were passed through as-is + // TODO: It would probably be faster to determine this + // without a try/catch and a new RegExp, but it's tricky + // to do safely. For now, this is safe and works. + var cs = pattern.substring(classStart + 1, i); + try { + } catch (er) { + // not a valid class! + var sp = this.parse(cs, SUBPARSE); + re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]'; + hasMagic = hasMagic || sp[1]; + inClass = false; + continue; + } + } + + // finish up the class. + hasMagic = true; + inClass = false; + re += c; + continue; + + default: + // swallow any state char that wasn't consumed + clearStateChar(); + + if (escaping) { + // no need + escaping = false; + } else if (reSpecials[c] && !(c === '^' && inClass)) { + re += '\\'; + } + + re += c; + + } // switch + } // for + + // handle the case where we left a class open. + // "[abc" is valid, equivalent to "\[abc" + if (inClass) { + // split where the last [ was, and escape it + // this is a huge pita. We now have to re-walk + // the contents of the would-be class to re-translate + // any characters that were passed through as-is + cs = pattern.substr(classStart + 1); + sp = this.parse(cs, SUBPARSE); + re = re.substr(0, reClassStart) + '\\[' + sp[0]; + hasMagic = hasMagic || sp[1]; + } + + // handle the case where we had a +( thing at the *end* + // of the pattern. + // each pattern list stack adds 3 chars, and we need to go through + // and escape any | chars that were passed through as-is for the regexp. + // Go through and escape them, taking care not to double-escape any + // | chars that were already escaped. + for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) { + var tail = re.slice(pl.reStart + pl.open.length); + this.debug('setting tail', re, pl); + // maybe some even number of \, then maybe 1 \, followed by a | + tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) { + if (!$2) { + // the | isn't already escaped, so escape it. + $2 = '\\'; + } + + // need to escape all those slashes *again*, without escaping the + // one that we need for escaping the | character. As it works out, + // escaping an even number of slashes can be done by simply repeating + // it exactly after itself. That's why this trick works. + // + // I am sorry that you have to see this. + return $1 + $1 + $2 + '|'; + }); + + this.debug('tail=%j\n %s', tail, tail, pl, re); + var t = pl.type === '*' ? star : pl.type === '?' ? qmark : '\\' + pl.type; + + hasMagic = true; + re = re.slice(0, pl.reStart) + t + '\\(' + tail; + } + + // handle trailing things that only matter at the very end. + clearStateChar(); + if (escaping) { + // trailing \\ + re += '\\\\'; + } + + // only need to apply the nodot start if the re starts with + // something that could conceivably capture a dot + var addPatternStart = false; + switch (re.charAt(0)) { + case '.': + case '[': + case '(': + addPatternStart = true; + } + + // Hack to work around lack of negative lookbehind in JS + // A pattern like: *.!(x).!(y|z) needs to ensure that a name + // like 'a.xyz.yz' doesn't match. So, the first negative + // lookahead, has to look ALL the way ahead, to the end of + // the pattern. + for (var n = negativeLists.length - 1; n > -1; n--) { + var nl = negativeLists[n]; + + var nlBefore = re.slice(0, nl.reStart); + var nlFirst = re.slice(nl.reStart, nl.reEnd - 8); + var nlLast = re.slice(nl.reEnd - 8, nl.reEnd); + var nlAfter = re.slice(nl.reEnd); + + nlLast += nlAfter; + + // Handle nested stuff like *(*.js|!(*.json)), where open parens + // mean that we should *not* include the ) in the bit that is considered + // "after" the negated section. + var openParensBefore = nlBefore.split('(').length - 1; + var cleanAfter = nlAfter; + for (i = 0; i < openParensBefore; i++) { + cleanAfter = cleanAfter.replace(/\)[+*?]?/, ''); + } + nlAfter = cleanAfter; + + var dollar = ''; + if (nlAfter === '' && isSub !== SUBPARSE) { + dollar = '$'; + } + var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast; + re = newRe; + } + + // if the re is not "" at this point, then we need to make sure + // it doesn't match against an empty path part. + // Otherwise a/* will match a/, which it should not. + if (re !== '' && hasMagic) { + re = '(?=.)' + re; + } + + if (addPatternStart) { + re = patternStart + re; + } + + // parsing just a piece of a larger pattern. + if (isSub === SUBPARSE) { + return [re, hasMagic]; + } + + // skip the regexp for non-magical patterns + // unescape anything in it, though, so that it'll be + // an exact match against a file etc. + if (!hasMagic) { + return globUnescape(pattern); + } + + var flags = options.nocase ? 'i' : ''; + try { + var regExp = new RegExp('^' + re + '$', flags); + } catch (er) { + // If it was an invalid regular expression, then it can't match + // anything. This trick looks for a character after the end of + // the string, which is of course impossible, except in multi-line + // mode, but it's not a /m regex. + return new RegExp('$.'); + } + + regExp._glob = pattern; + regExp._src = re; + + return regExp; + } + + minimatch.makeRe = function (pattern, options) { + return new Minimatch(pattern, options || {}).makeRe(); + }; + + Minimatch.prototype.makeRe = makeRe; + function makeRe() { + if (this.regexp || this.regexp === false) return this.regexp; + + // at this point, this.set is a 2d array of partial + // pattern strings, or "**". + // + // It's better to use .match(). This function shouldn't + // be used, really, but it's pretty convenient sometimes, + // when you just want to work with a regex. + var set = this.set; + + if (!set.length) { + this.regexp = false; + return this.regexp; + } + var options = this.options; + + var twoStar = options.noglobstar ? star : options.dot ? twoStarDot : twoStarNoDot; + var flags = options.nocase ? 'i' : ''; + + var re = set.map(function (pattern) { + return pattern.map(function (p) { + return p === GLOBSTAR ? twoStar : typeof p === 'string' ? regExpEscape(p) : p._src; + }).join('\\\/'); + }).join('|'); + + // must match entire pattern + // ending in a * or ** will make it less strict. + re = '^(?:' + re + ')$'; + + // can match anything, as long as it's not this. + if (this.negate) re = '^(?!' + re + ').*$'; + + try { + this.regexp = new RegExp(re, flags); + } catch (ex) { + this.regexp = false; + } + return this.regexp; + } + + minimatch.match = function (list, pattern, options) { + options = options || {}; + var mm = new Minimatch(pattern, options); + list = list.filter(function (f) { + return mm.match(f); + }); + if (mm.options.nonull && !list.length) { + list.push(pattern); + } + return list; + }; + + Minimatch.prototype.match = match; + function match(f, partial) { + this.debug('match', f, this.pattern); + // short-circuit in the case of busted things. + // comments, etc. + if (this.comment) return false; + if (this.empty) return f === ''; + + if (f === '/' && partial) return true; + + var options = this.options; + + // windows: need to use /, not \ + if (path$2.sep !== '/') { + f = f.split(path$2.sep).join('/'); + } + + // treat the test path as a set of pathparts. + f = f.split(slashSplit); + this.debug(this.pattern, 'split', f); + + // just ONE of the pattern sets in this.set needs to match + // in order for it to be valid. If negating, then just one + // match means that we have failed. + // Either way, return on the first hit. + + var set = this.set; + this.debug(this.pattern, 'set', set); + + // Find the basename of the path by looking for the last non-empty segment + var filename; + var i; + for (i = f.length - 1; i >= 0; i--) { + filename = f[i]; + if (filename) break; + } + + for (i = 0; i < set.length; i++) { + var pattern = set[i]; + var file = f; + if (options.matchBase && pattern.length === 1) { + file = [filename]; + } + var hit = this.matchOne(file, pattern, partial); + if (hit) { + if (options.flipNegate) return true; + return !this.negate; + } + } + + // didn't get any hits. this is success if it's a negative + // pattern, failure otherwise. + if (options.flipNegate) return false; + return this.negate; + } + + // set partial to true to test if, for example, + // "/a/b" matches the start of "/*/b/*/d" + // Partial means, if you run out of file before you run + // out of pattern, then that's fine, as long as all + // the parts match. + Minimatch.prototype.matchOne = function (file, pattern, partial) { + var options = this.options; + + this.debug('matchOne', { 'this': this, file: file, pattern: pattern }); + + this.debug('matchOne', file.length, pattern.length); + + for (var fi = 0, pi = 0, fl = file.length, pl = pattern.length; fi < fl && pi < pl; fi++, pi++) { + this.debug('matchOne loop'); + var p = pattern[pi]; + var f = file[fi]; + + this.debug(pattern, p, f); + + // should be impossible. + // some invalid regexp stuff in the set. + if (p === false) return false; + + if (p === GLOBSTAR) { + this.debug('GLOBSTAR', [pattern, p, f]); + + // "**" + // a/**/b/**/c would match the following: + // a/b/x/y/z/c + // a/x/y/z/b/c + // a/b/x/b/x/c + // a/b/c + // To do this, take the rest of the pattern after + // the **, and see if it would match the file remainder. + // If so, return success. + // If not, the ** "swallows" a segment, and try again. + // This is recursively awful. + // + // a/**/b/**/c matching a/b/x/y/z/c + // - a matches a + // - doublestar + // - matchOne(b/x/y/z/c, b/**/c) + // - b matches b + // - doublestar + // - matchOne(x/y/z/c, c) -> no + // - matchOne(y/z/c, c) -> no + // - matchOne(z/c, c) -> no + // - matchOne(c, c) yes, hit + var fr = fi; + var pr = pi + 1; + if (pr === pl) { + this.debug('** at the end'); + // a ** at the end will just swallow the rest. + // We have found a match. + // however, it will not swallow /.x, unless + // options.dot is set. + // . and .. are *never* matched by **, for explosively + // exponential reasons. + for (; fi < fl; fi++) { + if (file[fi] === '.' || file[fi] === '..' || !options.dot && file[fi].charAt(0) === '.') return false; + } + return true; + } + + // ok, let's see if we can swallow whatever we can. + while (fr < fl) { + var swallowee = file[fr]; + + this.debug('\nglobstar while', file, fr, pattern, pr, swallowee); + + // XXX remove this slice. Just pass the start index. + if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { + this.debug('globstar found match!', fr, fl, swallowee); + // found a match. + return true; + } else { + // can't swallow "." or ".." ever. + // can only swallow ".foo" when explicitly asked. + if (swallowee === '.' || swallowee === '..' || !options.dot && swallowee.charAt(0) === '.') { + this.debug('dot detected!', file, fr, pattern, pr); + break; + } + + // ** swallows a segment, and continue. + this.debug('globstar swallow a segment, and continue'); + fr++; + } + } + + // no match was found. + // However, in partial mode, we can't say this is necessarily over. + // If there's more *pattern* left, then + if (partial) { + // ran out of file + this.debug('\n>>> no match, partial?', file, fr, pattern, pr); + if (fr === fl) return true; + } + return false; + } + + // something other than ** + // non-magic patterns just have to match exactly + // patterns with magic have been turned into regexps. + var hit; + if (typeof p === 'string') { + if (options.nocase) { + hit = f.toLowerCase() === p.toLowerCase(); + } else { + hit = f === p; + } + this.debug('string match', p, f, hit); + } else { + hit = f.match(p); + this.debug('pattern match', p, f, hit); + } + + if (!hit) return false; + } + + // Note: ending in / means that we'll get a final "" + // at the end of the pattern. This can only match a + // corresponding "" at the end of the file. + // If the file ends in /, then it can only match a + // a pattern that ends in /, unless the pattern just + // doesn't have any more for it. But, a/b/ should *not* + // match "a/b/*", even though "" matches against the + // [^/]*? pattern, except in partial mode, where it might + // simply not be reached yet. + // However, a/b/ should still satisfy a/* + + // now either we fell off the end of the pattern, or we're done. + if (fi === fl && pi === pl) { + // ran out of pattern and filename at the same time. + // an exact hit! + return true; + } else if (fi === fl) { + // ran out of file, but still had pattern left. + // this is ok if we're doing the match as part of + // a glob fs traversal. + return partial; + } else if (pi === pl) { + // ran out of pattern, still have file left. + // this is only acceptable if we're on the very last + // empty segment of a file with a trailing slash. + // a/* should match a/b/ + var emptyFileEnd = fi === fl - 1 && file[fi] === ''; + return emptyFileEnd; + } + + // should be unreachable. + throw new Error('wtf?'); + }; + + // replace stuff like \* with * + function globUnescape(s) { + return s.replace(/\\(.)/g, '$1'); + } + + function regExpEscape(s) { + return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); + } + + console.log("=== PureRead: Beautify load ==="); + + /** + * Beautify html + * + * @param {string} storage.current.site.name + */ + function specbeautify(name, $target) { + switch (name) { + case "sspai.com": + //TO-DO + $target.find(".relation-apps").remove(); + $target.find(".ss-app-card").remove(); + break; + case "post.smzdm.com": + $target.find("img.face").addClass("sr-rd-content-nobeautify"); + $target.find(".insert-outer img").addClass("sr-rd-content-nobeautify"); + break; + case "infoq.com": + $target.find("img").map(function (index, item) { + if ($(item).css("float") == "left") { + $(item).addClass("sr-rd-content-nobeautify"); + } + }); + $target.find("script").remove(); + break; + case "appinn.com": + $target.find(".emoji").addClass("sr-rd-content-nobeautify"); + break; + case "hacpai.com": + $target.find(".emoji").addClass("sr-rd-content-nobeautify"); + break; + case "douban.com": + $target.find(".review-content").children().unwrap(); + $target.find("table").addClass("sr-rd-content-center"); + $target.find("p").css({ "white-space": "pre-wrap" }); + $target.find(".cc").removeClass(); + break; + case "qdaily.com": + $target.find("img").map(function (index, item) { + var $target = $(item), + height = Number.parseInt($target.css("height")); + if (height == 0) $target.remove(); + }); + $target.find(".com-insert-images").map(function (index, item) { + var $target = $(item), + imgs = $target.find("img").map(function (index, item) { + return "
" + item.outerHTML + "
"; + }), + str = imgs.get().join(""); + $target.empty().removeAttr("class").append(str); + }); + $target.find(".com-insert-embed").remove(); + break; + case "news.mtime.com": + $target.find(".newspictool").map(function (index, item) { + var $target = $(item), + $img = $target.find("img"), + $label = $target.find("p:last"); + $target.removeAttr("class").addClass("sr-rd-content-center").empty().append($img).append($label); + }); + break; + case "blog.csdn.net": + $target.find(".save_code").remove(); + $target.find(".pre-numbering").remove(); + $target.find("pre").removeAttr("style").removeAttr("class"); + $target.find("code").removeAttr("style"); + $target.find(".dp-highlighter").map(function (index, item) { + $(item).find(".bar .tools").remove(); + if ($(item).next().is("pre")) $(item).next().remove(); + }); + break; + case "news.sohu.com": + $target.find(".conserve-photo").remove(); + $target.find("table").addClass("sr-rd-content-center"); + break; + case "qq.com": + $target.find(".rv-root-v2, #backqqcom").remove(); + break; + case "azofreeware.com": + $target.find("iframe").remove(); + break; + case "apprcn.com": + $target.find("img").map(function (index, item) { + var $target = $(item), + src = $target.attr("src"); + if (src && src.includes("Apprcn_Wechat_Small.jpeg")) $target.parent().remove(); + }); + $target.find("a").map(function (index, item) { + var $target = $(item), + text = $target.text(); + if (text == "来自反斗软件") $target.parent().remove(); + }); + break; + case "tieba.baidu.com": + $target.find(".BDE_Smiley").addClass("sr-rd-content-nobeautify"); + $target.find(".replace_div").removeAttr("class").removeAttr("style"); + $target.find(".replace_tip").remove(); + $target.find(".d_post_content, .j_d_post_content, .post_bubble_top, .post_bubble_middle, .post_bubble_bottom").map(function (idx, target) { + $(target).removeAttr("class").removeAttr("style"); + }); + $("body").find(".p_author_face").map(function (idx, target) { + var $target = $(target).find("img"), + src = $target.attr("data-tb-lazyload"), + name = $target.attr("username"); + src && $("sr-rd-mult-avatar").find("span").map(function (idx, span) { + var $span = $(span), + text = $span.text(); + if (text == name) { + $span.parent().find("img").attr("src", src); + } + }); + }); + break; + case "jingyan.baidu.com": + $target.find(".exp-image-wraper").removeAttr("class").removeAttr("href"); + break; + case "question.zhihu.com": + $target.find(".zu-edit-button").remove(); + $target.find("a.external").map(function (idx, target) { + $(target).removeAttr("class").attr("style", "border: none;"); + }); + $target.find(".VagueImage").map(function (idx, target) { + var $target = $(target), + src = $target.attr("data-src"); + $target.replaceWith(""); + }); + break; + case "chiphell.com": + $target.find("img").map(function (index, item) { + var $target = $(item), + $parent = $target.parent(), + src = $target.attr("src"), + smilieid = $target.attr("smilieid"); + if ($parent.is("ignore_js_op")) $target.unwrap(); + smilieid && src && src.includes("static/image/smiley") && $target.addClass("sr-rd-content-nobeautify").attr("style", "width: 50px;"); + }); + $target.find(".quote").remove(); + break; + case "jiemian.com": + $target.find("script").remove(); + break; + case "36kr.com": + $target.find(".load-html-img").removeAttr("class"); + break; + case "cnblogs.com": + $target.find(".cnblogs_code").removeClass(); + $target.find(".cnblogs_code_hide").removeClass().removeAttr("style"); + $target.find(".cnblogs_code_toolbar").remove(); + $target.find(".code_img_opened").remove(); + $target.find(".code_img_closed").remove(); + break; + case "news.cnblogs.com": + $target.find(".topic_img").remove(); + break; + case "g-cores.com": + $target.find(".swiper-slide-active").find("img").map(function (index, item) { + var $target = $(item); + $target.parent().parent().parent().parent().parent().parent().removeAttr("class").removeAttr("style").html($target); + }); + break; + case "feng.com": + $target.find("span").removeAttr("style"); + break; + case "young.ifeng.com": + $target.find("span").removeAttr("style"); + break; + case "ftchinese.com": + $target.find("script").remove(); + break; + case "segmentfault.com": + $target.find(".widget-codetool").remove(); + break; + case "mp.weixin.qq.com": + $target.find('section[powered-by="xiumi.us"]').find("img").map(function (index, item) { + var $target = $(item), + src = $target.attr("data-src"); + $target.addClass("sr-rd-content-nobeautify").attr("src", src); + }); + break; + case "ruby-china.org": + $target.find(".twemoji").remove(); + break; + case "w3cplus.com": + $target.find("iframe").addClass("sr-rd-content-nobeautify"); + break; + case "zuojj.com": + $target.find(".syntaxhighlighter .Brush").attr("style", "font-size: .7em !important;"); + break; + case "aotu.io": + $target.find(".highlight table").map(function (index, item) { + var $target = $(item), + $pre = $target.find("pre"), + $table = $target.find("table"); + $target.html($pre[1]); + $table.unwrap(); + }); + $target.find("table").addClass("sr-rd-content-center"); + break; + case "colobu.com": + $target.find(".highlight table").map(function (index, item) { + var $target = $(item), + $pre = $target.find("pre"); + $target.html($pre[1]); + $target.unwrap(); + }); + break; + case "hao.caibaojian.com": + $target.find(".tlink").map(function (index, item) { + var $target = $(item); + $target.html(""); + }); + break; + case "wkee.net": + $target.find("script").remove(); + break; + case "linux.cn": + $target.find("pre").attr("style", "background-color: #161b20; background-image: none;"); + $target.find("code").attr("style", "background-color: transparent; background-image: none;"); + break; + case "zhuanlan.zhihu.com": + $target.find("div[data-src]").map(function (index, item) { + var $target = $(item), + src = $target.attr("data-src"); + $target.replaceWith("
"); + }); + break; + case "jianshu.com": + $target.find(".image-package").map(function (index, item) { + var $target = $(item), + $div = $target.find("img"); + $target.html($div); + }); + break; + case "medium.com": + $target.find("figure").map(function (index, item) { + var $target = $(item), + $img = $target.find("img"); + $target.replaceWith("
"); + }); + break; + case "worldcup.fifa.com": + $target.find("iframe").css({ width: "790px", height: "450px" }); + $target.find("div").removeClass(); + break; + } + } + + /** + * Remove spare tag + * + * @param {string} storage.current.site.name + * @param {jquery} jquery object + */ + function removeSpareTag(name, $target) { + var remove = false, + tag = ""; + + if (["lib.csdn.net", "huxiu.com", "my.oschina.net", "caixin.com", "163.com", "steachs.com", "hacpai.com", "apprcn.com", "mp.weixin.qq.com"].includes(name)) { + remove = true; + tag = "p"; + } else if (["nationalgeographic.com.cn", "dgtle.com", "news.mtime.com"].includes(name)) { + remove = true; + tag = "div"; + } else if (["chiphell.com"].includes(name)) { + remove = true; + tag = "font"; + } + if (remove) { + $target.find(tag).map(function (index, item) { + var str = $(item).text().toLowerCase().trim(); + if ($(item).find("img").length == 0 && str == "") $(item).remove(); + }); + } + } + + /** + * Beautify html, incldue: + * + * - change all
to + * - remove useless
+ * + * @param {jquery} jquery object + */ + function htmlbeautify($target) { + try { + $target.html(function (index, html) { + return html.trim().replace(/<\/?blockquote/g, function (value) { + return value[1] == "/" ? "\n?
(\n?
)*/g, "
").replace(/\/(div|p)>\n*(
\n)+/g, function (value) { + return value.replace("
", ""); + }); + }); + } catch (error) { + console.error(error); + return $target.html(); + } + } + + /** + * Common Beautify html, include: + * - task: all webiste image, remove old image and create new image + * - task: all webiste sr-blockquote, remove style + * - task: all webiste iframe, embed add center style + * - task: all hr tag add simpread-hidden class + * - task: all pre/code tag remove class + * - task: all a tag remove style + * + * @param {jquery} + */ + function commbeautify(name, $target) { + $target.find("img:not(.sr-rd-content-nobeautify)").map(function (index, item) { + var $target = $(item), + $orgpar = $target.parent(), + $img = $(""), + src = $target.attr("src"), + lazysrc = $target.attr("data-src"), + zuimei = $target.attr("data-original"), + cnbeta = $target.attr("original"), + jianshu = $target.attr("data-original-src"), + sina = $target.attr("real_src"), + fixOverflowImgsize = function fixOverflowImgsize() { + $img.removeClass("sr-rd-content-img-load"); + if ($img[0].clientWidth < 300 && $img[0].clientHeight < 300) { + $img.parent().removeClass("sr-rd-content-center").addClass("sr-rd-content-center-small"); + } else if ($img[0].clientWidth > 1000) { + $img.css("zoom", "0.6"); + } else if ($img[0].clientHeight > 620) { + if (/win|mac/i.test(navigator.platform)) { + $img.attr("height", 620); + if ($img[0].clientWidth < $("sr-rd-content").width()) $img.css({ "width": "auto" }); + } + } + if ($img[0].clientWidth > $("sr-rd-content").width()) $img.addClass("sr-rd-content-img"); + }, + loaderrorHandle = function loaderrorHandle() { + $img.addClass("simpread-hidden"); + if ($img.parent().hasClass("sr-rd-content-center")) { + $img.parent().removeAttr("class").addClass("simpread-hidden"); + } + }, + getImgAbsolutePath2 = function getImgAbsolutePath2(url, base) { + if ('string' !== typeof url || !url) { + return null; + } else if (url.match(/^[a-z]+\:\/\//i)) { + return url; + } else if (url.match(/^\/\//)) { + return 'http:' + url; + } else if (url.match(/^[a-z]+\:/i)) { + return url; + } else if ('string' !== typeof base) { + var a = document.createElement('a');a.href = url;if (!a.pathname) { + return null; + }return 'http://' + url; + } else { + base = getImgAbsolutePath2(base);if (base === null) { + return null; + } + }var a = document.createElement('a');a.href = base;if (url[0] === '/') { + base = []; + } else { + base = a.pathname.split('/');base.pop(); + }url = url.split('/');for (var i = 0; i < url.length; ++i) { + if (url[i] === '.') { + continue; + }if (url[i] === '..') { + if ('undefined' === typeof base.pop() || base.length === 0) { + return null; + } + } else { + base.push(url[i]); + } + }return a.protocol + '//' + a.hostname + base.join('/'); + }; + var newsrc = void 0, + $parent = $target.parent(), + tagname = $parent[0].tagName.toLowerCase(); + + // remove current image and create new image object + newsrc = cnbeta ? cnbeta : src; + newsrc = lazysrc ? lazysrc : newsrc; + newsrc = zuimei ? zuimei : newsrc; + newsrc = jianshu ? jianshu : newsrc; + newsrc = sina ? sina : newsrc; + //newsrc = getImgAbsolutePath( newsrc ); + if (newsrc && !newsrc.startsWith('http') && !newsrc.startsWith('data')) { + newsrc = getImgAbsolutePath2(newsrc, location.href); + } + + // hack code + //location.host.includes( "infoq.com" ) && ( newsrc = src ); + //!newsrc.startsWith( "http" ) && ( newsrc = newsrc.startsWith( "//" ) ? location.protocol + newsrc : location.origin + newsrc ); + + $img.attr("src", newsrc).replaceAll($target).wrap("
"); + if (!/win|mac/i.test(navigator.platform)) { + $img.on("load", function () { + return fixOverflowImgsize(); + }).on("error", function () { + return loaderrorHandle(); + }); + } else { + $img.one("load", function () { + return fixOverflowImgsize(); + }).one("error", function () { + return loaderrorHandle(); + }); + } + }); + $target.find("sr-blockquote").map(function (index, item) { + var $target = $(item), + $parent = $target.parent(); + $target.removeAttr("style").removeAttr("class"); + if (name == "dgtle.com") { + $parent.removeClass("quote"); + } + }); + $target.find("iframe:not(.sr-rd-content-nobeautify), embed:not(.sr-rd-content-nobeautify)").map(function (index, item) { + $(item).wrap("
"); + }); + $target.find("hr").map(function (index, item) { + $(item).addClass("simpread-hidden"); + }); + $target.find("pre").map(function (index, item) { + $(item).find("code").removeAttr("class"); + }); + $target.find("pre").removeAttr("class"); + $target.find("a").removeAttr("style"); + } + + /** + * Clean HTML usage $.parseHTML + * + * @param {jquery} $('sr-rd-content') + * @param {boolean} when true, is remove style, class attr + * @param {boolean} is_mathjax + */ + function cleanHTML($target, is_pure, is_mathjax) { + var clear = function clear(str) { + var parse = $.parseHTML(str); + var newHTML = ''; + parse.forEach(function (item, idx) { + var tag = item.tagName, + text = item.outerText, + html = item.outerHTML; + if (tag == undefined) { + newHTML += "

" + item.textContent.replace(/^\n|\n$/ig, "").trim() + "

"; + } else if (tag == "PRE") { + newHTML += html; + } else if (text == "" && !html.includes(' 0 && (isLi = true); + if (item.outerText.trim() != "") { + html += item.outerText.replace(/\n/ig, "").replace(//ig, '>') + "\n"; + } + }); + // pre → code + if (isLi == false) { + $(pre).find('code').each(function (idx, item) { + isCode = true; + if (item.outerText.trim() != "") { + html += item.outerText.replace(//ig, '>') + "\n"; + } + }); + } + // only pre + if (!isLi && !isCode) { + html += pre.outerText.replace(//ig, '>') + "\n"; + } + $(pre).removeAttr('style').removeAttr('class').removeAttr('id').html(html); + }); + + // set origin html + var orgHTML = $target.html(); + if ($($target.children()).attr('id') == 'readability-page-1' && $target.children().children().length == 1) { + orgHTML = $target.children().children().html(); + } else if ($target.children().length == 1) { + orgHTML = $target.children().html(); + } + orgHTML = orgHTML.replace(//ig, ''); + // clean html + $target.html(clear(orgHTML)); + + is_pure && $target.find('p').each(function (idx, item) { + var tag = item.tagName, + text = item.outerText, + html = item.outerHTML; + if (text.trim() == "" && !html.includes(' 0) { + return arr.join("").replace(/, $/, ""); + } else { + return null; + } + } + /** + * Set focus mode background color for focus mode + * + * @param {string} background color + * @param {number} background opacity + * @return {string} new background color + */ + function backgroundColor(bgcolor, opacity) { + var color = getColor(bgcolor), + newval = "rgba(" + color + ", " + opacity / 100 + ")"; + $(bgcls).css(bgcolorstyl, newval); + return newval; + } + + /** + * Set background opacity for focus mode + * + * @param {string} opacity + * @return {string} new background color or null + */ + function opacity(opacity) { + var bgcolor = $(bgcls).css(bgcolorstyl), + color = getColor(bgcolor), + newval = "rgba(" + color + ", " + opacity / 100 + ")"; + if (color) { + $(bgcls).css(bgcolorstyl, newval); + return newval; + } else { + return null; + } + } + + /** + * Set read mode font family for read mode + * + * @param {string} font family name e.g. PingFang SC; Microsoft Yahei + */ + function fontFamily(family) { + $("sr-read").css("font-family", family == "default" ? "" : family); + } + + /** + * Set read mode font size for read mode + * + * @param {string} font size, e.g. 70% 62.5% + */ + function fontSize(value) { + if (html_style_bal == "-1") { + html_style_bal = $("html").attr("style"); + html_style_bal == undefined && (html_style_bal = ""); + } + value ? $("html").attr("style", "font-size: " + value + "!important;" + html_style_bal) : $("html").attr("style", html_style_bal); + } + + /** + * Set read mode layout width for read mode + * + * @param {string} layout width + */ + function layout(width) { + $("sr-read").css("margin", width ? "20px " + width : ""); + } + + /** + * Add custom css to for read mode + * + * @param {string} read.custom[type] + * @param {object} read.custom + */ + function custom(type, props) { + var format = function format(name) { + return name.replace(/[A-Z]/, function (name) { + return "-" + name.toLowerCase(); + }); + }, + arr = Object.keys(props).map(function (v) { + return props[v] && format(v) + ": " + props[v] + ";"; + }); + var styles = arr.join(""); + switch (type) { + case "title": + styles = "sr-rd-title {" + styles + "}"; + break; + case "desc": + styles = "sr-rd-desc {" + styles + "}"; + break; + case "art": + styles = "sr-rd-content *, sr-rd-content p, sr-rd-content div {" + styles + "}"; + break; + case "pre": + styles = "sr-rd-content pre {" + styles + "}"; + break; + case "code": + styles = "sr-rd-content pre code, sr-rd-content pre code * {" + styles + "}"; + break; + } + + var $target = $("head").find("style#simpread-custom-" + type); + if ($target.length == 0) { + $("head").append(""); + } else { + $target.html(styles); + } + } + + /** + * Add css to for read mode + * + * @param {string} read.custom.css + * @param {object} read.custom.css value + */ + function css(type, styles) { + var $target = $("head").find("style#simpread-custom-" + type); + if ($target.length == 0) { + $("head").append(""); + } else { + $target.html(styles); + } + } + + /** + * Add/Remove current site styles( string ) to head for read mdoe + * + * @param {string} styles + */ + function siteCSS(styles) { + styles ? $("head").append("") : $("#simpread-site-css").remove(); + } + + /** + * Add custom to .preview tag + * + * @param {object} read.custom + * @param {string} theme backgroud color + */ + function preview(styles) { + Object.keys(styles).forEach(function (v) { + v != "css" && custom(v, styles[v]); + }); + css("css", styles["css"]); + } + + /** + * Verify custom is exist + * + * @param {string} verify type + * @param {object} read.custom value + */ + function vfyCustom(type, styles) { + switch (type) { + case "layout": + case "margin": + case "fontfamily": + case "custom": + return styles.css != ""; + case "fontsize": + return styles.title.fontSize != "" || styles.desc.fontSize != "" || styles.art.fontSize != "" || styles.css != ""; + case "theme": + return styles.css.search("simpread-theme-root") != -1; + } + } + + var ss = /*#__PURE__*/Object.freeze({ + GetColor: getColor, + BgColor: backgroundColor, + Opacity: opacity, + FontFamily: fontFamily, + FontSize: fontSize, + Layout: layout, + SiteCSS: siteCSS, + Preview: preview, + Custom: custom, + CSS: css, + VerifyCustom: vfyCustom + }); + + /* + * Copyright (c) 2010 Arc90 Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /*eslint-env es6:false*/ + /* + * Copyright (c) 2010 Arc90 Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + /* + * This code is heavily based on Arc90's readability.js (1.7.1) script + * available at: http://code.google.com/p/arc90labs-readability + */ + /** + * Public constructor. + * @param {HTMLDocument} doc The document to parse. + * @param {Object} options The options object. + */ + function Readability(a, b) { + if (b && b.documentElement) a = b, b = arguments[2];else if (!a || !a.documentElement) throw new Error("First argument to Readability constructor should be a document object.");b = b || {}, this._doc = a, this._articleTitle = null, this._articleByline = null, this._articleDir = null, this._articleSiteName = null, this._attempts = [], this._debug = !!b.debug, this._maxElemsToParse = b.maxElemsToParse || this.DEFAULT_MAX_ELEMS_TO_PARSE, this._nbTopCandidates = b.nbTopCandidates || this.DEFAULT_N_TOP_CANDIDATES, this._charThreshold = b.charThreshold || this.DEFAULT_CHAR_THRESHOLD, this._classesToPreserve = this.CLASSES_TO_PRESERVE.concat(b.classesToPreserve || []), this._flags = this.FLAG_STRIP_UNLIKELYS | this.FLAG_WEIGHT_CLASSES | this.FLAG_CLEAN_CONDITIONALLY;var c;this._debug ? (c = function c(a) { + var c, + d, + b = a.nodeName + " ";return a.nodeType == a.TEXT_NODE ? b + '("' + a.textContent + '")' : (c = a.className && "." + a.className.replace(/ /g, "."), d = "", a.id ? d = "(#" + a.id + c + ")" : c && (d = "(" + c + ")"), b + d); + }, this.log = function () { + var a, b;"undefined" != typeof dump ? (a = Array.prototype.map.call(arguments, function (a) { + return a && a.nodeName ? c(a) : a; + }).join(" "), dump("Reader: (Readability) " + a + "\n")) : "undefined" != typeof console && (b = ["Reader: (Readability) "].concat(arguments), console.log.apply(console, b)); + }) : this.log = function () {}; + }Readability.prototype = { FLAG_STRIP_UNLIKELYS: 1, FLAG_WEIGHT_CLASSES: 2, FLAG_CLEAN_CONDITIONALLY: 4, ELEMENT_NODE: 1, TEXT_NODE: 3, DEFAULT_MAX_ELEMS_TO_PARSE: 0, DEFAULT_N_TOP_CANDIDATES: 5, DEFAULT_TAGS_TO_SCORE: "section,h2,h3,h4,h5,h6,p,td,pre".toUpperCase().split(","), DEFAULT_CHAR_THRESHOLD: 500, REGEXPS: { unlikelyCandidates: /-ad-|ai2html|banner|breadcrumbs|combx|comment|community|cover-wrap|disqus|extra|foot|gdpr|header|legends|menu|related|remark|replies|rss|shoutbox|sidebar|skyscraper|social|sponsor|supplemental|ad-break|agegate|pagination|pager|popup|yom-remote/i, okMaybeItsACandidate: /and|article|body|column|main|shadow/i, positive: /article|body|content|entry|hentry|h-entry|main|page|pagination|post|text|blog|story/i, negative: /hidden|^hid$| hid$| hid |^hid |banner|combx|comment|com-|contact|foot|footer|footnote|gdpr|masthead|media|meta|outbrain|promo|related|scroll|share|shoutbox|sidebar|skyscraper|sponsor|shopping|tags|tool|widget/i, extraneous: /print|archive|comment|discuss|e[\-]?mail|share|reply|all|login|sign|single|utility/i, byline: /byline|author|dateline|writtenby|p-author/i, replaceFonts: /<(\/?)font[^>]*>/gi, normalize: /\s{2,}/g, videos: /\/\/(www\.)?((dailymotion|youtube|youtube-nocookie|player\.vimeo|v\.qq)\.com|(archive|upload\.wikimedia)\.org|player\.twitch\.tv)/i, nextLink: /(next|weiter|continue|>([^\|]|$)|禄([^\|]|$))/i, prevLink: /(prev|earl|old|new|<|芦)/i, whitespace: /^\s*$/, hasContent: /\S$/ }, DIV_TO_P_ELEMS: ["A", "BLOCKQUOTE", "DL", "DIV", "IMG", "OL", "P", "PRE", "TABLE", "UL", "SELECT"], ALTER_TO_DIV_EXCEPTIONS: ["DIV", "ARTICLE", "SECTION", "P"], PRESENTATIONAL_ATTRIBUTES: ["align", "background", "bgcolor", "border", "cellpadding", "cellspacing", "frame", "hspace", "rules", "style", "valign", "vspace"], DEPRECATED_SIZE_ATTRIBUTE_ELEMS: ["TABLE", "TH", "TD", "HR", "PRE"], PHRASING_ELEMS: ["ABBR", "AUDIO", "B", "BDO", "BR", "BUTTON", "CITE", "CODE", "DATA", "DATALIST", "DFN", "EM", "EMBED", "I", "IMG", "INPUT", "KBD", "LABEL", "MARK", "MATH", "METER", "NOSCRIPT", "OBJECT", "OUTPUT", "PROGRESS", "Q", "RUBY", "SAMP", "SCRIPT", "SELECT", "SMALL", "SPAN", "STRONG", "SUB", "SUP", "TEXTAREA", "TIME", "VAR", "WBR"], CLASSES_TO_PRESERVE: ["page"], _postProcessContent: function _postProcessContent(a) { + this._fixRelativeUris(a), this._cleanClasses(a); + }, _removeNodes: function _removeNodes(a, b) { + var c, d, e;for (c = a.length - 1; c >= 0; c--) { + d = a[c], e = d.parentNode, e && (!b || b.call(this, d, c, a)) && e.removeChild(d); + } + }, _replaceNodeTags: function _replaceNodeTags(a, b) { + var c, d;for (c = a.length - 1; c >= 0; c--) { + d = a[c], this._setNodeTag(d, b); + } + }, _forEachNode: function _forEachNode(a, b) { + Array.prototype.forEach.call(a, b, this); + }, _someNode: function _someNode(a, b) { + return Array.prototype.some.call(a, b, this); + }, _everyNode: function _everyNode(a, b) { + return Array.prototype.every.call(a, b, this); + }, _concatNodeLists: function _concatNodeLists() { + var a = Array.prototype.slice, + b = a.call(arguments), + c = b.map(function (b) { + return a.call(b); + });return Array.prototype.concat.apply([], c); + }, _getAllNodesWithTag: function _getAllNodesWithTag(a, b) { + return a.querySelectorAll ? a.querySelectorAll(b.join(",")) : [].concat.apply([], b.map(function (b) { + var c = a.getElementsByTagName(b);return Array.isArray(c) ? c : Array.from(c); + })); + }, _cleanClasses: function _cleanClasses(a) { + var b = this._classesToPreserve, + c = (a.getAttribute("class") || "").split(/\s+/).filter(function (a) { + return -1 != b.indexOf(a); + }).join(" ");for (c ? a.setAttribute("class", c) : a.removeAttribute("class"), a = a.firstElementChild; a; a = a.nextElementSibling) { + this._cleanClasses(a); + } + }, _fixRelativeUris: function _fixRelativeUris(a) { + function d(a) { + if (b == c && "#" == a.charAt(0)) return a;try { + return new URL(a, b).href; + } catch (d) {}return a; + }var f, + b = this._doc.baseURI, + c = this._doc.documentURI, + e = this._getAllNodesWithTag(a, ["a"]);this._forEachNode(e, function (a) { + var c, + b = a.getAttribute("href");b && (0 === b.indexOf("javascript:") ? (c = this._doc.createTextNode(a.textContent), a.parentNode.replaceChild(c, a)) : a.setAttribute("href", d(b))); + }), f = this._getAllNodesWithTag(a, ["img"]), this._forEachNode(f, function (a) { + var b = a.getAttribute("src");b && a.setAttribute("src", d(b)); + }); + }, _getArticleTitle: function _getArticleTitle() { + function f(a) { + return a.split(/\s+/).length; + }var e, + g, + h, + i, + j, + k, + a = this._doc, + b = "", + c = "";try { + b = c = a.title.trim(), "string" != typeof b && (b = c = this._getInnerText(a.getElementsByTagName("title")[0])); + } catch (d) {}return e = !1, / [\|\-\\\/>禄] /.test(b) ? (e = / [\\\/>禄] /.test(b), b = c.replace(/(.*)[\|\-\\\/>禄] .*/gi, "$1"), f(b) < 3 && (b = c.replace(/[^\|\-\\\/>禄]*[\|\-\\\/>禄](.*)/gi, "$1"))) : -1 !== b.indexOf(": ") ? (g = this._concatNodeLists(a.getElementsByTagName("h1"), a.getElementsByTagName("h2")), h = b.trim(), i = this._someNode(g, function (a) { + return a.textContent.trim() === h; + }), i || (b = c.substring(c.lastIndexOf(":") + 1), f(b) < 3 ? b = c.substring(c.indexOf(":") + 1) : f(c.substr(0, c.indexOf(":"))) > 5 && (b = c))) : (b.length > 150 || b.length < 15) && (j = a.getElementsByTagName("h1"), 1 === j.length && (b = this._getInnerText(j[0]))), b = b.trim().replace(this.REGEXPS.normalize, " "), k = f(b), 4 >= k && (!e || k != f(c.replace(/[\|\-\\\/>禄]+/g, "")) - 1) && (b = c), b; + }, _prepDocument: function _prepDocument() { + var a = this._doc;this._removeNodes(a.getElementsByTagName("style")), a.body && this._replaceBrs(a.body), this._replaceNodeTags(a.getElementsByTagName("font"), "SPAN"); + }, _nextElement: function _nextElement(a) { + for (var b = a; b && b.nodeType != this.ELEMENT_NODE && this.REGEXPS.whitespace.test(b.textContent);) { + b = b.nextSibling; + }return b; + }, _replaceBrs: function _replaceBrs(a) { + this._forEachNode(this._getAllNodesWithTag(a, ["br"]), function (a) { + for (var d, e, f, g, b = a.nextSibling, c = !1; (b = this._nextElement(b)) && "BR" == b.tagName;) { + c = !0, d = b.nextSibling, b.parentNode.removeChild(b), b = d; + }if (c) { + for (e = this._doc.createElement("p"), a.parentNode.replaceChild(e, a), b = e.nextSibling; b && ("BR" != b.tagName || (f = this._nextElement(b.nextSibling), !f || "BR" != f.tagName)) && this._isPhrasingContent(b);) { + g = b.nextSibling, e.appendChild(b), b = g; + }for (; e.lastChild && this._isWhitespace(e.lastChild);) { + e.removeChild(e.lastChild); + }"P" === e.parentNode.tagName && this._setNodeTag(e.parentNode, "DIV"); + } + }); + }, _setNodeTag: function _setNodeTag(a, b) { + var c, d;if (this.log("_setNodeTag", a, b), a.__JSDOMParser__) return a.localName = b.toLowerCase(), a.tagName = b.toUpperCase(), a;for (c = a.ownerDocument.createElement(b); a.firstChild;) { + c.appendChild(a.firstChild); + }for (a.parentNode.replaceChild(c, a), a.readability && (c.readability = a.readability), d = 0; d < a.attributes.length; d++) { + try { + c.setAttribute(a.attributes[d].name, a.attributes[d].value); + } catch (e) {} + }return c; + }, _prepArticle: function _prepArticle(a) { + var b, c, d, e;this._cleanStyles(a), this._markDataTables(a), this._cleanConditionally(a, "form"), this._cleanConditionally(a, "fieldset"), this._clean(a, "object"), this._clean(a, "embed"), this._clean(a, "h1"), this._clean(a, "footer"), this._clean(a, "link"), this._clean(a, "aside"), b = this.DEFAULT_CHAR_THRESHOLD, this._forEachNode(a.children, function (a) { + this._cleanMatchedNodes(a, function (a, c) { + return (/share/.test(c) && a.textContent.length < b + ); + }); + }), c = a.getElementsByTagName("h2"), 1 === c.length && (d = (c[0].textContent.length - this._articleTitle.length) / this._articleTitle.length, Math.abs(d) < .5 && (e = !1, e = d > 0 ? c[0].textContent.includes(this._articleTitle) : this._articleTitle.includes(c[0].textContent), e && this._clean(a, "h2"))), this._clean(a, "iframe"), this._clean(a, "input"), this._clean(a, "textarea"), this._clean(a, "select"), this._clean(a, "button"), this._cleanHeaders(a), this._cleanConditionally(a, "table"), this._cleanConditionally(a, "ul"), this._cleanConditionally(a, "div"), this._removeNodes(a.getElementsByTagName("p"), function (a) { + var b = a.getElementsByTagName("img").length, + c = a.getElementsByTagName("embed").length, + d = a.getElementsByTagName("object").length, + e = a.getElementsByTagName("iframe").length, + f = b + c + d + e;return 0 === f && !this._getInnerText(a, !1); + }), this._forEachNode(this._getAllNodesWithTag(a, ["br"]), function (a) { + var b = this._nextElement(a.nextSibling);b && "P" == b.tagName && a.parentNode.removeChild(a); + }), this._forEachNode(this._getAllNodesWithTag(a, ["table"]), function (a) { + var c, + d, + b = this._hasSingleTagInsideElement(a, "TBODY") ? a.firstElementChild : a;this._hasSingleTagInsideElement(b, "TR") && (c = b.firstElementChild, this._hasSingleTagInsideElement(c, "TD") && (d = c.firstElementChild, d = this._setNodeTag(d, this._everyNode(d.childNodes, this._isPhrasingContent) ? "P" : "DIV"), a.parentNode.replaceChild(d, a))); + }); + }, _initializeNode: function _initializeNode(a) { + switch (a.readability = { contentScore: 0 }, a.tagName) {case "DIV": + a.readability.contentScore += 5;break;case "PRE":case "TD":case "BLOCKQUOTE": + a.readability.contentScore += 3;break;case "ADDRESS":case "OL":case "UL":case "DL":case "DD":case "DT":case "LI":case "FORM": + a.readability.contentScore -= 3;break;case "H1":case "H2":case "H3":case "H4":case "H5":case "H6":case "TH": + a.readability.contentScore -= 5;}a.readability.contentScore += this._getClassWeight(a); + }, _removeAndGetNext: function _removeAndGetNext(a) { + var b = this._getNextNode(a, !0);return a.parentNode.removeChild(a), b; + }, _getNextNode: function _getNextNode(a, b) { + if (!b && a.firstElementChild) return a.firstElementChild;if (a.nextElementSibling) return a.nextElementSibling;do { + a = a.parentNode; + } while (a && !a.nextElementSibling);return a && a.nextElementSibling; + }, _checkByline: function _checkByline(a, b) { + var c, d;return this._articleByline ? !1 : (void 0 !== a.getAttribute && (c = a.getAttribute("rel"), d = a.getAttribute("itemprop")), ("author" === c || d && -1 !== d.indexOf("author") || this.REGEXPS.byline.test(b)) && this._isValidByline(a.textContent) ? (this._articleByline = a.textContent.trim(), !0) : !1); + }, _getNodeAncestors: function _getNodeAncestors(a, b) { + b = b || 0;for (var c = 0, d = []; a.parentNode && (d.push(a.parentNode), !b || ++c !== b);) { + a = a.parentNode; + }return d; + }, _grabArticle: function _grabArticle(a) { + var b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V;if (this.log("**** grabArticle ****"), b = this._doc, c = null !== a ? !0 : !1, a = a ? a : this._doc.body, !a) return this.log("No body found in document. Abort."), null;for (d = a.innerHTML;;) { + for (e = this._flagIsActive(this.FLAG_STRIP_UNLIKELYS), f = [], g = this._doc.documentElement; g;) { + if (h = g.className + " " + g.id, this._isProbablyVisible(g)) { + if (this._checkByline(g, h)) g = this._removeAndGetNext(g);else if (!e || !this.REGEXPS.unlikelyCandidates.test(h) || this.REGEXPS.okMaybeItsACandidate.test(h) || this._hasAncestorTag(g, "table") || "BODY" === g.tagName || "A" === g.tagName) { + if ("DIV" !== g.tagName && "SECTION" !== g.tagName && "HEADER" !== g.tagName && "H1" !== g.tagName && "H2" !== g.tagName && "H3" !== g.tagName && "H4" !== g.tagName && "H5" !== g.tagName && "H6" !== g.tagName || !this._isElementWithoutContent(g)) { + if (-1 !== this.DEFAULT_TAGS_TO_SCORE.indexOf(g.tagName) && f.push(g), "DIV" === g.tagName) { + for (i = null, j = g.firstChild; j;) { + if (k = j.nextSibling, this._isPhrasingContent(j)) null !== i ? i.appendChild(j) : this._isWhitespace(j) || (i = b.createElement("p"), g.replaceChild(i, j), i.appendChild(j));else if (null !== i) { + for (; i.lastChild && this._isWhitespace(i.lastChild);) { + i.removeChild(i.lastChild); + }i = null; + }j = k; + }this._hasSingleTagInsideElement(g, "P") && this._getLinkDensity(g) < .25 ? (l = g.children[0], g.parentNode.replaceChild(l, g), g = l, f.push(g)) : this._hasChildBlockElement(g) || (g = this._setNodeTag(g, "P"), f.push(g)); + }g = this._getNextNode(g); + } else g = this._removeAndGetNext(g); + } else this.log("Removing unlikely candidate - " + h), g = this._removeAndGetNext(g); + } else this.log("Removing hidden node - " + h), g = this._removeAndGetNext(g); + }for (m = [], this._forEachNode(f, function (a) { + var b, c, d;a.parentNode && "undefined" != typeof a.parentNode.tagName && (b = this._getInnerText(a), b.length < 25 || (c = this._getNodeAncestors(a, 3), 0 !== c.length && (d = 0, d += 1, d += b.split(",").length, d += Math.min(Math.floor(b.length / 100), 3), this._forEachNode(c, function (a, b) { + if (a.tagName && a.parentNode && "undefined" != typeof a.parentNode.tagName) { + if ("undefined" == typeof a.readability && (this._initializeNode(a), m.push(a)), 0 === b) var c = 1;else c = 1 === b ? 2 : 3 * b;a.readability.contentScore += d / c; + } + })))); + }), n = [], o = 0, p = m.length; p > o; o += 1) { + for (q = m[o], r = q.readability.contentScore * (1 - this._getLinkDensity(q)), q.readability.contentScore = r, this.log("Candidate:", q, "with score " + r), s = 0; s < this._nbTopCandidates; s++) { + if (t = n[s], !t || r > t.readability.contentScore) { + n.splice(s, 0, q), n.length > this._nbTopCandidates && n.pop();break; + } + } + }if (u = n[0] || null, v = !1, null === u || "BODY" === u.tagName) { + for (u = b.createElement("DIV"), v = !0, x = a.childNodes; x.length;) { + this.log("Moving child out:", x[0]), u.appendChild(x[0]); + }a.appendChild(u), this._initializeNode(u); + } else if (u) { + for (y = [], z = 1; z < n.length; z++) { + n[z].readability.contentScore / u.readability.contentScore >= .75 && y.push(this._getNodeAncestors(n[z])); + }if (A = 3, y.length >= A) for (w = u.parentNode; "BODY" !== w.tagName;) { + for (B = 0, C = 0; C < y.length && A > B; C++) { + B += Number(y[C].includes(w)); + }if (B >= A) { + u = w;break; + }w = w.parentNode; + }for (u.readability || this._initializeNode(u), w = u.parentNode, D = u.readability.contentScore, E = D / 3; "BODY" !== w.tagName;) { + if (w.readability) { + if (F = w.readability.contentScore, E > F) break;if (F > D) { + u = w;break; + }D = w.readability.contentScore, w = w.parentNode; + } else w = w.parentNode; + }for (w = u.parentNode; "BODY" != w.tagName && 1 == w.children.length;) { + u = w, w = u.parentNode; + }u.readability || this._initializeNode(u); + }for (G = b.createElement("DIV"), c && (G.id = "readability-content"), H = Math.max(10, .2 * u.readability.contentScore), w = u.parentNode, I = w.children, J = 0, K = I.length; K > J; J++) { + L = I[J], M = !1, this.log("Looking at sibling node:", L, L.readability ? "with score " + L.readability.contentScore : ""), this.log("Sibling has score", L.readability ? L.readability.contentScore : "Unknown"), L === u ? M = !0 : (N = 0, L.className === u.className && "" !== u.className && (N += .2 * u.readability.contentScore), L.readability && L.readability.contentScore + N >= H ? M = !0 : "P" === L.nodeName && (O = this._getLinkDensity(L), P = this._getInnerText(L), Q = P.length, Q > 80 && .25 > O ? M = !0 : 80 > Q && Q > 0 && 0 === O && -1 !== P.search(/\.( |$)/) && (M = !0))), M && (this.log("Appending node:", L), -1 === this.ALTER_TO_DIV_EXCEPTIONS.indexOf(L.nodeName) && (this.log("Altering sibling:", L, "to div."), L = this._setNodeTag(L, "DIV")), G.appendChild(L), J -= 1, K -= 1); + }if (this._debug && this.log("Article content pre-prep: " + G.innerHTML), this._prepArticle(G), this._debug && this.log("Article content post-prep: " + G.innerHTML), v) u.id = "readability-page-1", u.className = "page";else { + for (R = b.createElement("DIV"), R.id = "readability-page-1", R.className = "page", S = G.childNodes; S.length;) { + R.appendChild(S[0]); + }G.appendChild(R); + }if (this._debug && this.log("Article content after paging: " + G.innerHTML), T = !0, U = this._getInnerText(G, !0).length, U < this._charThreshold) if (T = !1, a.innerHTML = d, this._flagIsActive(this.FLAG_STRIP_UNLIKELYS)) this._removeFlag(this.FLAG_STRIP_UNLIKELYS), this._attempts.push({ articleContent: G, textLength: U });else if (this._flagIsActive(this.FLAG_WEIGHT_CLASSES)) this._removeFlag(this.FLAG_WEIGHT_CLASSES), this._attempts.push({ articleContent: G, textLength: U });else if (this._flagIsActive(this.FLAG_CLEAN_CONDITIONALLY)) this._removeFlag(this.FLAG_CLEAN_CONDITIONALLY), this._attempts.push({ articleContent: G, textLength: U });else { + if (this._attempts.push({ articleContent: G, textLength: U }), this._attempts.sort(function (a, b) { + return b.textLength - a.textLength; + }), !this._attempts[0].textLength) return null;G = this._attempts[0].articleContent, T = !0; + }if (T) return V = [w, u].concat(this._getNodeAncestors(w)), this._someNode(V, function (a) { + if (!a.tagName) return !1;var b = a.getAttribute("dir");return b ? (this._articleDir = b, !0) : !1; + }), G; + } + }, _isValidByline: function _isValidByline(a) { + return "string" == typeof a || a instanceof String ? (a = a.trim(), a.length > 0 && a.length < 100) : !1; + }, _getArticleMetadata: function _getArticleMetadata() { + var a = {}, + b = {}, + c = this._doc.getElementsByTagName("meta"), + d = /\s*(dc|dcterm|og|twitter)\s*:\s*(author|creator|description|title|site_name)\s*/gi, + e = /^\s*(?:(dc|dcterm|og|twitter|weibo:(article|webpage))\s*[\.:]\s*)?(author|creator|description|title|site_name)\s*$/i;return this._forEachNode(c, function (a) { + var h, + i, + j, + c = a.getAttribute("name"), + f = a.getAttribute("property"), + g = a.getAttribute("content");if (g) { + if (h = null, i = null, f && (h = f.match(d))) for (j = h.length - 1; j >= 0; j--) { + i = h[j].toLowerCase().replace(/\s/g, ""), b[i] = g.trim(); + }!h && c && e.test(c) && (i = c, g && (i = i.toLowerCase().replace(/\s/g, "").replace(/\./g, ":"), b[i] = g.trim())); + } + }), a.title = b["dc:title"] || b["dcterm:title"] || b["og:title"] || b["weibo:article:title"] || b["weibo:webpage:title"] || b["title"] || b["twitter:title"], a.title || (a.title = this._getArticleTitle()), a.byline = b["dc:creator"] || b["dcterm:creator"] || b["author"], a.excerpt = b["dc:description"] || b["dcterm:description"] || b["og:description"] || b["weibo:article:description"] || b["weibo:webpage:description"] || b["description"] || b["twitter:description"], a.siteName = b["og:site_name"], a; + }, _removeScripts: function _removeScripts(a) { + this._removeNodes(a.getElementsByTagName("script"), function (a) { + return a.nodeValue = "", a.removeAttribute("src"), !0; + }), this._removeNodes(a.getElementsByTagName("noscript")); + }, _hasSingleTagInsideElement: function _hasSingleTagInsideElement(a, b) { + return 1 != a.children.length || a.children[0].tagName !== b ? !1 : !this._someNode(a.childNodes, function (a) { + return a.nodeType === this.TEXT_NODE && this.REGEXPS.hasContent.test(a.textContent); + }); + }, _isElementWithoutContent: function _isElementWithoutContent(a) { + return a.nodeType === this.ELEMENT_NODE && 0 == a.textContent.trim().length && (0 == a.children.length || a.children.length == a.getElementsByTagName("br").length + a.getElementsByTagName("hr").length); + }, _hasChildBlockElement: function _hasChildBlockElement(a) { + return this._someNode(a.childNodes, function (a) { + return -1 !== this.DIV_TO_P_ELEMS.indexOf(a.tagName) || this._hasChildBlockElement(a); + }); + }, _isPhrasingContent: function _isPhrasingContent(a) { + return a.nodeType === this.TEXT_NODE || -1 !== this.PHRASING_ELEMS.indexOf(a.tagName) || ("A" === a.tagName || "DEL" === a.tagName || "INS" === a.tagName) && this._everyNode(a.childNodes, this._isPhrasingContent); + }, _isWhitespace: function _isWhitespace(a) { + return a.nodeType === this.TEXT_NODE && 0 === a.textContent.trim().length || a.nodeType === this.ELEMENT_NODE && "BR" === a.tagName; + }, _getInnerText: function _getInnerText(a, b) { + b = "undefined" == typeof b ? !0 : b;var c = a.textContent.trim();return b ? c.replace(this.REGEXPS.normalize, " ") : c; + }, _getCharCount: function _getCharCount(a, b) { + return b = b || ",", this._getInnerText(a).split(b).length - 1; + }, _cleanStyles: function _cleanStyles(a) { + var b, c;if (a && "svg" !== a.tagName.toLowerCase()) { + for (b = 0; b < this.PRESENTATIONAL_ATTRIBUTES.length; b++) { + a.removeAttribute(this.PRESENTATIONAL_ATTRIBUTES[b]); + }for (-1 !== this.DEPRECATED_SIZE_ATTRIBUTE_ELEMS.indexOf(a.tagName) && (a.removeAttribute("width"), a.removeAttribute("height")), c = a.firstElementChild; null !== c;) { + this._cleanStyles(c), c = c.nextElementSibling; + } + } + }, _getLinkDensity: function _getLinkDensity(a) { + var c, + b = this._getInnerText(a).length;return 0 === b ? 0 : (c = 0, this._forEachNode(a.getElementsByTagName("a"), function (a) { + c += this._getInnerText(a).length; + }), c / b); + }, _getClassWeight: function _getClassWeight(a) { + if (!this._flagIsActive(this.FLAG_WEIGHT_CLASSES)) return 0;var b = 0;return "string" == typeof a.className && "" !== a.className && (this.REGEXPS.negative.test(a.className) && (b -= 25), this.REGEXPS.positive.test(a.className) && (b += 25)), "string" == typeof a.id && "" !== a.id && (this.REGEXPS.negative.test(a.id) && (b -= 25), this.REGEXPS.positive.test(a.id) && (b += 25)), b; + }, _clean: function _clean(a, b) { + var c = -1 !== ["object", "embed", "iframe"].indexOf(b);this._removeNodes(a.getElementsByTagName(b), function (a) { + if (c) { + for (var b = 0; b < a.attributes.length; b++) { + if (this.REGEXPS.videos.test(a.attributes[b].value)) return !1; + }if ("object" === a.tagName && this.REGEXPS.videos.test(a.innerHTML)) return !1; + }return !0; + }); + }, _hasAncestorTag: function _hasAncestorTag(a, b, c, d) { + c = c || 3, b = b.toUpperCase();for (var e = 0; a.parentNode;) { + if (c > 0 && e > c) return !1;if (a.parentNode.tagName === b && (!d || d(a.parentNode))) return !0;a = a.parentNode, e++; + }return !1; + }, _getRowAndColumnCount: function _getRowAndColumnCount(a) { + var e, + f, + g, + h, + i, + j, + b = 0, + c = 0, + d = a.getElementsByTagName("tr");for (e = 0; e < d.length; e++) { + for (f = d[e].getAttribute("rowspan") || 0, f && (f = parseInt(f, 10)), b += f || 1, g = 0, h = d[e].getElementsByTagName("td"), i = 0; i < h.length; i++) { + j = h[i].getAttribute("colspan") || 0, j && (j = parseInt(j, 10)), g += j || 1; + }c = Math.max(c, g); + }return { rows: b, columns: c }; + }, _markDataTables: function _markDataTables(a) { + var c, + d, + e, + f, + g, + h, + i, + j, + k, + b = a.getElementsByTagName("table");for (c = 0; c < b.length; c++) { + d = b[c], e = d.getAttribute("role"), "presentation" != e ? (f = d.getAttribute("datatable"), "0" != f ? (g = d.getAttribute("summary"), g ? d._readabilityDataTable = !0 : (h = d.getElementsByTagName("caption")[0], h && h.childNodes.length > 0 ? d._readabilityDataTable = !0 : (i = ["col", "colgroup", "tfoot", "thead", "th"], j = function j(a) { + return !!d.getElementsByTagName(a)[0]; + }, i.some(j) ? (this.log("Data table because found data-y descendant"), d._readabilityDataTable = !0) : d.getElementsByTagName("table")[0] ? d._readabilityDataTable = !1 : (k = this._getRowAndColumnCount(d), d._readabilityDataTable = k.rows >= 10 || k.columns > 4 ? !0 : k.rows * k.columns > 10)))) : d._readabilityDataTable = !1) : d._readabilityDataTable = !1; + } + }, _cleanConditionally: function _cleanConditionally(a, b) { + if (this._flagIsActive(this.FLAG_CLEAN_CONDITIONALLY)) { + var c = "ul" === b || "ol" === b;this._removeNodes(a.getElementsByTagName(b), function (a) { + var e, + f, + g, + h, + i, + j, + k, + l, + m, + n, + o, + p, + q, + d = function d(a) { + return a._readabilityDataTable; + };if ("table" === b && d(a)) return !1;if (this._hasAncestorTag(a, "table", -1, d)) return !1;if (e = this._getClassWeight(a), f = 0, this.log("Cleaning Conditionally", a), 0 > e + f) return !0;if (this._getCharCount(a, ",") < 10) { + for (g = a.getElementsByTagName("p").length, h = a.getElementsByTagName("img").length, i = a.getElementsByTagName("li").length - 100, j = a.getElementsByTagName("input").length, k = 0, l = this._concatNodeLists(a.getElementsByTagName("object"), a.getElementsByTagName("embed"), a.getElementsByTagName("iframe")), m = 0; m < l.length; m++) { + for (n = 0; n < l[m].attributes.length; n++) { + if (this.REGEXPS.videos.test(l[m].attributes[n].value)) return !1; + }if ("object" === l[m].tagName && this.REGEXPS.videos.test(l[m].innerHTML)) return !1;k++; + }return o = this._getLinkDensity(a), p = this._getInnerText(a).length, q = h > 1 && .5 > g / h && !this._hasAncestorTag(a, "figure") || !c && i > g || j > Math.floor(g / 3) || !c && 25 > p && (0 === h || h > 2) && !this._hasAncestorTag(a, "figure") || !c && 25 > e && o > .2 || e >= 25 && o > .5 || 1 === k && 75 > p || k > 1; + }return !1; + }); + } + }, _cleanMatchedNodes: function _cleanMatchedNodes(a, b) { + for (var c = this._getNextNode(a, !0), d = this._getNextNode(a); d && d != c;) { + d = b(d, d.className + " " + d.id) ? this._removeAndGetNext(d) : this._getNextNode(d); + } + }, _cleanHeaders: function _cleanHeaders(a) { + for (var b = 1; 3 > b; b += 1) { + this._removeNodes(a.getElementsByTagName("h" + b), function (a) { + return this._getClassWeight(a) < 0; + }); + } + }, _flagIsActive: function _flagIsActive(a) { + return (this._flags & a) > 0; + }, _removeFlag: function _removeFlag(a) { + this._flags = this._flags & ~a; + }, _isProbablyVisible: function _isProbablyVisible(a) { + return !(a.style && "none" == a.style.display || a.hasAttribute("hidden")); + }, parse: function parse() { + var a, b, c, d, e;if (this._maxElemsToParse > 0 && (a = this._doc.getElementsByTagName("*").length, a > this._maxElemsToParse)) throw new Error("Aborting parsing document; " + a + " elements found");return this._removeScripts(this._doc), this._prepDocument(), b = this._getArticleMetadata(), this._articleTitle = b.title, (c = this._grabArticle()) ? (this.log("Grabbed: " + c.innerHTML), this._postProcessContent(c), b.excerpt || (d = c.getElementsByTagName("p"), d.length > 0 && (b.excerpt = d[0].textContent.trim())), e = c.textContent, { title: this._articleTitle, byline: b.byline || this._articleByline, dir: this._articleDir, content: c.innerHTML, textContent: e, length: e.length, excerpt: b.excerpt, siteName: b.siteName || this._articleSiteName }) : null; + } }; + + var rda = /*#__PURE__*/Object.freeze({ + Readability: Readability + }); + + var showdown_min = createCommonjsModule(function (module) { + /*! showdown v 1.9.0 - 10-11-2018 */ + (function () { + function e(e) { + var r = { omitExtraWLInCodeBlocks: { defaultValue: !1, describe: "Omit the default extra whiteline added to code blocks", type: "boolean" }, noHeaderId: { defaultValue: !1, describe: "Turn on/off generated header id", type: "boolean" }, prefixHeaderId: { defaultValue: !1, describe: "Add a prefix to the generated header ids. Passing a string will prefix that string to the header id. Setting to true will add a generic 'section-' prefix", type: "string" }, rawPrefixHeaderId: { defaultValue: !1, describe: 'Setting this option to true will prevent showdown from modifying the prefix. This might result in malformed IDs (if, for instance, the " char is used in the prefix)', type: "boolean" }, ghCompatibleHeaderId: { defaultValue: !1, describe: "Generate header ids compatible with github style (spaces are replaced with dashes, a bunch of non alphanumeric chars are removed)", type: "boolean" }, rawHeaderId: { defaultValue: !1, describe: "Remove only spaces, ' and \" from generated header ids (including prefixes), replacing them with dashes (-). WARNING: This might result in malformed ids", type: "boolean" }, headerLevelStart: { defaultValue: !1, describe: "The header blocks level start", type: "integer" }, parseImgDimensions: { defaultValue: !1, describe: "Turn on/off image dimension parsing", type: "boolean" }, simplifiedAutoLink: { defaultValue: !1, describe: "Turn on/off GFM autolink style", type: "boolean" }, excludeTrailingPunctuationFromURLs: { defaultValue: !1, describe: "Excludes trailing punctuation from links generated with autoLinking", type: "boolean" }, literalMidWordUnderscores: { defaultValue: !1, describe: "Parse midword underscores as literal underscores", type: "boolean" }, literalMidWordAsterisks: { defaultValue: !1, describe: "Parse midword asterisks as literal asterisks", type: "boolean" }, strikethrough: { defaultValue: !1, describe: "Turn on/off strikethrough support", type: "boolean" }, tables: { defaultValue: !1, describe: "Turn on/off tables support", type: "boolean" }, tablesHeaderId: { defaultValue: !1, describe: "Add an id to table headers", type: "boolean" }, ghCodeBlocks: { defaultValue: !0, describe: "Turn on/off GFM fenced code blocks support", type: "boolean" }, tasklists: { defaultValue: !1, describe: "Turn on/off GFM tasklist support", type: "boolean" }, smoothLivePreview: { defaultValue: !1, describe: "Prevents weird effects in live previews due to incomplete input", type: "boolean" }, smartIndentationFix: { defaultValue: !1, description: "Tries to smartly fix indentation in es6 strings", type: "boolean" }, disableForced4SpacesIndentedSublists: { defaultValue: !1, description: "Disables the requirement of indenting nested sublists by 4 spaces", type: "boolean" }, simpleLineBreaks: { defaultValue: !1, description: "Parses simple line breaks as
(GFM Style)", type: "boolean" }, requireSpaceBeforeHeadingText: { defaultValue: !1, description: "Makes adding a space between `#` and the header text mandatory (GFM Style)", type: "boolean" }, ghMentions: { defaultValue: !1, description: "Enables github @mentions", type: "boolean" }, ghMentionsLink: { defaultValue: "https://github.com/{u}", description: "Changes the link generated by @mentions. Only applies if ghMentions option is enabled.", type: "string" }, encodeEmails: { defaultValue: !0, description: "Encode e-mail addresses through the use of Character Entities, transforming ASCII e-mail addresses into its equivalent decimal entities", type: "boolean" }, openLinksInNewWindow: { defaultValue: !1, description: "Open all links in new windows", type: "boolean" }, backslashEscapesHTMLTags: { defaultValue: !1, description: "Support for HTML Tag escaping. ex:
foo
", type: "boolean" }, emoji: { defaultValue: !1, description: "Enable emoji support. Ex: `this is a :smile: emoji`", type: "boolean" }, underline: { defaultValue: !1, description: "Enable support for underline. Syntax is double or triple underscores: `__underline word__`. With this option enabled, underscores no longer parses into `` and ``", type: "boolean" }, completeHTMLDocument: { defaultValue: !1, description: "Outputs a complete html document, including ``, `` and `` tags", type: "boolean" }, metadata: { defaultValue: !1, description: "Enable support for document metadata (defined at the top of the document between `«««` and `»»»` or between `---` and `---`).", type: "boolean" }, splitAdjacentBlockquotes: { defaultValue: !1, description: "Split adjacent blockquote blocks", type: "boolean" } };if (!1 === e) return JSON.parse(JSON.stringify(r));var t = {};for (var a in r) { + r.hasOwnProperty(a) && (t[a] = r[a].defaultValue); + }return t; + }function r(e, r) { + var t = r ? "Error in " + r + " extension->" : "Error in unnamed extension", + n = { valid: !0, error: "" };a.helper.isArray(e) || (e = [e]);for (var s = 0; s < e.length; ++s) { + var o = t + " sub-extension " + s + ": ", + i = e[s];if ("object" != (typeof i === "undefined" ? "undefined" : _typeof(i))) return n.valid = !1, n.error = o + "must be an object, but " + (typeof i === "undefined" ? "undefined" : _typeof(i)) + " given", n;if (!a.helper.isString(i.type)) return n.valid = !1, n.error = o + 'property "type" must be a string, but ' + _typeof(i.type) + " given", n;var l = i.type = i.type.toLowerCase();if ("language" === l && (l = i.type = "lang"), "html" === l && (l = i.type = "output"), "lang" !== l && "output" !== l && "listener" !== l) return n.valid = !1, n.error = o + "type " + l + ' is not recognized. Valid values: "lang/language", "output/html" or "listener"', n;if ("listener" === l) { + if (a.helper.isUndefined(i.listeners)) return n.valid = !1, n.error = o + '. Extensions of type "listener" must have a property called "listeners"', n; + } else if (a.helper.isUndefined(i.filter) && a.helper.isUndefined(i.regex)) return n.valid = !1, n.error = o + l + ' extensions must define either a "regex" property or a "filter" method', n;if (i.listeners) { + if ("object" != _typeof(i.listeners)) return n.valid = !1, n.error = o + '"listeners" property must be an object but ' + _typeof(i.listeners) + " given", n;for (var c in i.listeners) { + if (i.listeners.hasOwnProperty(c) && "function" != typeof i.listeners[c]) return n.valid = !1, n.error = o + '"listeners" property must be an hash of [event name]: [callback]. listeners.' + c + " must be a function but " + _typeof(i.listeners[c]) + " given", n; + } + }if (i.filter) { + if ("function" != typeof i.filter) return n.valid = !1, n.error = o + '"filter" must be a function, but ' + _typeof(i.filter) + " given", n; + } else if (i.regex) { + if (a.helper.isString(i.regex) && (i.regex = new RegExp(i.regex, "g")), !(i.regex instanceof RegExp)) return n.valid = !1, n.error = o + '"regex" property must either be a string or a RegExp object, but ' + _typeof(i.regex) + " given", n;if (a.helper.isUndefined(i.replace)) return n.valid = !1, n.error = o + '"regex" extensions must implement a replace string or function', n; + } + }return n; + }function t(e, r) { + return "¨E" + r.charCodeAt(0) + "E"; + }var a = {}, + n = {}, + s = {}, + o = e(!0), + i = "vanilla", + l = { github: { omitExtraWLInCodeBlocks: !0, simplifiedAutoLink: !0, excludeTrailingPunctuationFromURLs: !0, literalMidWordUnderscores: !0, strikethrough: !0, tables: !0, tablesHeaderId: !0, ghCodeBlocks: !0, tasklists: !0, disableForced4SpacesIndentedSublists: !0, simpleLineBreaks: !0, requireSpaceBeforeHeadingText: !0, ghCompatibleHeaderId: !0, ghMentions: !0, backslashEscapesHTMLTags: !0, emoji: !0, splitAdjacentBlockquotes: !0 }, original: { noHeaderId: !0, ghCodeBlocks: !1 }, ghost: { omitExtraWLInCodeBlocks: !0, parseImgDimensions: !0, simplifiedAutoLink: !0, excludeTrailingPunctuationFromURLs: !0, literalMidWordUnderscores: !0, strikethrough: !0, tables: !0, tablesHeaderId: !0, ghCodeBlocks: !0, tasklists: !0, smoothLivePreview: !0, simpleLineBreaks: !0, requireSpaceBeforeHeadingText: !0, ghMentions: !1, encodeEmails: !0 }, vanilla: e(!0), allOn: function () { + var r = e(!0), + t = {};for (var a in r) { + r.hasOwnProperty(a) && (t[a] = !0); + }return t; + }() };a.helper = {}, a.extensions = {}, a.setOption = function (e, r) { + return o[e] = r, this; + }, a.getOption = function (e) { + return o[e]; + }, a.getOptions = function () { + return o; + }, a.resetOptions = function () { + o = e(!0); + }, a.setFlavor = function (e) { + if (!l.hasOwnProperty(e)) throw Error(e + " flavor was not found");a.resetOptions();var r = l[e];i = e;for (var t in r) { + r.hasOwnProperty(t) && (o[t] = r[t]); + } + }, a.getFlavor = function () { + return i; + }, a.getFlavorOptions = function (e) { + if (l.hasOwnProperty(e)) return l[e]; + }, a.getDefaultOptions = function (r) { + return e(r); + }, a.subParser = function (e, r) { + if (a.helper.isString(e)) { + if (void 0 === r) { + if (n.hasOwnProperty(e)) return n[e];throw Error("SubParser named " + e + " not registered!"); + }n[e] = r; + } + }, a.extension = function (e, t) { + if (!a.helper.isString(e)) throw Error("Extension 'name' must be a string");if (e = a.helper.stdExtName(e), a.helper.isUndefined(t)) { + if (!s.hasOwnProperty(e)) throw Error("Extension named " + e + " is not registered!");return s[e]; + }"function" == typeof t && (t = t()), a.helper.isArray(t) || (t = [t]);var n = r(t, e);if (!n.valid) throw Error(n.error);s[e] = t; + }, a.getAllExtensions = function () { + return s; + }, a.removeExtension = function (e) { + delete s[e]; + }, a.resetExtensions = function () { + s = {}; + }, a.validateExtension = function (e) { + var t = r(e, null);return !!t.valid || (console.warn(t.error), !1); + }, a.hasOwnProperty("helper") || (a.helper = {}), a.helper.isString = function (e) { + return "string" == typeof e || e instanceof String; + }, a.helper.isFunction = function (e) { + return e && "[object Function]" === {}.toString.call(e); + }, a.helper.isArray = function (e) { + return Array.isArray(e); + }, a.helper.isUndefined = function (e) { + return void 0 === e; + }, a.helper.forEach = function (e, r) { + if (a.helper.isUndefined(e)) throw new Error("obj param is required");if (a.helper.isUndefined(r)) throw new Error("callback param is required");if (!a.helper.isFunction(r)) throw new Error("callback param must be a function/closure");if ("function" == typeof e.forEach) e.forEach(r);else if (a.helper.isArray(e)) for (var t = 0; t < e.length; t++) { + r(e[t], t, e); + } else { + if ("object" != (typeof e === "undefined" ? "undefined" : _typeof(e))) throw new Error("obj does not seem to be an array or an iterable object");for (var n in e) { + e.hasOwnProperty(n) && r(e[n], n, e); + } + } + }, a.helper.stdExtName = function (e) { + return e.replace(/[_?*+\/\\.^-]/g, "").replace(/\s/g, "").toLowerCase(); + }, a.helper.escapeCharactersCallback = t, a.helper.escapeCharacters = function (e, r, a) { + var n = "([" + r.replace(/([\[\]\\])/g, "\\$1") + "])";a && (n = "\\\\" + n);var s = new RegExp(n, "g");return e = e.replace(s, t); + }, a.helper.unescapeHTMLEntities = function (e) { + return e.replace(/"/g, '"').replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&"); + };var c = function c(e, r, t, a) { + var n, + s, + o, + i, + l, + c = a || "", + u = c.indexOf("g") > -1, + d = new RegExp(r + "|" + t, "g" + c.replace(/g/g, "")), + p = new RegExp(r, c.replace(/g/g, "")), + h = [];do { + for (n = 0; o = d.exec(e);) { + if (p.test(o[0])) n++ || (i = (s = d.lastIndex) - o[0].length);else if (n && ! --n) { + l = o.index + o[0].length;var _ = { left: { start: i, end: s }, match: { start: s, end: o.index }, right: { start: o.index, end: l }, wholeMatch: { start: i, end: l } };if (h.push(_), !u) return h; + } + } + } while (n && (d.lastIndex = s));return h; + };a.helper.matchRecursiveRegExp = function (e, r, t, a) { + for (var n = c(e, r, t, a), s = [], o = 0; o < n.length; ++o) { + s.push([e.slice(n[o].wholeMatch.start, n[o].wholeMatch.end), e.slice(n[o].match.start, n[o].match.end), e.slice(n[o].left.start, n[o].left.end), e.slice(n[o].right.start, n[o].right.end)]); + }return s; + }, a.helper.replaceRecursiveRegExp = function (e, r, t, n, s) { + if (!a.helper.isFunction(r)) { + var o = r;r = function r() { + return o; + }; + }var i = c(e, t, n, s), + l = e, + u = i.length;if (u > 0) { + var d = [];0 !== i[0].wholeMatch.start && d.push(e.slice(0, i[0].wholeMatch.start));for (var p = 0; p < u; ++p) { + d.push(r(e.slice(i[p].wholeMatch.start, i[p].wholeMatch.end), e.slice(i[p].match.start, i[p].match.end), e.slice(i[p].left.start, i[p].left.end), e.slice(i[p].right.start, i[p].right.end))), p < u - 1 && d.push(e.slice(i[p].wholeMatch.end, i[p + 1].wholeMatch.start)); + }i[u - 1].wholeMatch.end < e.length && d.push(e.slice(i[u - 1].wholeMatch.end)), l = d.join(""); + }return l; + }, a.helper.regexIndexOf = function (e, r, t) { + if (!a.helper.isString(e)) throw "InvalidArgumentError: first parameter of showdown.helper.regexIndexOf function must be a string";if (r instanceof RegExp == !1) throw "InvalidArgumentError: second parameter of showdown.helper.regexIndexOf function must be an instance of RegExp";var n = e.substring(t || 0).search(r);return n >= 0 ? n + (t || 0) : n; + }, a.helper.splitAtIndex = function (e, r) { + if (!a.helper.isString(e)) throw "InvalidArgumentError: first parameter of showdown.helper.regexIndexOf function must be a string";return [e.substring(0, r), e.substring(r)]; + }, a.helper.encodeEmailAddress = function (e) { + var r = [function (e) { + return "&#" + e.charCodeAt(0) + ";"; + }, function (e) { + return "&#x" + e.charCodeAt(0).toString(16) + ";"; + }, function (e) { + return e; + }];return e = e.replace(/./g, function (e) { + if ("@" === e) e = r[Math.floor(2 * Math.random())](e);else { + var t = Math.random();e = t > .9 ? r[2](e) : t > .45 ? r[1](e) : r[0](e); + }return e; + }); + }, a.helper.padEnd = function (e, r, t) { + return r >>= 0, t = String(t || " "), e.length > r ? String(e) : ((r -= e.length) > t.length && (t += t.repeat(r / t.length)), String(e) + t.slice(0, r)); + }, "undefined" == typeof console && (console = { warn: function warn(e) { + alert(e); + }, log: function log(e) { + alert(e); + }, error: function error(e) { + throw e; + } }), a.helper.regexes = { asteriskDashAndColon: /([*_:~])/g }, a.helper.emojis = { "+1": "👍", "-1": "👎", 100: "💯", 1234: "🔢", "1st_place_medal": "🥇", "2nd_place_medal": "🥈", "3rd_place_medal": "🥉", "8ball": "🎱", a: "🅰️", ab: "🆎", abc: "🔤", abcd: "🔡", accept: "🉑", aerial_tramway: "🚡", airplane: "✈️", alarm_clock: "⏰", alembic: "⚗️", alien: "👽", ambulance: "🚑", amphora: "🏺", anchor: "⚓️", angel: "👼", anger: "💢", angry: "😠", anguished: "😧", ant: "🐜", apple: "🍎", aquarius: "♒️", aries: "♈️", arrow_backward: "◀️", arrow_double_down: "⏬", arrow_double_up: "⏫", arrow_down: "⬇️", arrow_down_small: "🔽", arrow_forward: "▶️", arrow_heading_down: "⤵️", arrow_heading_up: "⤴️", arrow_left: "⬅️", arrow_lower_left: "↙️", arrow_lower_right: "↘️", arrow_right: "➡️", arrow_right_hook: "↪️", arrow_up: "⬆️", arrow_up_down: "↕️", arrow_up_small: "🔼", arrow_upper_left: "↖️", arrow_upper_right: "↗️", arrows_clockwise: "🔃", arrows_counterclockwise: "🔄", art: "🎨", articulated_lorry: "🚛", artificial_satellite: "🛰", astonished: "😲", athletic_shoe: "👟", atm: "🏧", atom_symbol: "⚛️", avocado: "🥑", b: "🅱️", baby: "👶", baby_bottle: "🍼", baby_chick: "🐤", baby_symbol: "🚼", back: "🔙", bacon: "🥓", badminton: "🏸", baggage_claim: "🛄", baguette_bread: "🥖", balance_scale: "⚖️", balloon: "🎈", ballot_box: "🗳", ballot_box_with_check: "☑️", bamboo: "🎍", banana: "🍌", bangbang: "‼️", bank: "🏦", bar_chart: "📊", barber: "💈", baseball: "⚾️", basketball: "🏀", basketball_man: "⛹️", basketball_woman: "⛹️‍♀️", bat: "🦇", bath: "🛀", bathtub: "🛁", battery: "🔋", beach_umbrella: "🏖", bear: "🐻", bed: "🛏", bee: "🐝", beer: "🍺", beers: "🍻", beetle: "🐞", beginner: "🔰", bell: "🔔", bellhop_bell: "🛎", bento: "🍱", biking_man: "🚴", bike: "🚲", biking_woman: "🚴‍♀️", bikini: "👙", biohazard: "☣️", bird: "🐦", birthday: "🎂", black_circle: "⚫️", black_flag: "🏴", black_heart: "🖤", black_joker: "🃏", black_large_square: "⬛️", black_medium_small_square: "◾️", black_medium_square: "◼️", black_nib: "✒️", black_small_square: "▪️", black_square_button: "🔲", blonde_man: "👱", blonde_woman: "👱‍♀️", blossom: "🌼", blowfish: "🐡", blue_book: "📘", blue_car: "🚙", blue_heart: "💙", blush: "😊", boar: "🐗", boat: "⛵️", bomb: "💣", book: "📖", bookmark: "🔖", bookmark_tabs: "📑", books: "📚", boom: "💥", boot: "👢", bouquet: "💐", bowing_man: "🙇", bow_and_arrow: "🏹", bowing_woman: "🙇‍♀️", bowling: "🎳", boxing_glove: "🥊", boy: "👦", bread: "🍞", bride_with_veil: "👰", bridge_at_night: "🌉", briefcase: "💼", broken_heart: "💔", bug: "🐛", building_construction: "🏗", bulb: "💡", bullettrain_front: "🚅", bullettrain_side: "🚄", burrito: "🌯", bus: "🚌", business_suit_levitating: "🕴", busstop: "🚏", bust_in_silhouette: "👤", busts_in_silhouette: "👥", butterfly: "🦋", cactus: "🌵", cake: "🍰", calendar: "📆", call_me_hand: "🤙", calling: "📲", camel: "🐫", camera: "📷", camera_flash: "📸", camping: "🏕", cancer: "♋️", candle: "🕯", candy: "🍬", canoe: "🛶", capital_abcd: "🔠", capricorn: "♑️", car: "🚗", card_file_box: "🗃", card_index: "📇", card_index_dividers: "🗂", carousel_horse: "🎠", carrot: "🥕", cat: "🐱", cat2: "🐈", cd: "💿", chains: "⛓", champagne: "🍾", chart: "💹", chart_with_downwards_trend: "📉", chart_with_upwards_trend: "📈", checkered_flag: "🏁", cheese: "🧀", cherries: "🍒", cherry_blossom: "🌸", chestnut: "🌰", chicken: "🐔", children_crossing: "🚸", chipmunk: "🐿", chocolate_bar: "🍫", christmas_tree: "🎄", church: "⛪️", cinema: "🎦", circus_tent: "🎪", city_sunrise: "🌇", city_sunset: "🌆", cityscape: "🏙", cl: "🆑", clamp: "🗜", clap: "👏", clapper: "🎬", classical_building: "🏛", clinking_glasses: "🥂", clipboard: "📋", clock1: "🕐", clock10: "🕙", clock1030: "🕥", clock11: "🕚", clock1130: "🕦", clock12: "🕛", clock1230: "🕧", clock130: "🕜", clock2: "🕑", clock230: "🕝", clock3: "🕒", clock330: "🕞", clock4: "🕓", clock430: "🕟", clock5: "🕔", clock530: "🕠", clock6: "🕕", clock630: "🕡", clock7: "🕖", clock730: "🕢", clock8: "🕗", clock830: "🕣", clock9: "🕘", clock930: "🕤", closed_book: "📕", closed_lock_with_key: "🔐", closed_umbrella: "🌂", cloud: "☁️", cloud_with_lightning: "🌩", cloud_with_lightning_and_rain: "⛈", cloud_with_rain: "🌧", cloud_with_snow: "🌨", clown_face: "🤡", clubs: "♣️", cocktail: "🍸", coffee: "☕️", coffin: "⚰️", cold_sweat: "😰", comet: "☄️", computer: "💻", computer_mouse: "🖱", confetti_ball: "🎊", confounded: "😖", confused: "😕", congratulations: "㊗️", construction: "🚧", construction_worker_man: "👷", construction_worker_woman: "👷‍♀️", control_knobs: "🎛", convenience_store: "🏪", cookie: "🍪", cool: "🆒", policeman: "👮", copyright: "©️", corn: "🌽", couch_and_lamp: "🛋", couple: "👫", couple_with_heart_woman_man: "💑", couple_with_heart_man_man: "👨‍❤️‍👨", couple_with_heart_woman_woman: "👩‍❤️‍👩", couplekiss_man_man: "👨‍❤️‍💋‍👨", couplekiss_man_woman: "💏", couplekiss_woman_woman: "👩‍❤️‍💋‍👩", cow: "🐮", cow2: "🐄", cowboy_hat_face: "🤠", crab: "🦀", crayon: "🖍", credit_card: "💳", crescent_moon: "🌙", cricket: "🏏", crocodile: "🐊", croissant: "🥐", crossed_fingers: "🤞", crossed_flags: "🎌", crossed_swords: "⚔️", crown: "👑", cry: "😢", crying_cat_face: "😿", crystal_ball: "🔮", cucumber: "🥒", cupid: "💘", curly_loop: "➰", currency_exchange: "💱", curry: "🍛", custard: "🍮", customs: "🛃", cyclone: "🌀", dagger: "🗡", dancer: "💃", dancing_women: "👯", dancing_men: "👯‍♂️", dango: "🍡", dark_sunglasses: "🕶", dart: "🎯", dash: "💨", date: "📅", deciduous_tree: "🌳", deer: "🦌", department_store: "🏬", derelict_house: "🏚", desert: "🏜", desert_island: "🏝", desktop_computer: "🖥", male_detective: "🕵️", diamond_shape_with_a_dot_inside: "💠", diamonds: "♦️", disappointed: "😞", disappointed_relieved: "😥", dizzy: "💫", dizzy_face: "😵", do_not_litter: "🚯", dog: "🐶", dog2: "🐕", dollar: "💵", dolls: "🎎", dolphin: "🐬", door: "🚪", doughnut: "🍩", dove: "🕊", dragon: "🐉", dragon_face: "🐲", dress: "👗", dromedary_camel: "🐪", drooling_face: "🤤", droplet: "💧", drum: "🥁", duck: "🦆", dvd: "📀", "e-mail": "📧", eagle: "🦅", ear: "👂", ear_of_rice: "🌾", earth_africa: "🌍", earth_americas: "🌎", earth_asia: "🌏", egg: "🥚", eggplant: "🍆", eight_pointed_black_star: "✴️", eight_spoked_asterisk: "✳️", electric_plug: "🔌", elephant: "🐘", email: "✉️", end: "🔚", envelope_with_arrow: "📩", euro: "💶", european_castle: "🏰", european_post_office: "🏤", evergreen_tree: "🌲", exclamation: "❗️", expressionless: "😑", eye: "👁", eye_speech_bubble: "👁‍🗨", eyeglasses: "👓", eyes: "👀", face_with_head_bandage: "🤕", face_with_thermometer: "🤒", fist_oncoming: "👊", factory: "🏭", fallen_leaf: "🍂", family_man_woman_boy: "👪", family_man_boy: "👨‍👦", family_man_boy_boy: "👨‍👦‍👦", family_man_girl: "👨‍👧", family_man_girl_boy: "👨‍👧‍👦", family_man_girl_girl: "👨‍👧‍👧", family_man_man_boy: "👨‍👨‍👦", family_man_man_boy_boy: "👨‍👨‍👦‍👦", family_man_man_girl: "👨‍👨‍👧", family_man_man_girl_boy: "👨‍👨‍👧‍👦", family_man_man_girl_girl: "👨‍👨‍👧‍👧", family_man_woman_boy_boy: "👨‍👩‍👦‍👦", family_man_woman_girl: "👨‍👩‍👧", family_man_woman_girl_boy: "👨‍👩‍👧‍👦", family_man_woman_girl_girl: "👨‍👩‍👧‍👧", family_woman_boy: "👩‍👦", family_woman_boy_boy: "👩‍👦‍👦", family_woman_girl: "👩‍👧", family_woman_girl_boy: "👩‍👧‍👦", family_woman_girl_girl: "👩‍👧‍👧", family_woman_woman_boy: "👩‍👩‍👦", family_woman_woman_boy_boy: "👩‍👩‍👦‍👦", family_woman_woman_girl: "👩‍👩‍👧", family_woman_woman_girl_boy: "👩‍👩‍👧‍👦", family_woman_woman_girl_girl: "👩‍👩‍👧‍👧", fast_forward: "⏩", fax: "📠", fearful: "😨", feet: "🐾", female_detective: "🕵️‍♀️", ferris_wheel: "🎡", ferry: "⛴", field_hockey: "🏑", file_cabinet: "🗄", file_folder: "📁", film_projector: "📽", film_strip: "🎞", fire: "🔥", fire_engine: "🚒", fireworks: "🎆", first_quarter_moon: "🌓", first_quarter_moon_with_face: "🌛", fish: "🐟", fish_cake: "🍥", fishing_pole_and_fish: "🎣", fist_raised: "✊", fist_left: "🤛", fist_right: "🤜", flags: "🎏", flashlight: "🔦", fleur_de_lis: "⚜️", flight_arrival: "🛬", flight_departure: "🛫", floppy_disk: "💾", flower_playing_cards: "🎴", flushed: "😳", fog: "🌫", foggy: "🌁", football: "🏈", footprints: "👣", fork_and_knife: "🍴", fountain: "⛲️", fountain_pen: "🖋", four_leaf_clover: "🍀", fox_face: "🦊", framed_picture: "🖼", free: "🆓", fried_egg: "🍳", fried_shrimp: "🍤", fries: "🍟", frog: "🐸", frowning: "😦", frowning_face: "☹️", frowning_man: "🙍‍♂️", frowning_woman: "🙍", middle_finger: "🖕", fuelpump: "⛽️", full_moon: "🌕", full_moon_with_face: "🌝", funeral_urn: "⚱️", game_die: "🎲", gear: "⚙️", gem: "💎", gemini: "♊️", ghost: "👻", gift: "🎁", gift_heart: "💝", girl: "👧", globe_with_meridians: "🌐", goal_net: "🥅", goat: "🐐", golf: "⛳️", golfing_man: "🏌️", golfing_woman: "🏌️‍♀️", gorilla: "🦍", grapes: "🍇", green_apple: "🍏", green_book: "📗", green_heart: "💚", green_salad: "🥗", grey_exclamation: "❕", grey_question: "❔", grimacing: "😬", grin: "😁", grinning: "😀", guardsman: "💂", guardswoman: "💂‍♀️", guitar: "🎸", gun: "🔫", haircut_woman: "💇", haircut_man: "💇‍♂️", hamburger: "🍔", hammer: "🔨", hammer_and_pick: "⚒", hammer_and_wrench: "🛠", hamster: "🐹", hand: "✋", handbag: "👜", handshake: "🤝", hankey: "💩", hatched_chick: "🐥", hatching_chick: "🐣", headphones: "🎧", hear_no_evil: "🙉", heart: "❤️", heart_decoration: "💟", heart_eyes: "😍", heart_eyes_cat: "😻", heartbeat: "💓", heartpulse: "💗", hearts: "♥️", heavy_check_mark: "✔️", heavy_division_sign: "➗", heavy_dollar_sign: "💲", heavy_heart_exclamation: "❣️", heavy_minus_sign: "➖", heavy_multiplication_x: "✖️", heavy_plus_sign: "➕", helicopter: "🚁", herb: "🌿", hibiscus: "🌺", high_brightness: "🔆", high_heel: "👠", hocho: "🔪", hole: "🕳", honey_pot: "🍯", horse: "🐴", horse_racing: "🏇", hospital: "🏥", hot_pepper: "🌶", hotdog: "🌭", hotel: "🏨", hotsprings: "♨️", hourglass: "⌛️", hourglass_flowing_sand: "⏳", house: "🏠", house_with_garden: "🏡", houses: "🏘", hugs: "🤗", hushed: "😯", ice_cream: "🍨", ice_hockey: "🏒", ice_skate: "⛸", icecream: "🍦", id: "🆔", ideograph_advantage: "🉐", imp: "👿", inbox_tray: "📥", incoming_envelope: "📨", tipping_hand_woman: "💁", information_source: "ℹ️", innocent: "😇", interrobang: "⁉️", iphone: "📱", izakaya_lantern: "🏮", jack_o_lantern: "🎃", japan: "🗾", japanese_castle: "🏯", japanese_goblin: "👺", japanese_ogre: "👹", jeans: "👖", joy: "😂", joy_cat: "😹", joystick: "🕹", kaaba: "🕋", key: "🔑", keyboard: "⌨️", keycap_ten: "🔟", kick_scooter: "🛴", kimono: "👘", kiss: "💋", kissing: "😗", kissing_cat: "😽", kissing_closed_eyes: "😚", kissing_heart: "😘", kissing_smiling_eyes: "😙", kiwi_fruit: "🥝", koala: "🐨", koko: "🈁", label: "🏷", large_blue_circle: "🔵", large_blue_diamond: "🔷", large_orange_diamond: "🔶", last_quarter_moon: "🌗", last_quarter_moon_with_face: "🌜", latin_cross: "✝️", laughing: "😆", leaves: "🍃", ledger: "📒", left_luggage: "🛅", left_right_arrow: "↔️", leftwards_arrow_with_hook: "↩️", lemon: "🍋", leo: "♌️", leopard: "🐆", level_slider: "🎚", libra: "♎️", light_rail: "🚈", link: "🔗", lion: "🦁", lips: "👄", lipstick: "💄", lizard: "🦎", lock: "🔒", lock_with_ink_pen: "🔏", lollipop: "🍭", loop: "➿", loud_sound: "🔊", loudspeaker: "📢", love_hotel: "🏩", love_letter: "💌", low_brightness: "🔅", lying_face: "🤥", m: "Ⓜ️", mag: "🔍", mag_right: "🔎", mahjong: "🀄️", mailbox: "📫", mailbox_closed: "📪", mailbox_with_mail: "📬", mailbox_with_no_mail: "📭", man: "👨", man_artist: "👨‍🎨", man_astronaut: "👨‍🚀", man_cartwheeling: "🤸‍♂️", man_cook: "👨‍🍳", man_dancing: "🕺", man_facepalming: "🤦‍♂️", man_factory_worker: "👨‍🏭", man_farmer: "👨‍🌾", man_firefighter: "👨‍🚒", man_health_worker: "👨‍⚕️", man_in_tuxedo: "🤵", man_judge: "👨‍⚖️", man_juggling: "🤹‍♂️", man_mechanic: "👨‍🔧", man_office_worker: "👨‍💼", man_pilot: "👨‍✈️", man_playing_handball: "🤾‍♂️", man_playing_water_polo: "🤽‍♂️", man_scientist: "👨‍🔬", man_shrugging: "🤷‍♂️", man_singer: "👨‍🎤", man_student: "👨‍🎓", man_teacher: "👨‍🏫", man_technologist: "👨‍💻", man_with_gua_pi_mao: "👲", man_with_turban: "👳", tangerine: "🍊", mans_shoe: "👞", mantelpiece_clock: "🕰", maple_leaf: "🍁", martial_arts_uniform: "🥋", mask: "😷", massage_woman: "💆", massage_man: "💆‍♂️", meat_on_bone: "🍖", medal_military: "🎖", medal_sports: "🏅", mega: "📣", melon: "🍈", memo: "📝", men_wrestling: "🤼‍♂️", menorah: "🕎", mens: "🚹", metal: "🤘", metro: "🚇", microphone: "🎤", microscope: "🔬", milk_glass: "🥛", milky_way: "🌌", minibus: "🚐", minidisc: "💽", mobile_phone_off: "📴", money_mouth_face: "🤑", money_with_wings: "💸", moneybag: "💰", monkey: "🐒", monkey_face: "🐵", monorail: "🚝", moon: "🌔", mortar_board: "🎓", mosque: "🕌", motor_boat: "🛥", motor_scooter: "🛵", motorcycle: "🏍", motorway: "🛣", mount_fuji: "🗻", mountain: "⛰", mountain_biking_man: "🚵", mountain_biking_woman: "🚵‍♀️", mountain_cableway: "🚠", mountain_railway: "🚞", mountain_snow: "🏔", mouse: "🐭", mouse2: "🐁", movie_camera: "🎥", moyai: "🗿", mrs_claus: "🤶", muscle: "💪", mushroom: "🍄", musical_keyboard: "🎹", musical_note: "🎵", musical_score: "🎼", mute: "🔇", nail_care: "💅", name_badge: "📛", national_park: "🏞", nauseated_face: "🤢", necktie: "👔", negative_squared_cross_mark: "❎", nerd_face: "🤓", neutral_face: "😐", new: "🆕", new_moon: "🌑", new_moon_with_face: "🌚", newspaper: "📰", newspaper_roll: "🗞", next_track_button: "⏭", ng: "🆖", no_good_man: "🙅‍♂️", no_good_woman: "🙅", night_with_stars: "🌃", no_bell: "🔕", no_bicycles: "🚳", no_entry: "⛔️", no_entry_sign: "🚫", no_mobile_phones: "📵", no_mouth: "😶", no_pedestrians: "🚷", no_smoking: "🚭", "non-potable_water": "🚱", nose: "👃", notebook: "📓", notebook_with_decorative_cover: "📔", notes: "🎶", nut_and_bolt: "🔩", o: "⭕️", o2: "🅾️", ocean: "🌊", octopus: "🐙", oden: "🍢", office: "🏢", oil_drum: "🛢", ok: "🆗", ok_hand: "👌", ok_man: "🙆‍♂️", ok_woman: "🙆", old_key: "🗝", older_man: "👴", older_woman: "👵", om: "🕉", on: "🔛", oncoming_automobile: "🚘", oncoming_bus: "🚍", oncoming_police_car: "🚔", oncoming_taxi: "🚖", open_file_folder: "📂", open_hands: "👐", open_mouth: "😮", open_umbrella: "☂️", ophiuchus: "⛎", orange_book: "📙", orthodox_cross: "☦️", outbox_tray: "📤", owl: "🦉", ox: "🐂", package: "📦", page_facing_up: "📄", page_with_curl: "📃", pager: "📟", paintbrush: "🖌", palm_tree: "🌴", pancakes: "🥞", panda_face: "🐼", paperclip: "📎", paperclips: "🖇", parasol_on_ground: "⛱", parking: "🅿️", part_alternation_mark: "〽️", partly_sunny: "⛅️", passenger_ship: "🛳", passport_control: "🛂", pause_button: "⏸", peace_symbol: "☮️", peach: "🍑", peanuts: "🥜", pear: "🍐", pen: "🖊", pencil2: "✏️", penguin: "🐧", pensive: "😔", performing_arts: "🎭", persevere: "😣", person_fencing: "🤺", pouting_woman: "🙎", phone: "☎️", pick: "⛏", pig: "🐷", pig2: "🐖", pig_nose: "🐽", pill: "💊", pineapple: "🍍", ping_pong: "🏓", pisces: "♓️", pizza: "🍕", place_of_worship: "🛐", plate_with_cutlery: "🍽", play_or_pause_button: "⏯", point_down: "👇", point_left: "👈", point_right: "👉", point_up: "☝️", point_up_2: "👆", police_car: "🚓", policewoman: "👮‍♀️", poodle: "🐩", popcorn: "🍿", post_office: "🏣", postal_horn: "📯", postbox: "📮", potable_water: "🚰", potato: "🥔", pouch: "👝", poultry_leg: "🍗", pound: "💷", rage: "😡", pouting_cat: "😾", pouting_man: "🙎‍♂️", pray: "🙏", prayer_beads: "📿", pregnant_woman: "🤰", previous_track_button: "⏮", prince: "🤴", princess: "👸", printer: "🖨", purple_heart: "💜", purse: "👛", pushpin: "📌", put_litter_in_its_place: "🚮", question: "❓", rabbit: "🐰", rabbit2: "🐇", racehorse: "🐎", racing_car: "🏎", radio: "📻", radio_button: "🔘", radioactive: "☢️", railway_car: "🚃", railway_track: "🛤", rainbow: "🌈", rainbow_flag: "🏳️‍🌈", raised_back_of_hand: "🤚", raised_hand_with_fingers_splayed: "🖐", raised_hands: "🙌", raising_hand_woman: "🙋", raising_hand_man: "🙋‍♂️", ram: "🐏", ramen: "🍜", rat: "🐀", record_button: "⏺", recycle: "♻️", red_circle: "🔴", registered: "®️", relaxed: "☺️", relieved: "😌", reminder_ribbon: "🎗", repeat: "🔁", repeat_one: "🔂", rescue_worker_helmet: "⛑", restroom: "🚻", revolving_hearts: "💞", rewind: "⏪", rhinoceros: "🦏", ribbon: "🎀", rice: "🍚", rice_ball: "🍙", rice_cracker: "🍘", rice_scene: "🎑", right_anger_bubble: "🗯", ring: "💍", robot: "🤖", rocket: "🚀", rofl: "🤣", roll_eyes: "🙄", roller_coaster: "🎢", rooster: "🐓", rose: "🌹", rosette: "🏵", rotating_light: "🚨", round_pushpin: "📍", rowing_man: "🚣", rowing_woman: "🚣‍♀️", rugby_football: "🏉", running_man: "🏃", running_shirt_with_sash: "🎽", running_woman: "🏃‍♀️", sa: "🈂️", sagittarius: "♐️", sake: "🍶", sandal: "👡", santa: "🎅", satellite: "📡", saxophone: "🎷", school: "🏫", school_satchel: "🎒", scissors: "✂️", scorpion: "🦂", scorpius: "♏️", scream: "😱", scream_cat: "🙀", scroll: "📜", seat: "💺", secret: "㊙️", see_no_evil: "🙈", seedling: "🌱", selfie: "🤳", shallow_pan_of_food: "🥘", shamrock: "☘️", shark: "🦈", shaved_ice: "🍧", sheep: "🐑", shell: "🐚", shield: "🛡", shinto_shrine: "⛩", ship: "🚢", shirt: "👕", shopping: "🛍", shopping_cart: "🛒", shower: "🚿", shrimp: "🦐", signal_strength: "📶", six_pointed_star: "🔯", ski: "🎿", skier: "⛷", skull: "💀", skull_and_crossbones: "☠️", sleeping: "😴", sleeping_bed: "🛌", sleepy: "😪", slightly_frowning_face: "🙁", slightly_smiling_face: "🙂", slot_machine: "🎰", small_airplane: "🛩", small_blue_diamond: "🔹", small_orange_diamond: "🔸", small_red_triangle: "🔺", small_red_triangle_down: "🔻", smile: "😄", smile_cat: "😸", smiley: "😃", smiley_cat: "😺", smiling_imp: "😈", smirk: "😏", smirk_cat: "😼", smoking: "🚬", snail: "🐌", snake: "🐍", sneezing_face: "🤧", snowboarder: "🏂", snowflake: "❄️", snowman: "⛄️", snowman_with_snow: "☃️", sob: "😭", soccer: "⚽️", soon: "🔜", sos: "🆘", sound: "🔉", space_invader: "👾", spades: "♠️", spaghetti: "🍝", sparkle: "❇️", sparkler: "🎇", sparkles: "✨", sparkling_heart: "💖", speak_no_evil: "🙊", speaker: "🔈", speaking_head: "🗣", speech_balloon: "💬", speedboat: "🚤", spider: "🕷", spider_web: "🕸", spiral_calendar: "🗓", spiral_notepad: "🗒", spoon: "🥄", squid: "🦑", stadium: "🏟", star: "⭐️", star2: "🌟", star_and_crescent: "☪️", star_of_david: "✡️", stars: "🌠", station: "🚉", statue_of_liberty: "🗽", steam_locomotive: "🚂", stew: "🍲", stop_button: "⏹", stop_sign: "🛑", stopwatch: "⏱", straight_ruler: "📏", strawberry: "🍓", stuck_out_tongue: "😛", stuck_out_tongue_closed_eyes: "😝", stuck_out_tongue_winking_eye: "😜", studio_microphone: "🎙", stuffed_flatbread: "🥙", sun_behind_large_cloud: "🌥", sun_behind_rain_cloud: "🌦", sun_behind_small_cloud: "🌤", sun_with_face: "🌞", sunflower: "🌻", sunglasses: "😎", sunny: "☀️", sunrise: "🌅", sunrise_over_mountains: "🌄", surfing_man: "🏄", surfing_woman: "🏄‍♀️", sushi: "🍣", suspension_railway: "🚟", sweat: "😓", sweat_drops: "💦", sweat_smile: "😅", sweet_potato: "🍠", swimming_man: "🏊", swimming_woman: "🏊‍♀️", symbols: "🔣", synagogue: "🕍", syringe: "💉", taco: "🌮", tada: "🎉", tanabata_tree: "🎋", taurus: "♉️", taxi: "🚕", tea: "🍵", telephone_receiver: "📞", telescope: "🔭", tennis: "🎾", tent: "⛺️", thermometer: "🌡", thinking: "🤔", thought_balloon: "💭", ticket: "🎫", tickets: "🎟", tiger: "🐯", tiger2: "🐅", timer_clock: "⏲", tipping_hand_man: "💁‍♂️", tired_face: "😫", tm: "™️", toilet: "🚽", tokyo_tower: "🗼", tomato: "🍅", tongue: "👅", top: "🔝", tophat: "🎩", tornado: "🌪", trackball: "🖲", tractor: "🚜", traffic_light: "🚥", train: "🚋", train2: "🚆", tram: "🚊", triangular_flag_on_post: "🚩", triangular_ruler: "📐", trident: "🔱", triumph: "😤", trolleybus: "🚎", trophy: "🏆", tropical_drink: "🍹", tropical_fish: "🐠", truck: "🚚", trumpet: "🎺", tulip: "🌷", tumbler_glass: "🥃", turkey: "🦃", turtle: "🐢", tv: "📺", twisted_rightwards_arrows: "🔀", two_hearts: "💕", two_men_holding_hands: "👬", two_women_holding_hands: "👭", u5272: "🈹", u5408: "🈴", u55b6: "🈺", u6307: "🈯️", u6708: "🈷️", u6709: "🈶", u6e80: "🈵", u7121: "🈚️", u7533: "🈸", u7981: "🈲", u7a7a: "🈳", umbrella: "☔️", unamused: "😒", underage: "🔞", unicorn: "🦄", unlock: "🔓", up: "🆙", upside_down_face: "🙃", v: "✌️", vertical_traffic_light: "🚦", vhs: "📼", vibration_mode: "📳", video_camera: "📹", video_game: "🎮", violin: "🎻", virgo: "♍️", volcano: "🌋", volleyball: "🏐", vs: "🆚", vulcan_salute: "🖖", walking_man: "🚶", walking_woman: "🚶‍♀️", waning_crescent_moon: "🌘", waning_gibbous_moon: "🌖", warning: "⚠️", wastebasket: "🗑", watch: "⌚️", water_buffalo: "🐃", watermelon: "🍉", wave: "👋", wavy_dash: "〰️", waxing_crescent_moon: "🌒", wc: "🚾", weary: "😩", wedding: "💒", weight_lifting_man: "🏋️", weight_lifting_woman: "🏋️‍♀️", whale: "🐳", whale2: "🐋", wheel_of_dharma: "☸️", wheelchair: "♿️", white_check_mark: "✅", white_circle: "⚪️", white_flag: "🏳️", white_flower: "💮", white_large_square: "⬜️", white_medium_small_square: "◽️", white_medium_square: "◻️", white_small_square: "▫️", white_square_button: "🔳", wilted_flower: "🥀", wind_chime: "🎐", wind_face: "🌬", wine_glass: "🍷", wink: "😉", wolf: "🐺", woman: "👩", woman_artist: "👩‍🎨", woman_astronaut: "👩‍🚀", woman_cartwheeling: "🤸‍♀️", woman_cook: "👩‍🍳", woman_facepalming: "🤦‍♀️", woman_factory_worker: "👩‍🏭", woman_farmer: "👩‍🌾", woman_firefighter: "👩‍🚒", woman_health_worker: "👩‍⚕️", woman_judge: "👩‍⚖️", woman_juggling: "🤹‍♀️", woman_mechanic: "👩‍🔧", woman_office_worker: "👩‍💼", woman_pilot: "👩‍✈️", woman_playing_handball: "🤾‍♀️", woman_playing_water_polo: "🤽‍♀️", woman_scientist: "👩‍🔬", woman_shrugging: "🤷‍♀️", woman_singer: "👩‍🎤", woman_student: "👩‍🎓", woman_teacher: "👩‍🏫", woman_technologist: "👩‍💻", woman_with_turban: "👳‍♀️", womans_clothes: "👚", womans_hat: "👒", women_wrestling: "🤼‍♀️", womens: "🚺", world_map: "🗺", worried: "😟", wrench: "🔧", writing_hand: "✍️", x: "❌", yellow_heart: "💛", yen: "💴", yin_yang: "☯️", yum: "😋", zap: "⚡️", zipper_mouth_face: "🤐", zzz: "💤", octocat: ':octocat:', showdown: "S" }, a.Converter = function (e) { + function t(e, t) { + if (t = t || null, a.helper.isString(e)) { + if (e = a.helper.stdExtName(e), t = e, a.extensions[e]) return console.warn("DEPRECATION WARNING: " + e + " is an old extension that uses a deprecated loading method.Please inform the developer that the extension should be updated!"), void function (e, t) { + "function" == typeof e && (e = e(new a.Converter()));a.helper.isArray(e) || (e = [e]);var n = r(e, t);if (!n.valid) throw Error(n.error);for (var s = 0; s < e.length; ++s) { + switch (e[s].type) {case "lang": + u.push(e[s]);break;case "output": + d.push(e[s]);break;default: + throw Error("Extension loader error: Type unrecognized!!!");} + } + }(a.extensions[e], e);if (a.helper.isUndefined(s[e])) throw Error('Extension "' + e + '" could not be loaded. It was either not found or is not a valid extension.');e = s[e]; + }"function" == typeof e && (e = e()), a.helper.isArray(e) || (e = [e]);var o = r(e, t);if (!o.valid) throw Error(o.error);for (var i = 0; i < e.length; ++i) { + switch (e[i].type) {case "lang": + u.push(e[i]);break;case "output": + d.push(e[i]);}if (e[i].hasOwnProperty("listeners")) for (var l in e[i].listeners) { + e[i].listeners.hasOwnProperty(l) && n(l, e[i].listeners[l]); + } + } + }function n(e, r) { + if (!a.helper.isString(e)) throw Error("Invalid argument in converter.listen() method: name must be a string, but " + (typeof e === "undefined" ? "undefined" : _typeof(e)) + " given");if ("function" != typeof r) throw Error("Invalid argument in converter.listen() method: callback must be a function, but " + (typeof r === "undefined" ? "undefined" : _typeof(r)) + " given");p.hasOwnProperty(e) || (p[e] = []), p[e].push(r); + }var c = {}, + u = [], + d = [], + p = {}, + h = i, + _ = { parsed: {}, raw: "", format: "" };!function () { + e = e || {};for (var r in o) { + o.hasOwnProperty(r) && (c[r] = o[r]); + }if ("object" != (typeof e === "undefined" ? "undefined" : _typeof(e))) throw Error("Converter expects the passed parameter to be an object, but " + (typeof e === "undefined" ? "undefined" : _typeof(e)) + " was passed instead.");for (var n in e) { + e.hasOwnProperty(n) && (c[n] = e[n]); + }c.extensions && a.helper.forEach(c.extensions, t); + }(), this._dispatch = function (e, r, t, a) { + if (p.hasOwnProperty(e)) for (var n = 0; n < p[e].length; ++n) { + var s = p[e][n](e, r, this, t, a);s && void 0 !== s && (r = s); + }return r; + }, this.listen = function (e, r) { + return n(e, r), this; + }, this.makeHtml = function (e) { + if (!e) return e;var r = { gHtmlBlocks: [], gHtmlMdBlocks: [], gHtmlSpans: [], gUrls: {}, gTitles: {}, gDimensions: {}, gListLevel: 0, hashLinkCounts: {}, langExtensions: u, outputModifiers: d, converter: this, ghCodeBlocks: [], metadata: { parsed: {}, raw: "", format: "" } };return e = e.replace(/¨/g, "¨T"), e = e.replace(/\$/g, "¨D"), e = e.replace(/\r\n/g, "\n"), e = e.replace(/\r/g, "\n"), e = e.replace(/\u00A0/g, " "), c.smartIndentationFix && (e = function (e) { + var r = e.match(/^\s*/)[0].length, + t = new RegExp("^\\s{0," + r + "}", "gm");return e.replace(t, ""); + }(e)), e = "\n\n" + e + "\n\n", e = a.subParser("detab")(e, c, r), e = e.replace(/^[ \t]+$/gm, ""), a.helper.forEach(u, function (t) { + e = a.subParser("runExtension")(t, e, c, r); + }), e = a.subParser("metadata")(e, c, r), e = a.subParser("hashPreCodeTags")(e, c, r), e = a.subParser("githubCodeBlocks")(e, c, r), e = a.subParser("hashHTMLBlocks")(e, c, r), e = a.subParser("hashCodeTags")(e, c, r), e = a.subParser("stripLinkDefinitions")(e, c, r), e = a.subParser("blockGamut")(e, c, r), e = a.subParser("unhashHTMLSpans")(e, c, r), e = a.subParser("unescapeSpecialChars")(e, c, r), e = e.replace(/¨D/g, "$$"), e = e.replace(/¨T/g, "¨"), e = a.subParser("completeHTMLDocument")(e, c, r), a.helper.forEach(d, function (t) { + e = a.subParser("runExtension")(t, e, c, r); + }), _ = r.metadata, e; + }, this.makeMarkdown = this.makeMd = function (e, r) { + function t(e) { + for (var r = 0; r < e.childNodes.length; ++r) { + var a = e.childNodes[r];3 === a.nodeType ? /\S/.test(a.nodeValue) ? (a.nodeValue = a.nodeValue.split("\n").join(" "), a.nodeValue = a.nodeValue.replace(/(\s)+/g, "$1")) : (e.removeChild(a), --r) : 1 === a.nodeType && t(a); + } + }if (e = e.replace(/\r\n/g, "\n"), e = e.replace(/\r/g, "\n"), e = e.replace(/>[ \t]+¨NBSP;<"), !r) { + if (!window || !window.document) throw new Error("HTMLParser is undefined. If in a webworker or nodejs environment, you need to provide a WHATWG DOM and HTML such as JSDOM");r = window.document; + }var n = r.createElement("div");n.innerHTML = e;var s = { preList: function (e) { + for (var r = e.querySelectorAll("pre"), t = [], n = 0; n < r.length; ++n) { + if (1 === r[n].childElementCount && "code" === r[n].firstChild.tagName.toLowerCase()) { + var s = r[n].firstChild.innerHTML.trim(), + o = r[n].firstChild.getAttribute("data-language") || "";if ("" === o) for (var i = r[n].firstChild.className.split(" "), l = 0; l < i.length; ++l) { + var c = i[l].match(/^language-(.+)$/);if (null !== c) { + o = c[1];break; + } + }s = a.helper.unescapeHTMLEntities(s), t.push(s), r[n].outerHTML = ''; + } else t.push(r[n].innerHTML), r[n].innerHTML = "", r[n].setAttribute("prenum", n.toString()); + }return t; + }(n) };t(n);for (var o = n.childNodes, i = "", l = 0; l < o.length; l++) { + i += a.subParser("makeMarkdown.node")(o[l], s); + }return i; + }, this.setOption = function (e, r) { + c[e] = r; + }, this.getOption = function (e) { + return c[e]; + }, this.getOptions = function () { + return c; + }, this.addExtension = function (e, r) { + t(e, r = r || null); + }, this.useExtension = function (e) { + t(e); + }, this.setFlavor = function (e) { + if (!l.hasOwnProperty(e)) throw Error(e + " flavor was not found");var r = l[e];h = e;for (var t in r) { + r.hasOwnProperty(t) && (c[t] = r[t]); + } + }, this.getFlavor = function () { + return h; + }, this.removeExtension = function (e) { + a.helper.isArray(e) || (e = [e]);for (var r = 0; r < e.length; ++r) { + for (var t = e[r], n = 0; n < u.length; ++n) { + u[n] === t && u[n].splice(n, 1); + }for (; 0 < d.length; ++n) { + d[0] === t && d[0].splice(n, 1); + } + } + }, this.getAllExtensions = function () { + return { language: u, output: d }; + }, this.getMetadata = function (e) { + return e ? _.raw : _.parsed; + }, this.getMetadataFormat = function () { + return _.format; + }, this._setMetadataPair = function (e, r) { + _.parsed[e] = r; + }, this._setMetadataFormat = function (e) { + _.format = e; + }, this._setMetadataRaw = function (e) { + _.raw = e; + }; + }, a.subParser("anchors", function (e, r, t) { + var n = function n(e, _n, s, o, i, l, c) { + if (a.helper.isUndefined(c) && (c = ""), s = s.toLowerCase(), e.search(/\(? ?(['"].*['"])?\)$/m) > -1) o = "";else if (!o) { + if (s || (s = _n.toLowerCase().replace(/ ?\n/g, " ")), o = "#" + s, a.helper.isUndefined(t.gUrls[s])) return e;o = t.gUrls[s], a.helper.isUndefined(t.gTitles[s]) || (c = t.gTitles[s]); + }var u = '"; + };return e = (e = t.converter._dispatch("anchors.before", e, r, t)).replace(/\[((?:\[[^\]]*]|[^\[\]])*)] ?(?:\n *)?\[(.*?)]()()()()/g, n), e = e.replace(/\[((?:\[[^\]]*]|[^\[\]])*)]()[ \t]*\([ \t]?<([^>]*)>(?:[ \t]*((["'])([^"]*?)\5))?[ \t]?\)/g, n), e = e.replace(/\[((?:\[[^\]]*]|[^\[\]])*)]()[ \t]*\([ \t]??(?:[ \t]*((["'])([^"]*?)\5))?[ \t]?\)/g, n), e = e.replace(/\[([^\[\]]+)]()()()()()/g, n), r.ghMentions && (e = e.replace(/(^|\s)(\\)?(@([a-z\d]+(?:[a-z\d.-]+?[a-z\d]+)*))/gim, function (e, t, n, s, o) { + if ("\\" === n) return t + s;if (!a.helper.isString(r.ghMentionsLink)) throw new Error("ghMentionsLink option must be a string");var i = r.ghMentionsLink.replace(/\{u}/g, o), + l = "";return r.openLinksInNewWindow && (l = ' target="¨E95Eblank"'), t + '" + s + ""; + })), e = t.converter._dispatch("anchors.after", e, r, t); + });var u = /([*~_]+|\b)(((https?|ftp|dict):\/\/|www\.)[^'">\s]+?\.[^'">\s]+?)()(\1)?(?=\s|$)(?!["<>])/gi, + d = /([*~_]+|\b)(((https?|ftp|dict):\/\/|www\.)[^'">\s]+\.[^'">\s]+?)([.!?,()\[\]])?(\1)?(?=\s|$)(?!["<>])/gi, + p = /()<(((https?|ftp|dict):\/\/|www\.)[^'">\s]+)()>()/gi, + h = /(^|\s)(?:mailto:)?([A-Za-z0-9!#$%&'*+-/=?^_`{|}~.]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)(?=$|\s)/gim, + _ = /<()(?:mailto:)?([-.\w]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi, + g = function g(e) { + return function (r, t, n, s, o, i, l) { + var c = n = n.replace(a.helper.regexes.asteriskDashAndColon, a.helper.escapeCharactersCallback), + u = "", + d = "", + p = t || "", + h = l || "";return (/^www\./i.test(n) && (n = n.replace(/^www\./i, "http://www.")), e.excludeTrailingPunctuationFromURLs && i && (u = i), e.openLinksInNewWindow && (d = ' target="¨E95Eblank"'), p + '" + c + "" + u + h); + }; + }, + m = function m(e, r) { + return function (t, n, s) { + var o = "mailto:";return n = n || "", s = a.subParser("unescapeSpecialChars")(s, e, r), e.encodeEmails ? (o = a.helper.encodeEmailAddress(o + s), s = a.helper.encodeEmailAddress(s)) : o += s, n + '' + s + ""; + }; + };a.subParser("autoLinks", function (e, r, t) { + return e = t.converter._dispatch("autoLinks.before", e, r, t), e = e.replace(p, g(r)), e = e.replace(_, m(r, t)), e = t.converter._dispatch("autoLinks.after", e, r, t); + }), a.subParser("simplifiedAutoLinks", function (e, r, t) { + return r.simplifiedAutoLink ? (e = t.converter._dispatch("simplifiedAutoLinks.before", e, r, t), e = r.excludeTrailingPunctuationFromURLs ? e.replace(d, g(r)) : e.replace(u, g(r)), e = e.replace(h, m(r, t)), e = t.converter._dispatch("simplifiedAutoLinks.after", e, r, t)) : e; + }), a.subParser("blockGamut", function (e, r, t) { + return e = t.converter._dispatch("blockGamut.before", e, r, t), e = a.subParser("blockQuotes")(e, r, t), e = a.subParser("headers")(e, r, t), e = a.subParser("horizontalRule")(e, r, t), e = a.subParser("lists")(e, r, t), e = a.subParser("codeBlocks")(e, r, t), e = a.subParser("tables")(e, r, t), e = a.subParser("hashHTMLBlocks")(e, r, t), e = a.subParser("paragraphs")(e, r, t), e = t.converter._dispatch("blockGamut.after", e, r, t); + }), a.subParser("blockQuotes", function (e, r, t) { + e = t.converter._dispatch("blockQuotes.before", e, r, t), e += "\n\n";var n = /(^ {0,3}>[ \t]?.+\n(.+\n)*\n*)+/gm;return r.splitAdjacentBlockquotes && (n = /^ {0,3}>[\s\S]*?(?:\n\n)/gm), e = e.replace(n, function (e) { + return e = e.replace(/^[ \t]*>[ \t]?/gm, ""), e = e.replace(/¨0/g, ""), e = e.replace(/^[ \t]+$/gm, ""), e = a.subParser("githubCodeBlocks")(e, r, t), e = a.subParser("blockGamut")(e, r, t), e = e.replace(/(^|\n)/g, "$1 "), e = e.replace(/(\s*
[^\r]+?<\/pre>)/gm, function (e, r) {
+	          var t = r;return t = t.replace(/^  /gm, "¨0"), t = t.replace(/¨0/g, "");
+	        }), a.subParser("hashBlock")("
\n" + e + "\n
", r, t); + }), e = t.converter._dispatch("blockQuotes.after", e, r, t); + }), a.subParser("codeBlocks", function (e, r, t) { + e = t.converter._dispatch("codeBlocks.before", e, r, t);return e = (e += "¨0").replace(/(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=¨0))/g, function (e, n, s) { + var o = n, + i = s, + l = "\n";return o = a.subParser("outdent")(o, r, t), o = a.subParser("encodeCode")(o, r, t), o = a.subParser("detab")(o, r, t), o = o.replace(/^\n+/g, ""), o = o.replace(/\n+$/g, ""), r.omitExtraWLInCodeBlocks && (l = ""), o = "
" + o + l + "
", a.subParser("hashBlock")(o, r, t) + i; + }), e = e.replace(/¨0/, ""), e = t.converter._dispatch("codeBlocks.after", e, r, t); + }), a.subParser("codeSpans", function (e, r, t) { + return void 0 === (e = t.converter._dispatch("codeSpans.before", e, r, t)) && (e = ""), e = e.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm, function (e, n, s, o) { + var i = o;return i = i.replace(/^([ \t]*)/g, ""), i = i.replace(/[ \t]*$/g, ""), i = a.subParser("encodeCode")(i, r, t), i = n + "" + i + "", i = a.subParser("hashHTMLSpans")(i, r, t); + }), e = t.converter._dispatch("codeSpans.after", e, r, t); + }), a.subParser("completeHTMLDocument", function (e, r, t) { + if (!r.completeHTMLDocument) return e;e = t.converter._dispatch("completeHTMLDocument.before", e, r, t);var a = "html", + n = "\n", + s = "", + o = '\n', + i = "", + l = "";void 0 !== t.metadata.parsed.doctype && (n = "\n", "html" !== (a = t.metadata.parsed.doctype.toString().toLowerCase()) && "html5" !== a || (o = ''));for (var c in t.metadata.parsed) { + if (t.metadata.parsed.hasOwnProperty(c)) switch (c.toLowerCase()) {case "doctype": + break;case "title": + s = "" + t.metadata.parsed.title + "\n";break;case "charset": + o = "html" === a || "html5" === a ? '\n' : '\n';break;case "language":case "lang": + i = ' lang="' + t.metadata.parsed[c] + '"', l += '\n';break;default: + l += '\n';} + }return e = n + "\n\n" + s + o + l + "\n\n" + e.trim() + "\n\n", e = t.converter._dispatch("completeHTMLDocument.after", e, r, t); + }), a.subParser("detab", function (e, r, t) { + return e = t.converter._dispatch("detab.before", e, r, t), e = e.replace(/\t(?=\t)/g, " "), e = e.replace(/\t/g, "¨A¨B"), e = e.replace(/¨B(.+?)¨A/g, function (e, r) { + for (var t = r, a = 4 - t.length % 4, n = 0; n < a; n++) { + t += " "; + }return t; + }), e = e.replace(/¨A/g, " "), e = e.replace(/¨B/g, ""), e = t.converter._dispatch("detab.after", e, r, t); + }), a.subParser("ellipsis", function (e, r, t) { + return e = t.converter._dispatch("ellipsis.before", e, r, t), e = e.replace(/\.\.\./g, "…"), e = t.converter._dispatch("ellipsis.after", e, r, t); + }), a.subParser("emoji", function (e, r, t) { + if (!r.emoji) return e;return e = (e = t.converter._dispatch("emoji.before", e, r, t)).replace(/:([\S]+?):/g, function (e, r) { + return a.helper.emojis.hasOwnProperty(r) ? a.helper.emojis[r] : e; + }), e = t.converter._dispatch("emoji.after", e, r, t); + }), a.subParser("encodeAmpsAndAngles", function (e, r, t) { + return e = t.converter._dispatch("encodeAmpsAndAngles.before", e, r, t), e = e.replace(/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/g, "&"), e = e.replace(/<(?![a-z\/?$!])/gi, "<"), e = e.replace(//g, ">"), e = t.converter._dispatch("encodeAmpsAndAngles.after", e, r, t); + }), a.subParser("encodeBackslashEscapes", function (e, r, t) { + return e = t.converter._dispatch("encodeBackslashEscapes.before", e, r, t), e = e.replace(/\\(\\)/g, a.helper.escapeCharactersCallback), e = e.replace(/\\([`*_{}\[\]()>#+.!~=|-])/g, a.helper.escapeCharactersCallback), e = t.converter._dispatch("encodeBackslashEscapes.after", e, r, t); + }), a.subParser("encodeCode", function (e, r, t) { + return e = t.converter._dispatch("encodeCode.before", e, r, t), e = e.replace(/&/g, "&").replace(//g, ">").replace(/([*_{}\[\]\\=~-])/g, a.helper.escapeCharactersCallback), e = t.converter._dispatch("encodeCode.after", e, r, t); + }), a.subParser("escapeSpecialCharsWithinTagAttributes", function (e, r, t) { + return e = (e = t.converter._dispatch("escapeSpecialCharsWithinTagAttributes.before", e, r, t)).replace(/<\/?[a-z\d_:-]+(?:[\s]+[\s\S]+?)?>/gi, function (e) { + return e.replace(/(.)<\/?code>(?=.)/g, "$1`").replace(/([\\`*_~=|])/g, a.helper.escapeCharactersCallback); + }), e = e.replace(/-]|-[^>])(?:[^-]|-[^-])*)--)>/gi, function (e) { + return e.replace(/([\\`*_~=|])/g, a.helper.escapeCharactersCallback); + }), e = t.converter._dispatch("escapeSpecialCharsWithinTagAttributes.after", e, r, t); + }), a.subParser("githubCodeBlocks", function (e, r, t) { + return r.ghCodeBlocks ? (e = t.converter._dispatch("githubCodeBlocks.before", e, r, t), e += "¨0", e = e.replace(/(?:^|\n)(?: {0,3})(```+|~~~+)(?: *)([^\s`~]*)\n([\s\S]*?)\n(?: {0,3})\1/g, function (e, n, s, o) { + var i = r.omitExtraWLInCodeBlocks ? "" : "\n";return o = a.subParser("encodeCode")(o, r, t), o = a.subParser("detab")(o, r, t), o = o.replace(/^\n+/g, ""), o = o.replace(/\n+$/g, ""), o = "
" + o + i + "
", o = a.subParser("hashBlock")(o, r, t), "\n\n¨G" + (t.ghCodeBlocks.push({ text: e, codeblock: o }) - 1) + "G\n\n"; + }), e = e.replace(/¨0/, ""), t.converter._dispatch("githubCodeBlocks.after", e, r, t)) : e; + }), a.subParser("hashBlock", function (e, r, t) { + return e = t.converter._dispatch("hashBlock.before", e, r, t), e = e.replace(/(^\n+|\n+$)/g, ""), e = "\n\n¨K" + (t.gHtmlBlocks.push(e) - 1) + "K\n\n", e = t.converter._dispatch("hashBlock.after", e, r, t); + }), a.subParser("hashCodeTags", function (e, r, t) { + e = t.converter._dispatch("hashCodeTags.before", e, r, t);return e = a.helper.replaceRecursiveRegExp(e, function (e, n, s, o) { + var i = s + a.subParser("encodeCode")(n, r, t) + o;return "¨C" + (t.gHtmlSpans.push(i) - 1) + "C"; + }, "]*>", "", "gim"), e = t.converter._dispatch("hashCodeTags.after", e, r, t); + }), a.subParser("hashElement", function (e, r, t) { + return function (e, r) { + var a = r;return a = a.replace(/\n\n/g, "\n"), a = a.replace(/^\n/, ""), a = a.replace(/\n+$/g, ""), a = "\n\n¨K" + (t.gHtmlBlocks.push(a) - 1) + "K\n\n"; + }; + }), a.subParser("hashHTMLBlocks", function (e, r, t) { + e = t.converter._dispatch("hashHTMLBlocks.before", e, r, t);var n = ["pre", "div", "h1", "h2", "h3", "h4", "h5", "h6", "blockquote", "table", "dl", "ol", "ul", "script", "noscript", "form", "fieldset", "iframe", "math", "style", "section", "header", "footer", "nav", "article", "aside", "address", "audio", "canvas", "figure", "hgroup", "output", "video", "p"], + s = function s(e, r, a, n) { + var s = e;return -1 !== a.search(/\bmarkdown\b/) && (s = a + t.converter.makeHtml(r) + n), "\n\n¨K" + (t.gHtmlBlocks.push(s) - 1) + "K\n\n"; + };r.backslashEscapesHTMLTags && (e = e.replace(/\\<(\/?[^>]+?)>/g, function (e, r) { + return "<" + r + ">"; + }));for (var o = 0; o < n.length; ++o) { + for (var i, l = new RegExp("^ {0,3}(<" + n[o] + "\\b[^>]*>)", "im"), c = "<" + n[o] + "\\b[^>]*>", u = ""; -1 !== (i = a.helper.regexIndexOf(e, l));) { + var d = a.helper.splitAtIndex(e, i), + p = a.helper.replaceRecursiveRegExp(d[1], s, c, u, "im");if (p === d[1]) break;e = d[0].concat(p); + } + }return e = e.replace(/(\n {0,3}(<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g, a.subParser("hashElement")(e, r, t)), e = a.helper.replaceRecursiveRegExp(e, function (e) { + return "\n\n¨K" + (t.gHtmlBlocks.push(e) - 1) + "K\n\n"; + }, "^ {0,3}\x3c!--", "--\x3e", "gm"), e = e.replace(/(?:\n\n)( {0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g, a.subParser("hashElement")(e, r, t)), e = t.converter._dispatch("hashHTMLBlocks.after", e, r, t); + }), a.subParser("hashHTMLSpans", function (e, r, t) { + function a(e) { + return "¨C" + (t.gHtmlSpans.push(e) - 1) + "C"; + }return e = t.converter._dispatch("hashHTMLSpans.before", e, r, t), e = e.replace(/<[^>]+?\/>/gi, function (e) { + return a(e); + }), e = e.replace(/<([^>]+?)>[\s\S]*?<\/\1>/g, function (e) { + return a(e); + }), e = e.replace(/<([^>]+?)\s[^>]+?>[\s\S]*?<\/\1>/g, function (e) { + return a(e); + }), e = e.replace(/<[^>]+?>/gi, function (e) { + return a(e); + }), e = t.converter._dispatch("hashHTMLSpans.after", e, r, t); + }), a.subParser("unhashHTMLSpans", function (e, r, t) { + e = t.converter._dispatch("unhashHTMLSpans.before", e, r, t);for (var a = 0; a < t.gHtmlSpans.length; ++a) { + for (var n = t.gHtmlSpans[a], s = 0; /¨C(\d+)C/.test(n);) { + var o = RegExp.$1;if (n = n.replace("¨C" + o + "C", t.gHtmlSpans[o]), 10 === s) { + console.error("maximum nesting of 10 spans reached!!!");break; + }++s; + }e = e.replace("¨C" + a + "C", n); + }return e = t.converter._dispatch("unhashHTMLSpans.after", e, r, t); + }), a.subParser("hashPreCodeTags", function (e, r, t) { + e = t.converter._dispatch("hashPreCodeTags.before", e, r, t);return e = a.helper.replaceRecursiveRegExp(e, function (e, n, s, o) { + var i = s + a.subParser("encodeCode")(n, r, t) + o;return "\n\n¨G" + (t.ghCodeBlocks.push({ text: e, codeblock: i }) - 1) + "G\n\n"; + }, "^ {0,3}]*>\\s*]*>", "^ {0,3}\\s*
", "gim"), e = t.converter._dispatch("hashPreCodeTags.after", e, r, t); + }), a.subParser("headers", function (e, r, t) { + function n(e) { + var n, s;if (r.customizedHeaderId) { + var o = e.match(/\{([^{]+?)}\s*$/);o && o[1] && (e = o[1]); + }return n = e, s = a.helper.isString(r.prefixHeaderId) ? r.prefixHeaderId : !0 === r.prefixHeaderId ? "section-" : "", r.rawPrefixHeaderId || (n = s + n), n = r.ghCompatibleHeaderId ? n.replace(/ /g, "-").replace(/&/g, "").replace(/¨T/g, "").replace(/¨D/g, "").replace(/[&+$,\/:;=?@"#{}|^¨~\[\]`\\*)(%.!'<>]/g, "").toLowerCase() : r.rawHeaderId ? n.replace(/ /g, "-").replace(/&/g, "&").replace(/¨T/g, "¨").replace(/¨D/g, "$").replace(/["']/g, "-").toLowerCase() : n.replace(/[^\w]/g, "").toLowerCase(), r.rawPrefixHeaderId && (n = s + n), t.hashLinkCounts[n] ? n = n + "-" + t.hashLinkCounts[n]++ : t.hashLinkCounts[n] = 1, n; + }e = t.converter._dispatch("headers.before", e, r, t);var s = isNaN(parseInt(r.headerLevelStart)) ? 1 : parseInt(r.headerLevelStart), + o = r.smoothLivePreview ? /^(.+)[ \t]*\n={2,}[ \t]*\n+/gm : /^(.+)[ \t]*\n=+[ \t]*\n+/gm, + i = r.smoothLivePreview ? /^(.+)[ \t]*\n-{2,}[ \t]*\n+/gm : /^(.+)[ \t]*\n-+[ \t]*\n+/gm;e = (e = e.replace(o, function (e, o) { + var i = a.subParser("spanGamut")(o, r, t), + l = r.noHeaderId ? "" : ' id="' + n(o) + '"', + c = "" + i + "";return a.subParser("hashBlock")(c, r, t); + })).replace(i, function (e, o) { + var i = a.subParser("spanGamut")(o, r, t), + l = r.noHeaderId ? "" : ' id="' + n(o) + '"', + c = s + 1, + u = "" + i + "";return a.subParser("hashBlock")(u, r, t); + });var l = r.requireSpaceBeforeHeadingText ? /^(#{1,6})[ \t]+(.+?)[ \t]*#*\n+/gm : /^(#{1,6})[ \t]*(.+?)[ \t]*#*\n+/gm;return e = e.replace(l, function (e, o, i) { + var l = i;r.customizedHeaderId && (l = i.replace(/\s?\{([^{]+?)}\s*$/, ""));var c = a.subParser("spanGamut")(l, r, t), + u = r.noHeaderId ? "" : ' id="' + n(i) + '"', + d = s - 1 + o.length, + p = "" + c + "";return a.subParser("hashBlock")(p, r, t); + }), e = t.converter._dispatch("headers.after", e, r, t); + }), a.subParser("horizontalRule", function (e, r, t) { + e = t.converter._dispatch("horizontalRule.before", e, r, t);var n = a.subParser("hashBlock")("
", r, t);return e = e.replace(/^ {0,2}( ?-){3,}[ \t]*$/gm, n), e = e.replace(/^ {0,2}( ?\*){3,}[ \t]*$/gm, n), e = e.replace(/^ {0,2}( ?_){3,}[ \t]*$/gm, n), e = t.converter._dispatch("horizontalRule.after", e, r, t); + }), a.subParser("images", function (e, r, t) { + function n(e, r, n, s, o, i, l, c) { + var u = t.gUrls, + d = t.gTitles, + p = t.gDimensions;if (n = n.toLowerCase(), c || (c = ""), e.search(/\(? ?(['"].*['"])?\)$/m) > -1) s = "";else if ("" === s || null === s) { + if ("" !== n && null !== n || (n = r.toLowerCase().replace(/ ?\n/g, " ")), s = "#" + n, a.helper.isUndefined(u[n])) return e;s = u[n], a.helper.isUndefined(d[n]) || (c = d[n]), a.helper.isUndefined(p[n]) || (o = p[n].width, i = p[n].height); + }r = r.replace(/"/g, """).replace(a.helper.regexes.asteriskDashAndColon, a.helper.escapeCharactersCallback);var h = '' + r + '?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(["'])([^"]*?)\6)?[ \t]?\)/g, function (e, r, t, a, s, o, i, l) { + return a = a.replace(/\s/g, ""), n(e, r, t, a, s, o, 0, l); + }), e = e.replace(/!\[([^\]]*?)][ \t]*()\([ \t]?<([^>]*)>(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(?:(["'])([^"]*?)\6))?[ \t]?\)/g, n), e = e.replace(/!\[([^\]]*?)][ \t]*()\([ \t]??(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(["'])([^"]*?)\6)?[ \t]?\)/g, n), e = e.replace(/!\[([^\[\]]+)]()()()()()/g, n), e = t.converter._dispatch("images.after", e, r, t); + }), a.subParser("italicsAndBold", function (e, r, t) { + function a(e, r, t) { + return r + e + t; + }return e = t.converter._dispatch("italicsAndBold.before", e, r, t), e = r.literalMidWordUnderscores ? (e = (e = e.replace(/\b___(\S[\s\S]*?)___\b/g, function (e, r) { + return a(r, "", ""); + })).replace(/\b__(\S[\s\S]*?)__\b/g, function (e, r) { + return a(r, "", ""); + })).replace(/\b_(\S[\s\S]*?)_\b/g, function (e, r) { + return a(r, "", ""); + }) : (e = (e = e.replace(/___(\S[\s\S]*?)___/g, function (e, r) { + return (/\S$/.test(r) ? a(r, "", "") : e + ); + })).replace(/__(\S[\s\S]*?)__/g, function (e, r) { + return (/\S$/.test(r) ? a(r, "", "") : e + ); + })).replace(/_([^\s_][\s\S]*?)_/g, function (e, r) { + return (/\S$/.test(r) ? a(r, "", "") : e + ); + }), e = r.literalMidWordAsterisks ? (e = (e = e.replace(/([^*]|^)\B\*\*\*(\S[\s\S]*?)\*\*\*\B(?!\*)/g, function (e, r, t) { + return a(t, r + "", ""); + })).replace(/([^*]|^)\B\*\*(\S[\s\S]*?)\*\*\B(?!\*)/g, function (e, r, t) { + return a(t, r + "", ""); + })).replace(/([^*]|^)\B\*(\S[\s\S]*?)\*\B(?!\*)/g, function (e, r, t) { + return a(t, r + "", ""); + }) : (e = (e = e.replace(/\*\*\*(\S[\s\S]*?)\*\*\*/g, function (e, r) { + return (/\S$/.test(r) ? a(r, "", "") : e + ); + })).replace(/\*\*(\S[\s\S]*?)\*\*/g, function (e, r) { + return (/\S$/.test(r) ? a(r, "", "") : e + ); + })).replace(/\*([^\s*][\s\S]*?)\*/g, function (e, r) { + return (/\S$/.test(r) ? a(r, "", "") : e + ); + }), e = t.converter._dispatch("italicsAndBold.after", e, r, t); + }), a.subParser("lists", function (e, r, t) { + function n(e, n) { + t.gListLevel++, e = e.replace(/\n{2,}$/, "\n");var s = /(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0| {0,3}([*+-]|\d+[.])[ \t]+))/gm, + o = /\n[ \t]*\n(?!¨0)/.test(e += "¨0");return r.disableForced4SpacesIndentedSublists && (s = /(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0|\2([*+-]|\d+[.])[ \t]+))/gm), e = e.replace(s, function (e, n, s, i, l, c, u) { + u = u && "" !== u.trim();var d = a.subParser("outdent")(l, r, t), + p = "";return c && r.tasklists && (p = ' class="task-list-item" style="list-style-type: none;"', d = d.replace(/^[ \t]*\[(x|X| )?]/m, function () { + var e = ' -1 ? (d = a.subParser("githubCodeBlocks")(d, r, t), d = a.subParser("blockGamut")(d, r, t)) : (d = (d = a.subParser("lists")(d, r, t)).replace(/\n$/, ""), d = (d = a.subParser("hashHTMLBlocks")(d, r, t)).replace(/\n\n+/g, "\n\n"), d = o ? a.subParser("paragraphs")(d, r, t) : a.subParser("spanGamut")(d, r, t)), d = d.replace("¨A", ""), d = "" + d + "\n"; + }), e = e.replace(/¨0/g, ""), t.gListLevel--, n && (e = e.replace(/\s+$/, "")), e; + }function s(e, r) { + if ("ol" === r) { + var t = e.match(/^ *(\d+)\./);if (t && "1" !== t[1]) return ' start="' + t[1] + '"'; + }return ""; + }function o(e, t, a) { + var o = r.disableForced4SpacesIndentedSublists ? /^ ?\d+\.[ \t]/gm : /^ {0,3}\d+\.[ \t]/gm, + i = r.disableForced4SpacesIndentedSublists ? /^ ?[*+-][ \t]/gm : /^ {0,3}[*+-][ \t]/gm, + l = "ul" === t ? o : i, + c = "";if (-1 !== e.search(l)) !function r(u) { + var d = u.search(l), + p = s(e, t);-1 !== d ? (c += "\n\n<" + t + p + ">\n" + n(u.slice(0, d), !!a) + "\n", l = "ul" === (t = "ul" === t ? "ol" : "ul") ? o : i, r(u.slice(d))) : c += "\n\n<" + t + p + ">\n" + n(u, !!a) + "\n"; + }(e);else { + var u = s(e, t);c = "\n\n<" + t + u + ">\n" + n(e, !!a) + "\n"; + }return c; + }return e = t.converter._dispatch("lists.before", e, r, t), e += "¨0", e = t.gListLevel ? e.replace(/^(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(¨0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm, function (e, r, t) { + return o(r, t.search(/[*+-]/g) > -1 ? "ul" : "ol", !0); + }) : e.replace(/(\n\n|^\n?)(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(¨0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm, function (e, r, t, a) { + return o(t, a.search(/[*+-]/g) > -1 ? "ul" : "ol", !1); + }), e = e.replace(/¨0/, ""), e = t.converter._dispatch("lists.after", e, r, t); + }), a.subParser("metadata", function (e, r, t) { + function a(e) { + t.metadata.raw = e, (e = (e = e.replace(/&/g, "&").replace(/"/g, """)).replace(/\n {4}/g, " ")).replace(/^([\S ]+): +([\s\S]+?)$/gm, function (e, r, a) { + return t.metadata.parsed[r] = a, ""; + }); + }return r.metadata ? (e = t.converter._dispatch("metadata.before", e, r, t), e = e.replace(/^\s*«««+(\S*?)\n([\s\S]+?)\n»»»+\n/, function (e, r, t) { + return a(t), "¨M"; + }), e = e.replace(/^\s*---+(\S*?)\n([\s\S]+?)\n---+\n/, function (e, r, n) { + return r && (t.metadata.format = r), a(n), "¨M"; + }), e = e.replace(/¨M/g, ""), e = t.converter._dispatch("metadata.after", e, r, t)) : e; + }), a.subParser("outdent", function (e, r, t) { + return e = t.converter._dispatch("outdent.before", e, r, t), e = e.replace(/^(\t|[ ]{1,4})/gm, "¨0"), e = e.replace(/¨0/g, ""), e = t.converter._dispatch("outdent.after", e, r, t); + }), a.subParser("paragraphs", function (e, r, t) { + for (var n = (e = (e = (e = t.converter._dispatch("paragraphs.before", e, r, t)).replace(/^\n+/g, "")).replace(/\n+$/g, "")).split(/\n{2,}/g), s = [], o = n.length, i = 0; i < o; i++) { + var l = n[i];l.search(/¨(K|G)(\d+)\1/g) >= 0 ? s.push(l) : l.search(/\S/) >= 0 && (l = (l = a.subParser("spanGamut")(l, r, t)).replace(/^([ \t]*)/g, "

"), l += "

", s.push(l)); + }for (o = s.length, i = 0; i < o; i++) { + for (var c = "", u = s[i], d = !1; /¨(K|G)(\d+)\1/.test(u);) { + var p = RegExp.$1, + h = RegExp.$2;c = (c = "K" === p ? t.gHtmlBlocks[h] : d ? a.subParser("encodeCode")(t.ghCodeBlocks[h].text, r, t) : t.ghCodeBlocks[h].codeblock).replace(/\$/g, "$$$$"), u = u.replace(/(\n\n)?¨(K|G)\d+\2(\n\n)?/, c), /^]*>\s*]*>/.test(u) && (d = !0); + }s[i] = u; + }return e = s.join("\n"), e = e.replace(/^\n+/g, ""), e = e.replace(/\n+$/g, ""), t.converter._dispatch("paragraphs.after", e, r, t); + }), a.subParser("runExtension", function (e, r, t, a) { + if (e.filter) r = e.filter(r, a.converter, t);else if (e.regex) { + var n = e.regex;n instanceof RegExp || (n = new RegExp(n, "g")), r = r.replace(n, e.replace); + }return r; + }), a.subParser("spanGamut", function (e, r, t) { + return e = t.converter._dispatch("spanGamut.before", e, r, t), e = a.subParser("codeSpans")(e, r, t), e = a.subParser("escapeSpecialCharsWithinTagAttributes")(e, r, t), e = a.subParser("encodeBackslashEscapes")(e, r, t), e = a.subParser("images")(e, r, t), e = a.subParser("anchors")(e, r, t), e = a.subParser("autoLinks")(e, r, t), e = a.subParser("simplifiedAutoLinks")(e, r, t), e = a.subParser("emoji")(e, r, t), e = a.subParser("underline")(e, r, t), e = a.subParser("italicsAndBold")(e, r, t), e = a.subParser("strikethrough")(e, r, t), e = a.subParser("ellipsis")(e, r, t), e = a.subParser("hashHTMLSpans")(e, r, t), e = a.subParser("encodeAmpsAndAngles")(e, r, t), r.simpleLineBreaks ? /\n\n¨K/.test(e) || (e = e.replace(/\n+/g, "
\n")) : e = e.replace(/ +\n/g, "
\n"), e = t.converter._dispatch("spanGamut.after", e, r, t); + }), a.subParser("strikethrough", function (e, r, t) { + return r.strikethrough && (e = (e = t.converter._dispatch("strikethrough.before", e, r, t)).replace(/(?:~){2}([\s\S]+?)(?:~){2}/g, function (e, n) { + return function (e) { + return r.simplifiedAutoLink && (e = a.subParser("simplifiedAutoLinks")(e, r, t)), "" + e + ""; + }(n); + }), e = t.converter._dispatch("strikethrough.after", e, r, t)), e; + }), a.subParser("stripLinkDefinitions", function (e, r, t) { + var n = function n(e, _n2, s, o, i, l, c) { + return _n2 = _n2.toLowerCase(), s.match(/^data:.+?\/.+?;base64,/) ? t.gUrls[_n2] = s.replace(/\s/g, "") : t.gUrls[_n2] = a.subParser("encodeAmpsAndAngles")(s, r, t), l ? l + c : (c && (t.gTitles[_n2] = c.replace(/"|'/g, """)), r.parseImgDimensions && o && i && (t.gDimensions[_n2] = { width: o, height: i }), ""); + };return e = (e += "¨0").replace(/^ {0,3}\[(.+)]:[ \t]*\n?[ \t]*?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*\n?[ \t]*(?:(\n*)["|'(](.+?)["|')][ \t]*)?(?:\n\n|(?=¨0)|(?=\n\[))/gm, n), e = e.replace(/^ {0,3}\[(.+)]:[ \t]*\n?[ \t]*\s]+)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*\n?[ \t]*(?:(\n*)["|'(](.+?)["|')][ \t]*)?(?:\n+|(?=¨0))/gm, n), e = e.replace(/¨0/, ""); + }), a.subParser("tables", function (e, r, t) { + function n(e) { + return (/^:[ \t]*--*$/.test(e) ? ' style="text-align:left;"' : /^--*[ \t]*:[ \t]*$/.test(e) ? ' style="text-align:right;"' : /^:[ \t]*--*[ \t]*:$/.test(e) ? ' style="text-align:center;"' : "" + ); + }function s(e, n) { + var s = "";return e = e.trim(), (r.tablesHeaderId || r.tableHeaderId) && (s = ' id="' + e.replace(/ /g, "_").toLowerCase() + '"'), e = a.subParser("spanGamut")(e, r, t), "" + e + "\n"; + }function o(e, n) { + return "" + a.subParser("spanGamut")(e, r, t) + "\n"; + }function i(e) { + var i, + l = e.split("\n");for (i = 0; i < l.length; ++i) { + /^ {0,3}\|/.test(l[i]) && (l[i] = l[i].replace(/^ {0,3}\|/, "")), /\|[ \t]*$/.test(l[i]) && (l[i] = l[i].replace(/\|[ \t]*$/, "")), l[i] = a.subParser("codeSpans")(l[i], r, t); + }var c = l[0].split("|").map(function (e) { + return e.trim(); + }), + u = l[1].split("|").map(function (e) { + return e.trim(); + }), + d = [], + p = [], + h = [], + _ = [];for (l.shift(), l.shift(), i = 0; i < l.length; ++i) { + "" !== l[i].trim() && d.push(l[i].split("|").map(function (e) { + return e.trim(); + })); + }if (c.length < u.length) return e;for (i = 0; i < u.length; ++i) { + h.push(n(u[i])); + }for (i = 0; i < c.length; ++i) { + a.helper.isUndefined(h[i]) && (h[i] = ""), p.push(s(c[i], h[i])); + }for (i = 0; i < d.length; ++i) { + for (var g = [], m = 0; m < p.length; ++m) { + a.helper.isUndefined(d[i][m]), g.push(o(d[i][m], h[m])); + }_.push(g); + }return function (e, r) { + for (var t = "\n\n\n", a = e.length, n = 0; n < a; ++n) { + t += e[n]; + }for (t += "\n\n\n", n = 0; n < r.length; ++n) { + t += "\n";for (var s = 0; s < a; ++s) { + t += r[n][s]; + }t += "\n"; + }return t += "\n
\n"; + }(p, _); + }if (!r.tables) return e;return e = t.converter._dispatch("tables.before", e, r, t), e = e.replace(/\\(\|)/g, a.helper.escapeCharactersCallback), e = e.replace(/^ {0,3}\|?.+\|.+\n {0,3}\|?[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*:?[ \t]*(?:[-=]){2,}[\s\S]+?(?:\n\n|¨0)/gm, i), e = e.replace(/^ {0,3}\|.+\|[ \t]*\n {0,3}\|[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*\n( {0,3}\|.+\|[ \t]*\n)*(?:\n|¨0)/gm, i), e = t.converter._dispatch("tables.after", e, r, t); + }), a.subParser("underline", function (e, r, t) { + return r.underline ? (e = t.converter._dispatch("underline.before", e, r, t), e = r.literalMidWordUnderscores ? (e = e.replace(/\b___(\S[\s\S]*?)___\b/g, function (e, r) { + return "" + r + ""; + })).replace(/\b__(\S[\s\S]*?)__\b/g, function (e, r) { + return "" + r + ""; + }) : (e = e.replace(/___(\S[\s\S]*?)___/g, function (e, r) { + return (/\S$/.test(r) ? "" + r + "" : e + ); + })).replace(/__(\S[\s\S]*?)__/g, function (e, r) { + return (/\S$/.test(r) ? "" + r + "" : e + ); + }), e = e.replace(/(_)/g, a.helper.escapeCharactersCallback), e = t.converter._dispatch("underline.after", e, r, t)) : e; + }), a.subParser("unescapeSpecialChars", function (e, r, t) { + return e = t.converter._dispatch("unescapeSpecialChars.before", e, r, t), e = e.replace(/¨E(\d+)E/g, function (e, r) { + var t = parseInt(r);return String.fromCharCode(t); + }), e = t.converter._dispatch("unescapeSpecialChars.after", e, r, t); + }), a.subParser("makeMarkdown.blockquote", function (e, r) { + var t = "";if (e.hasChildNodes()) for (var n = e.childNodes, s = n.length, o = 0; o < s; ++o) { + var i = a.subParser("makeMarkdown.node")(n[o], r);"" !== i && (t += i); + }return t = t.trim(), t = "> " + t.split("\n").join("\n> "); + }), a.subParser("makeMarkdown.codeBlock", function (e, r) { + var t = e.getAttribute("language"), + a = e.getAttribute("precodenum");return "```" + t + "\n" + r.preList[a] + "\n```"; + }), a.subParser("makeMarkdown.codeSpan", function (e) { + return "`" + e.innerHTML + "`"; + }), a.subParser("makeMarkdown.emphasis", function (e, r) { + var t = "";if (e.hasChildNodes()) { + t += "*";for (var n = e.childNodes, s = n.length, o = 0; o < s; ++o) { + t += a.subParser("makeMarkdown.node")(n[o], r); + }t += "*"; + }return t; + }), a.subParser("makeMarkdown.header", function (e, r, t) { + var n = new Array(t + 1).join("#"), + s = "";if (e.hasChildNodes()) { + s = n + " ";for (var o = e.childNodes, i = o.length, l = 0; l < i; ++l) { + s += a.subParser("makeMarkdown.node")(o[l], r); + } + }return s; + }), a.subParser("makeMarkdown.hr", function () { + return "---"; + }), a.subParser("makeMarkdown.image", function (e) { + var r = "";return e.hasAttribute("src") && (r += "![" + e.getAttribute("alt") + "](", r += "<" + e.getAttribute("src") + ">", e.hasAttribute("width") && e.hasAttribute("height") && (r += " =" + e.getAttribute("width") + "x" + e.getAttribute("height")), e.hasAttribute("title") && (r += ' "' + e.getAttribute("title") + '"'), r += ")"), r; + }), a.subParser("makeMarkdown.links", function (e, r) { + var t = "";if (e.hasChildNodes() && e.hasAttribute("href")) { + var n = e.childNodes, + s = n.length;t = "[";for (var o = 0; o < s; ++o) { + t += a.subParser("makeMarkdown.node")(n[o], r); + }t += "](", t += "<" + e.getAttribute("href") + ">", e.hasAttribute("title") && (t += ' "' + e.getAttribute("title") + '"'), t += ")"; + }return t; + }), a.subParser("makeMarkdown.list", function (e, r, t) { + var n = "";if (!e.hasChildNodes()) return "";for (var s = e.childNodes, o = s.length, i = e.getAttribute("start") || 1, l = 0; l < o; ++l) { + if (void 0 !== s[l].tagName && "li" === s[l].tagName.toLowerCase()) { + n += ("ol" === t ? i.toString() + ". " : "- ") + a.subParser("makeMarkdown.listItem")(s[l], r), ++i; + } + }return (n += "\n\x3c!-- --\x3e\n").trim(); + }), a.subParser("makeMarkdown.listItem", function (e, r) { + for (var t = "", n = e.childNodes, s = n.length, o = 0; o < s; ++o) { + t += a.subParser("makeMarkdown.node")(n[o], r); + }return (/\n$/.test(t) ? t = t.split("\n").join("\n ").replace(/^ {4}$/gm, "").replace(/\n\n+/g, "\n\n") : t += "\n", t); + }), a.subParser("makeMarkdown.node", function (e, r, t) { + t = t || !1;var n = "";if (3 === e.nodeType) return a.subParser("makeMarkdown.txt")(e, r);if (8 === e.nodeType) return "\x3c!--" + e.data + "--\x3e\n\n";if (1 !== e.nodeType) return "";switch (e.tagName.toLowerCase()) {case "h1": + t || (n = a.subParser("makeMarkdown.header")(e, r, 1) + "\n\n");break;case "h2": + t || (n = a.subParser("makeMarkdown.header")(e, r, 2) + "\n\n");break;case "h3": + t || (n = a.subParser("makeMarkdown.header")(e, r, 3) + "\n\n");break;case "h4": + t || (n = a.subParser("makeMarkdown.header")(e, r, 4) + "\n\n");break;case "h5": + t || (n = a.subParser("makeMarkdown.header")(e, r, 5) + "\n\n");break;case "h6": + t || (n = a.subParser("makeMarkdown.header")(e, r, 6) + "\n\n");break;case "p": + t || (n = a.subParser("makeMarkdown.paragraph")(e, r) + "\n\n");break;case "blockquote": + t || (n = a.subParser("makeMarkdown.blockquote")(e, r) + "\n\n");break;case "hr": + t || (n = a.subParser("makeMarkdown.hr")(e, r) + "\n\n");break;case "ol": + t || (n = a.subParser("makeMarkdown.list")(e, r, "ol") + "\n\n");break;case "ul": + t || (n = a.subParser("makeMarkdown.list")(e, r, "ul") + "\n\n");break;case "precode": + t || (n = a.subParser("makeMarkdown.codeBlock")(e, r) + "\n\n");break;case "pre": + t || (n = a.subParser("makeMarkdown.pre")(e, r) + "\n\n");break;case "table": + t || (n = a.subParser("makeMarkdown.table")(e, r) + "\n\n");break;case "code": + n = a.subParser("makeMarkdown.codeSpan")(e, r);break;case "em":case "i": + n = a.subParser("makeMarkdown.emphasis")(e, r);break;case "strong":case "b": + n = a.subParser("makeMarkdown.strong")(e, r);break;case "del": + n = a.subParser("makeMarkdown.strikethrough")(e, r);break;case "a": + n = a.subParser("makeMarkdown.links")(e, r);break;case "img": + n = a.subParser("makeMarkdown.image")(e, r);break;default: + n = e.outerHTML + "\n\n";}return n; + }), a.subParser("makeMarkdown.paragraph", function (e, r) { + var t = "";if (e.hasChildNodes()) for (var n = e.childNodes, s = n.length, o = 0; o < s; ++o) { + t += a.subParser("makeMarkdown.node")(n[o], r); + }return t = t.trim(); + }), a.subParser("makeMarkdown.pre", function (e, r) { + var t = e.getAttribute("prenum");return "
" + r.preList[t] + "
"; + }), a.subParser("makeMarkdown.strikethrough", function (e, r) { + var t = "";if (e.hasChildNodes()) { + t += "~~";for (var n = e.childNodes, s = n.length, o = 0; o < s; ++o) { + t += a.subParser("makeMarkdown.node")(n[o], r); + }t += "~~"; + }return t; + }), a.subParser("makeMarkdown.strong", function (e, r) { + var t = "";if (e.hasChildNodes()) { + t += "**";for (var n = e.childNodes, s = n.length, o = 0; o < s; ++o) { + t += a.subParser("makeMarkdown.node")(n[o], r); + }t += "**"; + }return t; + }), a.subParser("makeMarkdown.table", function (e, r) { + var t, + n, + s = "", + o = [[], []], + i = e.querySelectorAll("thead>tr>th"), + l = e.querySelectorAll("tbody>tr");for (t = 0; t < i.length; ++t) { + var c = a.subParser("makeMarkdown.tableCell")(i[t], r), + u = "---";if (i[t].hasAttribute("style")) { + switch (i[t].getAttribute("style").toLowerCase().replace(/\s/g, "")) {case "text-align:left;": + u = ":---";break;case "text-align:right;": + u = "---:";break;case "text-align:center;": + u = ":---:";} + }o[0][t] = c.trim(), o[1][t] = u; + }for (t = 0; t < l.length; ++t) { + var d = o.push([]) - 1, + p = l[t].getElementsByTagName("td");for (n = 0; n < i.length; ++n) { + var h = " ";void 0 !== p[n] && (h = a.subParser("makeMarkdown.tableCell")(p[n], r)), o[d].push(h); + } + }var _ = 3;for (t = 0; t < o.length; ++t) { + for (n = 0; n < o[t].length; ++n) { + var g = o[t][n].length;g > _ && (_ = g); + } + }for (t = 0; t < o.length; ++t) { + for (n = 0; n < o[t].length; ++n) { + 1 === t ? ":" === o[t][n].slice(-1) ? o[t][n] = a.helper.padEnd(o[t][n].slice(-1), _ - 1, "-") + ":" : o[t][n] = a.helper.padEnd(o[t][n], _, "-") : o[t][n] = a.helper.padEnd(o[t][n], _); + }s += "| " + o[t].join(" | ") + " |\n"; + }return s.trim(); + }), a.subParser("makeMarkdown.tableCell", function (e, r) { + var t = "";if (!e.hasChildNodes()) return "";for (var n = e.childNodes, s = n.length, o = 0; o < s; ++o) { + t += a.subParser("makeMarkdown.node")(n[o], r, !0); + }return t.trim(); + }), a.subParser("makeMarkdown.txt", function (e) { + var r = e.nodeValue;return r = r.replace(/ +/g, " "), r = r.replace(/¨NBSP;/g, " "), r = a.helper.unescapeHTMLEntities(r), r = r.replace(/([*_~|`])/g, "\\$1"), r = r.replace(/^(\s*)>/g, "\\$1>"), r = r.replace(/^#/gm, "\\#"), r = r.replace(/^(\s*)([-=]{3,})(\s*)$/, "$1\\$2$3"), r = r.replace(/^( {0,3}\d+)\./gm, "$1\\."), r = r.replace(/^( {0,3})([+-])/gm, "$1\\$2"), r = r.replace(/]([\s]*)\(/g, "\\]$1\\("), r = r.replace(/^ {0,3}\[([\S \t]*?)]:/gm, "\\[$1]:"); + });"function" == typeof undefined && undefined.amd ? undefined(function () { + return a; + }) : "undefined" != 'object' && module.exports ? module.exports = a : this.showdown = a; + }).call(commonjsGlobal); + + }); + + var md = /*#__PURE__*/Object.freeze({ + default: showdown_min, + __moduleExports: showdown_min + }); + + console.log("=== PureRead: Plugin load ==="); + + var plugins = { + pangu: pangu_min, + minimatch: minimatch_1, + beautify: be, + style: ss, + rdability: rda, + markdown: md + }; + + /** + * Get PureRead Plugin + * + * @param {string} plugin name, when undefined, return all plugin + * @return {object} all plugins + * {string} plgin + */ + function Plugin(type) { + var result = void 0; + if (type == undefined) { + result = plugins; + } else { + result = plugins[type]; + } + return result; + } + + exports.Plugin = Plugin; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}))); diff --git a/src/vender/puread/puread.js b/src/vender/puread/puread.js deleted file mode 100644 index ec5e013b..00000000 --- a/src/vender/puread/puread.js +++ /dev/null @@ -1,231 +0,0 @@ -console.log( "=== PureRead: PureRead load ===" ) - -import * as util from './util'; -import AdapteSite from './adaptesite'; - -export default class PureRead extends AdapteSite { - - constructor( sites ) { - super( sites ); - this.version = "0.0.3"; - this.org_url = location.href; - this.html = {}; // clone site, include: title, desc, include, avatar, paging - this.plugin = {}; - } - - /** - * Verify current puread is same - * - * @return {boolean} true: same; false: not same; - */ - Exist() { - return this.org_url == location.href; - } - - /** - * Add Plugin - * - * @param {object} plugin object - */ - AddPlugin( plugin ) { - this.plugin = { - minimatch : plugin.minimatch, - pangu : plugin.pangu, - beautify : plugin.beautify, - stylesheet: plugin.style, - rdability : plugin.rdability, - }; - super.SetMinimatch( this.plugin.minimatch ); - super.SetRdability( this.plugin.rdability ); - } - - /** - * Create temp read mode - * - * @param {string} include: read, focus - * @param {dom} html dom element - */ - TempMode( mode, dom ) { - this.state = "temp"; - this.dom = dom; - this.Newsite( mode, dom.outerHTML ); - } - - /** - * Get read mode html - */ - ReadMode() { - this.html = wrap( this.current.site ); - } - - /** - * Get highlight( focus ) jquery, only usage focus mode - * - * @return {jquery} jquery object - */ - Include() { - let include = this.current.site.include, - $focus = []; - const target = util.selector( include ); - try { - if ( util.specTest( target ) ) { - const [ value, state ] = util.specAction( include ); - if ( state == 0 ) { - include = include.replace( /\[\[{\$\(|}\]\]|\).html\(\)/g, "" ); - $focus = $( util.specAction( `[[[${include}]]]` )[0] ); - } else if ( state == 3 ) { - $focus = value; - } - } else if ( target ) { - $focus = $( "body" ).find( target ); - } - } catch ( error ) { - console.error( "Get $focus failed", error ) - } - return $focus; - } - - /** - * Get exlcude jquery selector array list - * - * @param {jquery} jquery object - * @return {array} jquery selector - */ - Exclude( $target ) { - return excludeSelector( $target, this.current.site.exclude ); - } - - /** - * Beautify html - * - * @param {jquery} jquery - */ - Beautify( $target ) { - if ( this.plugin.beautify ) { - this.plugin.beautify.specbeautify( this.current.site.name, $target ); - this.plugin.beautify.removeSpareTag( this.current.site.name, $target ); - this.plugin.beautify.htmlbeautify( $target ); - this.plugin.beautify.commbeautify( this.current.site.name, $target ); - } - } - - /** - * Format usage pangu plugin - * - * @param {string} class name - */ - Format( cls ) { - this.plugin.pangu && - this.plugin.pangu.spacingElementByClassName( cls ); - } -} - -/** - * Wrap storage.current.site object - * - * @param {object} storage.current.site object - * @return {object} wrapper object - */ -function wrap( site ) { - const wrapper = util.clone( site ), - title = util.selector( site.title == "" ? "" : site.title ), - desc = util.selector( site.desc ), - include = util.selector( site.include ); - wrapper.title = site.title == "" || site.title == "<title>" ? $( "head title" ).text() : query( title ); - wrapper.desc = query( desc ); - wrapper.include = site.include == "" && site.html != "" ? site.html : query( include, "html" ); - wrapper.avatar && wrapper.avatar.length > 0 && wrapper.avatar[0].name == "" && delete wrapper.avatar; - wrapper.paging && wrapper.paging.length > 0 && wrapper.paging[0].prev == "" && delete wrapper.paging; - wrapper.avatar && wrapper.avatar.forEach( item => { - const key = Object.keys( item ).join(), - value = item[key]; - item[key] = query( util.selector( value ), "html" ); - }); - wrapper.paging && wrapper.paging.forEach( item => { - const key = Object.keys( item ).join(), - value = item[key]; - item[key] = query( util.selector( value ) ); - }); - return wrapper; -} - -/** - * Query content usage jquery - * - * @param {string} query content - * @param {string} type, incldue: text, html and multi - * @return {string} query result - */ -function query( content, type = "text" ) { - const $root = $( "html" ); - if ( util.specTest( content ) ) { - const [ value, state ] = util.specAction( content ); - if ( state == 0 ) { - content = value; - } else if ( state == 3 ) { - content = getcontent( $root.find( value ) ); - } - } else if ( type == "html" ) { - content = getcontent( $root.find( content ) ); - } else if ( type == "multi" ) { - // TO-DO - } else { - content = $root.find( content ).text().trim(); - } - return content; -} - -/** - * Get content from current.site.include - * - * @param {jquery} jquery object e.g. $root.find( content ) - * @return {string} $target html - */ -function getcontent( $target ) { - let html = ""; - switch ( $target.length ) { - case 0: - html = "<sr-rd-content-error></sr-rd-content-error>"; - break; - case 1: - html = $target.html().trim(); - break; - default: - html = $target.map( (index, item) => $(item).html() ).get().join( "<br>" ); - break; - } - return html; -} - -/** - * Get exclude tags list - * - * @param {jquery} jquery object - * @param {array} hidden html - * @return {string} tags list string - */ -function excludeSelector( $target, exclude ) { - let tags = [], tag = ""; - for ( let content of exclude ) { - if ( util.specTest( content )) { - const [ value, type ] = util.specAction( content ); - if ( type == 1 ) { - tag = value; - } else if ( type == 2 ) { - const arr = $target.html().match( new RegExp( value, "g" ) ); - if ( arr && arr.length > 0 ) { - const str = arr.join( "" ); - tag = `*[${str}]`; - } else { - tag = undefined; - } - } else if ( type == 3 ) { - value.remove(); - } - } else { - tag = util.selector( content ); - } - if ( tag ) tags.push( tag ); - } - return tags.join( "," ); -} \ No newline at end of file diff --git a/src/vender/puread/puread.min.js b/src/vender/puread/puread.min.js new file mode 100644 index 00000000..a57368b6 --- /dev/null +++ b/src/vender/puread/puread.min.js @@ -0,0 +1,1416 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global.PureRead = factory()); +}(this, (function () { 'use strict'; + + var classCallCheck = function (instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + }; + + var createClass = function () { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + return function (Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; + }(); + + var _extends = Object.assign || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + + return target; + }; + + var get = function get(object, property, receiver) { + if (object === null) object = Function.prototype; + var desc = Object.getOwnPropertyDescriptor(object, property); + + if (desc === undefined) { + var parent = Object.getPrototypeOf(object); + + if (parent === null) { + return undefined; + } else { + return get(parent, property, receiver); + } + } else if ("value" in desc) { + return desc.value; + } else { + var getter = desc.get; + + if (getter === undefined) { + return undefined; + } + + return getter.call(receiver); + } + }; + + var inherits = function (subClass, superClass) { + if (typeof superClass !== "function" && superClass !== null) { + throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); + } + + subClass.prototype = Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + enumerable: false, + writable: true, + configurable: true + } + }); + if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; + }; + + var possibleConstructorReturn = function (self, call) { + if (!self) { + throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + } + + return call && (typeof call === "object" || typeof call === "function") ? call : self; + }; + + var slicedToArray = 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 toConsumableArray = function (arr) { + if (Array.isArray(arr)) { + for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; + + return arr2; + } else { + return Array.from(arr); + } + }; + + console.log("=== PureRead: Util load ==="); + + /** + * Deep clone object + * + * @param {object} target object + * @return {object} new target object + */ + function clone(target) { + return $.extend(true, {}, target); + } + + /** + * Get URI + * + * @return {string} e.g. current site url is http://www.cnbeta.com/articles/1234.html return http://www.cnbeta.com/articles/ + */ + function getURI() { + var name = function name(pathname) { + pathname = pathname != "/" && pathname.endsWith("/") ? pathname = pathname.replace(/\/$/, "") : pathname; + return pathname.replace(/\/[%@#.~a-zA-Z0-9_-]+$|^\/$/g, ""); + }, + path = name(window.location.pathname); + return window.location.protocol + "//" + window.location.hostname + path + "/"; + } + + /** + * Get url and parser location + * + * @param {string} url + */ + function getLocation(href) { + if (document) { + var a = document.createElement("a"); + a.href = href; + return a; + } else { + var match = href.match(/^(https?\:)\/\/(([^:\/?#]*)(?:\:([0-9]+))?)([\/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/); + return match && { + href: href, + protocol: match[1], + host: match[2], + hostname: match[3], + port: match[4], + pathname: match[5], + search: match[6], + hash: match[7] + }; + } + } + + /** + * Verify html + * + * @param {string} input include html tag, e.g.: + <div class="article fmt article__content"> + * + * @return {array} 0: int include ( -1: fail; 0: empty html; 1: success; 2: special tag ) + * 1: result + */ + function verifyHtml(html) { + if (html == "") return [0, html];else if (specTest(html)) return [2, html]; + var item = html.match(/<\S+ (class|id)=("|')?[\w-_=;:' ]+("|')?>?$|<[^/][-_a-zA-Z0-9]+>?$/ig); + if (item && item.length > 0) { + return [1, item]; + } else { + return [-1, undefined]; + } + } + + /** + * Conver html to jquery object + * + * @param {string} input include html tag, e.g.: + <div class="article fmt article__content"> + * + * @return {string} formatting e.g.: + h2#news_title + div.introduction + div.content + div.clearfix + div.rating_box + span + special tag, @see specTest + e.g. [['<strong>▽</strong>']] [[[$('.article-btn')]]] + [[/src=\\S+(342459.png)\\S+'/]] [[{$('.content').html()}]] + * + */ + function selector(html) { + var _verifyHtml = verifyHtml(html), + _verifyHtml2 = slicedToArray(_verifyHtml, 2), + code = _verifyHtml2[0], + item = _verifyHtml2[1]; + + if (code == 2) return html;else if (code == 1) { + var _item$0$trim$replace$ = item[0].trim().replace(/['"<>]/g, "").replace(/ /ig, "=").split("="), + _item$0$trim$replace$2 = slicedToArray(_item$0$trim$replace$, 3), + tag = _item$0$trim$replace$2[0], + prop = _item$0$trim$replace$2[1], + value = _item$0$trim$replace$2[2]; // ["h2", "class", "title"] + + + if (!prop) prop = tag;else if (prop.toLowerCase() === "class") prop = tag + "." + value;else if (prop.toLowerCase() === "id") prop = tag + "#" + value; + return prop; + } else { + return null; + } + } + + /** + * Verify special action, action include: + - [[{juqery code}]] // new Function, e.g. $("xxx").xxx() return string + - [['text']] // remove '<text>' + - [[/regexp/]] // regexp e.g. $("sr-rd-content").find( "*[src='http://ifanr-cdn.b0.upaiyun.com/wp-content/uploads/2016/09/AppSo-qrcode-signature.jpg']" ) + - [[[juqery code]]] // new Function, e.g. $("xxx").find() return jquery object + + * + * @param {string} verify content + * @return {boolen} verify result + */ + function specTest(content) { + return (/^(\[\[)[\[{'/]{1}[ \S]+[}'/\]]\]\]{1}($)/g.test(content) + ); + } + + /** + * Exec special action, action include: @see specTest + * type: 0, 3 - be chiefly used in include logic + * type: 1, 2 - be chiefly used in exclude logic + * + * @param {string} content + * @return {array} 0: result; 1: type( include: -1:error 0:{} 1:'' 2:// 3:[]) + */ + function specAction(content) { + var _ref = [content.replace(/(^)\[\[|\]\]$/g, "")], + value = _ref[0], + type = _ref[1]; + + switch (value[0]) { + case "{": + value = value.replace(/^{|}$/g, ""); + content = function (v) { + return new Function("return " + v)(); + }(value); + type = 0; + break; + case "'": + content = value.replace(/^'|'$/g, ""); + var name = content.match(/^<[a-zA-Z0-9_-]+>/g).join("").replace(/<|>/g, ""); + var str = content.replace(/<[/a-zA-Z0-9_-]+>/g, ""); + content = name + ":contains(" + str + ")"; + type = 1; + break; + case "/": + content = value.replace(/^\/|\/$/g, "").replace(/\\{2}/g, "\\").replace(/'/g, '"'); + type = 2; + break; + case "[": + value = value.replace(/^{|}$/g, ""); + content = function (v) { + return new Function("return " + v)(); + }(value)[0]; + type = 3; + break; + default: + console.error("Not support current action.", content); + type = -1; + break; + } + return [content, type]; + } + + console.log("=== PureRead: AdapteSite load ==="); + + var site = { + url: "", + target: "", + matching: [], + name: "", // only read mode + title: "", // only read mode + desc: "", // only read mode + exclude: [], + include: "", + avatar: [], + paging: [] + }; + var minimatch = void 0, + rdability = void 0, + markdown = void 0, + host_href = void 0; + + var AdapteSite = function () { + function AdapteSite() { + var sites = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { global: [], custom: [], local: [] }; + classCallCheck(this, AdapteSite); + + this.url = getURI(); + this.sites = sites; // include: global, custom, local, person + this.current = {}; + this.state = "none"; // include: meta, txt, adapter, none, temp + this.origins = []; + this.mathjax = undefined; + host_href = location.href; // origin url + } + + /** + * Set url + */ + + + createClass(AdapteSite, [{ + key: "SetURL", + value: function SetURL(value) { + var uri = getLocation(value); + // Clone util.getURI() source + var name = function name(pathname) { + pathname = pathname != "/" && pathname.endsWith("/") ? pathname = pathname.replace(/\/$/, "") : pathname; + return pathname.replace(/\/[%@#.~a-zA-Z0-9_-]+$|^\/$/g, ""); + }, + path = name(uri.pathname); + this.url = uri.protocol + "//" + uri.hostname + path + "/"; + host_href = value; + } + + /** + * Set global minimatch + */ + + }, { + key: "SetMinimatch", + value: function SetMinimatch(value) { + minimatch = value; + } + + /** + * Set global rdability + */ + + }, { + key: "SetRdability", + value: function SetRdability(value) { + rdability = value; + } + + /** + * Set global markdown + */ + + }, { + key: "SetMarkdown", + value: function SetMarkdown(value) { + markdown = value; + } + + /** + * is MathJax mode + */ + + }, { + key: "isMathJax", + value: function isMathJax() { + var _this = this; + + if (this.mathjax == undefined) { + this.mathjax = false; + $('body').find('script').each(function (idx, item) { + item.type.startsWith('math') && (_this.mathjax = true); + }); + } + return this.mathjax; + } + + /** + * MathJax View + * + * @return {object} return type include: jquery; string e.g. <div id="xxxx"> ;undefined + */ + + }, { + key: "MathJaxMode", + value: function MathJaxMode() { + var $dom = readtmpl(); + if ($dom != -1) { + this.Newsite("read", $dom[0].outerHTML); + this.dom = $dom[0]; + this.state = "temp"; + return $dom; + } else { + var article = readmozilla(); + if (article && article.content != "") { + var a1 = article.content.replace('<div id="readability-page-1" class="page">', ''), + a2 = $(a1)[0], + a3 = a2.outerHTML.replace(a2.innerHTML, ""), + a4 = $(a3)[0], + tag = a4.tagName.toLowerCase(), + cls = a4.className, + id = a4.id; + if (id != "") { + return "<" + tag + " id=\"" + id + "\">"; + } else if (cls != "") { + return "<" + tag + " class=\"" + cls + "\">"; + } else return undefined; + } else return undefined; + } + } + + /** + * Not adapter usage mozilla readability and readtmpl + */ + + }, { + key: "Readability", + value: function Readability() { + try { + var article = readmozilla(); + if (article && article.content != "") { + this.Newsite("read", article.content); + this.dom = $(article.content)[0]; + this.state = "temp"; + } else throw "Readability error"; + } catch (error) { + var $dom = readtmpl(); + if ($dom != -1) { + this.Newsite("read", $dom[0].outerHTML); + this.dom = $dom[0]; + this.state = "temp"; + } else this.current.site = clone(site); + } + } + + /** + * Get site from url + * + * @param {string} include: global, custom, local + * @param {string} url + */ + + }, { + key: "Getsite", + value: function Getsite(type, url) { + return this.sites[type].find(function (item) { + return item[0] == url; + }); + } + + /** + * Get sites from url + */ + + }, { + key: "Getsites", + value: function Getsites() { + var _this2 = this; + + var matching = [], + meta = readmeta(); + this.current.url = this.url; + if (meta) { + this.current.auto = meta.auto; + this.current.url = meta.url; + delete meta.auto; + delete meta.url; + this.current.site = _extends({}, meta); + this.current.site.name.startsWith("metaread::") && (this.state = "meta"); + this.current.site.name.startsWith("txtread::") && (this.state = "txt"); + } else { + getsite("local", new Map(this.sites.local), this.url, matching); + getsite("global", new Map(this.sites.global), this.url, matching); + getsite("person", new Map(this.sites.person), this.url, matching); + getsite("custom", new Map(this.sites.custom), this.url, matching); + if (matching.length > 0) { + var found = void 0; + matching.forEach(function (site) { + if (site[1].active) { + found = site; + _this2.current.url = found[0]; + _this2.current.site = _this2.Safesite(_extends({}, found[1]), found[2], found[0]); + _this2.state = "adapter"; + } + }); + if (!found) { + var _found = matching[0]; + _found[1].active = true; + this.current.url = _found[0]; + this.current.site = this.Safesite(_extends({}, _found[1]), _found[2], _found[0]); + this.state = "adapter"; + } + console.log('%c Current parse is Adapter', 'background:#2196f3; color: #fff'); + } else { + var obj = readmulti(); + if (obj != -1) { + this.Newmultisite("read", obj); + this.state = "temp"; + } else { + this.Readability(); + } + } + } + this.current.site.matching = matching; + } + + /** + * Add new sites to this.sites.global( global sites ) + * + * @param {object} sites.[array] + * @return {int} update sites count + */ + + }, { + key: "Addsites", + value: function Addsites(result) { + var count = 0; + if (this.sites.global.length == 0) { + this.sites.global = this.Formatsites(result); + count = this.sites.global.length; + } else { + var obj = addsites(this.Formatsites(result), this.sites.global); + count = obj.count; + this.sites.global = obj.newsites; + } + return count; + } + + /** + * Add new sites to this.sites.local( local sites ) + * + * @param {object} new sites + * @return {array} this.sites.local + */ + + }, { + key: "Addlocalsites", + value: function Addlocalsites(new_sites) { + this.sites.local = [].concat(toConsumableArray(new_sites)); + return this.sites.local; + } + + /** + * Add all sites to this.sites + * + * @param {object} new sites + * @return {object} this.sites + */ + + }, { + key: "Addallsites", + value: function Addallsites(sites) { + this.sites = { + global: [].concat(toConsumableArray(sites.global)), + person: [].concat(toConsumableArray(sites.person)), + custom: [].concat(toConsumableArray(sites.custom)), + local: [].concat(toConsumableArray(sites.local)) + }; + return this.sites; + } + + /** + * Add new site( read only ) + * + * @param {string} include: focus, read + * @param {string} when read html is dom.outerHTML + */ + + }, { + key: "Newsite", + value: function Newsite(mode, html) { + var new_site = { mode: mode, url: window.location.href, site: { name: "tempread::" + window.location.host, title: "<title>", desc: "", include: "", exclude: [] } }; + html && (new_site.site.html = html); + this.current.mode = new_site.mode, this.current.url = new_site.url; + this.current.site = this.Safesite(_extends({}, new_site.site), "local", new_site.url); + console.log("【read only】current site object is ", this.current); + } + + /** + * Add new multi-site( read only ) + * + * @param {string} include: focus, read + * @param {object} multi-page, avator, include + */ + + }, { + key: "Newmultisite", + value: function Newmultisite(mode, multi) { + var new_site = { mode: mode, url: window.location.href, site: { name: "tempread::" + window.location.host, title: "<title>", desc: "", include: multi.include, exclude: [], avatar: multi.avatar } }; + this.current.mode = new_site.mode, this.current.url = new_site.url; + this.current.site = this.Safesite(_extends({}, new_site.site), "local", new_site.url); + console.log("【read only】current multi-site object is ", this.current); + } + + /** + * Update url and site from param + * + * @param {string} value is: global, custom, local + * @param {string} older url + * @param {array} [ url, new site] + */ + + }, { + key: "Updatesite", + value: function Updatesite(key, older, newer) { + var idx = this.sites[key].findIndex(function (item) { + return item[0] == older; + }); + idx == -1 && (idx = this.sites[key].length); + this.sites[key].splice(idx, 1, newer); + } + + /** + * Delete site from this.sites.local + * + * @param {string} value is: global, custom, local + * @param {string} older url + * @param {func} callback + */ + + }, { + key: "Deletesite", + value: function Deletesite(key, older, callback) { + var idx = this.sites[key].findIndex(function (item) { + return item[0] == older; + }); + idx != -1 && this.sites[key].splice(idx, 1); + callback(idx); + } + + /** + * Safe site, add all site props + * + * @param {object} modify site + * @param {string} target include: global custom local + * @param {string} url + * @returns {object} site + */ + + }, { + key: "Safesite", + value: function Safesite(site, target, url) { + site.url = url; + site.target = target; + site.name == "" && (site.name = "tempread::"); + (!site.avatar || site.avatar.length == 0) && (site.avatar = [{ name: "" }, { url: "" }]); + (!site.paging || site.paging.length == 0) && (site.paging = [{ prev: "" }, { next: "" }]); + return site; + } + + /** + * Clean useless site props + * + * @param {object} site + * @returns {object} site + */ + + }, { + key: "Cleansite", + value: function Cleansite(site) { + delete site.url; + delete site.html; + delete site.target; + delete site.matching; + site.avatar && site.avatar.length > 0 && site.avatar[0].name == "" && delete site.avatar; + site.paging && site.paging.length > 0 && site.paging[0].prev == "" && delete site.paging; + return site; + } + + /** + * Format sites object from local or remote json file + * + * @param {object} sites.[array] + * @return {array} foramat e.g. [[ <url>, object ],[ <url>, object ]] + */ + + }, { + key: "Formatsites", + value: function Formatsites(result) { + var format = new Map(); + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = result.sites[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var _site = _step.value; + + if (verifysite(_site) != 0) continue; + var url = _site.url; + delete _site.url; + format.set(url, _site); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return [].concat(toConsumableArray(format)); + } + + /** + * Clear sites + * + * @param {string} site type, only include: global, custom. local + */ + + }, { + key: "Clearsites", + value: function Clearsites(type) { + type ? this.sites[type] = [] : this.sites = { global: [], custom: [], local: [] }; + } + + /** + * Add urls to origins + * + * @param {json} result json + */ + + }, { + key: "Origins", + value: function Origins(result) { + var urls = result.origins.map(function (item) { + return item.url; + }); + urls = new Set(this.origins.concat(urls)); + urls.forEach(function (item) { + if (item.trim() == "" || !item.trim().startsWith("http") || !item.trim().endsWith(".json")) urls.delete(item); + }); + this.origins = [].concat(toConsumableArray(urls)); + return this.origins; + } + + /** + * Add new sites to this.sites.custom( custom sites ) + * + * @param {object} new sites + * @return {array} this.sites.custom + */ + + }, { + key: "Addorigins", + value: function Addorigins(new_sites) { + this.sites.custom = [].concat(toConsumableArray(new_sites)); + return this.sites.custom; + } + + /** + * Clear origins + * + * @returns custom.length + */ + + }, { + key: "Clearorigins", + value: function Clearorigins() { + var len = this.sites.custom.length; + this.sites.custom = []; + return len; + } + }]); + return AdapteSite; + }(); + function readmeta() { + if (minimatch(location.href, "file://**/*.txt") || minimatch(location.href, "http*://**/*.txt")) { + return readtxt(); + } + if ($($("body").children()[0]).is('pre') && (minimatch(location.href, "file://**/*.md") || minimatch(location.href, "http*://**/*.md"))) { + return readmd(); + } + var reg = /<\S+ (class|id)=("|')?[\w-_=;:' ]+("|')?>?$|<[^/][-_a-zA-Z0-9]+>?$/ig, + // from util.verifyHtml() + meta = { + name: $("meta[name='simpread:name']").attr("content"), + url: $("meta[name='simpread:url']").attr("content"), + title: $("meta[name='simpread:title']").attr("content"), + desc: $("meta[name='simpread:desc']").attr("content"), + include: $("meta[name='simpread:include']").attr("content"), + exp: $("meta[name='simpread:exclude']").attr("content"), + auto: $("meta[name='simpread:auto']").attr("content"), + exclude: [] + }; + if (meta.name && meta.include) { + if (meta.url && !minimatch(location.href, meta.url)) { + return undefined; + } + !meta.title && (meta.title = "<title>"); + !meta.desc && (meta.desc = ""); + !meta.exp && (meta.exp = ""); + meta.name = "metaread::" + meta.name; + meta.auto = meta.auto == "true" ? true : false; + var idx = ["title", "desc", "include", "exp"].findIndex(function (item) { + return meta[item] != "" && !meta[item].match(reg); + }); + meta.exclude.push(meta.exp); + delete meta.exp; + console.assert(idx == -1, "meta read mode error. ", meta); + idx == -1 && console.log('%c Current parse is Meta', 'background:#2196f3; color: #fff', meta); + return idx == -1 ? meta : undefined; + } else { + return undefined; + } + } + + /** + * Read txt, include: file and http + */ + function readtxt() { + var title = location.pathname.split("/").pop(), + type = location.protocol == "file:" ? "local" : "remote", + meta = { + name: "txtread::" + type, + title: "<title>", + desc: "", + include: "<pre>", + auto: false, + exclude: [] + }; + if (type == "remote") { + meta.include = ""; + meta.html = $("body pre").html().replace(/\n/ig, "<br>"); + } + !$("title").html() && $("head").append("<title>" + decodeURI(title.replace(".txt", "")) + ""); + console.log('%c Current parse is TXT', 'background:#2196f3; color: #fff', meta); + return meta; + } + + /** + * Read Markdown, include: file and http + */ + function readmd() { + var title = location.pathname.split("/").pop(), + type = location.protocol == "file:" ? "local" : "remote", + meta = { + name: "txtread::" + type, + title: "", + desc: "", + include: "", + auto: false, + exclude: [] + }; + var converter = new markdown.default.Converter(), + html = converter.makeHtml($("body pre").text()); + meta.html = html; + !$("title").html() && $("head").append("<title>" + decodeURI(title.replace(".md", "")) + ""); + console.log('%c Current parse is Markdown', 'background:#2196f3; color: #fff', meta); + return meta; + } + + /** + * Read mode template, include: + * + * - Hexo + * - WordPress + * - Common( include
) + * + * @return {jquery} jquery object + */ + function readtmpl() { + var $root = $("body"), + selectors = ["[itemprop='articleBody']", "article", ".post-content", ".entry-content", ".post-article", ".content-post", ".article-entry", ".article-content", ".article-body", ".markdown-body", ".post", ".content"]; + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; + + try { + for (var _iterator2 = selectors[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + var selector$$1 = _step2.value; + + var $target = $root.find(selector$$1); + if ($target.length > 0) { + console.log('%c Current parse is SimpRead', 'background:#2196f3; color: #fff', selector$$1); + return $target; + } + } + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2.return) { + _iterator2.return(); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } + + return -1; + } + + /** + * Read mode multi template, include: + * + * - Discuz + * - Discourse + * + * @return {object} true: object; false: -1 + */ + function readmulti() { + if (location.pathname.includes("thread") || location.pathname.includes("forum.php")) { + if ($('.t_f').length > 0 && $('.favatar').find('.authi').length > 0 && $('.avatar').find('img').length > 0) { + return { + avatar: [{ "name": "[[{$('.favatar').find('.authi')}]]" }, { "url": "[[{$('.avatar').find('img')}]]" }], + include: "[[{$('.t_f')}]]" + }; + } + } else if (/\/t\/[\w-]+\/\d+/.test(location.pathname) && $('meta[name=generator]').attr("content").includes("discourse")) { + return { + avatar: [{ "name": "[[{$('.topic-avatar').find('.a[data-user-card]')}]]" }, { "url": "[[{$('.topic-avatar').find('img')}]]" }], + include: "[[{$('.cooked')}]]" + }; + } + return -1; + } + + /** + * Read mode usage mozilla + * + * @return {object} article + */ + function readmozilla() { + var location = document.location, + uri = { + spec: location.href, + host: location.host, + prePath: location.protocol + "//" + location.host, + scheme: location.protocol.substr(0, location.protocol.indexOf(":")), + pathBase: location.protocol + "//" + location.host + location.pathname.substr(0, location.pathname.lastIndexOf("/") + 1) + }, + article = new rdability.Readability(uri, document.cloneNode(true)).parse(); + console.log('%c Current parse is Mozilla', 'background:#2196f3; color: #fff', article); + return article; + } + + /** + * Add new sites to old sites + * + * @param {array} new sites from local or remote + * @param {array} current sites from this.sites.global + * @return {object} count: new sites; forced: update sites( discard, all site must be forced update) + */ + function addsites(newsites, old) { + var oldsites = new Map(old), + urls = [].concat(toConsumableArray(oldsites.keys())); + var count = 0; + + newsites.map(function (site) { + if (!urls.includes(site[0])) { + count++; + } else if (urls.includes(site[0])) { + } + }); + return { count: count, newsites: newsites }; + } + + /** + * Find site by url from sites + * + * @param {string} type, include: global, local, custom + * @param {map} sites + * @param {string} url + * @param {array} matching sites + * + * @return {array} 0: current site; 1: current url, 2: type + */ + function getsite(type, sites, url) { + var matching = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : []; + + var domain = function domain(names) { + var arr = names.replace("www.", "").match(/\.\S+\.\S+/g); + if (arr) { + return arr[0].substr(1); + } else { + return names.replace("www.", ""); + } + }, + local = getLocation(host_href), + urls = [].concat(toConsumableArray(sites.keys())), + arr = url.match(/[.a-zA-z0-9-_]+/g), + uri = arr[1].replace("www.", ""), + hostname = domain(local.hostname), + isroot = function isroot() { + return local.pathname == "/" || /\/(default|index|portal).[0-9a-zA-Z]+$/.test(local.pathname); + }; + var _iteratorNormalCompletion3 = true; + var _didIteratorError3 = false; + var _iteratorError3 = undefined; + + try { + for (var _iterator3 = urls[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + var cur = _step3.value; + + var name = sites.get(cur).name, + sufname = domain(name); + if (!isroot() && !cur.endsWith("*") && cur.replace(/^http[s]?:/, "") == url.replace(/^http[s]?:/, "")) { + matching.push([cur, clone(sites.get(cur)), type]); + } else if (cur.match(/\*/g) && cur.match(/\*/g).length == 1 && !isroot() && cur.endsWith("*") && uri.includes(sufname) && hostname == sufname && url.includes(name)) { + // e.g. https://www.douban.com/* http://mp.weixin.qq.com/* + matching.push([cur, clone(sites.get(cur)), type]); + } else if (minimatch(local.origin + local.pathname, cur)) { + matching.push([cur, clone(sites.get(cur)), type]); + } + } + } catch (err) { + _didIteratorError3 = true; + _iteratorError3 = err; + } finally { + try { + if (!_iteratorNormalCompletion3 && _iterator3.return) { + _iterator3.return(); + } + } finally { + if (_didIteratorError3) { + throw _iteratorError3; + } + } + } + } + + /** + * Verify site validity, include: + * - name, url, include, error is -1 + * - title include desc, error is -2 + * - paging, error is -3 ~ -6 + * - avatar, error is -7 ~ -10 + * + * @param {object} site + */ + function verifysite(site) { + if (!site.name || !site.url || !site.include) return -1; + if (verifyHtml(site.title)[0] == -1 || verifyHtml(site.include)[0] == -1 || verifyHtml(site.desc)[0] == -1) { + return -2; + } + if (site.paging) { + if (site.paging.length != 2) return -3; + if (!site.paging[0].prev) return -4; + if (!site.paging[1].next) return -5; + if (verifyHtml(site.paging[0].prev)[0] == -1 || verifyHtml(site.paging[1].next)[0] == -1) { + return -6; + } + } + if (site.avatar) { + if (site.avatar.length != 2) return -7; + if (!site.avatar[0].name) return -8; + if (!site.avatar[1].url) return -9; + if (verifyHtml(site.avatar[0].name)[0] == -1 || verifyHtml(site.avatar[1].url)[0] == -1) { + return -10; + } + } + return 0; + } + + console.log("=== PureRead: PureRead load ==="); + + var PureRead = function (_AdapteSite) { + inherits(PureRead, _AdapteSite); + + function PureRead(sites) { + classCallCheck(this, PureRead); + + var _this = possibleConstructorReturn(this, (PureRead.__proto__ || Object.getPrototypeOf(PureRead)).call(this, sites)); + + _this.version = "0.0.4 build 0427"; + _this.org_url = location.href; + _this.html = {}; // clone site, include: title, desc, include, avatar, paging + _this.plugin = {}; + _this.pure = false; // when true, is remove style, class attr + _this.cleanup = false; // when true, call beautify.cleanHTML() + return _this; + } + + /** + * Verify current puread is same + * + * @return {boolean} true: same; false: not same; + */ + + + createClass(PureRead, [{ + key: 'Exist', + value: function Exist() { + return this.org_url == location.href; + } + + /** + * Add Plugin + * + * @param {object} plugin object + */ + + }, { + key: 'AddPlugin', + value: function AddPlugin(plugin) { + this.plugin = { + minimatch: plugin.minimatch, + pangu: plugin.pangu, + beautify: plugin.beautify, + stylesheet: plugin.style, + rdability: plugin.rdability, + markdown: plugin.markdown + }; + get(PureRead.prototype.__proto__ || Object.getPrototypeOf(PureRead.prototype), 'SetMinimatch', this).call(this, this.plugin.minimatch); + get(PureRead.prototype.__proto__ || Object.getPrototypeOf(PureRead.prototype), 'SetRdability', this).call(this, this.plugin.rdability); + get(PureRead.prototype.__proto__ || Object.getPrototypeOf(PureRead.prototype), 'SetMarkdown', this).call(this, this.plugin.markdown); + } + + /** + * Get read mode html + */ + + }, { + key: 'ReadMode', + value: function ReadMode() { + this.html = wrap(this.current.site); + } + + /** + * Create temp read mode + * + * @param {string} include: read, focus + * @param {dom} html dom element + */ + + }, { + key: 'TempMode', + value: function TempMode(mode, dom) { + this.state = "temp"; + this.dom = dom; + this.Newsite(mode, dom.outerHTML); + } + + /** + * Get Dom + * + * @param {string} html, e.g.
+ * @param {string} type, @see query + */ + + }, { + key: 'GetDom', + value: function GetDom(str, type) { + var include = selector(str), + dom = query(include, type); + return dom; + } + + /** + * Get highlight( focus ) jquery, only usage focus mode + * + * @return {jquery} jquery object + */ + + }, { + key: 'Include', + value: function Include() { + var include = this.current.site.include, + $focus = []; + var target = selector(include); + try { + if (specTest(target)) { + var _util$specAction = specAction(include), + _util$specAction2 = slicedToArray(_util$specAction, 2), + value = _util$specAction2[0], + state = _util$specAction2[1]; + + if (state == 0) { + include = include.replace(/\[\[{\$\(|}\]\]|\).html\(\)/g, ""); + $focus = $(specAction('[[[' + include + ']]]')[0]); + } else if (state == 3) { + $focus = value; + } + } else if (target) { + $focus = $("body").find(target); + } + } catch (error) { + console.error("Get $focus failed", error); + } + return $focus; + } + + /** + * Get exlcude jquery selector array list + * + * @param {jquery} jquery object + * @return {array} jquery selector + */ + + }, { + key: 'Exclude', + value: function Exclude($target) { + return excludeSelector($target, this.current.site.exclude); + } + + /** + * Beautify html + * + * @param {jquery} jquery + */ + + }, { + key: 'Beautify', + value: function Beautify($target) { + if (this.plugin.beautify) { + this.cleanup && this.plugin.beautify.cleanHTML($target, this.pure, this.isMathJax()); + this.plugin.beautify.specbeautify(this.current.site.name, $target); + this.plugin.beautify.removeSpareTag(this.current.site.name, $target); + this.plugin.beautify.htmlbeautify($target); + this.plugin.beautify.commbeautify(this.current.site.name, $target); + } + } + + /** + * Format usage pangu plugin + * + * @param {string} class name + */ + + }, { + key: 'Format', + value: function Format(cls) { + this.plugin.pangu && this.plugin.pangu.spacingElementByClassName(cls); + } + }]); + return PureRead; + }(AdapteSite); + function wrap(site) { + var wrapper = clone(site), + title = selector(site.title == "" ? "" : site.title), + desc = selector(site.desc), + include = selector(site.include); + wrapper.title = site.title == "" || site.title == "<title>" ? $("head title").text() : query(title); + wrapper.desc = query(desc); + wrapper.include = site.include == "" && site.html != "" ? site.html : query(include, "html"); + wrapper.avatar && wrapper.avatar.length > 0 && wrapper.avatar[0].name == "" && delete wrapper.avatar; + wrapper.paging && wrapper.paging.length > 0 && wrapper.paging[0].prev == "" && delete wrapper.paging; + wrapper.avatar && wrapper.avatar.forEach(function (item) { + var key = Object.keys(item).join(), + value = item[key]; + item[key] = query(selector(value), "html"); + }); + wrapper.paging && wrapper.paging.forEach(function (item) { + var key = Object.keys(item).join(), + value = item[key]; + item[key] = query(selector(value)); + }); + return wrapper; + } + + /** + * Query content usage jquery + * + * @param {string} query content + * @param {string} type, incldue: text, html and multi + * @return {string} query result + */ + function query(content) { + var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "text"; + + var $root = $("html"); + if (specTest(content)) { + var _util$specAction3 = specAction(content), + _util$specAction4 = slicedToArray(_util$specAction3, 2), + value = _util$specAction4[0], + state = _util$specAction4[1]; + + if (state == 0) { + content = value; + } else if (state == 3) { + content = getcontent($root.find(value)); + } + } else if (type == "html") { + content = getcontent($root.find(content)); + } else if (type == "multi") { + // TO-DO + } else { + content = $root.find(content).text().trim(); + } + return content; + } + + /** + * Get content from current.site.include + * + * @param {jquery} jquery object e.g. $root.find( content ) + * @return {string} $target html + */ + function getcontent($target) { + var html = ""; + switch ($target.length) { + case 0: + html = "<sr-rd-content-error></sr-rd-content-error>"; + break; + case 1: + html = $target.html().trim(); + break; + default: + html = $target.map(function (index, item) { + return $(item).html(); + }).get().join("<br>"); + break; + } + return html; + } + + /** + * Get exclude tags list + * + * @param {jquery} jquery object + * @param {array} hidden html + * @return {string} tags list string + */ + function excludeSelector($target, exclude) { + var tags = [], + tag = ""; + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = exclude[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var content = _step.value; + + if (specTest(content)) { + var _util$specAction5 = specAction(content), + _util$specAction6 = slicedToArray(_util$specAction5, 2), + value = _util$specAction6[0], + type = _util$specAction6[1]; + + if (type == 1) { + tag = value; + } else if (type == 2) { + var arr = $target.html().match(new RegExp(value, "g")); + if (arr && arr.length > 0) { + var str = arr.join(""); + tag = '*[' + str + ']'; + } else { + tag = undefined; + } + } else if (type == 3) { + value.remove(); + } + } else { + tag = selector(content); + } + if (tag) tags.push(tag); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + return tags.join(","); + } + + return PureRead; + +}))); diff --git a/src/vender/puread/util.js b/src/vender/puread/util.js deleted file mode 100644 index 94116d2b..00000000 --- a/src/vender/puread/util.js +++ /dev/null @@ -1,141 +0,0 @@ -console.log( "=== PureRead: Util load ===" ) - -/** - * Deep clone object - * - * @param {object} target object - * @return {object} new target object - */ -function clone( target ) { - return $.extend( true, {}, target ); -} - -/** - * Get URI - * - * @return {string} e.g. current site url is http://www.cnbeta.com/articles/1234.html return http://www.cnbeta.com/articles/ - */ -function getURI() { - const name = (pathname) => { - pathname = pathname != "/" && pathname.endsWith("/") ? pathname = pathname.replace( /\/$/, "" ) : pathname; - return pathname.replace( /\/[%@#.~a-zA-Z0-9_-]+$|^\/$/g, "" ); - }, - path = name( window.location.pathname ); - return `${ window.location.protocol }//${ window.location.hostname }${ path }/`; -} - -/** - * Verify html - * - * @param {string} input include html tag, e.g.: - <div class="article fmt article__content"> - * - * @return {array} 0: int include ( -1: fail; 0: empty html; 1: success; 2: special tag ) - * 1: result - */ -function verifyHtml( html ) { - if ( html == "" ) return [ 0, html ]; - else if ( specTest( html )) return [ 2, html ]; - const item = html.match( /<\S+ (class|id)=("|')?[\w-_=;:' ]+("|')?>?$|<[^/][-_a-zA-Z0-9]+>?$/ig ); - if ( item && item.length > 0 ) { - return [ 1, item ]; - } else { - return [ -1, undefined ]; - } -} - -/** - * Conver html to jquery object - * - * @param {string} input include html tag, e.g.: - <div class="article fmt article__content"> - * - * @return {string} formatting e.g.: - h2#news_title - div.introduction - div.content - div.clearfix - div.rating_box - span - special tag, @see specTest - e.g. [['<strong>▽</strong>']] [[[$('.article-btn')]]] - [[/src=\\S+(342459.png)\\S+'/]] [[{$('.content').html()}]] - * - */ -function selector( html ) { - const [ code, item ] = verifyHtml( html ); - if ( code == 2 ) return html; - else if ( code == 1 ) { - let [tag, prop, value] = item[0].trim().replace( /['"<>]/g, "" ).replace( / /ig, "=" ).split( "=" ); // ["h2", "class", "title"] - if ( !prop ) prop = tag; - else if ( prop.toLowerCase() === "class") prop = `${tag}.${value}`; - else if ( prop.toLowerCase() === "id" ) prop = `${tag}#${value}`; - return prop; - } else { - return null; - } -} - -/** - * Verify special action, action include: - - [[{juqery code}]] // new Function, e.g. $("xxx").xxx() return string - - [['text']] // remove '<text>' - - [[/regexp/]] // regexp e.g. $("sr-rd-content").find( "*[src='http://ifanr-cdn.b0.upaiyun.com/wp-content/uploads/2016/09/AppSo-qrcode-signature.jpg']" ) - - [[[juqery code]]] // new Function, e.g. $("xxx").find() return jquery object - - * - * @param {string} verify content - * @return {boolen} verify result - */ -function specTest( content ) { - return /^(\[\[)[\[{'/]{1}[ \S]+[}'/\]]\]\]{1}($)/g.test( content ); -} - -/** - * Exec special action, action include: @see specTest - * type: 0, 3 - be chiefly used in include logic - * type: 1, 2 - be chiefly used in exclude logic - * - * @param {string} content - * @return {array} 0: result; 1: type( include: -1:error 0:{} 1:'' 2:// 3:[]) - */ -function specAction( content ) { - let [ value, type ] = [ content.replace( /(^)\[\[|\]\]$/g, "" ) ]; - switch (value[0]) { - case "{": - value = value.replace( /^{|}$/g, "" ); - content = ( v=>new Function( `return ${v}` )() )(value); - type = 0; - break; - case "'": - content = value.replace( /^'|'$/g, "" ); - const name = content.match(/^<[a-zA-Z0-9_-]+>/g).join("").replace( /<|>/g, "" ); - const str = content.replace( /<[/a-zA-Z0-9_-]+>/g, "" ); - content = `${name}:contains(${str})`; - type = 1; - break; - case "/": - content = value.replace( /^\/|\/$/g, "" ).replace( /\\{2}/g, "\\" ).replace( /'/g, '"' ); - type = 2; - break; - case "[": - value = value.replace( /^{|}$/g, "" ); - content = ( v=>new Function( `return ${v}` )() )(value)[0]; - type = 3; - break; - default: - console.error( "Not support current action.", content ) - type = -1; - break; - } - return [ content, type ]; -} - -export { - clone, - getURI, - verifyHtml, - selector, - specTest, - specAction -} \ No newline at end of file diff --git a/webpack.config.js b/webpack.config.js index b274ee38..b306aed6 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -308,8 +308,8 @@ const webpack = require( 'webpack' ), tooltip : __dirname + '/src/vender/mduikit/tooltip.jsx', waves : __dirname + '/src/vender/mduikit/waves.js', - puread : __dirname + '/src/vender/puread/puread.js', - puplugin : __dirname + '/src/vender/puread/plugin.js', + puread : __dirname + '/src/vender/puread/puread.min.js', + puplugin : __dirname + '/src/vender/puread/puplugin.min.js', } }