From e52196d10e36ca6d8688337c213e8b106c452338 Mon Sep 17 00:00:00 2001 From: Vitaly Puzrin Date: Fri, 10 Oct 2014 07:55:25 +0400 Subject: [PATCH] Demo update --- demo/assets/index.js | 10 +- demo/index.html | 538 +-------- demo/index.jade | 14 +- demo/sample.md | 503 +------- dist/remarkable.js | 2475 ++++++++++++++++++++++++++++++++++++++-- dist/remarkable.min.js | 5 +- 6 files changed, 2463 insertions(+), 1082 deletions(-) diff --git a/demo/assets/index.js b/demo/assets/index.js index 0a03830..0808cd8 100644 --- a/demo/assets/index.js +++ b/demo/assets/index.js @@ -4,10 +4,12 @@ var mdHtml, mdSrc, permalink; var defaults = { - html: true, - xhtmlOut: true, - breaks: false, - langPrefix: 'language-', + html: true, // Enable html tags in source + xhtmlOut: true, // Use '/' to close single tags (
) + breaks: false, // Convert '\n' in paragraphs into
+ langPrefix: 'language-', // CSS language prefix for fenced blocks + linkify: false, // autoconvert url-like texts to links + typographer: false, // Enable smartypants and other sweet transforms // options below are for demo only _highlight: false, diff --git a/demo/index.html b/demo/index.html index 7e89453..3c1bbc8 100644 --- a/demo/index.html +++ b/demo/index.html @@ -17,15 +17,18 @@

Remarkable demo

code sample

var Remarkable = require('remarkable');
+
 var md = new Remarkable({
-  html: false,              // enable html tags in source
-  xhtml: false,             // use '/' to close single tags (<br />)
-  breaks: true,             // convert '\n' in paragraphs into <br>
-  langPrefix: 'language-',  // css language prefix for fenced blocks
-
-  // Should return HTML markup for highlighted text,
-  // or empty string to escape source
-  highlight: function (str, lang) { return ''; }
+  html:         false,        // Enable html tags in source
+  xhtmlOut:     false,        // Use '/' to close single tags (<br />)
+  breaks:       false,        // Convert '\n' in paragraphs into <br>
+  langPrefix:   'language-',  // CSS language prefix for fenced blocks
+  linkify:      false,        // autoconvert url-like texts to links
+  typographer:  false,        // Enable smartypants and other sweet transforms
+
+  // Highlighter function. Should return escaped html,
+  // or '' if input not changed
+  highlight: function (/*str, , lang*/) { return ''; }
 });
 
 console.log(md.parse('# Remarkable rulezz!'));
@@ -38,8 +41,8 @@ console.log(md.parse('# Remarkable rulezz!'));
           
         
         
-
@@ -47,6 +50,16 @@ console.log(md.parse('# Remarkable rulezz!')); breaks
+
+ +
+
+ +
-
diff --git a/demo/index.jade b/demo/index.jade index 9b804ed..348ca48 100644 --- a/demo/index.jade +++ b/demo/index.jade @@ -33,13 +33,21 @@ html input#html(type='checkbox') | html .checkbox - label._tip(title='add / to single tags (
instead of
') - input#xhtml(type='checkbox') - | xhtml + label._tip(title='produce xtml output (add / to single tags (
instead of
)') + input#xhtmlOut(type='checkbox') + | xhtmlOut .checkbox label._tip(title='newlines in paragraphs are rendered as
') input#breaks(type='checkbox') | breaks + .checkbox + label._tip(title='autoconvert link-like texts to links') + input#linkify(type='checkbox') + | linkify + .checkbox + label._tip(title='do typographyc replacements, (c) -> © and so on') + input#typographer(type='checkbox') + | typographer .checkbox label._tip(title='enable output highlight for fenced blocks') input#_highlight(type='checkbox') diff --git a/demo/sample.md b/demo/sample.md index 49a1cff..d3fc50e 100644 --- a/demo/sample.md +++ b/demo/sample.md @@ -1,20 +1,3 @@ -# Typography - -## Headings - -Headings from `h1` through `h6` are constructed with a `#` for each level: - -``` markdown -# h1 Heading -## h2 Heading -### h3 Heading -#### h4 Heading -##### h5 Heading -###### h6 Heading -``` - -Renders to: - # h1 Heading ## h2 Heading ### h3 Heading @@ -22,32 +5,9 @@ Renders to: ##### h5 Heading ###### h6 Heading -HTML: - -``` html -

h1 Heading

-

h2 Heading

-

h3 Heading

-

h4 Heading

-
h5 Heading
-
h6 Heading
-``` - -
-
-
- ## Horizontal Rules -The HTML `
` element is for creating a "thematic break" between paragraph-level elements. In markdown, you can create a `
` with any of the following: - -* `___`: three consecutive underscores -* `---`: three consecutive dashes -* `***`: three consecutive asterisks - -renders to: - ___ --- @@ -55,165 +15,49 @@ ___ *** -
-
-
+## Typographic replacements +Enable typographer option to see result. -## Body Copy +(c) (C) (r) (R) (tm) (TM) (p) (P) +- -Body copy written as normal, plain text will be wrapped with `

` tags in the rendered HTML. +test.. test... test..... test?..... test!.... -So this body copy: +!!!!!! ???? ,, -``` markdown -Lorem ipsum dolor sit amet, graecis denique ei vel, at duo primis mandamus. Et legere ocurreret pri, animal tacimates complectitur ad cum. Cu eum inermis inimicus efficiendi. Labore officiis his ex, soluta officiis concludaturque ei qui, vide sensibus vim ad. -``` -renders to this HTML: - -``` html -

Lorem ipsum dolor sit amet, graecis denique ei vel, at duo primis mandamus. Et legere ocurreret pri, animal tacimates complectitur ad cum. Cu eum inermis inimicus efficiendi. Labore officiis his ex, soluta officiis concludaturque ei qui, vide sensibus vim ad.

-``` - - -
-
-
+Remarkable -- awesome ## Emphasis -### Bold -For emphasizing a snippet of text with a heavier font-weight. +**This is bold text** -The following snippet of text is **rendered as bold text**. +__This is bold text__ -``` markdown -**rendered as bold text** -``` -renders to: - -**rendered as bold text** +*This is italic text* -and this HTML - -``` html -rendered as bold text -``` - -### Italics -For emphasizing a snippet of text with italics. - -The following snippet of text is _rendered as italicized text_. - -``` markdown -_rendered as italicized text_ -``` - -renders to: - -_rendered as italicized text_ - -and this HTML: - -``` html -rendered as italicized text -``` - - -### strikethrough -In GFM you can do strickthroughs. - -``` markdown -~~Strike through this text.~~ -``` -Which renders to: +_This is italic text_ ~~Strike through this text.~~ -
-
-
- - ## Blockquotes -For quoting blocks of content from another source within your document. - -Add `>` before any text you want to quote. - -``` markdown -Add `>` before any text you want to quote. -``` - -Renders to: > Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante. -and this HTML: - -``` html -
-

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.

-
-``` - Blockquotes can also be nested: -``` markdown -> Donec massa lacus, ultricies a ullamcorper in, fermentum sed augue. -Nunc augue augue, aliquam non hendrerit ac, commodo vel nisi. ->> Sed adipiscing elit vitae augue consectetur a gravida nunc vehicula. Donec auctor +> Donec massa lacus, ultricies a ullamcorper in, fermentum sed augue. +Nunc augue augue, aliquam non hendrerit ac, commodo vel nisi. +>> Sed adipiscing elit vitae augue consectetur a gravida nunc vehicula. Donec auctor odio non est accumsan facilisis. Aliquam id turpis in dolor tincidunt mollis ac eu diam. ->>> Donec massa lacus, ultricies a ullamcorper in, fermentum sed augue. -Nunc augue augue, aliquam non hendrerit ac, commodo vel nisi. -``` - -Renders to: - -> Donec massa lacus, ultricies a ullamcorper in, fermentum sed augue. -Nunc augue augue, aliquam non hendrerit ac, commodo vel nisi. ->> Sed adipiscing elit vitae augue consectetur a gravida nunc vehicula. Donec auctor -odio non est accumsan facilisis. Aliquam id turpis in dolor tincidunt mollis ac eu diam. ->>> Donec massa lacus, ultricies a ullamcorper in, fermentum sed augue. -Nunc augue augue, aliquam non hendrerit ac, commodo vel nisi. - - -
-
-
+>>> Donec massa lacus, ultricies a ullamcorper in, fermentum sed augue. +Nunc augue augue, aliquam non hendrerit ac, commodo vel nisi. ## Lists -### Unordered -A list of items in which the order of the items does not explicitly matter. - -You may use any of the following symbols to denote bullets for each list item: - -```markdown -* valid bullet -- valid bullet -+ valid bullet -``` - -For example - -``` markdown -+ Lorem ipsum dolor sit amet -+ Consectetur adipiscing elit -+ Integer molestie lorem at massa -+ Facilisis in pretium nisl aliquet -+ Nulla volutpat aliquam velit - - Phasellus iaculis neque - - Purus sodales ultricies - - Vestibulum laoreet porttitor sem - - Ac tristique libero volutpat at -+ Faucibus porta lacus fringilla vel -+ Aenean sit amet erat nunc -+ Eget porttitor lorem -``` -Renders to: +Unordered + Lorem ipsum dolor sit amet + Consectetur adipiscing elit @@ -224,86 +68,13 @@ Renders to: - Purus sodales ultricies - Vestibulum laoreet porttitor sem - Ac tristique libero volutpat at + * Consectetur adipiscing elit + * Integer molestie lorem at massa + Faucibus porta lacus fringilla vel + Aenean sit amet erat nunc + Eget porttitor lorem -And this HTML - -``` html -
    -
  • Lorem ipsum dolor sit amet
  • -
  • Consectetur adipiscing elit
  • -
  • Integer molestie lorem at massa
  • -
  • Facilisis in pretium nisl aliquet
  • -
  • Nulla volutpat aliquam velit -
      -
    • Phasellus iaculis neque
    • -
    • Purus sodales ultricies
    • -
    • Vestibulum laoreet porttitor sem
    • -
    • Ac tristique libero volutpat at
    • -
    -
  • -
  • Faucibus porta lacus fringilla vel
  • -
  • Aenean sit amet erat nunc
  • -
  • Eget porttitor lorem
  • -
-``` - -### Ordered - -A list of items in which the order of items does explicitly matter. - -``` markdown -1. Lorem ipsum dolor sit amet -2. Consectetur adipiscing elit -3. Integer molestie lorem at massa -4. Facilisis in pretium nisl aliquet -5. Nulla volutpat aliquam velit -6. Faucibus porta lacus fringilla vel -7. Aenean sit amet erat nunc -8. Eget porttitor lorem -``` -Renders to: - -1. Lorem ipsum dolor sit amet -2. Consectetur adipiscing elit -3. Integer molestie lorem at massa -4. Facilisis in pretium nisl aliquet -5. Nulla volutpat aliquam velit -6. Faucibus porta lacus fringilla vel -7. Aenean sit amet erat nunc -8. Eget porttitor lorem - -And this HTML: - -``` html -
    -
  1. Lorem ipsum dolor sit amet
  2. -
  3. Consectetur adipiscing elit
  4. -
  5. Integer molestie lorem at massa
  6. -
  7. Facilisis in pretium nisl aliquet
  8. -
  9. Nulla volutpat aliquam velit
  10. -
  11. Faucibus porta lacus fringilla vel
  12. -
  13. Aenean sit amet erat nunc
  14. -
  15. Eget porttitor lorem
  16. -
-``` - -**TIP**: If you just use `1.` for each number, GitHub will automatically number each item. For example: - -``` markdown -1. Lorem ipsum dolor sit amet -1. Consectetur adipiscing elit -1. Integer molestie lorem at massa -1. Facilisis in pretium nisl aliquet -1. Nulla volutpat aliquam velit -1. Faucibus porta lacus fringilla vel -1. Aenean sit amet erat nunc -1. Eget porttitor lorem -``` - -Renders to: +Ordered 1. Lorem ipsum dolor sit amet 2. Consectetur adipiscing elit @@ -315,33 +86,11 @@ Renders to: 8. Eget porttitor lorem -
-
-
- - ## Code -### Inline code -Wrap inline snippets of code with `` ` ``. - -For example, `
` should be wrapped as "inline". - -``` html -For example, `
` should be wrapped as "inline". -``` - - -### Indented code - -Or indent several lines of code by at least four spaces, as in: +Inline `code` -``` js - // Some comments - line 1 of code - line 2 of code - line 3 of code -``` +Indented code // Some comments line 1 of code @@ -349,59 +98,15 @@ Or indent several lines of code by at least four spaces, as in: line 3 of code -### Block code "fences" - -Use "fences" ```` ``` ```` to block in multiple lines of code. - -
-``` html
-Sample text here...
-```
-
- +Block code "fences" ``` Sample text here... ``` -HTML: - -``` html -
-  

Sample text here...

-
-``` - -### Syntax highlighting - -GFM, or "GitHub Flavored Markdown" also supports syntax highlighting. To activate it, simply add the file extension of the language you want to use directly after the first code "fence", ` ``` js `, and syntax highlighting will automatically be applied in the rendered HTML. For example, to apply syntax highlighting to JavaScript code: - -
-``` javascript
-grunt.initConfig({
-  assemble: {
-    options: {
-      assets: 'docs/assets',
-      data: 'src/data/*.{json,yml}',
-      helpers: 'src/custom-helpers.js',
-      partials: ['src/partials/**/*.{hbs,md}']
-    },
-    pages: {
-      options: {
-        layout: 'default.hbs'
-      },
-      files: {
-        './': ['src/templates/pages/index.hbs']
-      }
-    }
-  }
-};
-```
-
- -Renders to: +Syntax highlighting -``` javascript +``` js grunt.initConfig({ assemble: { options: { @@ -422,50 +127,7 @@ grunt.initConfig({ }; ``` -And this complicated HTML: - -``` xml -
grunt.initConfig({
-  assemble: {
-    options: {
-      assets: 'docs/assets',
-      data: 'src/data/*.{json,yml}',
-      helpers: 'src/custom-helpers.js',
-      partials: ['src/partials/**/*.{hbs,md}']
-    },
-    pages: {
-      options: {
-        layout: 'default.hbs'
-      },
-      files: {
-        './': ['src/templates/pages/index.hbs']
-      }
-    }
-  }
-};
-
-``` - - -
-
-
- - - ## Tables -Tables are created by adding pipes as dividers between each cell, and by adding a line of dashes (also separated by bars) beneath the header. Note that the pipes do not need to be vertically aligned. - - -``` markdown -| Option | Description | -| ------ | ----------- | -| data | path to data files to supply the data that will be passed into templates. | -| engine | engine to be used for processing templates. Handlebars is the default. | -| ext | extension to be used for dest files. | -``` - -Renders to: | Option | Description | | ------ | ----------- | @@ -473,40 +135,7 @@ Renders to: | engine | engine to be used for processing templates. Handlebars is the default. | | ext | extension to be used for dest files. | -And this HTML: - -``` html - - - - - - - - - - - - - - - - - -
OptionDescription
datapath to data files to supply the data that will be passed into templates.
engineengine to be used for processing templates. Handlebars is the default.
extextension to be used for dest files.
-``` - -### Right aligned text - -Adding a colon on the right side of the dashes below any heading will right align text for that column. - -``` markdown -| Option | Description | -| ------:| -----------:| -| data | path to data files to supply the data that will be passed into templates. | -| engine | engine to be used for processing templates. Handlebars is the default. | -| ext | extension to be used for dest files. | -``` +Right aligned columns | Option | Description | | ------:| -----------:| @@ -515,101 +144,25 @@ Adding a colon on the right side of the dashes below any heading will right alig | ext | extension to be used for dest files. | -
-
-
- - ## Links -### Basic link - -``` markdown -[Assemble](http://assemble.io) -``` - -Renders to (hover over the link, there is no tooltip): - -[Assemble](http://assemble.io) - -HTML: - -``` html -Assemble -``` - - -### Add a title - -``` markdown -[Upstage](https://github.com/upstage/ "Visit Upstage!") -``` - -Renders to (hover over the link, there should be a tooltip): - -[Upstage](https://github.com/upstage/ "Visit Upstage!") - -HTML: - -``` html -Upstage -``` - -### Named Anchors - -Named anchors enable you to jump to the specified anchor point on the same page. For example, each of these chapters: - -```markdown -# Table of Contents - * [Chapter 1](#chapter-1) - * [Chapter 2](#chapter-2) - * [Chapter 3](#chapter-3) -``` -will jump to these sections: - -```markdown -## Chapter 1 -Content for chapter one. - -## Chapter 2 -Content for chapter one. - -## Chapter 3 -Content for chapter one. -``` -**NOTE** that specific placement of the anchor tag seems to be arbitrary. They are placed inline here since it seems to be unobtrusive, and it works. +[link text](http://dev.nodeca.com) +[link with title](http://nodeca.github.io/pica/demo/ "title text!") -
-
-
+Autoconverted link https://github.com/nodeca/pica (enable linkify to see) ## Images -Images have a similar syntax to links but include a preceding exclamation point. -``` markdown -![Minion](http://octodex.github.com/images/minion.png) -``` ![Minion](http://octodex.github.com/images/minion.png) -or -``` markdown -![Alt text](http://octodex.github.com/images/stormtroopocat.jpg "The Stormtroopocat") -``` ![Alt text](http://octodex.github.com/images/stormtroopocat.jpg "The Stormtroopocat") Like links, Images also have a footnote style syntax -``` markdown -![Alt text][id] -``` ![Alt text][id] With a reference later in the document defining the URL location: [id]: http://octodex.github.com/images/dojocat.jpg "The Dojocat" - - - [id]: http://octodex.github.com/images/dojocat.jpg "The Dojocat" - diff --git a/dist/remarkable.js b/dist/remarkable.js index d2885d6..e4d8736 100644 --- a/dist/remarkable.js +++ b/dist/remarkable.js @@ -4,7 +4,7 @@ module.exports = require('./lib/'); -},{"./lib/":7}],1:[function(require,module,exports){ +},{"./lib/":11}],1:[function(require,module,exports){ // List of valid entities // // Generate with ./support/entities.js script @@ -2437,21 +2437,123 @@ module.exports = [ ]; },{}],5:[function(require,module,exports){ -// Default options +// Utilities +'use strics'; + + +// Merge objects +// +exports.assign = function (obj /*from1, from2, from3, ...*/) { + var sources = Array.prototype.slice.call(arguments, 1); + while (sources.length) { + var source = sources.shift(); + if (!source) { continue; } + + if (typeof(source) !== 'object') { + throw new TypeError(source + 'must be non-object'); + } + + for (var p in source) { + if (source.hasOwnProperty(p)) { + obj[p] = source[p]; + } + } + } + + return obj; +}; + +},{}],6:[function(require,module,exports){ +// Commonmark default options 'use strict'; module.exports = { - html: false, - xhtml: false, - breaks: false, - maxLevel: 20, - langPrefix: 'language-', - highlight: function (/*str*/) { return ''; } + html: true, // Enable html tags in source + xhtmlOut: true, // Use '/' to close single tags (
) + breaks: false, // Convert '\n' in paragraphs into
+ langPrefix: 'language-', // CSS language prefix for fenced blocks + linkify: false, // autoconvert url-like texts to links + typographer: false, // Enable smartypants and other sweet transforms + + // Highlighter function. Should return escaped html, + // or '' if input not changed + highlight: function (/*str, , lang*/) { return ''; }, + + maxNesting: 20 // Internal protection, recursion limit }; -},{}],6:[function(require,module,exports){ +},{}],7:[function(require,module,exports){ +// List of active rules for strict commonmark mode + +module.exports.block = [ + 'code', + 'blockquote', + 'fences', + 'heading', + 'hr', + 'htmlblock', + 'lheading', + 'list', + 'paragraph' +]; + +module.exports.inline = [ + 'autolink', + 'backticks', + 'emphasis', + 'entity', + 'escape', + 'escape_html_char', + 'htmltag', + 'links', + 'newline', + 'text' +]; + +},{}],8:[function(require,module,exports){ +// Remarkable default options + +'use strict'; + + +module.exports = { + html: false, // Enable html tags in source + xhtmlOut: false, // Use '/' to close single tags (
) + breaks: false, // Convert '\n' in paragraphs into
+ langPrefix: 'language-', // CSS language prefix for fenced blocks + linkify: false, // autoconvert url-like texts to links + typographer: false, // Enable smartypants and other sweet transforms + + // Highlighter function. Should return escaped html, + // or '' if input not changed + highlight: function (/*str, , lang*/) { return ''; }, + + maxNesting: 20 // Internal protection, recursion limit +}; + +},{}],9:[function(require,module,exports){ +// Default typograph options + +'use strict'; + + +module.exports = { + singleQuotes: '‘’', + doubleQuotes: '“”', // «» - russian, „“ - deutch + copyright: true, + trademark: true, + registered: true, + plusminus: true, + paragraph: true, + ellipsis: true, + dupes: true, + emDashes: true, + linkify: true +}; + +},{}],10:[function(require,module,exports){ // Common functions for parsers 'use strict'; @@ -2608,19 +2710,23 @@ exports.isValidEntityCode = isValidEntityCode; exports.fromCodePoint = fromCodePoint; exports.replaceEntities = replaceEntities; -},{"./common/entities":1}],7:[function(require,module,exports){ +},{"./common/entities":1}],11:[function(require,module,exports){ // Main perser class 'use strict'; -var assign = require('object-assign'); - - +var assign = require('./common/utils').assign; var Renderer = require('./renderer'); var ParserBlock = require('./parser_block'); var ParserInline = require('./parser_inline'); -var defaults = require('./defaults'); +var Typographer = require('./typographer'); + + +var defaults = require('./defaults/remarkable'); +var cmmDefaults = require('./defaults/commonmark'); +var cmmRules = require('./defaults/commonmark_rules'); + // Main class // @@ -2631,17 +2737,31 @@ function Remarkable(options) { this.inline = new ParserInline(); this.block = new ParserBlock(); this.renderer = new Renderer(); + this.typographer = new Typographer(); + this.linkifier = new Typographer(); - // a bunch of cross-references between parsers - // used for link reference definitions - this.block.inline = this.inline; + // Linkifier is a separate typographer, for convenience. + // Configure it here. + this.linkifier.ruler.enable([], true); + this.linkifier.ruler.after(require('./rules_typographer/linkify')); + + // Cross-references to simplify code (a bit dirty, but easy). + this.block.inline = this.inline; + this.inline.typographer = this.typographer; + this.inline.linkifier = this.linkifier; if (options) { this.set(options); } } Remarkable.prototype.set = function (options) { - assign(this.options, options); + if (String(options).toLowerCase() === 'commonmark') { + assign(this.options, cmmDefaults); + this.inline.ruler.enable(cmmRules.inline, true); + this.block.ruler.enable(cmmRules.block, true); + } else { + assign(this.options, options); + } }; @@ -2666,7 +2786,7 @@ Remarkable.prototype.render = function (src) { module.exports = Remarkable; -},{"./defaults":5,"./parser_block":9,"./parser_inline":10,"./renderer":12,"object-assign":36}],8:[function(require,module,exports){ +},{"./common/utils":5,"./defaults/commonmark":6,"./defaults/commonmark_rules":7,"./defaults/remarkable":8,"./parser_block":13,"./parser_inline":14,"./renderer":16,"./rules_typographer/linkify":41,"./typographer":43}],12:[function(require,module,exports){ 'use strict'; @@ -2834,7 +2954,7 @@ module.exports.parseLinkDestination = parseLinkDestination; module.exports.parseLinkTitle = parseLinkTitle; module.exports.normalizeReference = normalizeReference; -},{}],9:[function(require,module,exports){ +},{}],13:[function(require,module,exports){ // Block parser @@ -2993,7 +3113,7 @@ ParserBlock.prototype.parse = function (src, options, env) { module.exports = ParserBlock; -},{"./helpers":6,"./ruler":13,"./rules_block/blockquote":14,"./rules_block/code":15,"./rules_block/fences":16,"./rules_block/heading":17,"./rules_block/hr":18,"./rules_block/htmlblock":19,"./rules_block/lheading":20,"./rules_block/list":21,"./rules_block/paragraph":22,"./rules_block/state_block":23,"./rules_block/table":24}],10:[function(require,module,exports){ +},{"./helpers":10,"./ruler":17,"./rules_block/blockquote":18,"./rules_block/code":19,"./rules_block/fences":20,"./rules_block/heading":21,"./rules_block/hr":22,"./rules_block/htmlblock":23,"./rules_block/lheading":24,"./rules_block/list":25,"./rules_block/paragraph":26,"./rules_block/state_block":27,"./rules_block/table":28}],14:[function(require,module,exports){ // Inline parser 'use strict'; @@ -3013,6 +3133,7 @@ rules.push(require('./rules_inline/text')); rules.push(require('./rules_inline/newline')); rules.push(require('./rules_inline/escape')); rules.push(require('./rules_inline/backticks')); +rules.push(require('./rules_inline/del')); rules.push(require('./rules_inline/emphasis')); rules.push(require('./rules_inline/links')); rules.push(require('./rules_inline/autolink')); @@ -3029,7 +3150,7 @@ function ParserInline() { // Rule to skip pure text // - '{$%@}' reserved for extentions // - '<>"' added for internal html escaping - this.textMatch = /^[^\n\\`*_\[\]!&{}$%@<>"]+/; + this.textMatch = /^[^\n\\`*_\[\]!&{}$%@<>"~]+/; this.ruler = new Ruler(this.rulesUpdate.bind(this)); @@ -3098,6 +3219,7 @@ ParserInline.prototype.tokenize = function (state) { return state.tokens; }; + // Parse input string. // ParserInline.prototype.parse = function (str, options, env) { @@ -3105,13 +3227,20 @@ ParserInline.prototype.parse = function (str, options, env) { this.tokenize(state); + if (options.linkify) { + this.linkifier.process(state); + } + if (options.typographer) { + this.typographer.process(state); + } + return state.tokens; }; module.exports = ParserInline; -},{"./ruler":13,"./rules_inline/autolink":25,"./rules_inline/backticks":26,"./rules_inline/emphasis":27,"./rules_inline/entity":28,"./rules_inline/escape":29,"./rules_inline/escape_html_char":30,"./rules_inline/htmltag":31,"./rules_inline/links":32,"./rules_inline/newline":33,"./rules_inline/state_inline":34,"./rules_inline/text":35}],11:[function(require,module,exports){ +},{"./ruler":17,"./rules_inline/autolink":29,"./rules_inline/backticks":30,"./rules_inline/del":31,"./rules_inline/emphasis":32,"./rules_inline/entity":33,"./rules_inline/escape":34,"./rules_inline/escape_html_char":35,"./rules_inline/htmltag":36,"./rules_inline/links":37,"./rules_inline/newline":38,"./rules_inline/state_inline":39,"./rules_inline/text":40}],15:[function(require,module,exports){ 'use strict'; @@ -3182,11 +3311,11 @@ module.exports = function parse_reference(str, parser, options, env) { return pos; }; -},{"./helpers":6,"./links":8,"./rules_inline/state_inline":34}],12:[function(require,module,exports){ +},{"./helpers":10,"./links":12,"./rules_inline/state_inline":39}],16:[function(require,module,exports){ 'use strict'; -var assign = require('object-assign'); +var assign = require('./common/utils').assign; var escapeHtml = require('./helpers').escapeHtml; var unescapeMd = require('./helpers').unescapeMd; var replaceEntities = require('./helpers').replaceEntities; @@ -3266,7 +3395,7 @@ rules.heading_close = function (tokens, idx /*, options*/) { rules.hr = function (tokens, idx, options) { - return (options.xhtml ? '
' : '
') + getBreak(tokens, idx); + return (options.xhtmlOut ? '
' : '
') + getBreak(tokens, idx); }; @@ -3314,7 +3443,7 @@ rules.image = function (tokens, idx, options) { var src = ' src="' + escapeHtml(escapeUrl(tokens[idx].src)) + '"'; var title = tokens[idx].title ? (' title="' + escapeHtml(replaceEntities(tokens[idx].title)) + '"') : ''; var alt = ' alt="' + (tokens[idx].alt ? escapeHtml(replaceEntities(tokens[idx].alt)) : '') + '"'; - var suffix = options.xhtml ? ' /' : ''; + var suffix = options.xhtmlOut ? ' /' : ''; return ''; }; @@ -3365,11 +3494,19 @@ rules.em_close = function(/*tokens, idx, options*/) { }; +rules.del_open = function(/*tokens, idx, options*/) { + return ''; +}; +rules.del_close = function(/*tokens, idx, options*/) { + return ''; +}; + + rules.hardbreak = function (tokens, idx, options) { - return options.xhtml ? '
\n' : '
\n'; + return options.xhtmlOut ? '
\n' : '
\n'; }; rules.softbreak = function (tokens, idx, options) { - return options.breaks ? (options.xhtml ? '
\n' : '
\n') : '\n'; + return options.breaks ? (options.xhtmlOut ? '
\n' : '
\n') : '\n'; }; @@ -3457,13 +3594,13 @@ Renderer.prototype.render = function (tokens, options) { module.exports = Renderer; -},{"./helpers":6,"object-assign":36}],13:[function(require,module,exports){ +},{"./common/utils":5,"./helpers":10}],17:[function(require,module,exports){ // Ruler is helper class to build responsibility chains from parse rules. // It allows: // // - easy stack rules chains // - getting main chain and named chains content (as arrays of functions) - +// 'use strict'; @@ -3490,6 +3627,7 @@ function Ruler(compileFn) { // // { // name: XXX, + // enabled: Boolean, // fn: Function(), // alt: [ name2, name3 ] // } @@ -3536,7 +3674,7 @@ Ruler.prototype.at = function (name, fn, altNames) { // Or add to start, if name not defined // Ruler.prototype.before = function (name, fn, altNames) { - var index; + var index, rule; if (isFunction(name)) { altNames = fn; @@ -3544,20 +3682,21 @@ Ruler.prototype.before = function (name, fn, altNames) { name = ''; } - if (!name) { - this.rules.unshift({ - name: functionName(fn), - fn: fn, - alt: altNames || [] - }); + rule = { + name: functionName(fn), + enabled: true, + fn: fn, + alt: altNames || [] + }; + if (!name) { + this.rules.unshift(rule); } else { - index = this.find(name); if (index === -1) { throw new Error('Parser rule not found: ' + name); } - this.rules.splice(index, 0, fn); + this.rules.splice(index, 0, rule); } this.compile(); @@ -3568,7 +3707,7 @@ Ruler.prototype.before = function (name, fn, altNames) { // Or add to end, if name not defined // Ruler.prototype.after = function (name, fn, altNames) { - var index; + var index, rule; if (isFunction(name)) { altNames = fn; @@ -3576,15 +3715,16 @@ Ruler.prototype.after = function (name, fn, altNames) { name = ''; } - if (!name) { - this.rules.push({ - name: functionName(fn), - fn: fn, - alt: altNames || [] - }); + rule = { + name: functionName(fn), + enabled: true, + fn: fn, + alt: altNames || [] + }; + if (!name) { + this.rules.push(rule); } else { - index = this.find(name); if (index === -1) { throw new Error('Parser rule not found: ' + name); @@ -3603,13 +3743,15 @@ Ruler.prototype.getRules = function (chainName) { if (!chainName) { this.rules.forEach(function (rule) { - result.push(rule.fn); + if (rule.enabled) { + result.push(rule.fn); + } }); return result; } this.rules.forEach(function (rule) { - if (rule.alt.indexOf(chainName) >= 0) { + if (rule.alt.indexOf(chainName) >= 0 && rule.enabled) { result.push(rule.fn); } }); @@ -3617,9 +3759,57 @@ Ruler.prototype.getRules = function (chainName) { }; +// Enable list of rules by names. If `strict` is true, then all non listed +// rules will be disabled. +// +Ruler.prototype.enable = function (list, strict) { + if (!Array.isArray(list)) { + list = [ list ]; + } + + // In strict mode disable all existing rules first + if (strict) { + this.rules.forEach(function (rule) { + rule.enabled = false; + }); + } + + // Search by name and enable + list.forEach(function (name) { + var idx = this.find(name); + + if (idx < 0) { throw new Error('Rules namager: invalid rule name ' + name);} + this.rules[idx].enabled = true; + + }, this); + + this.compile(); +}; + + +// Disable list of rules by names. +// +Ruler.prototype.disable = function (list) { + if (!Array.isArray(list)) { + list = [ list ]; + } + + // Search by name and disable + list.forEach(function (name) { + var idx = this.find(name); + + if (idx < 0) { throw new Error('Rules namager: invalid rule name ' + name);} + this.rules[idx].enabled = false; + + }, this); + + this.compile(); +}; + + module.exports = Ruler; -},{}],14:[function(require,module,exports){ +},{}],18:[function(require,module,exports){ // Block quotes 'use strict'; @@ -3639,7 +3829,7 @@ module.exports = function blockquote(state, startLine, endLine, silent) { // check the block quote marker if (state.src.charCodeAt(pos++) !== 0x3E/* > */) { return false; } - if (state.level >= state.options.maxLevel) { return false; } + if (state.level >= state.options.maxNesting) { return false; } // we know that it's going to be a valid blockquote, // so no point trying to find the end of it in silent mode @@ -3744,7 +3934,7 @@ module.exports = function blockquote(state, startLine, endLine, silent) { return true; }; -},{"../helpers":6}],15:[function(require,module,exports){ +},{"../helpers":10}],19:[function(require,module,exports){ // Code block (4 spaces padded) 'use strict'; @@ -3788,7 +3978,7 @@ module.exports = function code(state, startLine, endLine, silent) { return true; }; -},{"../helpers":6}],16:[function(require,module,exports){ +},{"../helpers":10}],20:[function(require,module,exports){ // fences (``` lang, ~~~ lang) 'use strict'; @@ -3885,7 +4075,7 @@ module.exports = function fences(state, startLine, endLine, silent) { return true; }; -},{"../helpers":6}],17:[function(require,module,exports){ +},{"../helpers":10}],21:[function(require,module,exports){ // heading (#, ##, ...) 'use strict'; @@ -3953,7 +4143,7 @@ module.exports = function heading(state, startLine, endLine, silent) { return true; }; -},{"../helpers":6}],18:[function(require,module,exports){ +},{"../helpers":10}],22:[function(require,module,exports){ // Horizontal rule 'use strict'; @@ -3999,7 +4189,7 @@ module.exports = function hr(state, startLine, endLine, silent) { return true; }; -},{"../helpers":6}],19:[function(require,module,exports){ +},{"../helpers":10}],23:[function(require,module,exports){ // HTML block 'use strict'; @@ -4077,7 +4267,7 @@ module.exports = function htmlblock(state, startLine, endLine, silent) { return true; }; -},{"../common/html_blocks":2,"../helpers":6}],20:[function(require,module,exports){ +},{"../common/html_blocks":2,"../helpers":10}],24:[function(require,module,exports){ // lheading (---, ===) 'use strict'; @@ -4137,7 +4327,7 @@ module.exports = function lheading(state, startLine, endLine, silent) { return true; }; -},{"../helpers":6}],21:[function(require,module,exports){ +},{"../helpers":10}],25:[function(require,module,exports){ // Lists 'use strict'; @@ -4241,7 +4431,7 @@ module.exports = function list(state, startLine, endLine, silent) { return false; } - if (state.level >= state.options.maxLevel) { return false; } + if (state.level >= state.options.maxNesting) { return false; } // We should terminate list on style change. Remember first one to compare. markerCharCode = state.src.charCodeAt(posAfterMarker - 1); @@ -4385,7 +4575,7 @@ module.exports = function list(state, startLine, endLine, silent) { return true; }; -},{"../helpers":6}],22:[function(require,module,exports){ +},{"../helpers":10}],26:[function(require,module,exports){ // Paragraph 'use strict'; @@ -4442,7 +4632,7 @@ module.exports = function paragraph(state, startLine/*, endLine*/) { return true; }; -},{"../helpers":6,"../parser_ref":11}],23:[function(require,module,exports){ +},{"../helpers":10,"../parser_ref":15}],27:[function(require,module,exports){ // Parser state class 'use strict'; @@ -4558,7 +4748,7 @@ State.prototype.clone = function clone(src) { module.exports = State; -},{}],24:[function(require,module,exports){ +},{}],28:[function(require,module,exports){ // GFM table, non-standard 'use strict'; @@ -4644,7 +4834,7 @@ module.exports = function table(state, startLine, endLine, silent) { return true; }; -},{}],25:[function(require,module,exports){ +},{}],29:[function(require,module,exports){ // Process autolinks '' @@ -4709,7 +4899,7 @@ module.exports = function autolink(state) { return false; }; -},{"../common/url_schemas":4,"../helpers":6}],26:[function(require,module,exports){ +},{"../common/url_schemas":4,"../helpers":10}],30:[function(require,module,exports){ // Parse backticks var END_RE = /`+/g; @@ -4754,7 +4944,114 @@ module.exports = function backticks(state) { return true; }; -},{}],27:[function(require,module,exports){ +},{}],31:[function(require,module,exports){ +// Process ~~strikeout~~ + +'use strict'; + +module.exports = function del(state) { + var oldLength, + oldPending, + oldFlag, + found, + ok, + pos, + stack, + max = state.posMax, + start = state.pos, + lastChar, + nextChar; + + if (state.src.charCodeAt(start) !== 0x7E/* ~ */) { return false; } + if (start + 4 >= max) { return false; } + if (state.src.charCodeAt(start + 1) !== 0x7E/* ~ */) { return false; } + + // make del lower a priority tag with respect to links, same as ; + // this code also prevents recursion + if (state.validateInsideEm || state.validateInsideLink) { return false; } + + if (state.level >= state.options.level) { return false; } + + lastChar = state.pending.length !== 0 ? state.pending.charCodeAt(state.pending.length - 1) : -1; + nextChar = state.src.charCodeAt(start + 2); + + if (lastChar === 0x7E/* ~ */) { return false; } + if (nextChar === 0x7E/* */) { return false; } + if (nextChar === 0x20/* */) { return false; } + + pos = start + 2; + while (pos < max && state.src.charCodeAt(pos) === 0x7E/* ~ */) { pos++; } + if (pos !== start + 2) { + // sequence of 3+ markers taking as literal, same as in a emphasis + state.pos += pos - start; + state.pending += state.src.slice(start, pos); + return true; + } + + oldLength = state.tokens.length; + oldPending = state.pending; + oldFlag = state.validateInsideEm; + + state.pos = start + 2; + state.validateInsideEm = true; + stack = 1; + + while (state.pos + 1 < max) { + if (state.src.charCodeAt(state.pos) === 0x7E/* ~ */) { + if (state.src.charCodeAt(state.pos + 1) === 0x7E/* ~ */) { + lastChar = state.pending.length !== 0 ? state.pending.charCodeAt(state.pending.length - 1) : -1; + nextChar = state.pos + 2 < max ? state.src.charCodeAt(state.pos + 2) : -1; + if (nextChar !== 0x7E/* ~ */ && lastChar !== 0x7E/* ~ */) { + if (lastChar !== 0x20) { + // closing '~~' + stack--; + } else if (nextChar !== 0x20) { + // opening '~~' + stack++; + } // else { + // // standalone ' ~~ ' indented with spaces + //} + if (stack <= 0) { + found = true; + break; + } + } + } + } + + ok = state.parser.tokenizeSingle(state); + + if (!ok) { + state.pending += state.src[state.pos]; + state.pos++; + } + } + + // restore old state + state.tokens.length = oldLength; + state.pending = oldPending; + state.validateInsideEm = oldFlag; + + if (!found) { + // parser failed to find ending tag, so it's not valid emphasis + state.pos = start; + return false; + } + + // found! + state.posMax = state.pos; + state.pos = start + 2; + + state.push({ type: 'del_open', level: state.level++ }); + state.parser.tokenize(state); + state.push({ type: 'del_close', level: --state.level }); + + state.pos = state.posMax + 2; + state.posMax = max; + return true; +}; + +},{}],32:[function(require,module,exports){ // Process *this* and _that_ 'use strict'; @@ -4773,7 +5070,7 @@ function isAlphaNum(code) { // should be treated as a special case function parseStart(state, start) { var pos = start, lastChar, count, - max = Math.min(state.posMax, pos + 4), + max = state.posMax, marker = state.src.charCodeAt(start); lastChar = state.pending.length !== 0 ? state.pending.charCodeAt(state.pending.length - 1) : -1; @@ -4817,7 +5114,7 @@ function parseStart(state, start) { // should be treated as a special case function parseEnd(state, start) { var pos = start, lastChar, count, - max = Math.min(state.posMax, pos + 4), + max = state.posMax, marker = state.src.charCodeAt(start); lastChar = state.pending.length !== 0 ? state.pending.charCodeAt(state.pending.length - 1) : -1; @@ -4881,7 +5178,7 @@ module.exports = function emphasis(state/*, silent*/) { return true; } - if (state.level >= state.options.maxLevel) { return false; } + if (state.level >= state.options.maxNesting) { return false; } oldLength = state.tokens.length; oldPending = state.pending; @@ -4936,7 +5233,7 @@ module.exports = function emphasis(state/*, silent*/) { } count = parseStart(state, state.pos); - if (count >= 1) { + if (count >= 1 && count < 4) { stack.push(count); state.pos += count; continue; @@ -4990,7 +5287,7 @@ module.exports = function emphasis(state/*, silent*/) { return true; }; -},{}],28:[function(require,module,exports){ +},{}],33:[function(require,module,exports){ // Proceess html entity - {, ¯, ", ... 'use strict'; @@ -5038,7 +5335,7 @@ module.exports = function entity(state) { return true; }; -},{"../common/entities":1,"../helpers":6}],29:[function(require,module,exports){ +},{"../common/entities":1,"../helpers":10}],34:[function(require,module,exports){ // Proceess escaped chars and hardbreaks var ESCAPED = '\\!"#$%&\'()*+,./:;<=>?@[]^_`{|}~-' @@ -5092,7 +5389,7 @@ module.exports = function escape(state) { return true; }; -},{}],30:[function(require,module,exports){ +},{}],35:[function(require,module,exports){ // Process < > " (& was processed in markdown escape) module.exports = function escape_html_char(state) { @@ -5112,7 +5409,7 @@ module.exports = function escape_html_char(state) { return true; }; -},{}],31:[function(require,module,exports){ +},{}],36:[function(require,module,exports){ // Process html tags 'use strict'; @@ -5162,7 +5459,7 @@ module.exports = function htmltag(state) { return true; }; -},{"../common/html_re":3}],32:[function(require,module,exports){ +},{"../common/html_re":3}],37:[function(require,module,exports){ // Process [links]( "stuff") 'use strict'; @@ -5193,7 +5490,7 @@ function links(state) { } if (marker !== 0x5B/* [ */) { return false; } - if (state.level >= state.options.maxLevel) { return false; } + if (state.level >= state.options.maxNesting) { return false; } labelStart = start + 1; labelEnd = parseLinkLabel(state, start); @@ -5323,10 +5620,10 @@ function links(state) { module.exports = links; -},{"../links":8}],33:[function(require,module,exports){ +},{"../links":12}],38:[function(require,module,exports){ // Proceess '\n' -module.exports = function escape(state) { +module.exports = function newline(state) { var pmax, max, pos = state.pos; if (state.src.charCodeAt(pos) !== 0x0A/* \n */) { return false; } @@ -5369,7 +5666,7 @@ module.exports = function escape(state) { return true; }; -},{}],34:[function(require,module,exports){ +},{}],39:[function(require,module,exports){ // Inline parser state 'use strict'; @@ -5414,7 +5711,7 @@ StateInline.prototype.push = function (token) { module.exports = StateInline; -},{}],35:[function(require,module,exports){ +},{}],40:[function(require,module,exports){ // Skip text characters for text token, place those to pendibg buffer // and increment current pos @@ -5429,44 +5726,1998 @@ module.exports = function text(state) { return true; }; -},{}],36:[function(require,module,exports){ +},{}],41:[function(require,module,exports){ +// Replace link-like texts with link nodes. +// +// Currently restricted to http/https/ftp +// 'use strict'; -function ToObject(val) { - if (val == null) { - throw new TypeError('Object.assign cannot be called with null or undefined'); - } - return Object(val); +var Autolinker = require('autolinker'); +var escapeHtml = require('../helpers').escapeHtml; + + +var links = []; +var autolinker = new Autolinker({ + stripPrefix: false, + replaceFn: function (autolinker, match) { + // Only collect matched strings but don't change anything. + var url; + if (match.getType() === 'url') { + url = match.getUrl(); + if (/^(http|https|ftp|git)/.test(url)) { + links.push(url); + } + } + return false; + } +}); + + +module.exports = function linkify(t, state) { + var i, token, text, nodes, ln, pos, level, + tokens = state.tokens; + + for (i = tokens.length - 1; i >= 0; i--) { + token = tokens[i]; + + // Skip content of links + if (token.type === 'link_close') { + i--; + while (tokens[i].type !== 'link_open' && tokens[i].level !== token.level) { + i--; + } + i--; + continue; + } + + if (token.type === 'text' && + (token.content.indexOf('://') || + token.content.indexOf('www'))) { + text = token.content; + links = []; + autolinker.link(text); + + if (!links.length) { continue; } + + // Now split string to nodes + nodes = []; + level = token.level; + + for (ln = 0; ln < links.length; ln++) { + pos = text.indexOf(links[ln]); + if (pos) { + level = level; + nodes.push({ + type: 'text', + content: text.slice(0, pos), + level: level + }); + } + nodes.push({ + type: 'link_open', + href: links[ln], + title: '', + level: level++ + }); + nodes.push({ + type: 'text', + content: escapeHtml(links[ln]), + level: level + }); + nodes.push({ + type: 'link_close', + level: --level + }); + text = text.slice(pos + links[ln].length); + } + if (text.length) { + nodes.push({ + type: 'text', + content: text, + level: level + }); + } + + // replace cuttent node + state.tokens = tokens = [].concat(tokens.slice(0, i), nodes, tokens.slice(i + 1)); + } + } +}; + +},{"../helpers":10,"autolinker":44}],42:[function(require,module,exports){ +// Simple typographyc replacements +// +'use strict'; + + +module.exports = function replace(t, state) { + var i, token, text, + tokens = state.tokens, + options = t.options; + + for (i = tokens.length - 1; i >= 0; i--) { + token = tokens[i]; + if (token.type === 'text') { + text = token.content; + + if (text.indexOf('(') >= 0) { + if (options.copyright) { + text = text.replace(/\(c\)/gi, '©'); + } + if (options.trademark) { + text = text.replace(/\(tm\)/gi, '™'); + } + if (options.registered) { + text = text.replace(/\(r\)/gi, '®'); + } + if (options.paragraph) { + text = text.replace(/\(p\)/gi, '§'); + } + } + + if (options.plusminus && text.indexOf('+-') >= 0) { + text = text.replace(/\+-/g, '±'); + } + if (options.ellipsis && text.indexOf('..') >= 0) { + // .., ..., ....... -> … + // but ?..... & !..... -> ?.. & !.. + text = text.replace(/\.{2,}/g, '…').replace(/([?!])…/g, '$1..'); + } + if (options.dupes && + (text.indexOf('????') >= 0 || + text.indexOf('!!!!') >= 0 || + text.indexOf(',,') >= 0)) { + text = text.replace(/([?!]){4,}/g, '$1$1$1').replace(/,{2,}/g, ','); + } + if (options.emDashes && text.indexOf('--') >= 0) { + text = text.replace(/(^|\s)--(\s|$)/mg, '$1—$2'); + } + + token.content = text; + } + } +}; + +},{}],43:[function(require,module,exports){ +// Class of typographic replacements rules +// +'use strict'; + +// TODO: +// - fractionals 1/2, 1/4, 3/4 -> ½, ¼, ¾ +// - miltiplication 2 x 4 -> 2 × 4 + + +var defaults = require('./defaults/typographer'); +var assign = require('./common/utils').assign; +var Ruler = require('./ruler'); + + +var rules = []; + + +rules.push(require('./rules_typographer/replace')); + + +function Typographer() { + this.options = assign({}, defaults); + + this.ruler = new Ruler(this.rulesUpdate.bind(this)); + + for (var i = 0; i < rules.length; i++) { + this.ruler.after(rules[i]); + } } -module.exports = Object.assign || function (target, source) { - var pendingException; - var from; - var keys; - var to = ToObject(target); - - for (var s = 1; s < arguments.length; s++) { - from = arguments[s]; - keys = Object.keys(Object(from)); - - for (var i = 0; i < keys.length; i++) { - try { - to[keys[i]] = from[keys[i]]; - } catch (err) { - if (pendingException === undefined) { - pendingException = err; - } - } - } - } - - if (pendingException) { - throw pendingException; - } - - return to; + +Typographer.prototype.rulesUpdate = function () { + this._rules = this.ruler.getRules(); +}; + + +Typographer.prototype.set = function (options) { + assign(this.options, options); +}; + + +Typographer.prototype.process = function (state) { + var i, l, rules; + + if (!state.options.typographer) { return; } + + rules = this._rules; + + for (i = 0, l = rules.length; i < l; i++) { + rules[i](this, state); + } }; + +module.exports = Typographer; + +},{"./common/utils":5,"./defaults/typographer":9,"./ruler":17,"./rules_typographer/replace":42}],44:[function(require,module,exports){ +/*! + * Autolinker.js + * 0.12.2 + * + * Copyright(c) 2014 Gregory Jacobs + * MIT Licensed. http://www.opensource.org/licenses/mit-license.php + * + * https://github.com/gregjacobs/Autolinker.js + */ +/*global define, module */ +( function( root, factory ) { + + if( typeof define === 'function' && define.amd ) { + define( factory ); // Define as AMD module if an AMD loader is present (ex: RequireJS). + } else if( typeof exports !== 'undefined' ) { + module.exports = factory(); // Define as CommonJS module for Node.js, if available. + } else { + root.Autolinker = factory(); // Finally, define as a browser global if no module loader. + } +}( this, function() { + + /** + * @class Autolinker + * @extends Object + * + * Utility class used to process a given string of text, and wrap the URLs, email addresses, and Twitter handles in + * the appropriate anchor (<a>) tags to turn them into links. + * + * Any of the configuration options may be provided in an Object (map) provided to the Autolinker constructor, which + * will configure how the {@link #link link()} method will process the links. + * + * For example: + * + * var autolinker = new Autolinker( { + * newWindow : false, + * truncate : 30 + * } ); + * + * var html = autolinker.link( "Joe went to www.yahoo.com" ); + * // produces: 'Joe went to yahoo.com' + * + * + * The {@link #static-link static link()} method may also be used to inline options into a single call, which may + * be more convenient for one-off uses. For example: + * + * var html = Autolinker.link( "Joe went to www.yahoo.com", { + * newWindow : false, + * truncate : 30 + * } ); + * // produces: 'Joe went to yahoo.com' + * + * + * ## Custom Replacements of Links + * + * If the configuration options do not provide enough flexibility, a {@link #replaceFn} may be provided to fully customize + * the output of Autolinker. This function is called once for each URL/Email/Twitter handle match that is encountered. + * + * For example: + * + * var input = "..."; // string with URLs, Email Addresses, and Twitter Handles + * + * var linkedText = Autolinker.link( input, { + * replaceFn : function( autolinker, match ) { + * console.log( "href = ", match.getAnchorHref() ); + * console.log( "text = ", match.getAnchorText() ); + * + * switch( match.getType() ) { + * case 'url' : + * console.log( "url: ", match.getUrl() ); + * + * if( match.getUrl().indexOf( 'mysite.com' ) === -1 ) { + * var tag = autolinker.getTagBuilder().build( match ); // returns an `Autolinker.HtmlTag` instance, which provides mutator methods for easy changes + * tag.setAttr( 'rel', 'nofollow' ); + * tag.addClass( 'external-link' ); + * + * return tag; + * + * } else { + * return true; // let Autolinker perform its normal anchor tag replacement + * } + * + * case 'email' : + * var email = match.getEmail(); + * console.log( "email: ", email ); + * + * if( email === "my@own.address" ) { + * return false; // don't auto-link this particular email address; leave as-is + * } else { + * return; // no return value will have Autolinker perform its normal anchor tag replacement (same as returning `true`) + * } + * + * case 'twitter' : + * var twitterHandle = match.getTwitterHandle(); + * console.log( twitterHandle ); + * + * return '' + twitterHandle + ''; + * } + * } + * } ); + * + * + * The function may return the following values: + * + * - `true` (Boolean): Allow Autolinker to replace the match as it normally would. + * - `false` (Boolean): Do not replace the current match at all - leave as-is. + * - Any String: If a string is returned from the function, the string will be used directly as the replacement HTML for + * the match. + * - An {@link Autolinker.HtmlTag} instance, which can be used to build/modify an HTML tag before writing out its HTML text. + * + * @constructor + * @param {Object} [config] The configuration options for the Autolinker instance, specified in an Object (map). + */ + var Autolinker = function( cfg ) { + Autolinker.Util.assign( this, cfg ); // assign the properties of `cfg` onto the Autolinker instance. Prototype properties will be used for missing configs. + }; + + + Autolinker.prototype = { + constructor : Autolinker, // fix constructor property + + /** + * @cfg {Boolean} urls + * + * `true` if miscellaneous URLs should be automatically linked, `false` if they should not be. + */ + urls : true, + + /** + * @cfg {Boolean} email + * + * `true` if email addresses should be automatically linked, `false` if they should not be. + */ + email : true, + + /** + * @cfg {Boolean} twitter + * + * `true` if Twitter handles ("@example") should be automatically linked, `false` if they should not be. + */ + twitter : true, + + /** + * @cfg {Boolean} newWindow + * + * `true` if the links should open in a new window, `false` otherwise. + */ + newWindow : true, + + /** + * @cfg {Boolean} stripPrefix + * + * `true` if 'http://' or 'https://' and/or the 'www.' should be stripped from the beginning of URL links' text, + * `false` otherwise. + */ + stripPrefix : true, + + /** + * @cfg {Number} truncate + * + * A number for how many characters long URLs/emails/twitter handles should be truncated to inside the text of + * a link. If the URL/email/twitter is over this number of characters, it will be truncated to this length by + * adding a two period ellipsis ('..') to the end of the string. + * + * For example: A url like 'http://www.yahoo.com/some/long/path/to/a/file' truncated to 25 characters might look + * something like this: 'yahoo.com/some/long/pat..' + */ + + /** + * @cfg {String} className + * + * A CSS class name to add to the generated links. This class will be added to all links, as well as this class + * plus url/email/twitter suffixes for styling url/email/twitter links differently. + * + * For example, if this config is provided as "myLink", then: + * + * - URL links will have the CSS classes: "myLink myLink-url" + * - Email links will have the CSS classes: "myLink myLink-email", and + * - Twitter links will have the CSS classes: "myLink myLink-twitter" + */ + className : "", + + /** + * @cfg {Function} replaceFn + * + * A function to individually process each URL/Email/Twitter match found in the input string. + * + * See the class's description for usage. + * + * This function is called with the following parameters: + * + * @cfg {Autolinker} replaceFn.autolinker The Autolinker instance, which may be used to retrieve child objects from (such + * as the instance's {@link #getTagBuilder tag builder}). + * @cfg {Autolinker.match.Match} replaceFn.match The Match instance which can be used to retrieve information about the + * {@link Autolinker.match.Url URL}/{@link Autolinker.match.Email email}/{@link Autolinker.match.Twitter Twitter} + * match that the `replaceFn` is currently processing. + */ + + + /** + * @private + * @property {RegExp} htmlCharacterEntitiesRegex + * + * The regular expression that matches common HTML character entities. + * + * Ignoring & as it could be part of a query string -- handling it separately. + */ + htmlCharacterEntitiesRegex: /( | |<|<|>|>)/gi, + + /** + * @private + * @property {RegExp} matcherRegex + * + * The regular expression that matches URLs, email addresses, and Twitter handles. + * + * This regular expression has the following capturing groups: + * + * 1. Group that is used to determine if there is a Twitter handle match (i.e. \@someTwitterUser). Simply check for its + * existence to determine if there is a Twitter handle match. The next couple of capturing groups give information + * about the Twitter handle match. + * 2. The whitespace character before the \@sign in a Twitter handle. This is needed because there are no lookbehinds in + * JS regular expressions, and can be used to reconstruct the original string in a replace(). + * 3. The Twitter handle itself in a Twitter match. If the match is '@someTwitterUser', the handle is 'someTwitterUser'. + * 4. Group that matches an email address. Used to determine if the match is an email address, as well as holding the full + * address. Ex: 'me@my.com' + * 5. Group that matches a URL in the input text. Ex: 'http://google.com', 'www.google.com', or just 'google.com'. + * This also includes a path, url parameters, or hash anchors. Ex: google.com/path/to/file?q1=1&q2=2#myAnchor + * 6. A protocol-relative ('//') match for the case of a 'www.' prefixed URL. Will be an empty string if it is not a + * protocol-relative match. We need to know the character before the '//' in order to determine if it is a valid match + * or the // was in a string we don't want to auto-link. + * 7. A protocol-relative ('//') match for the case of a known TLD prefixed URL. Will be an empty string if it is not a + * protocol-relative match. See #6 for more info. + */ + matcherRegex : (function() { + var twitterRegex = /(^|[^\w])@(\w{1,15})/, // For matching a twitter handle. Ex: @gregory_jacobs + + emailRegex = /(?:[\-;:&=\+\$,\w\.]+@)/, // something@ for email addresses (a.k.a. local-part) + + protocolRegex = /(?:[A-Za-z]{3,9}:(?:\/\/)?)/, // match protocol, allow in format http:// or mailto: + wwwRegex = /(?:www\.)/, // starting with 'www.' + domainNameRegex = /[A-Za-z0-9\.\-]*[A-Za-z0-9\-]/, // anything looking at all like a domain, non-unicode domains, not ending in a period + tldRegex = /\.(?:international|construction|contractors|enterprises|photography|productions|foundation|immobilien|industries|management|properties|technology|christmas|community|directory|education|equipment|institute|marketing|solutions|vacations|bargains|boutique|builders|catering|cleaning|clothing|computer|democrat|diamonds|graphics|holdings|lighting|partners|plumbing|supplies|training|ventures|academy|careers|company|cruises|domains|exposed|flights|florist|gallery|guitars|holiday|kitchen|neustar|okinawa|recipes|rentals|reviews|shiksha|singles|support|systems|agency|berlin|camera|center|coffee|condos|dating|estate|events|expert|futbol|kaufen|luxury|maison|monash|museum|nagoya|photos|repair|report|social|supply|tattoo|tienda|travel|viajes|villas|vision|voting|voyage|actor|build|cards|cheap|codes|dance|email|glass|house|mango|ninja|parts|photo|shoes|solar|today|tokyo|tools|watch|works|aero|arpa|asia|best|bike|blue|buzz|camp|club|cool|coop|farm|fish|gift|guru|info|jobs|kiwi|kred|land|limo|link|menu|mobi|moda|name|pics|pink|post|qpon|rich|ruhr|sexy|tips|vote|voto|wang|wien|wiki|zone|bar|bid|biz|cab|cat|ceo|com|edu|gov|int|kim|mil|net|onl|org|pro|pub|red|tel|uno|wed|xxx|xyz|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cw|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|za|zm|zw)\b/, // match our known top level domains (TLDs) + + // Allow optional path, query string, and hash anchor, not ending in the following characters: "!:,.;" + // http://blog.codinghorror.com/the-problem-with-urls/ + urlSuffixRegex = /(?:[\-A-Za-z0-9+&@#\/%?=~_()|!:,.;]*[\-A-Za-z0-9+&@#\/%=~_()|])?/; // note: optional part of the full regex + + return new RegExp( [ + '(', // *** Capturing group $1, which can be used to check for a twitter handle match. Use group $3 for the actual twitter handle though. $2 may be used to reconstruct the original string in a replace() + // *** Capturing group $2, which matches the whitespace character before the '@' sign (needed because of no lookbehinds), and + // *** Capturing group $3, which matches the actual twitter handle + twitterRegex.source, + ')', + + '|', + + '(', // *** Capturing group $4, which is used to determine an email match + emailRegex.source, + domainNameRegex.source, + tldRegex.source, + ')', + + '|', + + '(', // *** Capturing group $5, which is used to match a URL + '(?:', // parens to cover match for protocol (optional), and domain + '(?:', // non-capturing paren for a protocol-prefixed url (ex: http://google.com) + protocolRegex.source, + domainNameRegex.source, + ')', + + '|', + + '(?:', // non-capturing paren for a 'www.' prefixed url (ex: www.google.com) + '(.?//)?', // *** Capturing group $6 for an optional protocol-relative URL. Must be at the beginning of the string or start with a non-word character + wwwRegex.source, + domainNameRegex.source, + ')', + + '|', + + '(?:', // non-capturing paren for known a TLD url (ex: google.com) + '(.?//)?', // *** Capturing group $7 for an optional protocol-relative URL. Must be at the beginning of the string or start with a non-word character + domainNameRegex.source, + tldRegex.source, + ')', + ')', + + urlSuffixRegex.source, // match for path, query string, and/or hash anchor + ')' + ].join( "" ), 'gi' ); + } )(), + + /** + * @private + * @property {RegExp} invalidProtocolRelMatchRegex + * + * The regular expression used to check a potential protocol-relative URL match, coming from the {@link #matcherRegex}. + * A protocol-relative URL is, for example, "//yahoo.com" + * + * This regular expression is used in conjunction with the {@link #matcherRegex}, and checks to see if there is a word character + * before the '//' in order to determine if we should actually autolink a protocol-relative URL. This is needed because there + * is no negative look-behind in JavaScript regular expressions. + * + * For instance, we want to autolink something like "//google.com", but we don't want to autolink something + * like "abc//google.com" + */ + invalidProtocolRelMatchRegex : /^[\w]\/\//, + + /** + * @private + * @property {RegExp} charBeforeProtocolRelMatchRegex + * + * The regular expression used to retrieve the character before a protocol-relative URL match. + * + * This is used in conjunction with the {@link #matcherRegex}, which needs to grab the character before a protocol-relative + * '//' due to the lack of a negative look-behind in JavaScript regular expressions. The character before the match is stripped + * from the URL. + */ + charBeforeProtocolRelMatchRegex : /^(.)?\/\//, + + /** + * @private + * @property {Autolinker.HtmlParser} htmlParser + * + * The HtmlParser instance used to skip over HTML tags, while finding text nodes to process. This is lazily instantiated + * in the {@link #getHtmlParser} method. + */ + + /** + * @private + * @property {Autolinker.AnchorTagBuilder} tagBuilder + * + * The AnchorTagBuilder instance used to build the URL/email/Twitter replacement anchor tags. This is lazily instantiated + * in the {@link #getTagBuilder} method. + */ + + + /** + * Automatically links URLs, email addresses, and Twitter handles found in the given chunk of HTML. + * Does not link URLs found within HTML tags. + * + * For instance, if given the text: `You should go to http://www.yahoo.com`, then the result + * will be `You should go to <a href="http://www.yahoo.com">http://www.yahoo.com</a>` + * + * This method finds the text around any HTML elements in the input `textOrHtml`, which will be the text that is processed. + * Any original HTML elements will be left as-is, as well as the text that is already wrapped in anchor (<a>) tags. + * + * @param {String} textOrHtml The HTML or text to link URLs, email addresses, and Twitter handles within. + * @return {String} The HTML, with URLs/emails/Twitter handles automatically linked. + */ + link : function( textOrHtml ) { + var me = this, // for closure + htmlParser = this.getHtmlParser(), + htmlCharacterEntitiesRegex = this.htmlCharacterEntitiesRegex, + anchorTagStackCount = 0, // used to only process text around anchor tags, and any inner text/html they may have + resultHtml = []; + + htmlParser.parse( textOrHtml, { + // Process HTML nodes in the input `textOrHtml` + processHtmlNode : function( tagText, tagName, isClosingTag ) { + if( tagName === 'a' ) { + if( !isClosingTag ) { // it's the start tag + anchorTagStackCount++; + } else { // it's the end tag + anchorTagStackCount = Math.max( anchorTagStackCount - 1, 0 ); // attempt to handle extraneous tags by making sure the stack count never goes below 0 + } + } + resultHtml.push( tagText ); // now add the text of the tag itself verbatim + }, + + // Process text nodes in the input `textOrHtml` + processTextNode : function( text ) { + if( anchorTagStackCount === 0 ) { + // If we're not within an tag, process the text node + var unescapedText = Autolinker.Util.splitAndCapture( text, htmlCharacterEntitiesRegex ); // split at HTML entities, but include the HTML entities in the results array + + for ( var i = 0, len = unescapedText.length; i < len; i++ ) { + var textToProcess = unescapedText[ i ], + processedTextNode = me.processTextNode( textToProcess ); + + resultHtml.push( processedTextNode ); + } + + } else { + // `text` is within an tag, simply append the text - we do not want to autolink anything + // already within an ... tag + resultHtml.push( text ); + } + } + } ); + + return resultHtml.join( "" ); + }, + + + /** + * Lazily instantiates and returns the {@link #htmlParser} instance for this Autolinker instance. + * + * @protected + * @return {Autolinker.HtmlParser} + */ + getHtmlParser : function() { + var htmlParser = this.htmlParser; + + if( !htmlParser ) { + htmlParser = this.htmlParser = new Autolinker.HtmlParser(); + } + + return htmlParser; + }, + + + /** + * Returns the {@link #tagBuilder} instance for this Autolinker instance, lazily instantiating it + * if it does not yet exist. + * + * This method may be used in a {@link #replaceFn} to generate the {@link Autolinker.HtmlTag HtmlTag} instance that + * Autolinker would normally generate, and then allow for modifications before returning it. For example: + * + * var html = Autolinker.link( "Test google.com", { + * replaceFn : function( autolinker, match ) { + * var tag = autolinker.getTagBuilder().build( match ); // returns an {@link Autolinker.HtmlTag} instance + * tag.setAttr( 'rel', 'nofollow' ); + * + * return tag; + * } + * } ); + * + * // generated html: + * // Test google.com + * + * @return {Autolinker.AnchorTagBuilder} + */ + getTagBuilder : function() { + var tagBuilder = this.tagBuilder; + + if( !tagBuilder ) { + tagBuilder = this.tagBuilder = new Autolinker.AnchorTagBuilder( { + newWindow : this.newWindow, + truncate : this.truncate, + className : this.className + } ); + } + + return tagBuilder; + }, + + + /** + * Process the text that lies inbetween HTML tags. This method does the actual wrapping of URLs with + * anchor tags. + * + * @private + * @param {String} text The text to auto-link. + * @return {String} The text with anchor tags auto-filled. + */ + processTextNode : function( text ) { + var me = this, // for closure + charBeforeProtocolRelMatchRegex = this.charBeforeProtocolRelMatchRegex; + + return text.replace( this.matcherRegex, function( matchStr, $1, $2, $3, $4, $5, $6, $7 ) { + var twitterMatch = $1, + twitterHandlePrefixWhitespaceChar = $2, // The whitespace char before the @ sign in a Twitter handle match. This is needed because of no lookbehinds in JS regexes. + twitterHandle = $3, // The actual twitterUser (i.e the word after the @ sign in a Twitter handle match) + emailAddressMatch = $4, // For both determining if it is an email address, and stores the actual email address + urlMatch = $5, // The matched URL string + protocolRelativeMatch = $6 || $7, // The '//' for a protocol-relative match, with the character that comes before the '//' + + prefixStr = "", // A string to use to prefix the anchor tag that is created. This is needed for the Twitter handle match + suffixStr = "", // A string to suffix the anchor tag that is created. This is used if there is a trailing parenthesis that should not be auto-linked. + + match; // Will be an Autolinker.match.Match object + + + // Return out with no changes for match types that are disabled (url, email, twitter), or for matches that are + // invalid (false positives from the matcherRegex, which can't use look-behinds since they are unavailable in JS). + if( !me.isValidMatch( twitterMatch, emailAddressMatch, urlMatch, protocolRelativeMatch ) ) { + return matchStr; + } + + // Handle a closing parenthesis at the end of the match, and exclude it if there is not a matching open parenthesis + // in the match itself. + if( me.matchHasUnbalancedClosingParen( matchStr ) ) { + matchStr = matchStr.substr( 0, matchStr.length - 1 ); // remove the trailing ")" + suffixStr = ")"; // this will be added after the generated tag + } + + + if( emailAddressMatch ) { + match = new Autolinker.match.Email( { matchedText: matchStr, email: emailAddressMatch } ); + + } else if( twitterMatch ) { + // fix up the `matchStr` if there was a preceding whitespace char, which was needed to determine the match + // itself (since there are no look-behinds in JS regexes) + if( twitterHandlePrefixWhitespaceChar ) { + prefixStr = twitterHandlePrefixWhitespaceChar; + matchStr = matchStr.slice( 1 ); // remove the prefixed whitespace char from the match + } + match = new Autolinker.match.Twitter( { matchedText: matchStr, twitterHandle: twitterHandle } ); + + } else { // url match + // If it's a protocol-relative '//' match, remove the character before the '//' (which the matcherRegex needed + // to match due to the lack of a negative look-behind in JavaScript regular expressions) + if( protocolRelativeMatch ) { + var charBeforeMatch = protocolRelativeMatch.match( charBeforeProtocolRelMatchRegex )[ 1 ] || ""; + + if( charBeforeMatch ) { // fix up the `matchStr` if there was a preceding char before a protocol-relative match, which was needed to determine the match itself (since there are no look-behinds in JS regexes) + prefixStr = charBeforeMatch; + matchStr = matchStr.slice( 1 ); // remove the prefixed char from the match + } + } + + match = new Autolinker.match.Url( { + matchedText : matchStr, + url : matchStr, + protocolRelativeMatch : protocolRelativeMatch, + stripPrefix : me.stripPrefix + } ); + } + + // Generate the replacement text for the match + var matchReturnVal = me.createMatchReturnVal( match, matchStr ); + return prefixStr + matchReturnVal + suffixStr; + } ); + }, + + + /** + * Determines if a given match found by {@link #processTextNode} is valid. Will return `false` for: + * + * 1) Disabled link types (i.e. having a Twitter match, but {@link #twitter} matching is disabled) + * 2) URL matches which do not have at least have one period ('.') in the domain name (effectively skipping over + * matches like "abc:def") + * 3) A protocol-relative url match (a URL beginning with '//') whose previous character is a word character + * (effectively skipping over strings like "abc//google.com") + * + * Otherwise, returns `true`. + * + * @private + * @param {String} twitterMatch The matched Twitter handle, if there was one. Will be empty string if the match is not a + * Twitter match. + * @param {String} emailAddressMatch The matched Email address, if there was one. Will be empty string if the match is not + * an Email address match. + * @param {String} urlMatch The matched URL, if there was one. Will be an empty string if the match is not a URL match. + * @param {String} protocolRelativeMatch The protocol-relative string for a URL match (i.e. '//'), possibly with a preceding + * character (ex, a space, such as: ' //', or a letter, such as: 'a//'). The match is invalid if there is a word character + * preceding the '//'. + * @return {Boolean} `true` if the match given is valid and should be processed, or `false` if the match is invalid and/or + * should just not be processed (such as, if it's a Twitter match, but {@link #twitter} matching is disabled}. + */ + isValidMatch : function( twitterMatch, emailAddressMatch, urlMatch, protocolRelativeMatch ) { + if( + ( twitterMatch && !this.twitter ) || ( emailAddressMatch && !this.email ) || ( urlMatch && !this.urls ) || + ( urlMatch && urlMatch.indexOf( '.' ) === -1 ) || // At least one period ('.') must exist in the URL match for us to consider it an actual URL + ( urlMatch && /^[A-Za-z]{3,9}:/.test( urlMatch ) && !/:.*?[A-Za-z]/.test( urlMatch ) ) || // At least one letter character must exist in the domain name after a protocol match. Ex: skip over something like "git:1.0" + ( protocolRelativeMatch && this.invalidProtocolRelMatchRegex.test( protocolRelativeMatch ) ) // a protocol-relative match which has a word character in front of it (so we can skip something like "abc//google.com") + ) { + return false; + } + + return true; + }, + + + /** + * Determines if a match found has an unmatched closing parenthesis. If so, this parenthesis will be removed + * from the match itself, and appended after the generated anchor tag in {@link #processTextNode}. + * + * A match may have an extra closing parenthesis at the end of the match because the regular expression must include parenthesis + * for URLs such as "wikipedia.com/something_(disambiguation)", which should be auto-linked. + * + * However, an extra parenthesis *will* be included when the URL itself is wrapped in parenthesis, such as in the case of + * "(wikipedia.com/something_(disambiguation))". In this case, the last closing parenthesis should *not* be part of the URL + * itself, and this method will return `true`. + * + * @private + * @param {String} matchStr The full match string from the {@link #matcherRegex}. + * @return {Boolean} `true` if there is an unbalanced closing parenthesis at the end of the `matchStr`, `false` otherwise. + */ + matchHasUnbalancedClosingParen : function( matchStr ) { + var lastChar = matchStr.charAt( matchStr.length - 1 ); + + if( lastChar === ')' ) { + var openParensMatch = matchStr.match( /\(/g ), + closeParensMatch = matchStr.match( /\)/g ), + numOpenParens = ( openParensMatch && openParensMatch.length ) || 0, + numCloseParens = ( closeParensMatch && closeParensMatch.length ) || 0; + + if( numOpenParens < numCloseParens ) { + return true; + } + } + + return false; + }, + + + /** + * Creates the return string value for a given match in the input string, for the {@link #processTextNode} method. + * + * This method handles the {@link #replaceFn}, if one was provided. + * + * @private + * @param {Autolinker.match.Match} match The Match object that represents the match. + * @param {String} matchStr The original match string, after having been preprocessed to fix match edge cases (see + * the `prefixStr` and `suffixStr` vars in {@link #processTextNode}. + * @return {String} The string that the `match` should be replaced with. This is usually the anchor tag string, but + * may be the `matchStr` itself if the match is not to be replaced. + */ + createMatchReturnVal : function( match, matchStr ) { + // Handle a custom `replaceFn` being provided + var replaceFnResult; + if( this.replaceFn ) { + replaceFnResult = this.replaceFn.call( this, this, match ); // Autolinker instance is the context, and the first arg + } + + if( typeof replaceFnResult === 'string' ) { + return replaceFnResult; // `replaceFn` returned a string, use that + + } else if( replaceFnResult === false ) { + return matchStr; // no replacement for the match + + } else if( replaceFnResult instanceof Autolinker.HtmlTag ) { + return replaceFnResult.toString(); + + } else { // replaceFnResult === true, or no/unknown return value from function + // Perform Autolinker's default anchor tag generation + var tagBuilder = this.getTagBuilder(), + anchorTag = tagBuilder.build( match ); // returns an Autolinker.HtmlTag instance + + return anchorTag.toString(); + } + } + + }; + + + /** + * Automatically links URLs, email addresses, and Twitter handles found in the given chunk of HTML. + * Does not link URLs found within HTML tags. + * + * For instance, if given the text: `You should go to http://www.yahoo.com`, then the result + * will be `You should go to <a href="http://www.yahoo.com">http://www.yahoo.com</a>` + * + * Example: + * + * var linkedText = Autolinker.link( "Go to google.com", { newWindow: false } ); + * // Produces: "Go to google.com" + * + * @static + * @method link + * @param {String} html The HTML text to link URLs within. + * @param {Object} [options] Any of the configuration options for the Autolinker class, specified in an Object (map). + * See the class description for an example call. + * @return {String} The HTML text, with URLs automatically linked + */ + Autolinker.link = function( text, options ) { + var autolinker = new Autolinker( options ); + return autolinker.link( text ); + }; + + + // Namespace for `match` classes + Autolinker.match = {}; + /*global Autolinker */ + /*jshint eqnull:true, boss:true */ + /** + * @class Autolinker.Util + * @singleton + * + * A few utility methods for Autolinker. + */ + Autolinker.Util = { + + /** + * @property {Function} abstractMethod + * + * A function object which represents an abstract method. + */ + abstractMethod : function() { throw "abstract"; }, + + + /** + * Assigns (shallow copies) the properties of `src` onto `dest`. + * + * @param {Object} dest The destination object. + * @param {Object} src The source object. + * @return {Object} The destination object. + */ + assign : function( dest, src ) { + for( var prop in src ) { + if( src.hasOwnProperty( prop ) ) { + dest[ prop ] = src[ prop ]; + } + } + + return dest; + }, + + + /** + * Extends `superclass` to create a new subclass, adding the `protoProps` to the new subclass's prototype. + * + * @param {Function} superclass The constructor function for the superclass. + * @param {Object} protoProps The methods/properties to add to the subclass's prototype. This may contain the + * special property `constructor`, which will be used as the new subclass's constructor function. + * @return {Function} The new subclass function. + */ + extend : function( superclass, protoProps ) { + var superclassProto = superclass.prototype; + + var F = function() {}; + F.prototype = superclassProto; + + var subclass; + if( protoProps.hasOwnProperty( 'constructor' ) ) { + subclass = protoProps.constructor; + } else { + subclass = function() { superclassProto.constructor.apply( this, arguments ); }; + } + + var subclassProto = subclass.prototype = new F(); // set up prototype chain + subclassProto.constructor = subclass; // fix constructor property + subclassProto.superclass = superclassProto; + + delete protoProps.constructor; // don't re-assign constructor property to the prototype, since a new function may have been created (`subclass`), which is now already there + Autolinker.Util.assign( subclassProto, protoProps ); + + return subclass; + }, + + + /** + * Truncates the `str` at `len - ellipsisChars.length`, and adds the `ellipsisChars` to the + * end of the string (by default, two periods: '..'). If the `str` length does not exceed + * `len`, the string will be returned unchanged. + * + * @param {String} str The string to truncate and add an ellipsis to. + * @param {Number} truncateLen The length to truncate the string at. + * @param {String} [ellipsisChars=..] The ellipsis character(s) to add to the end of `str` + * when truncated. Defaults to '..' + */ + ellipsis : function( str, truncateLen, ellipsisChars ) { + if( str.length > truncateLen ) { + ellipsisChars = ( ellipsisChars == null ) ? '..' : ellipsisChars; + str = str.substring( 0, truncateLen - ellipsisChars.length ) + ellipsisChars; + } + return str; + }, + + + /** + * Supports `Array.prototype.indexOf()` functionality for old IE (IE8 and below). + * + * @param {Array} arr The array to find an element of. + * @param {*} element The element to find in the array, and return the index of. + * @return {Number} The index of the `element`, or -1 if it was not found. + */ + indexOf : function( arr, element ) { + if( Array.prototype.indexOf ) { + return arr.indexOf( element ); + + } else { + for( var i = 0, len = arr.length; i < len; i++ ) { + if( arr[ i ] === element ) return i; + } + return -1; + } + }, + + + + /** + * Performs the functionality of what modern browsers do when `String.prototype.split()` is called + * with a regular expression that contains capturing parenthesis. + * + * For example: + * + * // Modern browsers: + * "a,b,c".split( /(,)/ ); // --> [ 'a', ',', 'b', ',', 'c' ] + * + * // Old IE (including IE8): + * "a,b,c".split( /(,)/ ); // --> [ 'a', 'b', 'c' ] + * + * This method emulates the functionality of modern browsers for the old IE case. + * + * @param {String} str The string to split. + * @param {RegExp} splitRegex The regular expression to split the input `str` on. The splitting + * character(s) will be spliced into the array, as in the "modern browsers" example in the + * description of this method. + * Note #1: the supplied regular expression **must** have the 'g' flag specified. + * Note #2: for simplicity's sake, the regular expression does not need + * to contain capturing parenthesis - it will be assumed that any match has them. + * @return {String[]} The split array of strings, with the splitting character(s) included. + */ + splitAndCapture : function( str, splitRegex ) { + if( !splitRegex.global ) throw new Error( "`splitRegex` must have the 'g' flag set" ); + + var result = [], + lastIdx = 0, + match; + + while( match = splitRegex.exec( str ) ) { + result.push( str.substring( lastIdx, match.index ) ); + result.push( match[ 0 ] ); // push the splitting char(s) + + lastIdx = match.index + match[ 0 ].length; + } + result.push( str.substring( lastIdx ) ); + + return result; + } + + }; + /*global Autolinker */ + /** + * @private + * @class Autolinker.HtmlParser + * @extends Object + * + * An HTML parser implementation which simply walks an HTML string and calls the provided visitor functions to process + * HTML and text nodes. + * + * Autolinker uses this to only link URLs/emails/Twitter handles within text nodes, basically ignoring HTML tags. + */ + Autolinker.HtmlParser = Autolinker.Util.extend( Object, { + + /** + * @private + * @property {RegExp} htmlRegex + * + * The regular expression used to pull out HTML tags from a string. Handles namespaced HTML tags and + * attribute names, as specified by http://www.w3.org/TR/html-markup/syntax.html. + * + * Capturing groups: + * + * 1. If it is an end tag, this group will have the '/'. + * 2. The tag name. + */ + htmlRegex : (function() { + var tagNameRegex = /[0-9a-zA-Z:]+/, + attrNameRegex = /[^\s\0"'>\/=\x01-\x1F\x7F]+/, // the unicode range accounts for excluding control chars, and the delete char + attrValueRegex = /(?:".*?"|'.*?'|[^'"=<>`\s]+)/, // double quoted, single quoted, or unquoted attribute values + nameEqualsValueRegex = attrNameRegex.source + '(?:\\s*=\\s*' + attrValueRegex.source + ')?'; // optional '=[value]' + + return new RegExp( [ + '<(?:!|(/))?', // Beginning of a tag. Either '<' for a start tag, ' tag. The slash or an empty string is Capturing Group 1. + + // The tag name (Capturing Group 2) + '(' + tagNameRegex.source + ')', + + // Zero or more attributes following the tag name + '(?:', + '\\s+', // one or more whitespace chars before an attribute + + // Either: + // A. tag="value", or + // B. "value" alone (for tag. Ex: ) + '(?:', nameEqualsValueRegex, '|', attrValueRegex.source + ')', + ')*', + + '\\s*/?', // any trailing spaces and optional '/' before the closing '>' + '>' + ].join( "" ), 'g' ); + } )(), + + + /** + * Walks an HTML string, calling the `options.processHtmlNode` function for each HTML tag that is encountered, and calling + * the `options.processTextNode` function when each text around HTML tags is encountered. + * + * @param {String} html The HTML to parse. + * @param {Object} [options] An Object (map) which may contain the following properties: + * + * @param {Function} [options.processHtmlNode] A visitor function which allows processing of an encountered HTML node. + * This function is called with the following arguments: + * @param {String} [options.processHtmlNode.tagText] The HTML tag text that was found. + * @param {String} [options.processHtmlNode.tagName] The tag name for the HTML tag that was found. Ex: 'a' for an anchor tag. + * @param {String} [options.processHtmlNode.isClosingTag] `true` if the tag is a closing tag (ex: </a>), `false` otherwise. + * + * @param {Function} [options.processTextNode] A visitor function which allows processing of an encountered text node. + * This function is called with the following arguments: + * @param {String} [options.processTextNode.text] The text node that was matched. + */ + parse : function( html, options ) { + options = options || {}; + + var processHtmlNodeVisitor = options.processHtmlNode || function() {}, + processTextNodeVisitor = options.processTextNode || function() {}, + htmlRegex = this.htmlRegex, + currentResult, + lastIndex = 0; + + // Loop over the HTML string, ignoring HTML tags, and processing the text that lies between them, + // wrapping the URLs in anchor tags + while( ( currentResult = htmlRegex.exec( html ) ) !== null ) { + var tagText = currentResult[ 0 ], + tagName = currentResult[ 2 ], + isClosingTag = !!currentResult[ 1 ], + inBetweenTagsText = html.substring( lastIndex, currentResult.index ); + + if( inBetweenTagsText ) { + processTextNodeVisitor( inBetweenTagsText ); + } + + processHtmlNodeVisitor( tagText, tagName, isClosingTag ); + + lastIndex = currentResult.index + tagText.length; + } + + // Process any remaining text after the last HTML element. Will process all of the text if there were no HTML elements. + if( lastIndex < html.length ) { + var text = html.substring( lastIndex ); + + if( text ) { + processTextNodeVisitor( text ); + } + } + } + + } ); + /*global Autolinker */ + /*jshint boss:true */ + /** + * @class Autolinker.HtmlTag + * @extends Object + * + * Represents an HTML tag, which can be used to easily build/modify HTML tags programmatically. + * + * Autolinker uses this abstraction to create HTML tags, and then write them out as strings. You may also use + * this class in your code, especially within a {@link Autolinker#replaceFn replaceFn}. + * + * ## Examples + * + * Example instantiation: + * + * var tag = new Autolinker.HtmlTag( { + * tagName : 'a', + * attrs : { 'href': 'http://google.com', 'class': 'external-link' }, + * innerHtml : 'Google' + * } ); + * + * tag.toString(); // Google + * + * // Individual accessor methods + * tag.getTagName(); // 'a' + * tag.getAttr( 'href' ); // 'http://google.com' + * tag.hasClass( 'external-link' ); // true + * + * + * Using mutator methods (which may be used in combination with instantiation config properties): + * + * var tag = new Autolinker.HtmlTag(); + * tag.setTagName( 'a' ); + * tag.setAttr( 'href', 'http://google.com' ); + * tag.addClass( 'external-link' ); + * tag.setInnerHtml( 'Google' ); + * + * tag.getTagName(); // 'a' + * tag.getAttr( 'href' ); // 'http://google.com' + * tag.hasClass( 'external-link' ); // true + * + * tag.toString(); // Google + * + * + * ## Example use within a {@link Autolinker#replaceFn replaceFn} + * + * var html = Autolinker.link( "Test google.com", { + * replaceFn : function( autolinker, match ) { + * var tag = autolinker.getTagBuilder().build( match ); // returns an {@link Autolinker.HtmlTag} instance, configured with the Match's href and anchor text + * tag.setAttr( 'rel', 'nofollow' ); + * + * return tag; + * } + * } ); + * + * // generated html: + * // Test google.com + * + * + * ## Example use with a new tag for the replacement + * + * var html = Autolinker.link( "Test google.com", { + * replaceFn : function( autolinker, match ) { + * var tag = new Autolinker.HtmlTag( { + * tagName : 'button', + * attrs : { 'title': 'Load URL: ' + match.getAnchorHref() }, + * innerHtml : 'Load URL: ' + match.getAnchorText() + * } ); + * + * return tag; + * } + * } ); + * + * // generated html: + * // Test + */ + Autolinker.HtmlTag = Autolinker.Util.extend( Object, { + + /** + * @cfg {String} tagName + * + * The tag name. Ex: 'a', 'button', etc. + * + * Not required at instantiation time, but should be set using {@link #setTagName} before {@link #toString} + * is executed. + */ + + /** + * @cfg {Object.} attrs + * + * An key/value Object (map) of attributes to create the tag with. The keys are the attribute names, and the + * values are the attribute values. + */ + + /** + * @cfg {String} innerHtml + * + * The inner HTML for the tag. + * + * Note the camel case name on `innerHtml`. Acronyms are camelCased in this utility (such as not to run into the acronym + * naming inconsistency that the DOM developers created with `XMLHttpRequest`). You may alternatively use {@link #innerHTML} + * if you prefer, but this one is recommended. + */ + + /** + * @cfg {String} innerHTML + * + * Alias of {@link #innerHtml}, accepted for consistency with the browser DOM api, but prefer the camelCased version + * for acronym names. + */ + + + /** + * @protected + * @property {RegExp} whitespaceRegex + * + * Regular expression used to match whitespace in a string of CSS classes. + */ + whitespaceRegex : /\s+/, + + + /** + * @constructor + * @param {Object} [cfg] The configuration properties for this class, in an Object (map) + */ + constructor : function( cfg ) { + Autolinker.Util.assign( this, cfg ); + + this.innerHtml = this.innerHtml || this.innerHTML; // accept either the camelCased form or the fully capitalized acronym + }, + + + /** + * Sets the tag name that will be used to generate the tag with. + * + * @param {String} tagName + * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained. + */ + setTagName : function( tagName ) { + this.tagName = tagName; + return this; + }, + + + /** + * Retrieves the tag name. + * + * @return {String} + */ + getTagName : function() { + return this.tagName || ""; + }, + + + /** + * Sets an attribute on the HtmlTag. + * + * @param {String} attrName The attribute name to set. + * @param {String} attrValue The attribute value to set. + * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained. + */ + setAttr : function( attrName, attrValue ) { + var tagAttrs = this.getAttrs(); + tagAttrs[ attrName ] = attrValue; + + return this; + }, + + + /** + * Retrieves an attribute from the HtmlTag. If the attribute does not exist, returns `undefined`. + * + * @param {String} name The attribute name to retrieve. + * @return {String} The attribute's value, or `undefined` if it does not exist on the HtmlTag. + */ + getAttr : function( attrName ) { + return this.getAttrs()[ attrName ]; + }, + + + /** + * Sets one or more attributes on the HtmlTag. + * + * @param {Object.} attrs A key/value Object (map) of the attributes to set. + * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained. + */ + setAttrs : function( attrs ) { + var tagAttrs = this.getAttrs(); + Autolinker.Util.assign( tagAttrs, attrs ); + + return this; + }, + + + /** + * Retrieves the attributes Object (map) for the HtmlTag. + * + * @return {Object.} A key/value object of the attributes for the HtmlTag. + */ + getAttrs : function() { + return this.attrs || ( this.attrs = {} ); + }, + + + /** + * Sets the provided `cssClass`, overwriting any current CSS classes on the HtmlTag. + * + * @param {String} cssClass One or more space-separated CSS classes to set (overwrite). + * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained. + */ + setClass : function( cssClass ) { + return this.setAttr( 'class', cssClass ); + }, + + + /** + * Convenience method to add one or more CSS classes to the HtmlTag. Will not add duplicate CSS classes. + * + * @param {String} cssClass One or more space-separated CSS classes to add. + * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained. + */ + addClass : function( cssClass ) { + var classAttr = this.getClass(), + whitespaceRegex = this.whitespaceRegex, + indexOf = Autolinker.Util.indexOf, // to support IE8 and below + classes = ( !classAttr ) ? [] : classAttr.split( whitespaceRegex ), + newClasses = cssClass.split( whitespaceRegex ), + newClass; + + while( newClass = newClasses.shift() ) { + if( indexOf( classes, newClass ) === -1 ) { + classes.push( newClass ); + } + } + + this.getAttrs()[ 'class' ] = classes.join( " " ); + return this; + }, + + + /** + * Convenience method to remove one or more CSS classes from the HtmlTag. + * + * @param {String} cssClass One or more space-separated CSS classes to remove. + * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained. + */ + removeClass : function( cssClass ) { + var classAttr = this.getClass(), + whitespaceRegex = this.whitespaceRegex, + indexOf = Autolinker.Util.indexOf, // to support IE8 and below + classes = ( !classAttr ) ? [] : classAttr.split( whitespaceRegex ), + removeClasses = cssClass.split( whitespaceRegex ), + removeClass; + + while( classes.length && ( removeClass = removeClasses.shift() ) ) { + var idx = indexOf( classes, removeClass ); + if( idx !== -1 ) { + classes.splice( idx, 1 ); + } + } + + this.getAttrs()[ 'class' ] = classes.join( " " ); + return this; + }, + + + /** + * Convenience method to retrieve the CSS class(es) for the HtmlTag, which will each be separated by spaces when + * there are multiple. + * + * @return {String} + */ + getClass : function() { + return this.getAttrs()[ 'class' ] || ""; + }, + + + /** + * Convenience method to check if the tag has a CSS class or not. + * + * @param {String} cssClass The CSS class to check for. + * @return {Boolean} `true` if the HtmlTag has the CSS class, `false` otherwise. + */ + hasClass : function( cssClass ) { + return ( ' ' + this.getClass() + ' ' ).indexOf( ' ' + cssClass + ' ' ) !== -1; + }, + + + /** + * Sets the inner HTML for the tag. + * + * @param {String} html The inner HTML to set. + * @return {Autolinker.HtmlTag} This HtmlTag instance, so that method calls may be chained. + */ + setInnerHtml : function( html ) { + this.innerHtml = html; + + return this; + }, + + + /** + * Retrieves the inner HTML for the tag. + * + * @return {String} + */ + getInnerHtml : function() { + return this.innerHtml || ""; + }, + + + /** + * Override of superclass method used to generate the HTML string for the tag. + * + * @return {String} + */ + toString : function() { + var tagName = this.getTagName(), + attrsStr = this.buildAttrsStr(); + + attrsStr = ( attrsStr ) ? ' ' + attrsStr : ''; // prepend a space if there are actually attributes + + return [ '<', tagName, attrsStr, '>', this.getInnerHtml(), '' ].join( "" ); + }, + + + /** + * Support method for {@link #toString}, returns the string space-separated key="value" pairs, used to populate + * the stringified HtmlTag. + * + * @protected + * @return {String} Example return: `attr1="value1" attr2="value2"` + */ + buildAttrsStr : function() { + if( !this.attrs ) return ""; // no `attrs` Object (map) has been set, return empty string + + var attrs = this.getAttrs(), + attrsArr = []; + + for( var prop in attrs ) { + if( attrs.hasOwnProperty( prop ) ) { + attrsArr.push( prop + '="' + attrs[ prop ] + '"' ); + } + } + return attrsArr.join( " " ); + } + + } ); + /*global Autolinker */ + /*jshint sub:true */ + /** + * @protected + * @class Autolinker.AnchorTagBuilder + * @extends Object + * + * Builds anchor (<a>) tags for the Autolinker utility when a match is found. + * + * Normally this class is instantiated, configured, and used internally by an {@link Autolinker} instance, but may + * actually be retrieved in a {@link Autolinker#replaceFn replaceFn} to create {@link Autolinker.HtmlTag HtmlTag} instances + * which may be modified before returning from the {@link Autolinker#replaceFn replaceFn}. For example: + * + * var html = Autolinker.link( "Test google.com", { + * replaceFn : function( autolinker, match ) { + * var tag = autolinker.getTagBuilder().build( match ); // returns an {@link Autolinker.HtmlTag} instance + * tag.setAttr( 'rel', 'nofollow' ); + * + * return tag; + * } + * } ); + * + * // generated html: + * // Test google.com + */ + Autolinker.AnchorTagBuilder = Autolinker.Util.extend( Object, { + + /** + * @cfg {Boolean} newWindow + * @inheritdoc Autolinker#newWindow + */ + + /** + * @cfg {Number} truncate + * @inheritdoc Autolinker#truncate + */ + + /** + * @cfg {String} className + * @inheritdoc Autolinker#className + */ + + + /** + * @constructor + * @param {Object} [cfg] The configuration options for the AnchorTagBuilder instance, specified in an Object (map). + */ + constructor : function( cfg ) { + Autolinker.Util.assign( this, cfg ); + }, + + + /** + * Generates the actual anchor (<a>) tag to use in place of the matched URL/email/Twitter text, + * via its `match` object. + * + * @param {Autolinker.match.Match} match The Match instance to generate an anchor tag from. + * @return {Autolinker.HtmlTag} The HtmlTag instance for the anchor tag. + */ + build : function( match ) { + var tag = new Autolinker.HtmlTag( { + tagName : 'a', + attrs : this.createAttrs( match.getType(), match.getAnchorHref() ), + innerHtml : this.processAnchorText( match.getAnchorText() ) + } ); + + return tag; + }, + + + /** + * Creates the Object (map) of the HTML attributes for the anchor (<a>) tag being generated. + * + * @protected + * @param {"url"/"email"/"twitter"} matchType The type of match that an anchor tag is being generated for. + * @param {String} href The href for the anchor tag. + * @return {Object} A key/value Object (map) of the anchor tag's attributes. + */ + createAttrs : function( matchType, anchorHref ) { + var attrs = { + 'href' : anchorHref // we'll always have the `href` attribute + }; + + var cssClass = this.createCssClass( matchType ); + if( cssClass ) { + attrs[ 'class' ] = cssClass; + } + if( this.newWindow ) { + attrs[ 'target' ] = "_blank"; + } + + return attrs; + }, + + + /** + * Creates the CSS class that will be used for a given anchor tag, based on the `matchType` and the {@link #className} + * config. + * + * @private + * @param {"url"/"email"/"twitter"} matchType The type of match that an anchor tag is being generated for. + * @return {String} The CSS class string for the link. Example return: "myLink myLink-url". If no {@link #className} + * was configured, returns an empty string. + */ + createCssClass : function( matchType ) { + var className = this.className; + + if( !className ) + return ""; + else + return className + " " + className + "-" + matchType; // ex: "myLink myLink-url", "myLink myLink-email", or "myLink myLink-twitter" + }, + + + /** + * Processes the `anchorText` by truncating the text according to the {@link #truncate} config. + * + * @private + * @param {String} anchorText The anchor tag's text (i.e. what will be displayed). + * @return {String} The processed `anchorText`. + */ + processAnchorText : function( anchorText ) { + anchorText = this.doTruncate( anchorText ); + + return anchorText; + }, + + + /** + * Performs the truncation of the `anchorText`, if the `anchorText` is longer than the {@link #truncate} option. + * Truncates the text to 2 characters fewer than the {@link #truncate} option, and adds ".." to the end. + * + * @private + * @param {String} text The anchor tag's text (i.e. what will be displayed). + * @return {String} The truncated anchor text. + */ + doTruncate : function( anchorText ) { + return Autolinker.Util.ellipsis( anchorText, this.truncate || Number.POSITIVE_INFINITY ); + } + + } ); + /*global Autolinker */ + /** + * @abstract + * @class Autolinker.match.Match + * + * Represents a match found in an input string which should be Autolinked. A Match object is what is provided in a + * {@link Autolinker#replaceFn replaceFn}, and may be used to query for details about the match. + * + * For example: + * + * var input = "..."; // string with URLs, Email Addresses, and Twitter Handles + * + * var linkedText = Autolinker.link( input, { + * replaceFn : function( autolinker, match ) { + * console.log( "href = ", match.getAnchorHref() ); + * console.log( "text = ", match.getAnchorText() ); + * + * switch( match.getType() ) { + * case 'url' : + * console.log( "url: ", match.getUrl() ); + * + * case 'email' : + * console.log( "email: ", match.getEmail() ); + * + * case 'twitter' : + * console.log( "twitter: ", match.getTwitterHandle() ); + * } + * } + * } ); + * + * See the {@link Autolinker} class for more details on using the {@link Autolinker#replaceFn replaceFn}. + */ + Autolinker.match.Match = Autolinker.Util.extend( Object, { + + /** + * @cfg {String} matchedText (required) + * + * The original text that was matched. + */ + + + /** + * @constructor + * @param {Object} cfg The configuration properties for the Match instance, specified in an Object (map). + */ + constructor : function( cfg ) { + Autolinker.Util.assign( this, cfg ); + }, + + + /** + * Returns a string name for the type of match that this class represents. + * + * @abstract + * @return {String} + */ + getType : Autolinker.Util.abstractMethod, + + + /** + * Returns the original text that was matched. + * + * @return {String} + */ + getMatchedText : function() { + return this.matchedText; + }, + + + /** + * Returns the anchor href that should be generated for the match. + * + * @abstract + * @return {String} + */ + getAnchorHref : Autolinker.Util.abstractMethod, + + + /** + * Returns the anchor text that should be generated for the match. + * + * @abstract + * @return {String} + */ + getAnchorText : Autolinker.Util.abstractMethod + + } ); + /*global Autolinker */ + /** + * @class Autolinker.match.Email + * @extends Autolinker.match.Match + * + * Represents a Email match found in an input string which should be Autolinked. + * + * See this class's superclass ({@link Autolinker.match.Match}) for more details. + */ + Autolinker.match.Email = Autolinker.Util.extend( Autolinker.match.Match, { + + /** + * @cfg {String} email (required) + * + * The email address that was matched. + */ + + + /** + * Returns a string name for the type of match that this class represents. + * + * @return {String} + */ + getType : function() { + return 'email'; + }, + + + /** + * Returns the email address that was matched. + * + * @return {String} + */ + getEmail : function() { + return this.email; + }, + + + /** + * Returns the anchor href that should be generated for the match. + * + * @return {String} + */ + getAnchorHref : function() { + return 'mailto:' + this.email; + }, + + + /** + * Returns the anchor text that should be generated for the match. + * + * @return {String} + */ + getAnchorText : function() { + return this.email; + } + + } ); + /*global Autolinker */ + /** + * @class Autolinker.match.Twitter + * @extends Autolinker.match.Match + * + * Represents a Twitter match found in an input string which should be Autolinked. + * + * See this class's superclass ({@link Autolinker.match.Match}) for more details. + */ + Autolinker.match.Twitter = Autolinker.Util.extend( Autolinker.match.Match, { + + /** + * @cfg {String} twitterHandle (required) + * + * The Twitter handle that was matched. + */ + + + /** + * Returns the type of match that this class represents. + * + * @return {String} + */ + getType : function() { + return 'twitter'; + }, + + + /** + * Returns a string name for the type of match that this class represents. + * + * @return {String} + */ + getTwitterHandle : function() { + return this.twitterHandle; + }, + + + /** + * Returns the anchor href that should be generated for the match. + * + * @return {String} + */ + getAnchorHref : function() { + return 'https://twitter.com/' + this.twitterHandle; + }, + + + /** + * Returns the anchor text that should be generated for the match. + * + * @return {String} + */ + getAnchorText : function() { + return '@' + this.twitterHandle; + } + + } ); + /*global Autolinker */ + /** + * @class Autolinker.match.Url + * @extends Autolinker.match.Match + * + * Represents a Url match found in an input string which should be Autolinked. + * + * See this class's superclass ({@link Autolinker.match.Match}) for more details. + */ + Autolinker.match.Url = Autolinker.Util.extend( Autolinker.match.Match, { + + /** + * @cfg {String} url (required) + * + * The url that was matched. + */ + + /** + * @cfg {Boolean} protocolRelativeMatch (required) + * + * `true` if the URL is a protocol-relative match. A protocol-relative match is a URL that starts with '//', + * and will be either http:// or https:// based on the protocol that the site is loaded under. + */ + + /** + * @cfg {Boolean} stripPrefix (required) + * @inheritdoc {@link Autolinker#stripPrefix} + */ + + + /** + * @private + * @property {RegExp} urlPrefixRegex + * + * A regular expression used to remove the 'http://' or 'https://' and/or the 'www.' from URLs. + */ + urlPrefixRegex: /^(https?:\/\/)?(www\.)?/i, + + /** + * @private + * @property {RegExp} protocolRelativeRegex + * + * The regular expression used to remove the protocol-relative '//' from the {@link #url} string, for purposes + * of {@link #getAnchorText}. A protocol-relative URL is, for example, "//yahoo.com" + */ + protocolRelativeRegex : /^\/\//, + + /** + * @protected + * @property {RegExp} checkForProtocolRegex + * + * A regular expression used to check if the {@link #url} is missing a protocol (in which case, 'http://' + * will be added). + */ + checkForProtocolRegex: /^[A-Za-z]{3,9}:/, + + + /** + * Returns a string name for the type of match that this class represents. + * + * @return {String} + */ + getType : function() { + return 'url'; + }, + + + /** + * Returns the url that was matched, assuming the protocol to be 'http://' if the match + * was missing a protocol. + * + * @return {String} + */ + getUrl : function() { + var url = this.url; + + // if the url string doesn't begin with a protocol, assume http:// + if( !this.protocolRelativeMatch && !this.checkForProtocolRegex.test( url ) ) { + url = this.url = 'http://' + url; + } + + return url; + }, + + + /** + * Returns the anchor href that should be generated for the match. + * + * @return {String} + */ + getAnchorHref : function() { + var url = this.getUrl(); + + return url.replace( /&/g, '&' ); // any &'s in the URL should be converted back to '&' if they were displayed as & in the source html + }, + + + /** + * Returns the anchor text that should be generated for the match. + * + * @return {String} + */ + getAnchorText : function() { + var anchorText = this.getUrl(); + + if( this.protocolRelativeMatch ) { + // Strip off any protocol-relative '//' from the anchor text + anchorText = this.stripProtocolRelativePrefix( anchorText ); + } + if( this.stripPrefix ) { + anchorText = this.stripUrlPrefix( anchorText ); + } + anchorText = this.removeTrailingSlash( anchorText ); // remove trailing slash, if there is one + + return anchorText; + }, + + + // --------------------------------------- + + // Utility Functionality + + /** + * Strips the URL prefix (such as "http://" or "https://") from the given text. + * + * @private + * @param {String} text The text of the anchor that is being generated, for which to strip off the + * url prefix (such as stripping off "http://") + * @return {String} The `anchorText`, with the prefix stripped. + */ + stripUrlPrefix : function( text ) { + return text.replace( this.urlPrefixRegex, '' ); + }, + + + /** + * Strips any protocol-relative '//' from the anchor text. + * + * @private + * @param {String} text The text of the anchor that is being generated, for which to strip off the + * protocol-relative prefix (such as stripping off "//") + * @return {String} The `anchorText`, with the protocol-relative prefix stripped. + */ + stripProtocolRelativePrefix : function( text ) { + return text.replace( this.protocolRelativeRegex, '' ); + }, + + + /** + * Removes any trailing slash from the given `anchorText`, in preparation for the text to be displayed. + * + * @private + * @param {String} anchorText The text of the anchor that is being generated, for which to remove any trailing + * slash ('/') that may exist. + * @return {String} The `anchorText`, with the trailing slash removed. + */ + removeTrailingSlash : function( anchorText ) { + if( anchorText.charAt( anchorText.length - 1 ) === '/' ) { + anchorText = anchorText.slice( 0, -1 ); + } + return anchorText; + } + + } ); + + return Autolinker; + +} ) ); },{}]},{},[])("./") }); \ No newline at end of file diff --git a/dist/remarkable.min.js b/dist/remarkable.min.js index abfa28d..ef6a482 100644 --- a/dist/remarkable.min.js +++ b/dist/remarkable.min.js @@ -1,3 +1,4 @@ /* remarkable 1.0.0 https://github.com//jonschlinkert/remarkable */ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var r;"undefined"!=typeof window?r=window:"undefined"!=typeof global?r=global:"undefined"!=typeof self&&(r=self),r.Remarkable=e()}}(function(){return function e(r,t,s){function n(o,l){if(!t[o]){if(!r[o]){var a="function"==typeof require&&require;if(!l&&a)return a(o,!0);if(i)return i(o,!0);var c=new Error("Cannot find module '"+o+"'");throw c.code="MODULE_NOT_FOUND",c}var u=t[o]={exports:{}};r[o][0].call(u.exports,function(e){var t=r[o][1][e];return n(t?t:e)},u,u.exports,e,r,t,s)}return t[o].exports}for(var i="function"==typeof require&&require,o=0;o",Gt:"≫",gt:">",gtcc:"⪧",gtcir:"⩺",gtdot:"⋗",gtlPar:"⦕",gtquest:"⩼",gtrapprox:"⪆",gtrarr:"⥸",gtrdot:"⋗",gtreqless:"⋛",gtreqqless:"⪌",gtrless:"≷",gtrsim:"≳",gvertneqq:"≩︀",gvnE:"≩︀",Hacek:"ˇ",hairsp:" ",half:"½",hamilt:"ℋ",HARDcy:"Ъ",hardcy:"ъ",hArr:"⇔",harr:"↔",harrcir:"⥈",harrw:"↭",Hat:"^",hbar:"ℏ",Hcirc:"Ĥ",hcirc:"ĥ",hearts:"♥",heartsuit:"♥",hellip:"…",hercon:"⊹",Hfr:"ℌ",hfr:"𝔥",HilbertSpace:"ℋ",hksearow:"⤥",hkswarow:"⤦",hoarr:"⇿",homtht:"∻",hookleftarrow:"↩",hookrightarrow:"↪",Hopf:"ℍ",hopf:"𝕙",horbar:"―",HorizontalLine:"─",Hscr:"ℋ",hscr:"𝒽",hslash:"ℏ",Hstrok:"Ħ",hstrok:"ħ",HumpDownHump:"≎",HumpEqual:"≏",hybull:"⁃",hyphen:"‐",Iacute:"Í",iacute:"í",ic:"⁣",Icirc:"Î",icirc:"î",Icy:"И",icy:"и",Idot:"İ",IEcy:"Е",iecy:"е",iexcl:"¡",iff:"⇔",Ifr:"ℑ",ifr:"𝔦",Igrave:"Ì",igrave:"ì",ii:"ⅈ",iiiint:"⨌",iiint:"∭",iinfin:"⧜",iiota:"℩",IJlig:"IJ",ijlig:"ij",Im:"ℑ",Imacr:"Ī",imacr:"ī",image:"ℑ",ImaginaryI:"ⅈ",imagline:"ℐ",imagpart:"ℑ",imath:"ı",imof:"⊷",imped:"Ƶ",Implies:"⇒","in":"∈",incare:"℅",infin:"∞",infintie:"⧝",inodot:"ı",Int:"∬","int":"∫",intcal:"⊺",integers:"ℤ",Integral:"∫",intercal:"⊺",Intersection:"⋂",intlarhk:"⨗",intprod:"⨼",InvisibleComma:"⁣",InvisibleTimes:"⁢",IOcy:"Ё",iocy:"ё",Iogon:"Į",iogon:"į",Iopf:"𝕀",iopf:"𝕚",Iota:"Ι",iota:"ι",iprod:"⨼",iquest:"¿",Iscr:"ℐ",iscr:"𝒾",isin:"∈",isindot:"⋵",isinE:"⋹",isins:"⋴",isinsv:"⋳",isinv:"∈",it:"⁢",Itilde:"Ĩ",itilde:"ĩ",Iukcy:"І",iukcy:"і",Iuml:"Ï",iuml:"ï",Jcirc:"Ĵ",jcirc:"ĵ",Jcy:"Й",jcy:"й",Jfr:"𝔍",jfr:"𝔧",jmath:"ȷ",Jopf:"𝕁",jopf:"𝕛",Jscr:"𝒥",jscr:"𝒿",Jsercy:"Ј",jsercy:"ј",Jukcy:"Є",jukcy:"є",Kappa:"Κ",kappa:"κ",kappav:"ϰ",Kcedil:"Ķ",kcedil:"ķ",Kcy:"К",kcy:"к",Kfr:"𝔎",kfr:"𝔨",kgreen:"ĸ",KHcy:"Х",khcy:"х",KJcy:"Ќ",kjcy:"ќ",Kopf:"𝕂",kopf:"𝕜",Kscr:"𝒦",kscr:"𝓀",lAarr:"⇚",Lacute:"Ĺ",lacute:"ĺ",laemptyv:"⦴",lagran:"ℒ",Lambda:"Λ",lambda:"λ",Lang:"⟪",lang:"⟨",langd:"⦑",langle:"⟨",lap:"⪅",Laplacetrf:"ℒ",laquo:"«",Larr:"↞",lArr:"⇐",larr:"←",larrb:"⇤",larrbfs:"⤟",larrfs:"⤝",larrhk:"↩",larrlp:"↫",larrpl:"⤹",larrsim:"⥳",larrtl:"↢",lat:"⪫",lAtail:"⤛",latail:"⤙",late:"⪭",lates:"⪭︀",lBarr:"⤎",lbarr:"⤌",lbbrk:"❲",lbrace:"{",lbrack:"[",lbrke:"⦋",lbrksld:"⦏",lbrkslu:"⦍",Lcaron:"Ľ",lcaron:"ľ",Lcedil:"Ļ",lcedil:"ļ",lceil:"⌈",lcub:"{",Lcy:"Л",lcy:"л",ldca:"⤶",ldquo:"“",ldquor:"„",ldrdhar:"⥧",ldrushar:"⥋",ldsh:"↲",lE:"≦",le:"≤",LeftAngleBracket:"⟨",LeftArrow:"←",Leftarrow:"⇐",leftarrow:"←",LeftArrowBar:"⇤",LeftArrowRightArrow:"⇆",leftarrowtail:"↢",LeftCeiling:"⌈",LeftDoubleBracket:"⟦",LeftDownTeeVector:"⥡",LeftDownVector:"⇃",LeftDownVectorBar:"⥙",LeftFloor:"⌊",leftharpoondown:"↽",leftharpoonup:"↼",leftleftarrows:"⇇",LeftRightArrow:"↔",Leftrightarrow:"⇔",leftrightarrow:"↔",leftrightarrows:"⇆",leftrightharpoons:"⇋",leftrightsquigarrow:"↭",LeftRightVector:"⥎",LeftTee:"⊣",LeftTeeArrow:"↤",LeftTeeVector:"⥚",leftthreetimes:"⋋",LeftTriangle:"⊲",LeftTriangleBar:"⧏",LeftTriangleEqual:"⊴",LeftUpDownVector:"⥑",LeftUpTeeVector:"⥠",LeftUpVector:"↿",LeftUpVectorBar:"⥘",LeftVector:"↼",LeftVectorBar:"⥒",lEg:"⪋",leg:"⋚",leq:"≤",leqq:"≦",leqslant:"⩽",les:"⩽",lescc:"⪨",lesdot:"⩿",lesdoto:"⪁",lesdotor:"⪃",lesg:"⋚︀",lesges:"⪓",lessapprox:"⪅",lessdot:"⋖",lesseqgtr:"⋚",lesseqqgtr:"⪋",LessEqualGreater:"⋚",LessFullEqual:"≦",LessGreater:"≶",lessgtr:"≶",LessLess:"⪡",lesssim:"≲",LessSlantEqual:"⩽",LessTilde:"≲",lfisht:"⥼",lfloor:"⌊",Lfr:"𝔏",lfr:"𝔩",lg:"≶",lgE:"⪑",lHar:"⥢",lhard:"↽",lharu:"↼",lharul:"⥪",lhblk:"▄",LJcy:"Љ",ljcy:"љ",Ll:"⋘",ll:"≪",llarr:"⇇",llcorner:"⌞",Lleftarrow:"⇚",llhard:"⥫",lltri:"◺",Lmidot:"Ŀ",lmidot:"ŀ",lmoust:"⎰",lmoustache:"⎰",lnap:"⪉",lnapprox:"⪉",lnE:"≨",lne:"⪇",lneq:"⪇",lneqq:"≨",lnsim:"⋦",loang:"⟬",loarr:"⇽",lobrk:"⟦",LongLeftArrow:"⟵",Longleftarrow:"⟸",longleftarrow:"⟵",LongLeftRightArrow:"⟷",Longleftrightarrow:"⟺",longleftrightarrow:"⟷",longmapsto:"⟼",LongRightArrow:"⟶",Longrightarrow:"⟹",longrightarrow:"⟶",looparrowleft:"↫",looparrowright:"↬",lopar:"⦅",Lopf:"𝕃",lopf:"𝕝",loplus:"⨭",lotimes:"⨴",lowast:"∗",lowbar:"_",LowerLeftArrow:"↙",LowerRightArrow:"↘",loz:"◊",lozenge:"◊",lozf:"⧫",lpar:"(",lparlt:"⦓",lrarr:"⇆",lrcorner:"⌟",lrhar:"⇋",lrhard:"⥭",lrm:"‎",lrtri:"⊿",lsaquo:"‹",Lscr:"ℒ",lscr:"𝓁",Lsh:"↰",lsh:"↰",lsim:"≲",lsime:"⪍",lsimg:"⪏",lsqb:"[",lsquo:"‘",lsquor:"‚",Lstrok:"Ł",lstrok:"ł",LT:"<",Lt:"≪",lt:"<",ltcc:"⪦",ltcir:"⩹",ltdot:"⋖",lthree:"⋋",ltimes:"⋉",ltlarr:"⥶",ltquest:"⩻",ltri:"◃",ltrie:"⊴",ltrif:"◂",ltrPar:"⦖",lurdshar:"⥊",luruhar:"⥦",lvertneqq:"≨︀",lvnE:"≨︀",macr:"¯",male:"♂",malt:"✠",maltese:"✠",Map:"⤅",map:"↦",mapsto:"↦",mapstodown:"↧",mapstoleft:"↤",mapstoup:"↥",marker:"▮",mcomma:"⨩",Mcy:"М",mcy:"м",mdash:"—",mDDot:"∺",measuredangle:"∡",MediumSpace:" ",Mellintrf:"ℳ",Mfr:"𝔐",mfr:"𝔪",mho:"℧",micro:"µ",mid:"∣",midast:"*",midcir:"⫰",middot:"·",minus:"−",minusb:"⊟",minusd:"∸",minusdu:"⨪",MinusPlus:"∓",mlcp:"⫛",mldr:"…",mnplus:"∓",models:"⊧",Mopf:"𝕄",mopf:"𝕞",mp:"∓",Mscr:"ℳ",mscr:"𝓂",mstpos:"∾",Mu:"Μ",mu:"μ",multimap:"⊸",mumap:"⊸",nabla:"∇",Nacute:"Ń",nacute:"ń",nang:"∠⃒",nap:"≉",napE:"⩰̸",napid:"≋̸",napos:"ʼn",napprox:"≉",natur:"♮",natural:"♮",naturals:"ℕ",nbsp:" ",nbump:"≎̸",nbumpe:"≏̸",ncap:"⩃",Ncaron:"Ň",ncaron:"ň",Ncedil:"Ņ",ncedil:"ņ",ncong:"≇",ncongdot:"⩭̸",ncup:"⩂",Ncy:"Н",ncy:"н",ndash:"–",ne:"≠",nearhk:"⤤",neArr:"⇗",nearr:"↗",nearrow:"↗",nedot:"≐̸",NegativeMediumSpace:"​",NegativeThickSpace:"​",NegativeThinSpace:"​",NegativeVeryThinSpace:"​",nequiv:"≢",nesear:"⤨",nesim:"≂̸",NestedGreaterGreater:"≫",NestedLessLess:"≪",NewLine:"\n",nexist:"∄",nexists:"∄",Nfr:"𝔑",nfr:"𝔫",ngE:"≧̸",nge:"≱",ngeq:"≱",ngeqq:"≧̸",ngeqslant:"⩾̸",nges:"⩾̸",nGg:"⋙̸",ngsim:"≵",nGt:"≫⃒",ngt:"≯",ngtr:"≯",nGtv:"≫̸",nhArr:"⇎",nharr:"↮",nhpar:"⫲",ni:"∋",nis:"⋼",nisd:"⋺",niv:"∋",NJcy:"Њ",njcy:"њ",nlArr:"⇍",nlarr:"↚",nldr:"‥",nlE:"≦̸",nle:"≰",nLeftarrow:"⇍",nleftarrow:"↚",nLeftrightarrow:"⇎",nleftrightarrow:"↮",nleq:"≰",nleqq:"≦̸",nleqslant:"⩽̸",nles:"⩽̸",nless:"≮",nLl:"⋘̸",nlsim:"≴",nLt:"≪⃒",nlt:"≮",nltri:"⋪",nltrie:"⋬",nLtv:"≪̸",nmid:"∤",NoBreak:"⁠",NonBreakingSpace:" ",Nopf:"ℕ",nopf:"𝕟",Not:"⫬",not:"¬",NotCongruent:"≢",NotCupCap:"≭",NotDoubleVerticalBar:"∦",NotElement:"∉",NotEqual:"≠",NotEqualTilde:"≂̸",NotExists:"∄",NotGreater:"≯",NotGreaterEqual:"≱",NotGreaterFullEqual:"≧̸",NotGreaterGreater:"≫̸",NotGreaterLess:"≹",NotGreaterSlantEqual:"⩾̸",NotGreaterTilde:"≵",NotHumpDownHump:"≎̸",NotHumpEqual:"≏̸",notin:"∉",notindot:"⋵̸",notinE:"⋹̸",notinva:"∉",notinvb:"⋷",notinvc:"⋶",NotLeftTriangle:"⋪",NotLeftTriangleBar:"⧏̸",NotLeftTriangleEqual:"⋬",NotLess:"≮",NotLessEqual:"≰",NotLessGreater:"≸",NotLessLess:"≪̸",NotLessSlantEqual:"⩽̸",NotLessTilde:"≴",NotNestedGreaterGreater:"⪢̸",NotNestedLessLess:"⪡̸",notni:"∌",notniva:"∌",notnivb:"⋾",notnivc:"⋽",NotPrecedes:"⊀",NotPrecedesEqual:"⪯̸",NotPrecedesSlantEqual:"⋠",NotReverseElement:"∌",NotRightTriangle:"⋫",NotRightTriangleBar:"⧐̸",NotRightTriangleEqual:"⋭",NotSquareSubset:"⊏̸",NotSquareSubsetEqual:"⋢",NotSquareSuperset:"⊐̸",NotSquareSupersetEqual:"⋣",NotSubset:"⊂⃒",NotSubsetEqual:"⊈",NotSucceeds:"⊁",NotSucceedsEqual:"⪰̸",NotSucceedsSlantEqual:"⋡",NotSucceedsTilde:"≿̸",NotSuperset:"⊃⃒",NotSupersetEqual:"⊉",NotTilde:"≁",NotTildeEqual:"≄",NotTildeFullEqual:"≇",NotTildeTilde:"≉",NotVerticalBar:"∤",npar:"∦",nparallel:"∦",nparsl:"⫽⃥",npart:"∂̸",npolint:"⨔",npr:"⊀",nprcue:"⋠",npre:"⪯̸",nprec:"⊀",npreceq:"⪯̸",nrArr:"⇏",nrarr:"↛",nrarrc:"⤳̸",nrarrw:"↝̸",nRightarrow:"⇏",nrightarrow:"↛",nrtri:"⋫",nrtrie:"⋭",nsc:"⊁",nsccue:"⋡",nsce:"⪰̸",Nscr:"𝒩",nscr:"𝓃",nshortmid:"∤",nshortparallel:"∦",nsim:"≁",nsime:"≄",nsimeq:"≄",nsmid:"∤",nspar:"∦",nsqsube:"⋢",nsqsupe:"⋣",nsub:"⊄",nsubE:"⫅̸",nsube:"⊈",nsubset:"⊂⃒",nsubseteq:"⊈",nsubseteqq:"⫅̸",nsucc:"⊁",nsucceq:"⪰̸",nsup:"⊅",nsupE:"⫆̸",nsupe:"⊉",nsupset:"⊃⃒",nsupseteq:"⊉",nsupseteqq:"⫆̸",ntgl:"≹",Ntilde:"Ñ",ntilde:"ñ",ntlg:"≸",ntriangleleft:"⋪",ntrianglelefteq:"⋬",ntriangleright:"⋫",ntrianglerighteq:"⋭",Nu:"Ν",nu:"ν",num:"#",numero:"№",numsp:" ",nvap:"≍⃒",nVDash:"⊯",nVdash:"⊮",nvDash:"⊭",nvdash:"⊬",nvge:"≥⃒",nvgt:">⃒",nvHarr:"⤄",nvinfin:"⧞",nvlArr:"⤂",nvle:"≤⃒",nvlt:"<⃒",nvltrie:"⊴⃒",nvrArr:"⤃",nvrtrie:"⊵⃒",nvsim:"∼⃒",nwarhk:"⤣",nwArr:"⇖",nwarr:"↖",nwarrow:"↖",nwnear:"⤧",Oacute:"Ó",oacute:"ó",oast:"⊛",ocir:"⊚",Ocirc:"Ô",ocirc:"ô",Ocy:"О",ocy:"о",odash:"⊝",Odblac:"Ő",odblac:"ő",odiv:"⨸",odot:"⊙",odsold:"⦼",OElig:"Œ",oelig:"œ",ofcir:"⦿",Ofr:"𝔒",ofr:"𝔬",ogon:"˛",Ograve:"Ò",ograve:"ò",ogt:"⧁",ohbar:"⦵",ohm:"Ω",oint:"∮",olarr:"↺",olcir:"⦾",olcross:"⦻",oline:"‾",olt:"⧀",Omacr:"Ō",omacr:"ō",Omega:"Ω",omega:"ω",Omicron:"Ο",omicron:"ο",omid:"⦶",ominus:"⊖",Oopf:"𝕆",oopf:"𝕠",opar:"⦷",OpenCurlyDoubleQuote:"“",OpenCurlyQuote:"‘",operp:"⦹",oplus:"⊕",Or:"⩔",or:"∨",orarr:"↻",ord:"⩝",order:"ℴ",orderof:"ℴ",ordf:"ª",ordm:"º",origof:"⊶",oror:"⩖",orslope:"⩗",orv:"⩛",oS:"Ⓢ",Oscr:"𝒪",oscr:"ℴ",Oslash:"Ø",oslash:"ø",osol:"⊘",Otilde:"Õ",otilde:"õ",Otimes:"⨷",otimes:"⊗",otimesas:"⨶",Ouml:"Ö",ouml:"ö",ovbar:"⌽",OverBar:"‾",OverBrace:"⏞",OverBracket:"⎴",OverParenthesis:"⏜",par:"∥",para:"¶",parallel:"∥",parsim:"⫳",parsl:"⫽",part:"∂",PartialD:"∂",Pcy:"П",pcy:"п",percnt:"%",period:".",permil:"‰",perp:"⊥",pertenk:"‱",Pfr:"𝔓",pfr:"𝔭",Phi:"Φ",phi:"φ",phiv:"ϕ",phmmat:"ℳ",phone:"☎",Pi:"Π",pi:"π",pitchfork:"⋔",piv:"ϖ",planck:"ℏ",planckh:"ℎ",plankv:"ℏ",plus:"+",plusacir:"⨣",plusb:"⊞",pluscir:"⨢",plusdo:"∔",plusdu:"⨥",pluse:"⩲",PlusMinus:"±",plusmn:"±",plussim:"⨦",plustwo:"⨧",pm:"±",Poincareplane:"ℌ",pointint:"⨕",Popf:"ℙ",popf:"𝕡",pound:"£",Pr:"⪻",pr:"≺",prap:"⪷",prcue:"≼",prE:"⪳",pre:"⪯",prec:"≺",precapprox:"⪷",preccurlyeq:"≼",Precedes:"≺",PrecedesEqual:"⪯",PrecedesSlantEqual:"≼",PrecedesTilde:"≾",preceq:"⪯",precnapprox:"⪹",precneqq:"⪵",precnsim:"⋨",precsim:"≾",Prime:"″",prime:"′",primes:"ℙ",prnap:"⪹",prnE:"⪵",prnsim:"⋨",prod:"∏",Product:"∏",profalar:"⌮",profline:"⌒",profsurf:"⌓",prop:"∝",Proportion:"∷",Proportional:"∝",propto:"∝",prsim:"≾",prurel:"⊰",Pscr:"𝒫",pscr:"𝓅",Psi:"Ψ",psi:"ψ",puncsp:" ",Qfr:"𝔔",qfr:"𝔮",qint:"⨌",Qopf:"ℚ",qopf:"𝕢",qprime:"⁗",Qscr:"𝒬",qscr:"𝓆",quaternions:"ℍ",quatint:"⨖",quest:"?",questeq:"≟",QUOT:'"',quot:'"',rAarr:"⇛",race:"∽̱",Racute:"Ŕ",racute:"ŕ",radic:"√",raemptyv:"⦳",Rang:"⟫",rang:"⟩",rangd:"⦒",range:"⦥",rangle:"⟩",raquo:"»",Rarr:"↠",rArr:"⇒",rarr:"→",rarrap:"⥵",rarrb:"⇥",rarrbfs:"⤠",rarrc:"⤳",rarrfs:"⤞",rarrhk:"↪",rarrlp:"↬",rarrpl:"⥅",rarrsim:"⥴",Rarrtl:"⤖",rarrtl:"↣",rarrw:"↝",rAtail:"⤜",ratail:"⤚",ratio:"∶",rationals:"ℚ",RBarr:"⤐",rBarr:"⤏",rbarr:"⤍",rbbrk:"❳",rbrace:"}",rbrack:"]",rbrke:"⦌",rbrksld:"⦎",rbrkslu:"⦐",Rcaron:"Ř",rcaron:"ř",Rcedil:"Ŗ",rcedil:"ŗ",rceil:"⌉",rcub:"}",Rcy:"Р",rcy:"р",rdca:"⤷",rdldhar:"⥩",rdquo:"”",rdquor:"”",rdsh:"↳",Re:"ℜ",real:"ℜ",realine:"ℛ",realpart:"ℜ",reals:"ℝ",rect:"▭",REG:"®",reg:"®",ReverseElement:"∋",ReverseEquilibrium:"⇋",ReverseUpEquilibrium:"⥯",rfisht:"⥽",rfloor:"⌋",Rfr:"ℜ",rfr:"𝔯",rHar:"⥤",rhard:"⇁",rharu:"⇀",rharul:"⥬",Rho:"Ρ",rho:"ρ",rhov:"ϱ",RightAngleBracket:"⟩",RightArrow:"→",Rightarrow:"⇒",rightarrow:"→",RightArrowBar:"⇥",RightArrowLeftArrow:"⇄",rightarrowtail:"↣",RightCeiling:"⌉",RightDoubleBracket:"⟧",RightDownTeeVector:"⥝",RightDownVector:"⇂",RightDownVectorBar:"⥕",RightFloor:"⌋",rightharpoondown:"⇁",rightharpoonup:"⇀",rightleftarrows:"⇄",rightleftharpoons:"⇌",rightrightarrows:"⇉",rightsquigarrow:"↝",RightTee:"⊢",RightTeeArrow:"↦",RightTeeVector:"⥛",rightthreetimes:"⋌",RightTriangle:"⊳",RightTriangleBar:"⧐",RightTriangleEqual:"⊵",RightUpDownVector:"⥏",RightUpTeeVector:"⥜",RightUpVector:"↾",RightUpVectorBar:"⥔",RightVector:"⇀",RightVectorBar:"⥓",ring:"˚",risingdotseq:"≓",rlarr:"⇄",rlhar:"⇌",rlm:"‏",rmoust:"⎱",rmoustache:"⎱",rnmid:"⫮",roang:"⟭",roarr:"⇾",robrk:"⟧",ropar:"⦆",Ropf:"ℝ",ropf:"𝕣",roplus:"⨮",rotimes:"⨵",RoundImplies:"⥰",rpar:")",rpargt:"⦔",rppolint:"⨒",rrarr:"⇉",Rrightarrow:"⇛",rsaquo:"›",Rscr:"ℛ",rscr:"𝓇",Rsh:"↱",rsh:"↱",rsqb:"]",rsquo:"’",rsquor:"’",rthree:"⋌",rtimes:"⋊",rtri:"▹",rtrie:"⊵",rtrif:"▸",rtriltri:"⧎",RuleDelayed:"⧴",ruluhar:"⥨",rx:"℞",Sacute:"Ś",sacute:"ś",sbquo:"‚",Sc:"⪼",sc:"≻",scap:"⪸",Scaron:"Š",scaron:"š",sccue:"≽",scE:"⪴",sce:"⪰",Scedil:"Ş",scedil:"ş",Scirc:"Ŝ",scirc:"ŝ",scnap:"⪺",scnE:"⪶",scnsim:"⋩",scpolint:"⨓",scsim:"≿",Scy:"С",scy:"с",sdot:"⋅",sdotb:"⊡",sdote:"⩦",searhk:"⤥",seArr:"⇘",searr:"↘",searrow:"↘",sect:"§",semi:";",seswar:"⤩",setminus:"∖",setmn:"∖",sext:"✶",Sfr:"𝔖",sfr:"𝔰",sfrown:"⌢",sharp:"♯",SHCHcy:"Щ",shchcy:"щ",SHcy:"Ш",shcy:"ш",ShortDownArrow:"↓",ShortLeftArrow:"←",shortmid:"∣",shortparallel:"∥",ShortRightArrow:"→",ShortUpArrow:"↑",shy:"­",Sigma:"Σ",sigma:"σ",sigmaf:"ς",sigmav:"ς",sim:"∼",simdot:"⩪",sime:"≃",simeq:"≃",simg:"⪞",simgE:"⪠",siml:"⪝",simlE:"⪟",simne:"≆",simplus:"⨤",simrarr:"⥲",slarr:"←",SmallCircle:"∘",smallsetminus:"∖",smashp:"⨳",smeparsl:"⧤",smid:"∣",smile:"⌣",smt:"⪪",smte:"⪬",smtes:"⪬︀",SOFTcy:"Ь",softcy:"ь",sol:"/",solb:"⧄",solbar:"⌿",Sopf:"𝕊",sopf:"𝕤",spades:"♠",spadesuit:"♠",spar:"∥",sqcap:"⊓",sqcaps:"⊓︀",sqcup:"⊔",sqcups:"⊔︀",Sqrt:"√",sqsub:"⊏",sqsube:"⊑",sqsubset:"⊏",sqsubseteq:"⊑",sqsup:"⊐",sqsupe:"⊒",sqsupset:"⊐",sqsupseteq:"⊒",squ:"□",Square:"□",square:"□",SquareIntersection:"⊓",SquareSubset:"⊏",SquareSubsetEqual:"⊑",SquareSuperset:"⊐",SquareSupersetEqual:"⊒",SquareUnion:"⊔",squarf:"▪",squf:"▪",srarr:"→",Sscr:"𝒮",sscr:"𝓈",ssetmn:"∖",ssmile:"⌣",sstarf:"⋆",Star:"⋆",star:"☆",starf:"★",straightepsilon:"ϵ",straightphi:"ϕ",strns:"¯",Sub:"⋐",sub:"⊂",subdot:"⪽",subE:"⫅",sube:"⊆",subedot:"⫃",submult:"⫁",subnE:"⫋",subne:"⊊",subplus:"⪿",subrarr:"⥹",Subset:"⋐",subset:"⊂",subseteq:"⊆",subseteqq:"⫅",SubsetEqual:"⊆",subsetneq:"⊊",subsetneqq:"⫋",subsim:"⫇",subsub:"⫕",subsup:"⫓",succ:"≻",succapprox:"⪸",succcurlyeq:"≽",Succeeds:"≻",SucceedsEqual:"⪰",SucceedsSlantEqual:"≽",SucceedsTilde:"≿",succeq:"⪰",succnapprox:"⪺",succneqq:"⪶",succnsim:"⋩",succsim:"≿",SuchThat:"∋",Sum:"∑",sum:"∑",sung:"♪",Sup:"⋑",sup:"⊃",sup1:"¹",sup2:"²",sup3:"³",supdot:"⪾",supdsub:"⫘",supE:"⫆",supe:"⊇",supedot:"⫄",Superset:"⊃",SupersetEqual:"⊇",suphsol:"⟉",suphsub:"⫗",suplarr:"⥻",supmult:"⫂",supnE:"⫌",supne:"⊋",supplus:"⫀",Supset:"⋑",supset:"⊃",supseteq:"⊇",supseteqq:"⫆",supsetneq:"⊋",supsetneqq:"⫌",supsim:"⫈",supsub:"⫔",supsup:"⫖",swarhk:"⤦",swArr:"⇙",swarr:"↙",swarrow:"↙",swnwar:"⤪",szlig:"ß",Tab:" ",target:"⌖",Tau:"Τ",tau:"τ",tbrk:"⎴",Tcaron:"Ť",tcaron:"ť",Tcedil:"Ţ",tcedil:"ţ",Tcy:"Т",tcy:"т",tdot:"⃛",telrec:"⌕",Tfr:"𝔗",tfr:"𝔱",there4:"∴",Therefore:"∴",therefore:"∴",Theta:"Θ",theta:"θ",thetasym:"ϑ",thetav:"ϑ",thickapprox:"≈",thicksim:"∼",ThickSpace:"  ",thinsp:" ",ThinSpace:" ",thkap:"≈",thksim:"∼",THORN:"Þ",thorn:"þ",Tilde:"∼",tilde:"˜",TildeEqual:"≃",TildeFullEqual:"≅",TildeTilde:"≈",times:"×",timesb:"⊠",timesbar:"⨱",timesd:"⨰",tint:"∭",toea:"⤨",top:"⊤",topbot:"⌶",topcir:"⫱",Topf:"𝕋",topf:"𝕥",topfork:"⫚",tosa:"⤩",tprime:"‴",TRADE:"™",trade:"™",triangle:"▵",triangledown:"▿",triangleleft:"◃",trianglelefteq:"⊴",triangleq:"≜",triangleright:"▹",trianglerighteq:"⊵",tridot:"◬",trie:"≜",triminus:"⨺",TripleDot:"⃛",triplus:"⨹",trisb:"⧍",tritime:"⨻",trpezium:"⏢",Tscr:"𝒯",tscr:"𝓉",TScy:"Ц",tscy:"ц",TSHcy:"Ћ",tshcy:"ћ",Tstrok:"Ŧ",tstrok:"ŧ",twixt:"≬",twoheadleftarrow:"↞",twoheadrightarrow:"↠",Uacute:"Ú",uacute:"ú",Uarr:"↟",uArr:"⇑",uarr:"↑",Uarrocir:"⥉",Ubrcy:"Ў",ubrcy:"ў",Ubreve:"Ŭ",ubreve:"ŭ",Ucirc:"Û",ucirc:"û",Ucy:"У",ucy:"у",udarr:"⇅",Udblac:"Ű",udblac:"ű",udhar:"⥮",ufisht:"⥾",Ufr:"𝔘",ufr:"𝔲",Ugrave:"Ù",ugrave:"ù",uHar:"⥣",uharl:"↿",uharr:"↾",uhblk:"▀",ulcorn:"⌜",ulcorner:"⌜",ulcrop:"⌏",ultri:"◸",Umacr:"Ū",umacr:"ū",uml:"¨",UnderBar:"_",UnderBrace:"⏟",UnderBracket:"⎵",UnderParenthesis:"⏝",Union:"⋃",UnionPlus:"⊎",Uogon:"Ų",uogon:"ų",Uopf:"𝕌",uopf:"𝕦",UpArrow:"↑",Uparrow:"⇑",uparrow:"↑",UpArrowBar:"⤒",UpArrowDownArrow:"⇅",UpDownArrow:"↕",Updownarrow:"⇕",updownarrow:"↕",UpEquilibrium:"⥮",upharpoonleft:"↿",upharpoonright:"↾",uplus:"⊎",UpperLeftArrow:"↖",UpperRightArrow:"↗",Upsi:"ϒ",upsi:"υ",upsih:"ϒ",Upsilon:"Υ",upsilon:"υ",UpTee:"⊥",UpTeeArrow:"↥",upuparrows:"⇈",urcorn:"⌝",urcorner:"⌝",urcrop:"⌎",Uring:"Ů",uring:"ů",urtri:"◹",Uscr:"𝒰",uscr:"𝓊",utdot:"⋰",Utilde:"Ũ",utilde:"ũ",utri:"▵",utrif:"▴",uuarr:"⇈",Uuml:"Ü",uuml:"ü",uwangle:"⦧",vangrt:"⦜",varepsilon:"ϵ",varkappa:"ϰ",varnothing:"∅",varphi:"ϕ",varpi:"ϖ",varpropto:"∝",vArr:"⇕",varr:"↕",varrho:"ϱ",varsigma:"ς",varsubsetneq:"⊊︀",varsubsetneqq:"⫋︀",varsupsetneq:"⊋︀",varsupsetneqq:"⫌︀",vartheta:"ϑ",vartriangleleft:"⊲",vartriangleright:"⊳",Vbar:"⫫",vBar:"⫨",vBarv:"⫩",Vcy:"В",vcy:"в",VDash:"⊫",Vdash:"⊩",vDash:"⊨",vdash:"⊢",Vdashl:"⫦",Vee:"⋁",vee:"∨",veebar:"⊻",veeeq:"≚",vellip:"⋮",Verbar:"‖",verbar:"|",Vert:"‖",vert:"|",VerticalBar:"∣",VerticalLine:"|",VerticalSeparator:"❘",VerticalTilde:"≀",VeryThinSpace:" ",Vfr:"𝔙",vfr:"𝔳",vltri:"⊲",vnsub:"⊂⃒",vnsup:"⊃⃒",Vopf:"𝕍",vopf:"𝕧",vprop:"∝",vrtri:"⊳",Vscr:"𝒱",vscr:"𝓋",vsubnE:"⫋︀",vsubne:"⊊︀",vsupnE:"⫌︀",vsupne:"⊋︀",Vvdash:"⊪",vzigzag:"⦚",Wcirc:"Ŵ",wcirc:"ŵ",wedbar:"⩟",Wedge:"⋀",wedge:"∧",wedgeq:"≙",weierp:"℘",Wfr:"𝔚",wfr:"𝔴",Wopf:"𝕎",wopf:"𝕨",wp:"℘",wr:"≀",wreath:"≀",Wscr:"𝒲",wscr:"𝓌",xcap:"⋂",xcirc:"◯",xcup:"⋃",xdtri:"▽",Xfr:"𝔛",xfr:"𝔵",xhArr:"⟺",xharr:"⟷",Xi:"Ξ",xi:"ξ",xlArr:"⟸",xlarr:"⟵",xmap:"⟼",xnis:"⋻",xodot:"⨀",Xopf:"𝕏",xopf:"𝕩",xoplus:"⨁",xotime:"⨂",xrArr:"⟹",xrarr:"⟶",Xscr:"𝒳",xscr:"𝓍",xsqcup:"⨆",xuplus:"⨄",xutri:"△",xvee:"⋁",xwedge:"⋀",Yacute:"Ý",yacute:"ý",YAcy:"Я",yacy:"я",Ycirc:"Ŷ",ycirc:"ŷ",Ycy:"Ы",ycy:"ы",yen:"¥",Yfr:"𝔜",yfr:"𝔶",YIcy:"Ї",yicy:"ї",Yopf:"𝕐",yopf:"𝕪",Yscr:"𝒴",yscr:"𝓎",YUcy:"Ю",yucy:"ю",Yuml:"Ÿ",yuml:"ÿ",Zacute:"Ź",zacute:"ź",Zcaron:"Ž",zcaron:"ž",Zcy:"З",zcy:"з",Zdot:"Ż",zdot:"ż",zeetrf:"ℨ",ZeroWidthSpace:"​",Zeta:"Ζ",zeta:"ζ",Zfr:"ℨ",zfr:"𝔷",ZHcy:"Ж",zhcy:"ж",zigrarr:"⇝",Zopf:"ℤ",zopf:"𝕫",Zscr:"𝒵",zscr:"𝓏",zwj:"‍",zwnj:"‌"}},{}],2:[function(e,r){"use strict";r.exports=["article","aside","button","blockquote","body","canvas","caption","col","colgroup","dd","div","dl","dt","embed","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","hr","iframe","li","map","object","ol","output","p","pre","progress","script","section","style","table","tbody","td","textarea","tfoot","th","tr","thead","ul","video"]},{}],3:[function(e,r){"use strict";function t(e,r){return e=e.source,r=r||"",function t(s,n){return s?(n=n.source||n,e=e.replace(s,n),t):new RegExp(e,r)}}var s=/[a-zA-Z_:][a-zA-Z0-9:._-]*/,n=/[^"'=<>`\x00-\x20]+/,i=/'[^']*'/,o=/"[^"]*"/,l=t(/(?:unquoted|single_quoted|double_quoted)/)("unquoted",n)("single_quoted",i)("double_quoted",o)(),a=t(/(?:\s+attr_name(?:\s*=\s*attr_value)?)/)("attr_name",s)("attr_value",l)(),c=t(/<[A-Za-z][A-Za-z0-9]*attribute*\s*\/?>/)("attribute",a)(),u=/<\/[A-Za-z][A-Za-z0-9]*\s*>/,p=//,h=/<[?].*?[?]>/,f=/]*>/,d=/])*\]\]>/,g=t(/^(?:open_tag|close_tag|comment|processing|declaration|cdata)/)("open_tag",c)("close_tag",u)("comment",p)("processing",h)("declaration",f)("cdata",d)();r.exports.HTML_TAG_RE=g},{}],4:[function(e,r){"use strict";r.exports=["coap","doi","javascript","aaa","aaas","about","acap","cap","cid","crid","data","dav","dict","dns","file","ftp","geo","go","gopher","h323","http","https","iax","icap","im","imap","info","ipp","iris","iris.beep","iris.xpc","iris.xpcs","iris.lwz","ldap","mailto","mid","msrp","msrps","mtqp","mupdate","news","nfs","ni","nih","nntp","opaquelocktoken","pop","pres","rtsp","service","session","shttp","sieve","sip","sips","sms","snmp","soap.beep","soap.beeps","tag","tel","telnet","tftp","thismessage","tn3270","tip","tv","urn","vemmi","ws","wss","xcon","xcon-userid","xmlrpc.beep","xmlrpc.beeps","xmpp","z39.50r","z39.50s","adiumxtra","afp","afs","aim","apt","attachment","aw","beshare","bitcoin","bolo","callto","chrome","chrome-extension","com-eventbrite-attendee","content","cvs","dlna-playsingle","dlna-playcontainer","dtn","dvb","ed2k","facetime","feed","finger","fish","gg","git","gizmoproject","gtalk","hcp","icon","ipn","irc","irc6","ircs","itms","jar","jms","keyparc","lastfm","ldaps","magnet","maps","market","message","mms","ms-help","msnim","mumble","mvn","notes","oid","palm","paparazzi","platform","proxy","psyc","query","res","resource","rmi","rsync","rtmp","secondlife","sftp","sgn","skype","smb","soldat","spotify","ssh","steam","svn","teamspeak","things","udp","unreal","ut2004","ventrilo","view-source","webcal","wtai","wyciwyg","xfire","xri","ymsgr"]},{}],5:[function(e,r){"use strict";r.exports={html:!1,xhtml:!1,breaks:!1,maxLevel:20,langPrefix:"language-",highlight:function(){return""}}},{}],6:[function(e,r,t){"use strict";function s(e){return 32===e}function n(e,r){return e.bMarks[r]+e.tShift[r]>=e.eMarks[r]}function i(e,r){for(var t=e.lineMax;t>r&&!(e.bMarks[r]+e.tShift[r]r&&s(e.src.charCodeAt(r));r++);return r}function l(e,r,t){for(var s=e.src.length;s>r&&e.src.charCodeAt(r)===t;r++);return r}function a(e,r,t,s){if(s>=r)return r;for(;r>s;)if(t!==e.src.charCodeAt(--r))return r+1;return r}function c(e,r,t,s,n){var i,o,l,a,c=r;if(r>=t)return"";if(c+1===t)return o=e.bMarks[c]+Math.min(e.tShift[c],s),l=n?e.bMarks[t]:e.eMarks[t-1],e.src.slice(o,l);for(a=new Array(t-r),i=0;t>c;c++,i++)o=e.bMarks[c]+Math.min(e.tShift[c],s),l=t>c+1||n?e.eMarks[c]+1:e.eMarks[c],a[i]=e.src.slice(o,l);return a.join("")}function u(e){return e.indexOf("&")>=0&&(e=e.replace(/&/g,"&")),e.indexOf("<")>=0&&(e=e.replace(/")>=0&&(e=e.replace(/>/g,">")),e.indexOf('"')>=0&&(e=e.replace(/"/g,""")),e}function p(e){return e.indexOf("\\")<0?e:e.replace(g,"$1")}function h(e){return e>=55296&&57343>=e?!1:e>=245&&255>=e?!1:192===e||193===e?!1:e>=64976&&65007>=e?!1:65535===(65535&e)||65534===(65535&e)?!1:31>=e?!1:e>=127&&159>=e?!1:e>1114111?!1:!0}function f(e){if(e>65535){e-=65536;var r=55296+(e>>10),t=56320+(1023&e);return String.fromCharCode(r,t)}return String.fromCharCode(e)}function d(e){return e.indexOf("&")<0?e:e.replace(b,function(e,r){return m.hasOwnProperty(r)?m[r]:e})}var g=/\\([\\!"#$%&'()*+,.\/:;<=>?@[\]^_`{|}~-])/g,b=/&([a-z][a-z0-9]{1,31});/gi,m=e("./common/entities");t.isWhiteSpace=s,t.isEmpty=n,t.skipEmptyLines=i,t.skipSpaces=o,t.skipChars=l,t.getLines=c,t.skipCharsBack=a,t.escapeHtml=u,t.unescapeMd=p,t.isValidEntityCode=h,t.fromCodePoint=f,t.replaceEntities=d},{"./common/entities":1}],7:[function(e,r){"use strict";function t(e){this.options=s({},l),this.state=null,this.inline=new o,this.block=new i,this.renderer=new n,this.block.inline=this.inline,e&&this.set(e)}var s=e("object-assign"),n=e("./renderer"),i=e("./parser_block"),o=e("./parser_inline"),l=e("./defaults");t.prototype.set=function(e){s(this.options,e)},t.prototype.render=function(e){var r,t,s,n,i={references:Object.create(null)};for(r=this.block.parse(e,this.options,i),s=0,n=r.length;n>s;s++)t=r[s],"inline"===t.type&&(t.children=this.inline.parse(t.content,this.options,i));return this.renderer.render(r,this.options,i)},r.exports=t},{"./defaults":5,"./parser_block":9,"./parser_inline":10,"./renderer":12,"object-assign":36}],8:[function(e,r){"use strict";function t(e,r){var t,s,n,i,o=-1,l=e.posMax,a=e.pos,c=e.tokens.length,u=e.pending,p=e.validateInsideLink;if(e.validateInsideLink)return-1;for(e.pos=r+1,e.validateInsideLink=!0,t=1;e.posr;){if(t=e.src.charCodeAt(r),10===t)return!1;if(62===t)return e.pos=r+1,e.link_content=i,!0;92===t&&n>r+1?(r++,i+=e.src[r++]):i+=e.src[r++]}return!1}for(s=0;n>r&&(t=e.src.charCodeAt(r),32!==t)&&!(32>t||127===t);)if(92===t&&n>r+1)r++,i+=e.src[r++];else{if(40===t&&(s++,s>1))break;if(41===t&&(s--,0>s))break;i+=e.src[r++]}return i.length?(e.pos=r,e.link_content=i,!0):!1}function n(e,r){var t,s,n=e.posMax,i=e.src.charCodeAt(r);if(34!==i&&39!==i&&40!==i)return!1; -for(r++,t="",40===i&&(i=41);n>r;){if(s=e.src.charCodeAt(r),s===i)return e.pos=r+1,e.link_content=t,!0;92===s&&n>r+1?(r++,t+=e.src[r++]):t+=e.src[r++]}return!1}function i(e){return e.trim().replace(/\s+/g," ").toLowerCase()}r.exports.parseLinkLabel=t,r.exports.parseLinkDestination=s,r.exports.parseLinkTitle=n,r.exports.normalizeReference=i},{}],9:[function(e,r){"use strict";function t(){this._rules=[],this._rulesParagraphTerm=[],this._rulesBlockquoteTerm=[],this._rulesListTerm=[],this.ruler=new s(this.rulesUpdate.bind(this));for(var e=0;ec)||(e.line=c=i(e,c,t),c>=t)||e.tShift[c]n&&!(s=l[n](e,c,t,!1));n++);if(!s)throw new Error("No matching rules found");if(c===e.line)throw new Error("None of rules updated state.line");if(e.tight=!u,o(e,e.line-1)&&(u=!0),c=e.line,t>c&&o(e,c)){if(u=!0,c++,t>c&&e.listMode&&o(e,c))break;e.line=c}}},t.prototype.parse=function(e,r,t){var s,i=0,o=0;return e?(e.indexOf("\r")>=0&&(e=e.replace(/\r/,"")),e.indexOf(" ")>=0&&(e=e.replace(/\u00a0/g," ")),e.indexOf("␤")>=0&&(e=e.replace(/\u2424/g,"\n")),e.indexOf(" ")>=0&&(e=e.replace(/[\n\t]/g,function(r,t){var s;return 10===e.charCodeAt(t)?(i=t+1,o=0,r):(s=" ".slice((t-i-o)%4),o=t-i+1,s)})),s=new n(e,this,[],r,t),this.tokenize(s,s.line,s.lineMax),s.tokens):""},r.exports=t},{"./helpers":6,"./ruler":13,"./rules_block/blockquote":14,"./rules_block/code":15,"./rules_block/fences":16,"./rules_block/heading":17,"./rules_block/hr":18,"./rules_block/htmlblock":19,"./rules_block/lheading":20,"./rules_block/list":21,"./rules_block/paragraph":22,"./rules_block/state_block":23,"./rules_block/table":24}],10:[function(e,r){"use strict";function t(){this._rules=[],this.textMatch=/^[^\n\\`*_\[\]!&{}$%@<>"]+/,this.ruler=new s(this.rulesUpdate.bind(this));for(var e=0;et&&!(r=s[t](e));t++);return r},t.prototype.tokenize=function(e){for(var r,t,s=this._rules,n=this._rules.length,i=e.posMax;e.post&&!(r=s[t](e));t++);if(r){if(e.pos>=i)break}else e.pending+=e.src[e.pos++]}return e.pending&&e.pushPending(),e.tokens},t.prototype.parse=function(e,r,t){var s=new n(e,this,r,t);return this.tokenize(s),s.tokens},r.exports=t},{"./ruler":13,"./rules_inline/autolink":25,"./rules_inline/backticks":26,"./rules_inline/emphasis":27,"./rules_inline/entity":28,"./rules_inline/escape":29,"./rules_inline/escape_html_char":30,"./rules_inline/htmltag":31,"./rules_inline/links":32,"./rules_inline/newline":33,"./rules_inline/state_inline":34,"./rules_inline/text":35}],11:[function(e,r){"use strict";var t=e("./rules_inline/state_inline"),s=e("./helpers").skipSpaces,n=e("./links").parseLinkLabel,i=e("./links").parseLinkDestination,o=e("./links").parseLinkTitle,l=e("./links").normalizeReference;r.exports=function(e,r,a,c){var u,p,h,f,d,g,b,m,k;if(91!==e.charCodeAt(0))return-1;if(-1===e.indexOf("]:"))return-1;if(u=new t(e,r,a,c),p=n(u,0),0>p||58!==e.charCodeAt(p+1))return-1;for(f=u.posMax,h=p+2;f>h&&(d=u.src.charCodeAt(h),32===d||10===d);h++);if(!i(u,h))return-1;for(b=u.link_content,h=u.pos,g=h,h+=1;f>h&&(d=u.src.charCodeAt(h),32===d||10===d);h++);return f>h&&g!==h&&o(u,h)?(m=u.link_content,h=u.pos):(m="",h=g),h=s(u,h),f>h&&10!==u.src.charCodeAt(h)?-1:(k=l(e.slice(1,p)),c.references[k]=c.references[k]||{title:m,href:b},h)}},{"./helpers":6,"./links":8,"./rules_inline/state_inline":34}],12:[function(e,r){"use strict";function t(e){try{return encodeURI(e)}catch(r){}return""}function s(e){try{return decodeURI(e)}catch(r){}return""}function n(e,r){return++r\n"},u.blockquote_close=function(e,r){return""+n(e,r)},u.code=function(e,r){return e[r].block?"
"+l(e[r].content)+"
"+n(e,r):""+l(e[r].content)+""},u.fence=function(e,r,t){var s,i,o=e[r],u="",p=t.langPrefix||"",h="";return o.params&&(s=o.params.split(/ +/g),h=l(c(a(s[0]))),u=' class="'+p+h+'"'),i=t.highlight(o.content,h)||l(o.content),"
"+n(e,r)},u.heading_open=function(e,r){return""},u.heading_close=function(e,r){return"\n"},u.hr=function(e,r,t){return(t.xhtml?"
":"
")+n(e,r)},u.bullet_list_open=function(){return"
    \n"},u.bullet_list_close=function(e,r){return"
"+n(e,r)},u.list_item_open=function(){return"
  • "},u.list_item_close=function(){return"
  • \n"},u.ordered_list_open=function(e,r){var t=e[r];return"1?' start="'+t.order+'"':"")+">\n"},u.ordered_list_close=function(e,r){return""+n(e,r)},u.paragraph_open=function(){return"

    "},u.paragraph_close=function(e,r){return"

    "+n(e,r)},u.link_open=function(e,r){var n=e[r].title?' title="'+l(c(e[r].title))+'"':"";return'"},u.link_close=function(){return""},u.image=function(e,r,s){var n=' src="'+l(t(e[r].src))+'"',i=e[r].title?' title="'+l(c(e[r].title))+'"':"",o=' alt="'+(e[r].alt?l(c(e[r].alt)):"")+'"',a=s.xhtml?" /":"";return""},u.table_open=function(){return"\n"},u.table_close=function(){return"
    \n"},u.tr_open=function(){return"\n"},u.tr_close=function(){return"\n"},u.th_open=function(e,r){var t=e[r];return""},u.th_close=function(){return"\n"},u.td_open=function(e,r){var t=e[r];return""},u.td_close=function(){return"\n"},u.strong_open=function(){return""},u.strong_close=function(){return""},u.em_open=function(){return""},u.em_close=function(){return""},u.hardbreak=function(e,r,t){return t.xhtml?"
    \n":"
    \n"},u.softbreak=function(e,r,t){return t.breaks?t.xhtml?"
    \n":"
    \n":"\n"},u.text=function(e,r){return e[r].content},u.htmlblock=function(e,r){return e[r].content},u.htmltag=function(e,r){return e[r].content},i.prototype.render=function(e,r){var t,s,n,i,o,l="",a=this.rules,c=[],u=!1;for(t=0,s=e.length;s>t;t++)if(i=e[t].type,n=a[i],("ordered_list_open"===i||"bullet_list_open"===i)&&(c.push(u),u=e[t].tight),("ordered_list_close"===i||"bullet_list_close"===i)&&(u=c.pop()),"blockquote_open"===i&&(c.push(u),u=!1),"blockquote_close"===i&&(u=c.pop()),"paragraph_open"!==i||!u)if("paragraph_close"===i&&u)t+1=0&&r.push(t.fn)}),r):(this.rules.forEach(function(e){r.push(e.fn)}),r)},r.exports=i},{}],14:[function(e,r){"use strict";var t=e("../helpers").skipSpaces;r.exports=function(e,r,s,n){var i,o,l,a,c,u,p,h,f,d=e.parser._rulesBlockquoteTerm,g=e.bMarks[r]+e.tShift[r],b=e.eMarks[r];if(g>b)return!1;if(62!==e.src.charCodeAt(g++))return!1;if(e.level>=e.options.maxLevel)return!1;if(n)return!0;for(32===e.src.charCodeAt(g)&&g++,e.bqMarks[r]++,e.bqLevel++,c=e.blkIndent,e.blkIndent=0,a=[e.bMarks[r]],e.bMarks[r]=g,g=b>g?t(e,g):g,o=g>=b,l=[e.tShift[r]],e.tShift[r]=g-e.bMarks[r],i=r+1;s>i&&(g=e.bMarks[i]+e.tShift[i],b=e.eMarks[i],!(g>=b));i++)if(62!==e.src.charCodeAt(g++)){if(o)break;for(f=!1,p=0,h=d.length;h>p;p++)if(d[p](e,i,s,!0)){f=!0;break}if(f)break;a.push(e.bMarks[i]),l.push(e.tShift[i])}else e.bqMarks[i]++,32===e.src.charCodeAt(g)&&g++,a.push(e.bMarks[i]),e.bMarks[i]=g,g=b>g?t(e,g):g,o=g>=b,l.push(e.tShift[i]),e.tShift[i]=g-e.bMarks[i];for(u=e.listMode,e.listMode=!1,e.tokens.push({type:"blockquote_open",level:e.level++}),e.parser.tokenize(e,r,i),e.tokens.push({type:"blockquote_close",level:--e.level}),e.listMode=u,p=0;po&&!(e.bqMarks[o]=4))break;o++,l=o}return i?!0:(e.tokens.push({type:"code",content:s(e,r,l,4+e.blkIndent,!0),block:!0,level:e.level}),e.line=o,!0)}},{"../helpers":6}],16:[function(e,r){"use strict";var t=e("../helpers").skipSpaces,s=e("../helpers").skipChars,n=e("../helpers").getLines;r.exports=function(e,r,i,o){var l,a,c,u,p,h=!1,f=e.bMarks[r]+e.tShift[r],d=e.eMarks[r];if(f+3>d)return!1;if(l=e.src.charCodeAt(f),126!==l&&96!==l)return!1;if(p=f,f=s(e,f,l),a=f-p,3>a)return!1;if(c=e.src.slice(f,d).trim(),c.indexOf("`")>=0)return!1;if(o)return!0;for(u=r;(u++,!(u>=i))&&(f=p=e.bMarks[u]+e.tShift[u],d=e.eMarks[u],!(d>f&&e.tShift[u]f&&e.bqMarks[u]f-p||(f=t(e,f),d>f)))){h=!0;break}return a=e.tShift[r],e.tokens.push({type:"fence",params:c,content:n(e,r+1,u,a,!0),level:e.level}),e.line=u+(h?1:0),!0}},{"../helpers":6}],17:[function(e,r){"use strict";var t=e("../helpers").isWhiteSpace,s=e("../helpers").skipSpaces,n=e("../helpers").skipCharsBack;r.exports=function(e,r,i,o){var l,a,c=e.bMarks[r]+e.tShift[r],u=e.eMarks[r];if(c>=u)return!1;if(l=e.src.charCodeAt(c),35!==l||c>=u)return!1;for(a=1,l=e.src.charCodeAt(++c);35===l&&u>c&&6>=a;)a++,l=e.src.charCodeAt(++c);return a>6||u>c&&!t(l)?!1:(c=s(e,c),u=n(e,u,32,c),u=n(e,u,35,c),uc&&e.tokens.push({type:"inline",content:e.src.slice(c,u).trim(),level:e.level+1}),e.tokens.push({type:"heading_close",hLevel:a,level:e.level}),e.line=r+1,!0))}},{"../helpers":6}],18:[function(e,r){"use strict";var t=e("../helpers").isWhiteSpace;r.exports=function(e,r,s,n){var i,o,l,a=e.bMarks[r],c=e.eMarks[r];if(a+=e.tShift[r],a>c)return!1;if(i=e.src.charCodeAt(a++),42!==i&&45!==i&&95!==i)return!1;for(o=1;c>a;){if(l=e.src.charCodeAt(a++),l!==i&&!t(l))return!1;l===i&&o++}return 3>o?!1:n?!0:(e.tokens.push({type:"hr",level:e.level}),e.line=r+1,!0)}},{"../helpers":6}],19:[function(e,r){"use strict";function t(e){var r=32|e;return r>=97&&122>=r}var s=e("../helpers").isEmpty,n=e("../helpers").getLines,i=e("../common/html_blocks"),o=/^<([a-zA-Z]{1,15})[\s\/>]/,l=/^<\/([a-zA-Z]{1,15})[\s>]/;r.exports=function(e,r,a,c){var u,p,h,f=e.bMarks[r],d=e.eMarks[r],g=e.tShift[r];if(f+=g,!e.options.html)return!1;if(g>3||f+2>=d||e.blkLevel>0)return!1;if(60!==e.src.charCodeAt(f))return!1;if(u=e.src.charCodeAt(f+1),33===u||63===u){if(c)return!0}else{if(47!==u&&!t(u))return!1;if(47===u){if(p=e.src.slice(f,d).match(l),!p)return!1}else if(p=e.src.slice(f,d).match(o),!p)return!1;if(i.indexOf(p[1].toLowerCase())<0)return!1;if(c)return!0}for(h=r+1;h=i?!1:e.tShift[u]3?!1:(a=e.bMarks[u]+e.tShift[u],c=e.eMarks[u],l=e.src.charCodeAt(a),45!==l&&61!==l?!1:(a=s(e,a,l),a=t(e,a),c>a?!1:o?!0:(a=e.bMarks[r]+e.tShift[r],c=n(e,e.eMarks[r],32,a),e.tokens.push({type:"heading_open",hLevel:61===l?1:2,level:e.level}),e.tokens.push({type:"inline",content:e.src.slice(a,c).trim(),level:e.level+1}),e.tokens.push({type:"heading_close",hLevel:61===l?1:2,level:e.level}),e.line=u+1,!0)))}},{"../helpers":6}],21:[function(e,r){"use strict";function t(e,r){var t,s,n;return s=e.bMarks[r]+e.tShift[r],n=e.eMarks[r],s>=n?-1:(t=e.src.charCodeAt(s++),42!==t&&45!==t&&43!==t?-1:n>s&&32!==e.src.charCodeAt(s)?-1:s)}function s(e,r){var t,s=e.bMarks[r]+e.tShift[r],n=e.eMarks[r];if(s+1>=n)return-1;if(t=e.src.charCodeAt(s++),48>t||t>57)return-1;for(;;){if(s>=n)return-1;if(t=e.src.charCodeAt(s++),!(t>=48&&57>=t)){if(41===t||46===t)break;return-1}}return n>s&&32!==e.src.charCodeAt(s)?-1:s}var n=e("../helpers").isEmpty,i=e("../helpers").skipSpaces;r.exports=function(e,r,o,l){var a,c,u,p,h,f,d,g,b,m,k,v,q,y,w,x,_,A,L,S=e.parser._rulesListTerm;if((g=s(e,r))>=0)q=!0;else{if(!((g=t(e,r))>=0))return!1;q=!1}if(e.level>=e.options.maxLevel)return!1;if(v=e.src.charCodeAt(g-1),l)return!0;for(w=e.tokens.length,q?(d=e.bMarks[r]+e.tShift[r],k=Number(e.src.substr(d,g-d-1)),e.tokens.push({type:"ordered_list_open",order:k,tight:!0,level:e.level++})):e.tokens.push({type:"bullet_list_open",tight:!0,level:e.level++}),a=r,x=!1;o>a&&(y=i(e,g),b=e.eMarks[a],m=y>=b?1:y-g,m>4&&(m=1),1>m&&(m=1),c=g-e.bMarks[a]+m,e.tokens.push({type:"list_item_open",level:e.level++}),p=e.blkIndent,h=e.tight,u=e.tShift[r],f=e.listMode,e.tShift[r]=y-e.bMarks[r],e.blkIndent=c,e.tight=!0,e.listMode=!0,e.parser.tokenize(e,r,o,!0),(!e.tight||x)&&(e.tokens[w].tight=!1),x=e.line-r>1&&n(e,e.line-1),e.blkIndent=p,e.tShift[r]=u,e.tight=h,e.listMode=f,e.tokens.push({type:"list_item_close",level:--e.level}),a=r=e.line,y=e.bMarks[r],!(a>=o));){if(n(e,a)){if(a>=o||n(e,a))break;a++}if(e.tShift[a]_;_++)if(S[_](e,a,o,!0)){L=!0;break}if(L)break;if(q){if(g=s(e,a),0>g)break}else if(g=t(e,a),0>g)break;if(v!==e.src.charCodeAt(g-1))break}return e.tokens.push(q?{type:"ordered_list_close",level:--e.level}:{type:"bullet_list_close",level:--e.level}),e.line=a,!0}},{"../helpers":6}],22:[function(e,r){"use strict";var t=e("../helpers").isEmpty,s=e("../helpers").getLines,n=e("../parser_ref");r.exports=function(e,r){var i,o,l,a,c,u,p=r+1,h=e.parser._rulesParagraphTerm;for(i=e.lineMax;i>p&&!t(e,p);p++)if(!(e.tShift[p]-e.blkIndent>3)){for(a=!1,c=0,u=h.length;u>c;c++)if(h[c](e,p,i,!0)){a=!0;break}if(a)break}for(o=s(e,r,p,e.blkIndent,!1).trim();o.length&&(l=n(o,e.parser.inline,e.options,e.env),!(0>l));)o=o.slice(l).trim();return o.length&&(e.tokens.push({type:"paragraph_open",level:e.level}),e.tokens.push({type:"inline",content:o,level:e.level+1}),e.tokens.push({type:"paragraph_close",level:e.level})),e.line=p,!0}},{"../helpers":6,"../parser_ref":11}],23:[function(e,r){"use strict";function t(e,r,t,s,n){var i,o,l,a,c,u,p;for(this.src=e,this.parser=r,this.options=s,this.env=n,this.tokens=t,this.bMarks=[],this.eMarks=[],this.tShift=[],o=this.src,u=0,p=!1,l=a=u=0,c=o.length;c>a;a++)i=o.charCodeAt(a),p||32!==i||u++,p||32===i||(this.tShift.push(u),p=!0),(13===i||10===i)&&(this.bMarks.push(l),this.eMarks.push(a),p=!1,u=0,l=a+1),13===i&&c>a&&10===o.charCodeAt(a)&&(a++,l++);for((13!==i||10!==i)&&(this.bMarks.push(l),this.eMarks.push(c),this.tShift.push(u)),this.bMarks.push(o.length),this.eMarks.push(o.length),this.tShift.push(0),this.pos=0,this.blkLevel=0,this.blkIndent=0,this.line=0,this.lineMax=this.bMarks.length-1,this.tight=!1,this.listMode=!1,this.bqLevel=0,this.bqMarks=[],l=0;ls)return!1;if(i=e.src.charCodeAt(e.bMarks[r+1]+e.tShift[r+1]),124!==i&&45!==i)return!1;if(l=t(e,r+1,/^ *\|?(( *[:-]-+[:-] *\|)+( *[:-]-+[:-] *))\|? *$/),!l)return!1;for(p=l[1].split("|"),h=[],a=0;ac&&(u=t(e,c,/^ *\|?(.*?\|.*?)\|? *$/),u);c++){for(p=u[1].split("|"),e.tokens.push({type:"tr_open",level:e.level++}),a=0;a/,i=/^<([a-zA-Z.\-]{1,25}):([^<>\x00-\x20]*)>/;r.exports=function(e){var r,o,l,a=e.pos;return 60!==e.src.charCodeAt(a)?!1:(r=e.src.slice(a),r.indexOf(">")<0?!1:(o=r.match(i))?s.indexOf(o[1].toLowerCase())<0?!1:(e.push({type:"link_open",href:o[0].slice(1,-1),level:e.level}),e.push({type:"text",content:t(o[0].slice(1,-1)),level:e.level+1}),e.push({type:"link_close",level:e.level}),e.pos+=o[0].length,!0):(l=r.match(n),l?(e.push({type:"link_open",href:"mailto:"+l[0].slice(1,-1),level:e.level}),e.push({type:"text",content:t(l[0].slice(1,-1)),level:e.level+1}),e.push({type:"link_close",level:e.level}),e.pos+=l[0].length,!0):!1))}},{"../common/url_schemas":4,"../helpers":6}],26:[function(e,r){var t=/`+/g;r.exports=function(e){var r,s,n,i,o,l=e.pos,a=e.src.charCodeAt(l);if(96!==a)return!1;for(r=l,l++,n=e.posMax;n>l&&96===e.src.charCodeAt(l);)l++;for(i=e.src.slice(r,l),t=/`+/g,t.lastIndex=l;null!==(o=t.exec(e.src));)if(o[0].length===i.length)return s=e.src.slice(l,t.lastIndex-i.length),e.push({type:"code",content:s.replace(/[ \n]+/g," ").trim(),block:!1,level:e.level}),e.pos+=2*i.length+s.length,!0;return e.pending+=i,e.pos+=i.length,!0}},{}],27:[function(e,r){"use strict";function t(e){return e>=48&&57>=e||e>=65&&90>=e||e>=97&&122>=e}function s(e,r){var s,n,i=r,o=Math.min(e.posMax,i+4),l=e.src.charCodeAt(r);if(s=0!==e.pending.length?e.pending.charCodeAt(e.pending.length-1):-1,s===l)return-1;for(;o>i&&e.src.charCodeAt(i)===l;)i++;return i>=o?-1:(n=i-r,n>=4?n:32===e.src.charCodeAt(i)?-1:95===l&&t(s)?-1:n)}function n(e,r){var s,n,i=r,o=Math.min(e.posMax,i+4),l=e.src.charCodeAt(r);for(s=0!==e.pending.length?e.pending.charCodeAt(e.pending.length-1):-1;o>i&&e.src.charCodeAt(i)===l;)i++;return n=i-r,n>=4?n:32===s?-1:95===l&&o>i&&t(e.src.charCodeAt(i))?-1:n}r.exports=function(e){var r,t,i,o,l,a,c,u,p,h,f,d,g=e.posMax,b=e.pos,m=e.src.charCodeAt(b);if(95!==m&&42!==m)return!1;if(e.validateInsideEm||e.validateInsideLink)return!1;if(r=s(e,b),0>r)return!1;if(r>=4)return e.pos+=r,e.pending+=e.src.slice(b,r),!0;if(e.level>=e.options.maxLevel)return!1;for(i=e.tokens.length,o=e.pending,l=e.validateInsideEm,e.pos=b+r,h=[r],e.validateInsideEm=!0;e.pos=1&&4>t){for(u=h.pop(),p=t;u!==p;){if(3===u){h.push(3-p);break}if(u>p){f=!0;break}if(p-=u,0===h.length)break;e.pos+=u,u=h.pop()}if(f)break;if(0===h.length){r=u,a=!0;break}e.pos+=t;continue}if(t=s(e,e.pos),t>=1){h.push(t),e.pos+=t;continue}}c=e.parser.tokenizeSingle(e),c?d=!1:(d=e.src.charCodeAt(e.pos)===m,e.pending+=e.src[e.pos],e.pos++)}return e.tokens.length=i,e.pending=o,e.validateInsideEm=l,a?(e.posMax=e.pos,e.pos=b+r,(2===r||3===r)&&e.push({type:"strong_open",level:e.level++}),(1===r||3===r)&&e.push({type:"em_open",level:e.level++}),e.parser.tokenize(e),(1===r||3===r)&&e.push({type:"em_close",level:--e.level}),(2===r||3===r)&&e.push({type:"strong_close",level:--e.level}),e.pos=e.posMax+r,e.posMax=g,!0):(e.pos=b,!1)}},{}],28:[function(e,r){"use strict";var t=e("../common/entities"),s=e("../helpers").escapeHtml,n=e("../helpers").isValidEntityCode,i=e("../helpers").fromCodePoint,o=/^&#((?:x[a-f0-9]{1,8}|[0-9]{1,8}));/i,l=/^&([a-z][a-z0-9]{1,31});/i;r.exports=function(e){var r,a,c,u=e.pos,p=e.posMax;if(38!==e.src.charCodeAt(u))return!1;if(p>u+1)if(r=e.src.charCodeAt(u+1),35===r){if(c=e.src.slice(u).match(o))return a="x"===c[1][0].toLowerCase()?parseInt(c[1].slice(1),16):parseInt(c[1],10),e.pending+=n(a)?s(i(a)):i(65533),e.pos+=c[0].length,!0}else if(c=e.src.slice(u).match(l),c&&t.hasOwnProperty(c[1]))return e.pending+=s(t[c[1]]),e.pos+=c[0].length,!0;return e.pending+="&",e.pos++,!0}},{"../common/entities":1,"../helpers":6}],29:[function(e,r){var t="\\!\"#$%&'()*+,./:;<=>?@[]^_`{|}~-".split("").map(function(e){return e.charCodeAt(0)});r.exports=function(e){var r,s=e.pos,n=e.posMax;if(92!==e.src.charCodeAt(s))return!1;if(s++,n>s){if(r=e.src.charCodeAt(s),t.indexOf(r)>=0)return e.pending+=38===r?"&":60===r?"<":62===r?">":34===r?""":e.src[s],e.pos+=2,!0;if(10===r){for(e.push({type:"hardbreak",level:e.level}),s++;n>s&&32===e.src.charCodeAt(s);)s++;return e.pos=s,!0}}return e.pending+="\\",e.pos++,!0}},{}],30:[function(e,r){r.exports=function(e){var r=e.src.charCodeAt(e.pos);if(60===r)e.pending+="<";else if(62===r)e.pending+=">";else{if(34!==r)return!1;e.pending+="""}return e.pos++,!0}},{}],31:[function(e,r){"use strict";function t(e){var r=32|e;return r>=97&&122>=r}var s=e("../common/html_re").HTML_TAG_RE;r.exports=function(e){var r,n,i,o=e.pos;return e.options.html?(i=e.posMax,60!==e.src.charCodeAt(o)||o+2>=i?!1:(r=e.src.charCodeAt(o+1),(33===r||63===r||47===r||t(r))&&(n=e.src.slice(o).match(s))?(e.push({type:"htmltag",content:e.src.slice(o,o+n[0].length),level:e.level}),e.pos+=n[0].length,!0):!1)):!1}},{"../common/html_re":3}],32:[function(e,r){"use strict";function t(e){var r,t,l,a,c,u,p,h,f=!1,d=e.posMax,g=e.pos,b=e.src.charCodeAt(g);if(33===b&&(f=!0,b=e.src.charCodeAt(++g)),91!==b)return!1;if(e.level>=e.options.maxLevel)return!1;if(r=g+1,t=s(e,g),0>t)return!1;if(u=t+1,d>u&&40===e.src.charCodeAt(u)){for(u++;d>u&&(h=e.src.charCodeAt(u),32===h||10===h);u++);if(u>=d)return!1;for(g=u,n(e,u)?(a=e.link_content,u=e.pos):a="",g=u;d>u&&(h=e.src.charCodeAt(u),32===h||10===h);u++);if(d>u&&g!==u&&i(e,u))for(c=e.link_content,u=e.pos;d>u&&(h=e.src.charCodeAt(u),32===h||10===h);u++);else c="";if(u>=d||41!==e.src.charCodeAt(u))return e.pos=r-1,!1;u++}else{for(;d>u&&(h=e.src.charCodeAt(u),32===h||10===h);u++);if(d>u&&91===e.src.charCodeAt(u)&&(g=u+1,u=s(e,u),u>=0?l=e.src.slice(g,u++):u=g-1),l||(l=e.src.slice(r,t)),p=e.env.references[o(l)],!p)return e.pos=r-1,!1;a=p.href,c=p.title}return e.pos=r,e.posMax=t,f?e.push({type:"image",src:a,title:c,alt:e.src.substr(r,t-r),level:e.level}):(e.push({type:"link_open",href:a,title:c,level:e.level++}),e.parser.tokenize(e),e.push({type:"link_close",level:--e.level})),e.pos=u,e.posMax=d,!0}var s=e("../links").parseLinkLabel,n=e("../links").parseLinkDestination,i=e("../links").parseLinkTitle,o=e("../links").normalizeReference;r.exports=t},{"../links":8}],33:[function(e,r){r.exports=function(e){var r,t,s=e.pos;if(10!==e.src.charCodeAt(s))return!1;for(r=e.pending.length-1,t=e.posMax,r>=0&&32===e.pending.charCodeAt(r)?r>=1&&32===e.pending.charCodeAt(r-1)?(e.pending=e.pending.replace(/ +$/,""),e.push({type:"hardbreak",level:e.level})):(e.pending=e.pending.slice(0,-1),e.push({type:"softbreak",level:e.level})):e.push({type:"softbreak",level:e.level}),s++;t>s&&32===e.src.charCodeAt(s);)s++;return e.pos=s,!0}},{}],34:[function(e,r){"use strict";function t(e,r,t,s){this.src=e,this.env=s,this.options=t,this.parser=r,this.tokens=[],this.pos=0,this.pending="",this.posMax=this.src.length,this.validateInsideEm=!1,this.validateInsideLink=!1,this.level=0,this.link_content="",this.pendingLevel=0}t.prototype.pushPending=function(){var e=this.pending;this.tokens.push({type:"text",content:e,level:this.pendingLevel}),this.pending=""},t.prototype.push=function(e){this.pending&&this.pushPending(),this.tokens.push(e),this.pendingLevel=this.level},r.exports=t},{}],35:[function(e,r){r.exports=function(e){var r=e.src.slice(e.pos).match(e.parser.textMatch);return r?(e.pending+=r[0],e.pos+=r[0].length,!0):!1}},{}],36:[function(e,r){"use strict";function t(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}r.exports=Object.assign||function(e){for(var r,s,n,i=t(e),o=1;o",Gt:"≫",gt:">",gtcc:"⪧",gtcir:"⩺",gtdot:"⋗",gtlPar:"⦕",gtquest:"⩼",gtrapprox:"⪆",gtrarr:"⥸",gtrdot:"⋗",gtreqless:"⋛",gtreqqless:"⪌",gtrless:"≷",gtrsim:"≳",gvertneqq:"≩︀",gvnE:"≩︀",Hacek:"ˇ",hairsp:" ",half:"½",hamilt:"ℋ",HARDcy:"Ъ",hardcy:"ъ",hArr:"⇔",harr:"↔",harrcir:"⥈",harrw:"↭",Hat:"^",hbar:"ℏ",Hcirc:"Ĥ",hcirc:"ĥ",hearts:"♥",heartsuit:"♥",hellip:"…",hercon:"⊹",Hfr:"ℌ",hfr:"𝔥",HilbertSpace:"ℋ",hksearow:"⤥",hkswarow:"⤦",hoarr:"⇿",homtht:"∻",hookleftarrow:"↩",hookrightarrow:"↪",Hopf:"ℍ",hopf:"𝕙",horbar:"―",HorizontalLine:"─",Hscr:"ℋ",hscr:"𝒽",hslash:"ℏ",Hstrok:"Ħ",hstrok:"ħ",HumpDownHump:"≎",HumpEqual:"≏",hybull:"⁃",hyphen:"‐",Iacute:"Í",iacute:"í",ic:"⁣",Icirc:"Î",icirc:"î",Icy:"И",icy:"и",Idot:"İ",IEcy:"Е",iecy:"е",iexcl:"¡",iff:"⇔",Ifr:"ℑ",ifr:"𝔦",Igrave:"Ì",igrave:"ì",ii:"ⅈ",iiiint:"⨌",iiint:"∭",iinfin:"⧜",iiota:"℩",IJlig:"IJ",ijlig:"ij",Im:"ℑ",Imacr:"Ī",imacr:"ī",image:"ℑ",ImaginaryI:"ⅈ",imagline:"ℐ",imagpart:"ℑ",imath:"ı",imof:"⊷",imped:"Ƶ",Implies:"⇒","in":"∈",incare:"℅",infin:"∞",infintie:"⧝",inodot:"ı",Int:"∬","int":"∫",intcal:"⊺",integers:"ℤ",Integral:"∫",intercal:"⊺",Intersection:"⋂",intlarhk:"⨗",intprod:"⨼",InvisibleComma:"⁣",InvisibleTimes:"⁢",IOcy:"Ё",iocy:"ё",Iogon:"Į",iogon:"į",Iopf:"𝕀",iopf:"𝕚",Iota:"Ι",iota:"ι",iprod:"⨼",iquest:"¿",Iscr:"ℐ",iscr:"𝒾",isin:"∈",isindot:"⋵",isinE:"⋹",isins:"⋴",isinsv:"⋳",isinv:"∈",it:"⁢",Itilde:"Ĩ",itilde:"ĩ",Iukcy:"І",iukcy:"і",Iuml:"Ï",iuml:"ï",Jcirc:"Ĵ",jcirc:"ĵ",Jcy:"Й",jcy:"й",Jfr:"𝔍",jfr:"𝔧",jmath:"ȷ",Jopf:"𝕁",jopf:"𝕛",Jscr:"𝒥",jscr:"𝒿",Jsercy:"Ј",jsercy:"ј",Jukcy:"Є",jukcy:"є",Kappa:"Κ",kappa:"κ",kappav:"ϰ",Kcedil:"Ķ",kcedil:"ķ",Kcy:"К",kcy:"к",Kfr:"𝔎",kfr:"𝔨",kgreen:"ĸ",KHcy:"Х",khcy:"х",KJcy:"Ќ",kjcy:"ќ",Kopf:"𝕂",kopf:"𝕜",Kscr:"𝒦",kscr:"𝓀",lAarr:"⇚",Lacute:"Ĺ",lacute:"ĺ",laemptyv:"⦴",lagran:"ℒ",Lambda:"Λ",lambda:"λ",Lang:"⟪",lang:"⟨",langd:"⦑",langle:"⟨",lap:"⪅",Laplacetrf:"ℒ",laquo:"«",Larr:"↞",lArr:"⇐",larr:"←",larrb:"⇤",larrbfs:"⤟",larrfs:"⤝",larrhk:"↩",larrlp:"↫",larrpl:"⤹",larrsim:"⥳",larrtl:"↢",lat:"⪫",lAtail:"⤛",latail:"⤙",late:"⪭",lates:"⪭︀",lBarr:"⤎",lbarr:"⤌",lbbrk:"❲",lbrace:"{",lbrack:"[",lbrke:"⦋",lbrksld:"⦏",lbrkslu:"⦍",Lcaron:"Ľ",lcaron:"ľ",Lcedil:"Ļ",lcedil:"ļ",lceil:"⌈",lcub:"{",Lcy:"Л",lcy:"л",ldca:"⤶",ldquo:"“",ldquor:"„",ldrdhar:"⥧",ldrushar:"⥋",ldsh:"↲",lE:"≦",le:"≤",LeftAngleBracket:"⟨",LeftArrow:"←",Leftarrow:"⇐",leftarrow:"←",LeftArrowBar:"⇤",LeftArrowRightArrow:"⇆",leftarrowtail:"↢",LeftCeiling:"⌈",LeftDoubleBracket:"⟦",LeftDownTeeVector:"⥡",LeftDownVector:"⇃",LeftDownVectorBar:"⥙",LeftFloor:"⌊",leftharpoondown:"↽",leftharpoonup:"↼",leftleftarrows:"⇇",LeftRightArrow:"↔",Leftrightarrow:"⇔",leftrightarrow:"↔",leftrightarrows:"⇆",leftrightharpoons:"⇋",leftrightsquigarrow:"↭",LeftRightVector:"⥎",LeftTee:"⊣",LeftTeeArrow:"↤",LeftTeeVector:"⥚",leftthreetimes:"⋋",LeftTriangle:"⊲",LeftTriangleBar:"⧏",LeftTriangleEqual:"⊴",LeftUpDownVector:"⥑",LeftUpTeeVector:"⥠",LeftUpVector:"↿",LeftUpVectorBar:"⥘",LeftVector:"↼",LeftVectorBar:"⥒",lEg:"⪋",leg:"⋚",leq:"≤",leqq:"≦",leqslant:"⩽",les:"⩽",lescc:"⪨",lesdot:"⩿",lesdoto:"⪁",lesdotor:"⪃",lesg:"⋚︀",lesges:"⪓",lessapprox:"⪅",lessdot:"⋖",lesseqgtr:"⋚",lesseqqgtr:"⪋",LessEqualGreater:"⋚",LessFullEqual:"≦",LessGreater:"≶",lessgtr:"≶",LessLess:"⪡",lesssim:"≲",LessSlantEqual:"⩽",LessTilde:"≲",lfisht:"⥼",lfloor:"⌊",Lfr:"𝔏",lfr:"𝔩",lg:"≶",lgE:"⪑",lHar:"⥢",lhard:"↽",lharu:"↼",lharul:"⥪",lhblk:"▄",LJcy:"Љ",ljcy:"љ",Ll:"⋘",ll:"≪",llarr:"⇇",llcorner:"⌞",Lleftarrow:"⇚",llhard:"⥫",lltri:"◺",Lmidot:"Ŀ",lmidot:"ŀ",lmoust:"⎰",lmoustache:"⎰",lnap:"⪉",lnapprox:"⪉",lnE:"≨",lne:"⪇",lneq:"⪇",lneqq:"≨",lnsim:"⋦",loang:"⟬",loarr:"⇽",lobrk:"⟦",LongLeftArrow:"⟵",Longleftarrow:"⟸",longleftarrow:"⟵",LongLeftRightArrow:"⟷",Longleftrightarrow:"⟺",longleftrightarrow:"⟷",longmapsto:"⟼",LongRightArrow:"⟶",Longrightarrow:"⟹",longrightarrow:"⟶",looparrowleft:"↫",looparrowright:"↬",lopar:"⦅",Lopf:"𝕃",lopf:"𝕝",loplus:"⨭",lotimes:"⨴",lowast:"∗",lowbar:"_",LowerLeftArrow:"↙",LowerRightArrow:"↘",loz:"◊",lozenge:"◊",lozf:"⧫",lpar:"(",lparlt:"⦓",lrarr:"⇆",lrcorner:"⌟",lrhar:"⇋",lrhard:"⥭",lrm:"‎",lrtri:"⊿",lsaquo:"‹",Lscr:"ℒ",lscr:"𝓁",Lsh:"↰",lsh:"↰",lsim:"≲",lsime:"⪍",lsimg:"⪏",lsqb:"[",lsquo:"‘",lsquor:"‚",Lstrok:"Ł",lstrok:"ł",LT:"<",Lt:"≪",lt:"<",ltcc:"⪦",ltcir:"⩹",ltdot:"⋖",lthree:"⋋",ltimes:"⋉",ltlarr:"⥶",ltquest:"⩻",ltri:"◃",ltrie:"⊴",ltrif:"◂",ltrPar:"⦖",lurdshar:"⥊",luruhar:"⥦",lvertneqq:"≨︀",lvnE:"≨︀",macr:"¯",male:"♂",malt:"✠",maltese:"✠",Map:"⤅",map:"↦",mapsto:"↦",mapstodown:"↧",mapstoleft:"↤",mapstoup:"↥",marker:"▮",mcomma:"⨩",Mcy:"М",mcy:"м",mdash:"—",mDDot:"∺",measuredangle:"∡",MediumSpace:" ",Mellintrf:"ℳ",Mfr:"𝔐",mfr:"𝔪",mho:"℧",micro:"µ",mid:"∣",midast:"*",midcir:"⫰",middot:"·",minus:"−",minusb:"⊟",minusd:"∸",minusdu:"⨪",MinusPlus:"∓",mlcp:"⫛",mldr:"…",mnplus:"∓",models:"⊧",Mopf:"𝕄",mopf:"𝕞",mp:"∓",Mscr:"ℳ",mscr:"𝓂",mstpos:"∾",Mu:"Μ",mu:"μ",multimap:"⊸",mumap:"⊸",nabla:"∇",Nacute:"Ń",nacute:"ń",nang:"∠⃒",nap:"≉",napE:"⩰̸",napid:"≋̸",napos:"ʼn",napprox:"≉",natur:"♮",natural:"♮",naturals:"ℕ",nbsp:" ",nbump:"≎̸",nbumpe:"≏̸",ncap:"⩃",Ncaron:"Ň",ncaron:"ň",Ncedil:"Ņ",ncedil:"ņ",ncong:"≇",ncongdot:"⩭̸",ncup:"⩂",Ncy:"Н",ncy:"н",ndash:"–",ne:"≠",nearhk:"⤤",neArr:"⇗",nearr:"↗",nearrow:"↗",nedot:"≐̸",NegativeMediumSpace:"​",NegativeThickSpace:"​",NegativeThinSpace:"​",NegativeVeryThinSpace:"​",nequiv:"≢",nesear:"⤨",nesim:"≂̸",NestedGreaterGreater:"≫",NestedLessLess:"≪",NewLine:"\n",nexist:"∄",nexists:"∄",Nfr:"𝔑",nfr:"𝔫",ngE:"≧̸",nge:"≱",ngeq:"≱",ngeqq:"≧̸",ngeqslant:"⩾̸",nges:"⩾̸",nGg:"⋙̸",ngsim:"≵",nGt:"≫⃒",ngt:"≯",ngtr:"≯",nGtv:"≫̸",nhArr:"⇎",nharr:"↮",nhpar:"⫲",ni:"∋",nis:"⋼",nisd:"⋺",niv:"∋",NJcy:"Њ",njcy:"њ",nlArr:"⇍",nlarr:"↚",nldr:"‥",nlE:"≦̸",nle:"≰",nLeftarrow:"⇍",nleftarrow:"↚",nLeftrightarrow:"⇎",nleftrightarrow:"↮",nleq:"≰",nleqq:"≦̸",nleqslant:"⩽̸",nles:"⩽̸",nless:"≮",nLl:"⋘̸",nlsim:"≴",nLt:"≪⃒",nlt:"≮",nltri:"⋪",nltrie:"⋬",nLtv:"≪̸",nmid:"∤",NoBreak:"⁠",NonBreakingSpace:" ",Nopf:"ℕ",nopf:"𝕟",Not:"⫬",not:"¬",NotCongruent:"≢",NotCupCap:"≭",NotDoubleVerticalBar:"∦",NotElement:"∉",NotEqual:"≠",NotEqualTilde:"≂̸",NotExists:"∄",NotGreater:"≯",NotGreaterEqual:"≱",NotGreaterFullEqual:"≧̸",NotGreaterGreater:"≫̸",NotGreaterLess:"≹",NotGreaterSlantEqual:"⩾̸",NotGreaterTilde:"≵",NotHumpDownHump:"≎̸",NotHumpEqual:"≏̸",notin:"∉",notindot:"⋵̸",notinE:"⋹̸",notinva:"∉",notinvb:"⋷",notinvc:"⋶",NotLeftTriangle:"⋪",NotLeftTriangleBar:"⧏̸",NotLeftTriangleEqual:"⋬",NotLess:"≮",NotLessEqual:"≰",NotLessGreater:"≸",NotLessLess:"≪̸",NotLessSlantEqual:"⩽̸",NotLessTilde:"≴",NotNestedGreaterGreater:"⪢̸",NotNestedLessLess:"⪡̸",notni:"∌",notniva:"∌",notnivb:"⋾",notnivc:"⋽",NotPrecedes:"⊀",NotPrecedesEqual:"⪯̸",NotPrecedesSlantEqual:"⋠",NotReverseElement:"∌",NotRightTriangle:"⋫",NotRightTriangleBar:"⧐̸",NotRightTriangleEqual:"⋭",NotSquareSubset:"⊏̸",NotSquareSubsetEqual:"⋢",NotSquareSuperset:"⊐̸",NotSquareSupersetEqual:"⋣",NotSubset:"⊂⃒",NotSubsetEqual:"⊈",NotSucceeds:"⊁",NotSucceedsEqual:"⪰̸",NotSucceedsSlantEqual:"⋡",NotSucceedsTilde:"≿̸",NotSuperset:"⊃⃒",NotSupersetEqual:"⊉",NotTilde:"≁",NotTildeEqual:"≄",NotTildeFullEqual:"≇",NotTildeTilde:"≉",NotVerticalBar:"∤",npar:"∦",nparallel:"∦",nparsl:"⫽⃥",npart:"∂̸",npolint:"⨔",npr:"⊀",nprcue:"⋠",npre:"⪯̸",nprec:"⊀",npreceq:"⪯̸",nrArr:"⇏",nrarr:"↛",nrarrc:"⤳̸",nrarrw:"↝̸",nRightarrow:"⇏",nrightarrow:"↛",nrtri:"⋫",nrtrie:"⋭",nsc:"⊁",nsccue:"⋡",nsce:"⪰̸",Nscr:"𝒩",nscr:"𝓃",nshortmid:"∤",nshortparallel:"∦",nsim:"≁",nsime:"≄",nsimeq:"≄",nsmid:"∤",nspar:"∦",nsqsube:"⋢",nsqsupe:"⋣",nsub:"⊄",nsubE:"⫅̸",nsube:"⊈",nsubset:"⊂⃒",nsubseteq:"⊈",nsubseteqq:"⫅̸",nsucc:"⊁",nsucceq:"⪰̸",nsup:"⊅",nsupE:"⫆̸",nsupe:"⊉",nsupset:"⊃⃒",nsupseteq:"⊉",nsupseteqq:"⫆̸",ntgl:"≹",Ntilde:"Ñ",ntilde:"ñ",ntlg:"≸",ntriangleleft:"⋪",ntrianglelefteq:"⋬",ntriangleright:"⋫",ntrianglerighteq:"⋭",Nu:"Ν",nu:"ν",num:"#",numero:"№",numsp:" ",nvap:"≍⃒",nVDash:"⊯",nVdash:"⊮",nvDash:"⊭",nvdash:"⊬",nvge:"≥⃒",nvgt:">⃒",nvHarr:"⤄",nvinfin:"⧞",nvlArr:"⤂",nvle:"≤⃒",nvlt:"<⃒",nvltrie:"⊴⃒",nvrArr:"⤃",nvrtrie:"⊵⃒",nvsim:"∼⃒",nwarhk:"⤣",nwArr:"⇖",nwarr:"↖",nwarrow:"↖",nwnear:"⤧",Oacute:"Ó",oacute:"ó",oast:"⊛",ocir:"⊚",Ocirc:"Ô",ocirc:"ô",Ocy:"О",ocy:"о",odash:"⊝",Odblac:"Ő",odblac:"ő",odiv:"⨸",odot:"⊙",odsold:"⦼",OElig:"Œ",oelig:"œ",ofcir:"⦿",Ofr:"𝔒",ofr:"𝔬",ogon:"˛",Ograve:"Ò",ograve:"ò",ogt:"⧁",ohbar:"⦵",ohm:"Ω",oint:"∮",olarr:"↺",olcir:"⦾",olcross:"⦻",oline:"‾",olt:"⧀",Omacr:"Ō",omacr:"ō",Omega:"Ω",omega:"ω",Omicron:"Ο",omicron:"ο",omid:"⦶",ominus:"⊖",Oopf:"𝕆",oopf:"𝕠",opar:"⦷",OpenCurlyDoubleQuote:"“",OpenCurlyQuote:"‘",operp:"⦹",oplus:"⊕",Or:"⩔",or:"∨",orarr:"↻",ord:"⩝",order:"ℴ",orderof:"ℴ",ordf:"ª",ordm:"º",origof:"⊶",oror:"⩖",orslope:"⩗",orv:"⩛",oS:"Ⓢ",Oscr:"𝒪",oscr:"ℴ",Oslash:"Ø",oslash:"ø",osol:"⊘",Otilde:"Õ",otilde:"õ",Otimes:"⨷",otimes:"⊗",otimesas:"⨶",Ouml:"Ö",ouml:"ö",ovbar:"⌽",OverBar:"‾",OverBrace:"⏞",OverBracket:"⎴",OverParenthesis:"⏜",par:"∥",para:"¶",parallel:"∥",parsim:"⫳",parsl:"⫽",part:"∂",PartialD:"∂",Pcy:"П",pcy:"п",percnt:"%",period:".",permil:"‰",perp:"⊥",pertenk:"‱",Pfr:"𝔓",pfr:"𝔭",Phi:"Φ",phi:"φ",phiv:"ϕ",phmmat:"ℳ",phone:"☎",Pi:"Π",pi:"π",pitchfork:"⋔",piv:"ϖ",planck:"ℏ",planckh:"ℎ",plankv:"ℏ",plus:"+",plusacir:"⨣",plusb:"⊞",pluscir:"⨢",plusdo:"∔",plusdu:"⨥",pluse:"⩲",PlusMinus:"±",plusmn:"±",plussim:"⨦",plustwo:"⨧",pm:"±",Poincareplane:"ℌ",pointint:"⨕",Popf:"ℙ",popf:"𝕡",pound:"£",Pr:"⪻",pr:"≺",prap:"⪷",prcue:"≼",prE:"⪳",pre:"⪯",prec:"≺",precapprox:"⪷",preccurlyeq:"≼",Precedes:"≺",PrecedesEqual:"⪯",PrecedesSlantEqual:"≼",PrecedesTilde:"≾",preceq:"⪯",precnapprox:"⪹",precneqq:"⪵",precnsim:"⋨",precsim:"≾",Prime:"″",prime:"′",primes:"ℙ",prnap:"⪹",prnE:"⪵",prnsim:"⋨",prod:"∏",Product:"∏",profalar:"⌮",profline:"⌒",profsurf:"⌓",prop:"∝",Proportion:"∷",Proportional:"∝",propto:"∝",prsim:"≾",prurel:"⊰",Pscr:"𝒫",pscr:"𝓅",Psi:"Ψ",psi:"ψ",puncsp:" ",Qfr:"𝔔",qfr:"𝔮",qint:"⨌",Qopf:"ℚ",qopf:"𝕢",qprime:"⁗",Qscr:"𝒬",qscr:"𝓆",quaternions:"ℍ",quatint:"⨖",quest:"?",questeq:"≟",QUOT:'"',quot:'"',rAarr:"⇛",race:"∽̱",Racute:"Ŕ",racute:"ŕ",radic:"√",raemptyv:"⦳",Rang:"⟫",rang:"⟩",rangd:"⦒",range:"⦥",rangle:"⟩",raquo:"»",Rarr:"↠",rArr:"⇒",rarr:"→",rarrap:"⥵",rarrb:"⇥",rarrbfs:"⤠",rarrc:"⤳",rarrfs:"⤞",rarrhk:"↪",rarrlp:"↬",rarrpl:"⥅",rarrsim:"⥴",Rarrtl:"⤖",rarrtl:"↣",rarrw:"↝",rAtail:"⤜",ratail:"⤚",ratio:"∶",rationals:"ℚ",RBarr:"⤐",rBarr:"⤏",rbarr:"⤍",rbbrk:"❳",rbrace:"}",rbrack:"]",rbrke:"⦌",rbrksld:"⦎",rbrkslu:"⦐",Rcaron:"Ř",rcaron:"ř",Rcedil:"Ŗ",rcedil:"ŗ",rceil:"⌉",rcub:"}",Rcy:"Р",rcy:"р",rdca:"⤷",rdldhar:"⥩",rdquo:"”",rdquor:"”",rdsh:"↳",Re:"ℜ",real:"ℜ",realine:"ℛ",realpart:"ℜ",reals:"ℝ",rect:"▭",REG:"®",reg:"®",ReverseElement:"∋",ReverseEquilibrium:"⇋",ReverseUpEquilibrium:"⥯",rfisht:"⥽",rfloor:"⌋",Rfr:"ℜ",rfr:"𝔯",rHar:"⥤",rhard:"⇁",rharu:"⇀",rharul:"⥬",Rho:"Ρ",rho:"ρ",rhov:"ϱ",RightAngleBracket:"⟩",RightArrow:"→",Rightarrow:"⇒",rightarrow:"→",RightArrowBar:"⇥",RightArrowLeftArrow:"⇄",rightarrowtail:"↣",RightCeiling:"⌉",RightDoubleBracket:"⟧",RightDownTeeVector:"⥝",RightDownVector:"⇂",RightDownVectorBar:"⥕",RightFloor:"⌋",rightharpoondown:"⇁",rightharpoonup:"⇀",rightleftarrows:"⇄",rightleftharpoons:"⇌",rightrightarrows:"⇉",rightsquigarrow:"↝",RightTee:"⊢",RightTeeArrow:"↦",RightTeeVector:"⥛",rightthreetimes:"⋌",RightTriangle:"⊳",RightTriangleBar:"⧐",RightTriangleEqual:"⊵",RightUpDownVector:"⥏",RightUpTeeVector:"⥜",RightUpVector:"↾",RightUpVectorBar:"⥔",RightVector:"⇀",RightVectorBar:"⥓",ring:"˚",risingdotseq:"≓",rlarr:"⇄",rlhar:"⇌",rlm:"‏",rmoust:"⎱",rmoustache:"⎱",rnmid:"⫮",roang:"⟭",roarr:"⇾",robrk:"⟧",ropar:"⦆",Ropf:"ℝ",ropf:"𝕣",roplus:"⨮",rotimes:"⨵",RoundImplies:"⥰",rpar:")",rpargt:"⦔",rppolint:"⨒",rrarr:"⇉",Rrightarrow:"⇛",rsaquo:"›",Rscr:"ℛ",rscr:"𝓇",Rsh:"↱",rsh:"↱",rsqb:"]",rsquo:"’",rsquor:"’",rthree:"⋌",rtimes:"⋊",rtri:"▹",rtrie:"⊵",rtrif:"▸",rtriltri:"⧎",RuleDelayed:"⧴",ruluhar:"⥨",rx:"℞",Sacute:"Ś",sacute:"ś",sbquo:"‚",Sc:"⪼",sc:"≻",scap:"⪸",Scaron:"Š",scaron:"š",sccue:"≽",scE:"⪴",sce:"⪰",Scedil:"Ş",scedil:"ş",Scirc:"Ŝ",scirc:"ŝ",scnap:"⪺",scnE:"⪶",scnsim:"⋩",scpolint:"⨓",scsim:"≿",Scy:"С",scy:"с",sdot:"⋅",sdotb:"⊡",sdote:"⩦",searhk:"⤥",seArr:"⇘",searr:"↘",searrow:"↘",sect:"§",semi:";",seswar:"⤩",setminus:"∖",setmn:"∖",sext:"✶",Sfr:"𝔖",sfr:"𝔰",sfrown:"⌢",sharp:"♯",SHCHcy:"Щ",shchcy:"щ",SHcy:"Ш",shcy:"ш",ShortDownArrow:"↓",ShortLeftArrow:"←",shortmid:"∣",shortparallel:"∥",ShortRightArrow:"→",ShortUpArrow:"↑",shy:"­",Sigma:"Σ",sigma:"σ",sigmaf:"ς",sigmav:"ς",sim:"∼",simdot:"⩪",sime:"≃",simeq:"≃",simg:"⪞",simgE:"⪠",siml:"⪝",simlE:"⪟",simne:"≆",simplus:"⨤",simrarr:"⥲",slarr:"←",SmallCircle:"∘",smallsetminus:"∖",smashp:"⨳",smeparsl:"⧤",smid:"∣",smile:"⌣",smt:"⪪",smte:"⪬",smtes:"⪬︀",SOFTcy:"Ь",softcy:"ь",sol:"/",solb:"⧄",solbar:"⌿",Sopf:"𝕊",sopf:"𝕤",spades:"♠",spadesuit:"♠",spar:"∥",sqcap:"⊓",sqcaps:"⊓︀",sqcup:"⊔",sqcups:"⊔︀",Sqrt:"√",sqsub:"⊏",sqsube:"⊑",sqsubset:"⊏",sqsubseteq:"⊑",sqsup:"⊐",sqsupe:"⊒",sqsupset:"⊐",sqsupseteq:"⊒",squ:"□",Square:"□",square:"□",SquareIntersection:"⊓",SquareSubset:"⊏",SquareSubsetEqual:"⊑",SquareSuperset:"⊐",SquareSupersetEqual:"⊒",SquareUnion:"⊔",squarf:"▪",squf:"▪",srarr:"→",Sscr:"𝒮",sscr:"𝓈",ssetmn:"∖",ssmile:"⌣",sstarf:"⋆",Star:"⋆",star:"☆",starf:"★",straightepsilon:"ϵ",straightphi:"ϕ",strns:"¯",Sub:"⋐",sub:"⊂",subdot:"⪽",subE:"⫅",sube:"⊆",subedot:"⫃",submult:"⫁",subnE:"⫋",subne:"⊊",subplus:"⪿",subrarr:"⥹",Subset:"⋐",subset:"⊂",subseteq:"⊆",subseteqq:"⫅",SubsetEqual:"⊆",subsetneq:"⊊",subsetneqq:"⫋",subsim:"⫇",subsub:"⫕",subsup:"⫓",succ:"≻",succapprox:"⪸",succcurlyeq:"≽",Succeeds:"≻",SucceedsEqual:"⪰",SucceedsSlantEqual:"≽",SucceedsTilde:"≿",succeq:"⪰",succnapprox:"⪺",succneqq:"⪶",succnsim:"⋩",succsim:"≿",SuchThat:"∋",Sum:"∑",sum:"∑",sung:"♪",Sup:"⋑",sup:"⊃",sup1:"¹",sup2:"²",sup3:"³",supdot:"⪾",supdsub:"⫘",supE:"⫆",supe:"⊇",supedot:"⫄",Superset:"⊃",SupersetEqual:"⊇",suphsol:"⟉",suphsub:"⫗",suplarr:"⥻",supmult:"⫂",supnE:"⫌",supne:"⊋",supplus:"⫀",Supset:"⋑",supset:"⊃",supseteq:"⊇",supseteqq:"⫆",supsetneq:"⊋",supsetneqq:"⫌",supsim:"⫈",supsub:"⫔",supsup:"⫖",swarhk:"⤦",swArr:"⇙",swarr:"↙",swarrow:"↙",swnwar:"⤪",szlig:"ß",Tab:" ",target:"⌖",Tau:"Τ",tau:"τ",tbrk:"⎴",Tcaron:"Ť",tcaron:"ť",Tcedil:"Ţ",tcedil:"ţ",Tcy:"Т",tcy:"т",tdot:"⃛",telrec:"⌕",Tfr:"𝔗",tfr:"𝔱",there4:"∴",Therefore:"∴",therefore:"∴",Theta:"Θ",theta:"θ",thetasym:"ϑ",thetav:"ϑ",thickapprox:"≈",thicksim:"∼",ThickSpace:"  ",thinsp:" ",ThinSpace:" ",thkap:"≈",thksim:"∼",THORN:"Þ",thorn:"þ",Tilde:"∼",tilde:"˜",TildeEqual:"≃",TildeFullEqual:"≅",TildeTilde:"≈",times:"×",timesb:"⊠",timesbar:"⨱",timesd:"⨰",tint:"∭",toea:"⤨",top:"⊤",topbot:"⌶",topcir:"⫱",Topf:"𝕋",topf:"𝕥",topfork:"⫚",tosa:"⤩",tprime:"‴",TRADE:"™",trade:"™",triangle:"▵",triangledown:"▿",triangleleft:"◃",trianglelefteq:"⊴",triangleq:"≜",triangleright:"▹",trianglerighteq:"⊵",tridot:"◬",trie:"≜",triminus:"⨺",TripleDot:"⃛",triplus:"⨹",trisb:"⧍",tritime:"⨻",trpezium:"⏢",Tscr:"𝒯",tscr:"𝓉",TScy:"Ц",tscy:"ц",TSHcy:"Ћ",tshcy:"ћ",Tstrok:"Ŧ",tstrok:"ŧ",twixt:"≬",twoheadleftarrow:"↞",twoheadrightarrow:"↠",Uacute:"Ú",uacute:"ú",Uarr:"↟",uArr:"⇑",uarr:"↑",Uarrocir:"⥉",Ubrcy:"Ў",ubrcy:"ў",Ubreve:"Ŭ",ubreve:"ŭ",Ucirc:"Û",ucirc:"û",Ucy:"У",ucy:"у",udarr:"⇅",Udblac:"Ű",udblac:"ű",udhar:"⥮",ufisht:"⥾",Ufr:"𝔘",ufr:"𝔲",Ugrave:"Ù",ugrave:"ù",uHar:"⥣",uharl:"↿",uharr:"↾",uhblk:"▀",ulcorn:"⌜",ulcorner:"⌜",ulcrop:"⌏",ultri:"◸",Umacr:"Ū",umacr:"ū",uml:"¨",UnderBar:"_",UnderBrace:"⏟",UnderBracket:"⎵",UnderParenthesis:"⏝",Union:"⋃",UnionPlus:"⊎",Uogon:"Ų",uogon:"ų",Uopf:"𝕌",uopf:"𝕦",UpArrow:"↑",Uparrow:"⇑",uparrow:"↑",UpArrowBar:"⤒",UpArrowDownArrow:"⇅",UpDownArrow:"↕",Updownarrow:"⇕",updownarrow:"↕",UpEquilibrium:"⥮",upharpoonleft:"↿",upharpoonright:"↾",uplus:"⊎",UpperLeftArrow:"↖",UpperRightArrow:"↗",Upsi:"ϒ",upsi:"υ",upsih:"ϒ",Upsilon:"Υ",upsilon:"υ",UpTee:"⊥",UpTeeArrow:"↥",upuparrows:"⇈",urcorn:"⌝",urcorner:"⌝",urcrop:"⌎",Uring:"Ů",uring:"ů",urtri:"◹",Uscr:"𝒰",uscr:"𝓊",utdot:"⋰",Utilde:"Ũ",utilde:"ũ",utri:"▵",utrif:"▴",uuarr:"⇈",Uuml:"Ü",uuml:"ü",uwangle:"⦧",vangrt:"⦜",varepsilon:"ϵ",varkappa:"ϰ",varnothing:"∅",varphi:"ϕ",varpi:"ϖ",varpropto:"∝",vArr:"⇕",varr:"↕",varrho:"ϱ",varsigma:"ς",varsubsetneq:"⊊︀",varsubsetneqq:"⫋︀",varsupsetneq:"⊋︀",varsupsetneqq:"⫌︀",vartheta:"ϑ",vartriangleleft:"⊲",vartriangleright:"⊳",Vbar:"⫫",vBar:"⫨",vBarv:"⫩",Vcy:"В",vcy:"в",VDash:"⊫",Vdash:"⊩",vDash:"⊨",vdash:"⊢",Vdashl:"⫦",Vee:"⋁",vee:"∨",veebar:"⊻",veeeq:"≚",vellip:"⋮",Verbar:"‖",verbar:"|",Vert:"‖",vert:"|",VerticalBar:"∣",VerticalLine:"|",VerticalSeparator:"❘",VerticalTilde:"≀",VeryThinSpace:" ",Vfr:"𝔙",vfr:"𝔳",vltri:"⊲",vnsub:"⊂⃒",vnsup:"⊃⃒",Vopf:"𝕍",vopf:"𝕧",vprop:"∝",vrtri:"⊳",Vscr:"𝒱",vscr:"𝓋",vsubnE:"⫋︀",vsubne:"⊊︀",vsupnE:"⫌︀",vsupne:"⊋︀",Vvdash:"⊪",vzigzag:"⦚",Wcirc:"Ŵ",wcirc:"ŵ",wedbar:"⩟",Wedge:"⋀",wedge:"∧",wedgeq:"≙",weierp:"℘",Wfr:"𝔚",wfr:"𝔴",Wopf:"𝕎",wopf:"𝕨",wp:"℘",wr:"≀",wreath:"≀",Wscr:"𝒲",wscr:"𝓌",xcap:"⋂",xcirc:"◯",xcup:"⋃",xdtri:"▽",Xfr:"𝔛",xfr:"𝔵",xhArr:"⟺",xharr:"⟷",Xi:"Ξ",xi:"ξ",xlArr:"⟸",xlarr:"⟵",xmap:"⟼",xnis:"⋻",xodot:"⨀",Xopf:"𝕏",xopf:"𝕩",xoplus:"⨁",xotime:"⨂",xrArr:"⟹",xrarr:"⟶",Xscr:"𝒳",xscr:"𝓍",xsqcup:"⨆",xuplus:"⨄",xutri:"△",xvee:"⋁",xwedge:"⋀",Yacute:"Ý",yacute:"ý",YAcy:"Я",yacy:"я",Ycirc:"Ŷ",ycirc:"ŷ",Ycy:"Ы",ycy:"ы",yen:"¥",Yfr:"𝔜",yfr:"𝔶",YIcy:"Ї",yicy:"ї",Yopf:"𝕐",yopf:"𝕪",Yscr:"𝒴",yscr:"𝓎",YUcy:"Ю",yucy:"ю",Yuml:"Ÿ",yuml:"ÿ",Zacute:"Ź",zacute:"ź",Zcaron:"Ž",zcaron:"ž",Zcy:"З",zcy:"з",Zdot:"Ż",zdot:"ż",zeetrf:"ℨ",ZeroWidthSpace:"​",Zeta:"Ζ",zeta:"ζ",Zfr:"ℨ",zfr:"𝔷",ZHcy:"Ж",zhcy:"ж",zigrarr:"⇝",Zopf:"ℤ",zopf:"𝕫",Zscr:"𝒵",zscr:"𝓏",zwj:"‍",zwnj:"‌"}},{}],2:[function(e,r){"use strict";r.exports=["article","aside","button","blockquote","body","canvas","caption","col","colgroup","dd","div","dl","dt","embed","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","hr","iframe","li","map","object","ol","output","p","pre","progress","script","section","style","table","tbody","td","textarea","tfoot","th","tr","thead","ul","video"]},{}],3:[function(e,r){"use strict";function t(e,r){return e=e.source,r=r||"",function t(n,s){return n?(s=s.source||s,e=e.replace(n,s),t):new RegExp(e,r)}}var n=/[a-zA-Z_:][a-zA-Z0-9:._-]*/,s=/[^"'=<>`\x00-\x20]+/,i=/'[^']*'/,o=/"[^"]*"/,l=t(/(?:unquoted|single_quoted|double_quoted)/)("unquoted",s)("single_quoted",i)("double_quoted",o)(),a=t(/(?:\s+attr_name(?:\s*=\s*attr_value)?)/)("attr_name",n)("attr_value",l)(),c=t(/<[A-Za-z][A-Za-z0-9]*attribute*\s*\/?>/)("attribute",a)(),u=/<\/[A-Za-z][A-Za-z0-9]*\s*>/,p=//,h=/<[?].*?[?]>/,f=/]*>/,d=/])*\]\]>/,g=t(/^(?:open_tag|close_tag|comment|processing|declaration|cdata)/)("open_tag",c)("close_tag",u)("comment",p)("processing",h)("declaration",f)("cdata",d)();r.exports.HTML_TAG_RE=g},{}],4:[function(e,r){"use strict";r.exports=["coap","doi","javascript","aaa","aaas","about","acap","cap","cid","crid","data","dav","dict","dns","file","ftp","geo","go","gopher","h323","http","https","iax","icap","im","imap","info","ipp","iris","iris.beep","iris.xpc","iris.xpcs","iris.lwz","ldap","mailto","mid","msrp","msrps","mtqp","mupdate","news","nfs","ni","nih","nntp","opaquelocktoken","pop","pres","rtsp","service","session","shttp","sieve","sip","sips","sms","snmp","soap.beep","soap.beeps","tag","tel","telnet","tftp","thismessage","tn3270","tip","tv","urn","vemmi","ws","wss","xcon","xcon-userid","xmlrpc.beep","xmlrpc.beeps","xmpp","z39.50r","z39.50s","adiumxtra","afp","afs","aim","apt","attachment","aw","beshare","bitcoin","bolo","callto","chrome","chrome-extension","com-eventbrite-attendee","content","cvs","dlna-playsingle","dlna-playcontainer","dtn","dvb","ed2k","facetime","feed","finger","fish","gg","git","gizmoproject","gtalk","hcp","icon","ipn","irc","irc6","ircs","itms","jar","jms","keyparc","lastfm","ldaps","magnet","maps","market","message","mms","ms-help","msnim","mumble","mvn","notes","oid","palm","paparazzi","platform","proxy","psyc","query","res","resource","rmi","rsync","rtmp","secondlife","sftp","sgn","skype","smb","soldat","spotify","ssh","steam","svn","teamspeak","things","udp","unreal","ut2004","ventrilo","view-source","webcal","wtai","wyciwyg","xfire","xri","ymsgr"]},{}],5:[function(e,r,t){"use strics";t.assign=function(e){for(var r=Array.prototype.slice.call(arguments,1);r.length;){var t=r.shift();if(t){if("object"!=typeof t)throw new TypeError(t+"must be non-object");for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])}}return e}},{}],6:[function(e,r){"use strict";r.exports={html:!0,xhtmlOut:!0,breaks:!1,langPrefix:"language-",linkify:!1,typographer:!1,highlight:function(){return""},maxNesting:20}},{}],7:[function(e,r){r.exports.block=["code","blockquote","fences","heading","hr","htmlblock","lheading","list","paragraph"],r.exports.inline=["autolink","backticks","emphasis","entity","escape","escape_html_char","htmltag","links","newline","text"]},{}],8:[function(e,r){"use strict";r.exports={html:!1,xhtmlOut:!1,breaks:!1,langPrefix:"language-",linkify:!1,typographer:!1,highlight:function(){return""},maxNesting:20}},{}],9:[function(e,r){"use strict";r.exports={singleQuotes:"‘’",doubleQuotes:"“”",copyright:!0,trademark:!0,registered:!0,plusminus:!0,paragraph:!0,ellipsis:!0,dupes:!0,emDashes:!0,linkify:!0}},{}],10:[function(e,r,t){"use strict";function n(e){return 32===e}function s(e,r){return e.bMarks[r]+e.tShift[r]>=e.eMarks[r]}function i(e,r){for(var t=e.lineMax;t>r&&!(e.bMarks[r]+e.tShift[r]r&&n(e.src.charCodeAt(r));r++);return r}function l(e,r,t){for(var n=e.src.length;n>r&&e.src.charCodeAt(r)===t;r++);return r}function a(e,r,t,n){if(n>=r)return r;for(;r>n;)if(t!==e.src.charCodeAt(--r))return r+1;return r}function c(e,r,t,n,s){var i,o,l,a,c=r;if(r>=t)return"";if(c+1===t)return o=e.bMarks[c]+Math.min(e.tShift[c],n),l=s?e.bMarks[t]:e.eMarks[t-1],e.src.slice(o,l);for(a=new Array(t-r),i=0;t>c;c++,i++)o=e.bMarks[c]+Math.min(e.tShift[c],n),l=t>c+1||s?e.eMarks[c]+1:e.eMarks[c],a[i]=e.src.slice(o,l);return a.join("")}function u(e){return e.indexOf("&")>=0&&(e=e.replace(/&/g,"&")),e.indexOf("<")>=0&&(e=e.replace(/")>=0&&(e=e.replace(/>/g,">")),e.indexOf('"')>=0&&(e=e.replace(/"/g,""")),e}function p(e){return e.indexOf("\\")<0?e:e.replace(g,"$1")}function h(e){return e>=55296&&57343>=e?!1:e>=245&&255>=e?!1:192===e||193===e?!1:e>=64976&&65007>=e?!1:65535===(65535&e)||65534===(65535&e)?!1:31>=e?!1:e>=127&&159>=e?!1:e>1114111?!1:!0}function f(e){if(e>65535){e-=65536;var r=55296+(e>>10),t=56320+(1023&e);return String.fromCharCode(r,t)}return String.fromCharCode(e)}function d(e){return e.indexOf("&")<0?e:e.replace(m,function(e,r){return b.hasOwnProperty(r)?b[r]:e})}var g=/\\([\\!"#$%&'()*+,.\/:;<=>?@[\]^_`{|}~-])/g,m=/&([a-z][a-z0-9]{1,31});/gi,b=e("./common/entities");t.isWhiteSpace=n,t.isEmpty=s,t.skipEmptyLines=i,t.skipSpaces=o,t.skipChars=l,t.getLines=c,t.skipCharsBack=a,t.escapeHtml=u,t.unescapeMd=p,t.isValidEntityCode=h,t.fromCodePoint=f,t.replaceEntities=d},{"./common/entities":1}],11:[function(e,r){"use strict";function t(r){this.options=n({},a),this.state=null,this.inline=new o,this.block=new i,this.renderer=new s,this.typographer=new l,this.linkifier=new l,this.linkifier.ruler.enable([],!0),this.linkifier.ruler.after(e("./rules_typographer/linkify")),this.block.inline=this.inline,this.inline.typographer=this.typographer,this.inline.linkifier=this.linkifier,r&&this.set(r)}var n=e("./common/utils").assign,s=e("./renderer"),i=e("./parser_block"),o=e("./parser_inline"),l=e("./typographer"),a=e("./defaults/remarkable"),c=e("./defaults/commonmark"),u=e("./defaults/commonmark_rules");t.prototype.set=function(e){"commonmark"===String(e).toLowerCase()?(n(this.options,c),this.inline.ruler.enable(u.inline,!0),this.block.ruler.enable(u.block,!0)):n(this.options,e) +},t.prototype.render=function(e){var r,t,n,s,i={references:Object.create(null)};for(r=this.block.parse(e,this.options,i),n=0,s=r.length;s>n;n++)t=r[n],"inline"===t.type&&(t.children=this.inline.parse(t.content,this.options,i));return this.renderer.render(r,this.options,i)},r.exports=t},{"./common/utils":5,"./defaults/commonmark":6,"./defaults/commonmark_rules":7,"./defaults/remarkable":8,"./parser_block":13,"./parser_inline":14,"./renderer":16,"./rules_typographer/linkify":41,"./typographer":43}],12:[function(e,r){"use strict";function t(e,r){var t,n,s,i,o=-1,l=e.posMax,a=e.pos,c=e.tokens.length,u=e.pending,p=e.validateInsideLink;if(e.validateInsideLink)return-1;for(e.pos=r+1,e.validateInsideLink=!0,t=1;e.posr;){if(t=e.src.charCodeAt(r),10===t)return!1;if(62===t)return e.pos=r+1,e.link_content=i,!0;92===t&&s>r+1?(r++,i+=e.src[r++]):i+=e.src[r++]}return!1}for(n=0;s>r&&(t=e.src.charCodeAt(r),32!==t)&&!(32>t||127===t);)if(92===t&&s>r+1)r++,i+=e.src[r++];else{if(40===t&&(n++,n>1))break;if(41===t&&(n--,0>n))break;i+=e.src[r++]}return i.length?(e.pos=r,e.link_content=i,!0):!1}function s(e,r){var t,n,s=e.posMax,i=e.src.charCodeAt(r);if(34!==i&&39!==i&&40!==i)return!1;for(r++,t="",40===i&&(i=41);s>r;){if(n=e.src.charCodeAt(r),n===i)return e.pos=r+1,e.link_content=t,!0;92===n&&s>r+1?(r++,t+=e.src[r++]):t+=e.src[r++]}return!1}function i(e){return e.trim().replace(/\s+/g," ").toLowerCase()}r.exports.parseLinkLabel=t,r.exports.parseLinkDestination=n,r.exports.parseLinkTitle=s,r.exports.normalizeReference=i},{}],13:[function(e,r){"use strict";function t(){this._rules=[],this._rulesParagraphTerm=[],this._rulesBlockquoteTerm=[],this._rulesListTerm=[],this.ruler=new n(this.rulesUpdate.bind(this));for(var e=0;ec)||(e.line=c=i(e,c,t),c>=t)||e.tShift[c]s&&!(n=l[s](e,c,t,!1));s++);if(!n)throw new Error("No matching rules found");if(c===e.line)throw new Error("None of rules updated state.line");if(e.tight=!u,o(e,e.line-1)&&(u=!0),c=e.line,t>c&&o(e,c)){if(u=!0,c++,t>c&&e.listMode&&o(e,c))break;e.line=c}}},t.prototype.parse=function(e,r,t){var n,i=0,o=0;return e?(e.indexOf("\r")>=0&&(e=e.replace(/\r/,"")),e.indexOf(" ")>=0&&(e=e.replace(/\u00a0/g," ")),e.indexOf("␤")>=0&&(e=e.replace(/\u2424/g,"\n")),e.indexOf(" ")>=0&&(e=e.replace(/[\n\t]/g,function(r,t){var n;return 10===e.charCodeAt(t)?(i=t+1,o=0,r):(n=" ".slice((t-i-o)%4),o=t-i+1,n)})),n=new s(e,this,[],r,t),this.tokenize(n,n.line,n.lineMax),n.tokens):""},r.exports=t},{"./helpers":10,"./ruler":17,"./rules_block/blockquote":18,"./rules_block/code":19,"./rules_block/fences":20,"./rules_block/heading":21,"./rules_block/hr":22,"./rules_block/htmlblock":23,"./rules_block/lheading":24,"./rules_block/list":25,"./rules_block/paragraph":26,"./rules_block/state_block":27,"./rules_block/table":28}],14:[function(e,r){"use strict";function t(){this._rules=[],this.textMatch=/^[^\n\\`*_\[\]!&{}$%@<>"~]+/,this.ruler=new n(this.rulesUpdate.bind(this));for(var e=0;et&&!(r=n[t](e));t++);return r},t.prototype.tokenize=function(e){for(var r,t,n=this._rules,s=this._rules.length,i=e.posMax;e.post&&!(r=n[t](e));t++);if(r){if(e.pos>=i)break}else e.pending+=e.src[e.pos++]}return e.pending&&e.pushPending(),e.tokens},t.prototype.parse=function(e,r,t){var n=new s(e,this,r,t);return this.tokenize(n),r.linkify&&this.linkifier.process(n),r.typographer&&this.typographer.process(n),n.tokens},r.exports=t},{"./ruler":17,"./rules_inline/autolink":29,"./rules_inline/backticks":30,"./rules_inline/del":31,"./rules_inline/emphasis":32,"./rules_inline/entity":33,"./rules_inline/escape":34,"./rules_inline/escape_html_char":35,"./rules_inline/htmltag":36,"./rules_inline/links":37,"./rules_inline/newline":38,"./rules_inline/state_inline":39,"./rules_inline/text":40}],15:[function(e,r){"use strict";var t=e("./rules_inline/state_inline"),n=e("./helpers").skipSpaces,s=e("./links").parseLinkLabel,i=e("./links").parseLinkDestination,o=e("./links").parseLinkTitle,l=e("./links").normalizeReference;r.exports=function(e,r,a,c){var u,p,h,f,d,g,m,b,v;if(91!==e.charCodeAt(0))return-1;if(-1===e.indexOf("]:"))return-1;if(u=new t(e,r,a,c),p=s(u,0),0>p||58!==e.charCodeAt(p+1))return-1;for(f=u.posMax,h=p+2;f>h&&(d=u.src.charCodeAt(h),32===d||10===d);h++);if(!i(u,h))return-1;for(m=u.link_content,h=u.pos,g=h,h+=1;f>h&&(d=u.src.charCodeAt(h),32===d||10===d);h++);return f>h&&g!==h&&o(u,h)?(b=u.link_content,h=u.pos):(b="",h=g),h=n(u,h),f>h&&10!==u.src.charCodeAt(h)?-1:(v=l(e.slice(1,p)),c.references[v]=c.references[v]||{title:b,href:m},h)}},{"./helpers":10,"./links":12,"./rules_inline/state_inline":39}],16:[function(e,r){"use strict";function t(e){try{return encodeURI(e)}catch(r){}return""}function n(e){try{return decodeURI(e)}catch(r){}return""}function s(e,r){return++r\n"},u.blockquote_close=function(e,r){return""+s(e,r)},u.code=function(e,r){return e[r].block?"
    "+l(e[r].content)+"
    "+s(e,r):""+l(e[r].content)+""},u.fence=function(e,r,t){var n,i,o=e[r],u="",p=t.langPrefix||"",h="";return o.params&&(n=o.params.split(/ +/g),h=l(c(a(n[0]))),u=' class="'+p+h+'"'),i=t.highlight(o.content,h)||l(o.content),"
    "+i+"
    "+s(e,r)},u.heading_open=function(e,r){return""},u.heading_close=function(e,r){return"\n"},u.hr=function(e,r,t){return(t.xhtmlOut?"
    ":"
    ")+s(e,r)},u.bullet_list_open=function(){return"
      \n"},u.bullet_list_close=function(e,r){return"
    "+s(e,r)},u.list_item_open=function(){return"
  • "},u.list_item_close=function(){return"
  • \n"},u.ordered_list_open=function(e,r){var t=e[r];return"1?' start="'+t.order+'"':"")+">\n"},u.ordered_list_close=function(e,r){return""+s(e,r)},u.paragraph_open=function(){return"

    "},u.paragraph_close=function(e,r){return"

    "+s(e,r)},u.link_open=function(e,r){var s=e[r].title?' title="'+l(c(e[r].title))+'"':"";return'"},u.link_close=function(){return""},u.image=function(e,r,n){var s=' src="'+l(t(e[r].src))+'"',i=e[r].title?' title="'+l(c(e[r].title))+'"':"",o=' alt="'+(e[r].alt?l(c(e[r].alt)):"")+'"',a=n.xhtmlOut?" /":"";return""},u.table_open=function(){return"\n"},u.table_close=function(){return"
    \n"},u.tr_open=function(){return"\n"},u.tr_close=function(){return"\n"},u.th_open=function(e,r){var t=e[r];return""},u.th_close=function(){return"\n"},u.td_open=function(e,r){var t=e[r];return""},u.td_close=function(){return"\n"},u.strong_open=function(){return""},u.strong_close=function(){return""},u.em_open=function(){return""},u.em_close=function(){return""},u.del_open=function(){return""},u.del_close=function(){return""},u.hardbreak=function(e,r,t){return t.xhtmlOut?"
    \n":"
    \n"},u.softbreak=function(e,r,t){return t.breaks?t.xhtmlOut?"
    \n":"
    \n":"\n"},u.text=function(e,r){return e[r].content},u.htmlblock=function(e,r){return e[r].content},u.htmltag=function(e,r){return e[r].content},i.prototype.render=function(e,r){var t,n,s,i,o,l="",a=this.rules,c=[],u=!1;for(t=0,n=e.length;n>t;t++)if(i=e[t].type,s=a[i],("ordered_list_open"===i||"bullet_list_open"===i)&&(c.push(u),u=e[t].tight),("ordered_list_close"===i||"bullet_list_close"===i)&&(u=c.pop()),"blockquote_open"===i&&(c.push(u),u=!1),"blockquote_close"===i&&(u=c.pop()),"paragraph_open"!==i||!u)if("paragraph_close"===i&&u)t+1=0&&t.enabled&&r.push(t.fn)}),r):(this.rules.forEach(function(e){e.enabled&&r.push(e.fn)}),r)},i.prototype.enable=function(e,r){Array.isArray(e)||(e=[e]),r&&this.rules.forEach(function(e){e.enabled=!1}),e.forEach(function(e){var r=this.find(e);if(0>r)throw new Error("Rules namager: invalid rule name "+e);this.rules[r].enabled=!0},this),this.compile()},i.prototype.disable=function(e){Array.isArray(e)||(e=[e]),e.forEach(function(e){var r=this.find(e);if(0>r)throw new Error("Rules namager: invalid rule name "+e);this.rules[r].enabled=!1},this),this.compile()},r.exports=i},{}],18:[function(e,r){"use strict";var t=e("../helpers").skipSpaces;r.exports=function(e,r,n,s){var i,o,l,a,c,u,p,h,f,d=e.parser._rulesBlockquoteTerm,g=e.bMarks[r]+e.tShift[r],m=e.eMarks[r];if(g>m)return!1;if(62!==e.src.charCodeAt(g++))return!1;if(e.level>=e.options.maxNesting)return!1;if(s)return!0;for(32===e.src.charCodeAt(g)&&g++,e.bqMarks[r]++,e.bqLevel++,c=e.blkIndent,e.blkIndent=0,a=[e.bMarks[r]],e.bMarks[r]=g,g=m>g?t(e,g):g,o=g>=m,l=[e.tShift[r]],e.tShift[r]=g-e.bMarks[r],i=r+1;n>i&&(g=e.bMarks[i]+e.tShift[i],m=e.eMarks[i],!(g>=m));i++)if(62!==e.src.charCodeAt(g++)){if(o)break;for(f=!1,p=0,h=d.length;h>p;p++)if(d[p](e,i,n,!0)){f=!0;break}if(f)break;a.push(e.bMarks[i]),l.push(e.tShift[i])}else e.bqMarks[i]++,32===e.src.charCodeAt(g)&&g++,a.push(e.bMarks[i]),e.bMarks[i]=g,g=m>g?t(e,g):g,o=g>=m,l.push(e.tShift[i]),e.tShift[i]=g-e.bMarks[i];for(u=e.listMode,e.listMode=!1,e.tokens.push({type:"blockquote_open",level:e.level++}),e.parser.tokenize(e,r,i),e.tokens.push({type:"blockquote_close",level:--e.level}),e.listMode=u,p=0;po&&!(e.bqMarks[o]=4))break;o++,l=o}return i?!0:(e.tokens.push({type:"code",content:n(e,r,l,4+e.blkIndent,!0),block:!0,level:e.level}),e.line=o,!0)}},{"../helpers":10}],20:[function(e,r){"use strict";var t=e("../helpers").skipSpaces,n=e("../helpers").skipChars,s=e("../helpers").getLines;r.exports=function(e,r,i,o){var l,a,c,u,p,h=!1,f=e.bMarks[r]+e.tShift[r],d=e.eMarks[r];if(f+3>d)return!1;if(l=e.src.charCodeAt(f),126!==l&&96!==l)return!1;if(p=f,f=n(e,f,l),a=f-p,3>a)return!1;if(c=e.src.slice(f,d).trim(),c.indexOf("`")>=0)return!1;if(o)return!0;for(u=r;(u++,!(u>=i))&&(f=p=e.bMarks[u]+e.tShift[u],d=e.eMarks[u],!(d>f&&e.tShift[u]f&&e.bqMarks[u]f-p||(f=t(e,f),d>f)))){h=!0;break}return a=e.tShift[r],e.tokens.push({type:"fence",params:c,content:s(e,r+1,u,a,!0),level:e.level}),e.line=u+(h?1:0),!0}},{"../helpers":10}],21:[function(e,r){"use strict";var t=e("../helpers").isWhiteSpace,n=e("../helpers").skipSpaces,s=e("../helpers").skipCharsBack;r.exports=function(e,r,i,o){var l,a,c=e.bMarks[r]+e.tShift[r],u=e.eMarks[r];if(c>=u)return!1;if(l=e.src.charCodeAt(c),35!==l||c>=u)return!1;for(a=1,l=e.src.charCodeAt(++c);35===l&&u>c&&6>=a;)a++,l=e.src.charCodeAt(++c);return a>6||u>c&&!t(l)?!1:(c=n(e,c),u=s(e,u,32,c),u=s(e,u,35,c),uc&&e.tokens.push({type:"inline",content:e.src.slice(c,u).trim(),level:e.level+1}),e.tokens.push({type:"heading_close",hLevel:a,level:e.level}),e.line=r+1,!0))}},{"../helpers":10}],22:[function(e,r){"use strict";var t=e("../helpers").isWhiteSpace;r.exports=function(e,r,n,s){var i,o,l,a=e.bMarks[r],c=e.eMarks[r];if(a+=e.tShift[r],a>c)return!1;if(i=e.src.charCodeAt(a++),42!==i&&45!==i&&95!==i)return!1;for(o=1;c>a;){if(l=e.src.charCodeAt(a++),l!==i&&!t(l))return!1;l===i&&o++}return 3>o?!1:s?!0:(e.tokens.push({type:"hr",level:e.level}),e.line=r+1,!0)}},{"../helpers":10}],23:[function(e,r){"use strict";function t(e){var r=32|e;return r>=97&&122>=r}var n=e("../helpers").isEmpty,s=e("../helpers").getLines,i=e("../common/html_blocks"),o=/^<([a-zA-Z]{1,15})[\s\/>]/,l=/^<\/([a-zA-Z]{1,15})[\s>]/;r.exports=function(e,r,a,c){var u,p,h,f=e.bMarks[r],d=e.eMarks[r],g=e.tShift[r];if(f+=g,!e.options.html)return!1;if(g>3||f+2>=d||e.blkLevel>0)return!1;if(60!==e.src.charCodeAt(f))return!1;if(u=e.src.charCodeAt(f+1),33===u||63===u){if(c)return!0}else{if(47!==u&&!t(u))return!1;if(47===u){if(p=e.src.slice(f,d).match(l),!p)return!1}else if(p=e.src.slice(f,d).match(o),!p)return!1;if(i.indexOf(p[1].toLowerCase())<0)return!1;if(c)return!0}for(h=r+1;h=i?!1:e.tShift[u]3?!1:(a=e.bMarks[u]+e.tShift[u],c=e.eMarks[u],l=e.src.charCodeAt(a),45!==l&&61!==l?!1:(a=n(e,a,l),a=t(e,a),c>a?!1:o?!0:(a=e.bMarks[r]+e.tShift[r],c=s(e,e.eMarks[r],32,a),e.tokens.push({type:"heading_open",hLevel:61===l?1:2,level:e.level}),e.tokens.push({type:"inline",content:e.src.slice(a,c).trim(),level:e.level+1}),e.tokens.push({type:"heading_close",hLevel:61===l?1:2,level:e.level}),e.line=u+1,!0)))}},{"../helpers":10}],25:[function(e,r){"use strict";function t(e,r){var t,n,s;return n=e.bMarks[r]+e.tShift[r],s=e.eMarks[r],n>=s?-1:(t=e.src.charCodeAt(n++),42!==t&&45!==t&&43!==t?-1:s>n&&32!==e.src.charCodeAt(n)?-1:n)}function n(e,r){var t,n=e.bMarks[r]+e.tShift[r],s=e.eMarks[r];if(n+1>=s)return-1;if(t=e.src.charCodeAt(n++),48>t||t>57)return-1;for(;;){if(n>=s)return-1;if(t=e.src.charCodeAt(n++),!(t>=48&&57>=t)){if(41===t||46===t)break;return-1}}return s>n&&32!==e.src.charCodeAt(n)?-1:n}var s=e("../helpers").isEmpty,i=e("../helpers").skipSpaces;r.exports=function(e,r,o,l){var a,c,u,p,h,f,d,g,m,b,v,k,y,x,w,q,A,_,C,L=e.parser._rulesListTerm;if((g=n(e,r))>=0)y=!0;else{if(!((g=t(e,r))>=0))return!1;y=!1}if(e.level>=e.options.maxNesting)return!1;if(k=e.src.charCodeAt(g-1),l)return!0;for(w=e.tokens.length,y?(d=e.bMarks[r]+e.tShift[r],v=Number(e.src.substr(d,g-d-1)),e.tokens.push({type:"ordered_list_open",order:v,tight:!0,level:e.level++})):e.tokens.push({type:"bullet_list_open",tight:!0,level:e.level++}),a=r,q=!1;o>a&&(x=i(e,g),m=e.eMarks[a],b=x>=m?1:x-g,b>4&&(b=1),1>b&&(b=1),c=g-e.bMarks[a]+b,e.tokens.push({type:"list_item_open",level:e.level++}),p=e.blkIndent,h=e.tight,u=e.tShift[r],f=e.listMode,e.tShift[r]=x-e.bMarks[r],e.blkIndent=c,e.tight=!0,e.listMode=!0,e.parser.tokenize(e,r,o,!0),(!e.tight||q)&&(e.tokens[w].tight=!1),q=e.line-r>1&&s(e,e.line-1),e.blkIndent=p,e.tShift[r]=u,e.tight=h,e.listMode=f,e.tokens.push({type:"list_item_close",level:--e.level}),a=r=e.line,x=e.bMarks[r],!(a>=o));){if(s(e,a)){if(a>=o||s(e,a))break;a++}if(e.tShift[a]A;A++)if(L[A](e,a,o,!0)){C=!0;break}if(C)break;if(y){if(g=n(e,a),0>g)break}else if(g=t(e,a),0>g)break;if(k!==e.src.charCodeAt(g-1))break}return e.tokens.push(y?{type:"ordered_list_close",level:--e.level}:{type:"bullet_list_close",level:--e.level}),e.line=a,!0}},{"../helpers":10}],26:[function(e,r){"use strict";var t=e("../helpers").isEmpty,n=e("../helpers").getLines,s=e("../parser_ref");r.exports=function(e,r){var i,o,l,a,c,u,p=r+1,h=e.parser._rulesParagraphTerm;for(i=e.lineMax;i>p&&!t(e,p);p++)if(!(e.tShift[p]-e.blkIndent>3)){for(a=!1,c=0,u=h.length;u>c;c++)if(h[c](e,p,i,!0)){a=!0;break}if(a)break}for(o=n(e,r,p,e.blkIndent,!1).trim();o.length&&(l=s(o,e.parser.inline,e.options,e.env),!(0>l));)o=o.slice(l).trim();return o.length&&(e.tokens.push({type:"paragraph_open",level:e.level}),e.tokens.push({type:"inline",content:o,level:e.level+1}),e.tokens.push({type:"paragraph_close",level:e.level})),e.line=p,!0}},{"../helpers":10,"../parser_ref":15}],27:[function(e,r){"use strict";function t(e,r,t,n,s){var i,o,l,a,c,u,p;for(this.src=e,this.parser=r,this.options=n,this.env=s,this.tokens=t,this.bMarks=[],this.eMarks=[],this.tShift=[],o=this.src,u=0,p=!1,l=a=u=0,c=o.length;c>a;a++)i=o.charCodeAt(a),p||32!==i||u++,p||32===i||(this.tShift.push(u),p=!0),(13===i||10===i)&&(this.bMarks.push(l),this.eMarks.push(a),p=!1,u=0,l=a+1),13===i&&c>a&&10===o.charCodeAt(a)&&(a++,l++);for((13!==i||10!==i)&&(this.bMarks.push(l),this.eMarks.push(c),this.tShift.push(u)),this.bMarks.push(o.length),this.eMarks.push(o.length),this.tShift.push(0),this.pos=0,this.blkLevel=0,this.blkIndent=0,this.line=0,this.lineMax=this.bMarks.length-1,this.tight=!1,this.listMode=!1,this.bqLevel=0,this.bqMarks=[],l=0;ln)return!1;if(i=e.src.charCodeAt(e.bMarks[r+1]+e.tShift[r+1]),124!==i&&45!==i)return!1;if(l=t(e,r+1,/^ *\|?(( *[:-]-+[:-] *\|)+( *[:-]-+[:-] *))\|? *$/),!l)return!1;for(p=l[1].split("|"),h=[],a=0;ac&&(u=t(e,c,/^ *\|?(.*?\|.*?)\|? *$/),u);c++){for(p=u[1].split("|"),e.tokens.push({type:"tr_open",level:e.level++}),a=0;a/,i=/^<([a-zA-Z.\-]{1,25}):([^<>\x00-\x20]*)>/;r.exports=function(e){var r,o,l,a=e.pos;return 60!==e.src.charCodeAt(a)?!1:(r=e.src.slice(a),r.indexOf(">")<0?!1:(o=r.match(i))?n.indexOf(o[1].toLowerCase())<0?!1:(e.push({type:"link_open",href:o[0].slice(1,-1),level:e.level}),e.push({type:"text",content:t(o[0].slice(1,-1)),level:e.level+1}),e.push({type:"link_close",level:e.level}),e.pos+=o[0].length,!0):(l=r.match(s),l?(e.push({type:"link_open",href:"mailto:"+l[0].slice(1,-1),level:e.level}),e.push({type:"text",content:t(l[0].slice(1,-1)),level:e.level+1}),e.push({type:"link_close",level:e.level}),e.pos+=l[0].length,!0):!1))}},{"../common/url_schemas":4,"../helpers":10}],30:[function(e,r){var t=/`+/g;r.exports=function(e){var r,n,s,i,o,l=e.pos,a=e.src.charCodeAt(l);if(96!==a)return!1;for(r=l,l++,s=e.posMax;s>l&&96===e.src.charCodeAt(l);)l++;for(i=e.src.slice(r,l),t=/`+/g,t.lastIndex=l;null!==(o=t.exec(e.src));)if(o[0].length===i.length)return n=e.src.slice(l,t.lastIndex-i.length),e.push({type:"code",content:n.replace(/[ \n]+/g," ").trim(),block:!1,level:e.level}),e.pos+=2*i.length+n.length,!0;return e.pending+=i,e.pos+=i.length,!0}},{}],31:[function(e,r){"use strict";r.exports=function(e){var r,t,n,s,i,o,l,a,c,u=e.posMax,p=e.pos;if(126!==e.src.charCodeAt(p))return!1;if(p+4>=u)return!1;if(126!==e.src.charCodeAt(p+1))return!1;if(e.validateInsideEm||e.validateInsideLink)return!1;if(e.level>=e.options.level)return!1;if(a=0!==e.pending.length?e.pending.charCodeAt(e.pending.length-1):-1,c=e.src.charCodeAt(p+2),126===a)return!1;if(126===c)return!1;if(32===c)return!1;for(o=p+2;u>o&&126===e.src.charCodeAt(o);)o++;if(o!==p+2)return e.pos+=o-p,e.pending+=e.src.slice(p,o),!0;for(r=e.tokens.length,t=e.pending,n=e.validateInsideEm,e.pos=p+2,e.validateInsideEm=!0,l=1;e.pos+1=l))){s=!0;break}i=e.parser.tokenizeSingle(e),i||(e.pending+=e.src[e.pos],e.pos++)}return e.tokens.length=r,e.pending=t,e.validateInsideEm=n,s?(e.posMax=e.pos,e.pos=p+2,e.push({type:"del_open",level:e.level++}),e.parser.tokenize(e),e.push({type:"del_close",level:--e.level}),e.pos=e.posMax+2,e.posMax=u,!0):(e.pos=p,!1)}},{}],32:[function(e,r){"use strict";function t(e){return e>=48&&57>=e||e>=65&&90>=e||e>=97&&122>=e}function n(e,r){var n,s,i=r,o=e.posMax,l=e.src.charCodeAt(r);if(n=0!==e.pending.length?e.pending.charCodeAt(e.pending.length-1):-1,n===l)return-1;for(;o>i&&e.src.charCodeAt(i)===l;)i++;return i>=o?-1:(s=i-r,s>=4?s:32===e.src.charCodeAt(i)?-1:95===l&&t(n)?-1:s)}function s(e,r){var n,s,i=r,o=e.posMax,l=e.src.charCodeAt(r);for(n=0!==e.pending.length?e.pending.charCodeAt(e.pending.length-1):-1;o>i&&e.src.charCodeAt(i)===l;)i++;return s=i-r,s>=4?s:32===n?-1:95===l&&o>i&&t(e.src.charCodeAt(i))?-1:s}r.exports=function(e){var r,t,i,o,l,a,c,u,p,h,f,d,g=e.posMax,m=e.pos,b=e.src.charCodeAt(m);if(95!==b&&42!==b)return!1;if(e.validateInsideEm||e.validateInsideLink)return!1;if(r=n(e,m),0>r)return!1;if(r>=4)return e.pos+=r,e.pending+=e.src.slice(m,r),!0;if(e.level>=e.options.maxNesting)return!1;for(i=e.tokens.length,o=e.pending,l=e.validateInsideEm,e.pos=m+r,h=[r],e.validateInsideEm=!0;e.pos=1&&4>t){for(u=h.pop(),p=t;u!==p;){if(3===u){h.push(3-p);break}if(u>p){f=!0;break}if(p-=u,0===h.length)break;e.pos+=u,u=h.pop()}if(f)break;if(0===h.length){r=u,a=!0;break}e.pos+=t;continue}if(t=n(e,e.pos),t>=1&&4>t){h.push(t),e.pos+=t;continue}}c=e.parser.tokenizeSingle(e),c?d=!1:(d=e.src.charCodeAt(e.pos)===b,e.pending+=e.src[e.pos],e.pos++)}return e.tokens.length=i,e.pending=o,e.validateInsideEm=l,a?(e.posMax=e.pos,e.pos=m+r,(2===r||3===r)&&e.push({type:"strong_open",level:e.level++}),(1===r||3===r)&&e.push({type:"em_open",level:e.level++}),e.parser.tokenize(e),(1===r||3===r)&&e.push({type:"em_close",level:--e.level}),(2===r||3===r)&&e.push({type:"strong_close",level:--e.level}),e.pos=e.posMax+r,e.posMax=g,!0):(e.pos=m,!1)}},{}],33:[function(e,r){"use strict";var t=e("../common/entities"),n=e("../helpers").escapeHtml,s=e("../helpers").isValidEntityCode,i=e("../helpers").fromCodePoint,o=/^&#((?:x[a-f0-9]{1,8}|[0-9]{1,8}));/i,l=/^&([a-z][a-z0-9]{1,31});/i;r.exports=function(e){var r,a,c,u=e.pos,p=e.posMax;if(38!==e.src.charCodeAt(u))return!1;if(p>u+1)if(r=e.src.charCodeAt(u+1),35===r){if(c=e.src.slice(u).match(o))return a="x"===c[1][0].toLowerCase()?parseInt(c[1].slice(1),16):parseInt(c[1],10),e.pending+=s(a)?n(i(a)):i(65533),e.pos+=c[0].length,!0}else if(c=e.src.slice(u).match(l),c&&t.hasOwnProperty(c[1]))return e.pending+=n(t[c[1]]),e.pos+=c[0].length,!0;return e.pending+="&",e.pos++,!0}},{"../common/entities":1,"../helpers":10}],34:[function(e,r){var t="\\!\"#$%&'()*+,./:;<=>?@[]^_`{|}~-".split("").map(function(e){return e.charCodeAt(0)});r.exports=function(e){var r,n=e.pos,s=e.posMax;if(92!==e.src.charCodeAt(n))return!1;if(n++,s>n){if(r=e.src.charCodeAt(n),t.indexOf(r)>=0)return e.pending+=38===r?"&":60===r?"<":62===r?">":34===r?""":e.src[n],e.pos+=2,!0;if(10===r){for(e.push({type:"hardbreak",level:e.level}),n++;s>n&&32===e.src.charCodeAt(n);)n++;return e.pos=n,!0}}return e.pending+="\\",e.pos++,!0}},{}],35:[function(e,r){r.exports=function(e){var r=e.src.charCodeAt(e.pos);if(60===r)e.pending+="<";else if(62===r)e.pending+=">";else{if(34!==r)return!1;e.pending+="""}return e.pos++,!0}},{}],36:[function(e,r){"use strict";function t(e){var r=32|e;return r>=97&&122>=r}var n=e("../common/html_re").HTML_TAG_RE;r.exports=function(e){var r,s,i,o=e.pos;return e.options.html?(i=e.posMax,60!==e.src.charCodeAt(o)||o+2>=i?!1:(r=e.src.charCodeAt(o+1),(33===r||63===r||47===r||t(r))&&(s=e.src.slice(o).match(n))?(e.push({type:"htmltag",content:e.src.slice(o,o+s[0].length),level:e.level}),e.pos+=s[0].length,!0):!1)):!1}},{"../common/html_re":3}],37:[function(e,r){"use strict";function t(e){var r,t,l,a,c,u,p,h,f=!1,d=e.posMax,g=e.pos,m=e.src.charCodeAt(g);if(33===m&&(f=!0,m=e.src.charCodeAt(++g)),91!==m)return!1;if(e.level>=e.options.maxNesting)return!1;if(r=g+1,t=n(e,g),0>t)return!1;if(u=t+1,d>u&&40===e.src.charCodeAt(u)){for(u++;d>u&&(h=e.src.charCodeAt(u),32===h||10===h);u++);if(u>=d)return!1;for(g=u,s(e,u)?(a=e.link_content,u=e.pos):a="",g=u;d>u&&(h=e.src.charCodeAt(u),32===h||10===h);u++);if(d>u&&g!==u&&i(e,u))for(c=e.link_content,u=e.pos;d>u&&(h=e.src.charCodeAt(u),32===h||10===h);u++);else c="";if(u>=d||41!==e.src.charCodeAt(u))return e.pos=r-1,!1;u++}else{for(;d>u&&(h=e.src.charCodeAt(u),32===h||10===h);u++);if(d>u&&91===e.src.charCodeAt(u)&&(g=u+1,u=n(e,u),u>=0?l=e.src.slice(g,u++):u=g-1),l||(l=e.src.slice(r,t)),p=e.env.references[o(l)],!p)return e.pos=r-1,!1;a=p.href,c=p.title}return e.pos=r,e.posMax=t,f?e.push({type:"image",src:a,title:c,alt:e.src.substr(r,t-r),level:e.level}):(e.push({type:"link_open",href:a,title:c,level:e.level++}),e.parser.tokenize(e),e.push({type:"link_close",level:--e.level})),e.pos=u,e.posMax=d,!0}var n=e("../links").parseLinkLabel,s=e("../links").parseLinkDestination,i=e("../links").parseLinkTitle,o=e("../links").normalizeReference;r.exports=t},{"../links":12}],38:[function(e,r){r.exports=function(e){var r,t,n=e.pos;if(10!==e.src.charCodeAt(n))return!1;for(r=e.pending.length-1,t=e.posMax,r>=0&&32===e.pending.charCodeAt(r)?r>=1&&32===e.pending.charCodeAt(r-1)?(e.pending=e.pending.replace(/ +$/,""),e.push({type:"hardbreak",level:e.level})):(e.pending=e.pending.slice(0,-1),e.push({type:"softbreak",level:e.level})):e.push({type:"softbreak",level:e.level}),n++;t>n&&32===e.src.charCodeAt(n);)n++;return e.pos=n,!0}},{}],39:[function(e,r){"use strict";function t(e,r,t,n){this.src=e,this.env=n,this.options=t,this.parser=r,this.tokens=[],this.pos=0,this.pending="",this.posMax=this.src.length,this.validateInsideEm=!1,this.validateInsideLink=!1,this.level=0,this.link_content="",this.pendingLevel=0}t.prototype.pushPending=function(){var e=this.pending;this.tokens.push({type:"text",content:e,level:this.pendingLevel}),this.pending=""},t.prototype.push=function(e){this.pending&&this.pushPending(),this.tokens.push(e),this.pendingLevel=this.level},r.exports=t},{}],40:[function(e,r){r.exports=function(e){var r=e.src.slice(e.pos).match(e.parser.textMatch);return r?(e.pending+=r[0],e.pos+=r[0].length,!0):!1}},{}],41:[function(e,r){"use strict";var t=e("autolinker"),n=e("../helpers").escapeHtml,s=[],i=new t({stripPrefix:!1,replaceFn:function(e,r){var t;return"url"===r.getType()&&(t=r.getUrl(),/^(http|https|ftp|git)/.test(t)&&s.push(t)),!1}});r.exports=function(e,r){var t,o,l,a,c,u,p,h=r.tokens;for(t=h.length-1;t>=0;t--)if(o=h[t],"link_close"!==o.type){if("text"===o.type&&(o.content.indexOf("://")||o.content.indexOf("www"))){if(l=o.content,s=[],i.link(l),!s.length)continue;for(a=[],p=o.level,c=0;c=0;t--)n=i[t],"text"===n.type&&(s=n.content,s.indexOf("(")>=0&&(o.copyright&&(s=s.replace(/\(c\)/gi,"©")),o.trademark&&(s=s.replace(/\(tm\)/gi,"™")),o.registered&&(s=s.replace(/\(r\)/gi,"®")),o.paragraph&&(s=s.replace(/\(p\)/gi,"§"))),o.plusminus&&s.indexOf("+-")>=0&&(s=s.replace(/\+-/g,"±")),o.ellipsis&&s.indexOf("..")>=0&&(s=s.replace(/\.{2,}/g,"…").replace(/([?!])…/g,"$1..")),o.dupes&&(s.indexOf("????")>=0||s.indexOf("!!!!")>=0||s.indexOf(",,")>=0)&&(s=s.replace(/([?!]){4,}/g,"$1$1$1").replace(/,{2,}/g,",")),o.emDashes&&s.indexOf("--")>=0&&(s=s.replace(/(^|\s)--(\s|$)/gm,"$1—$2")),n.content=s) +}},{}],43:[function(e,r){"use strict";function t(){this.options=s({},n),this.ruler=new i(this.rulesUpdate.bind(this));for(var e=0;er;r++)n[r](this,e)},r.exports=t},{"./common/utils":5,"./defaults/typographer":9,"./ruler":17,"./rules_typographer/replace":42}],44:[function(r,t,n){!function(r,s){"function"==typeof e&&e.amd?e(s):"undefined"!=typeof n?t.exports=s():r.Autolinker=s()}(this,function(){var e=function(r){e.Util.assign(this,r)};return e.prototype={constructor:e,urls:!0,email:!0,twitter:!0,newWindow:!0,stripPrefix:!0,className:"",htmlCharacterEntitiesRegex:/( | |<|<|>|>)/gi,matcherRegex:function(){var e=/(^|[^\w])@(\w{1,15})/,r=/(?:[\-;:&=\+\$,\w\.]+@)/,t=/(?:[A-Za-z]{3,9}:(?:\/\/)?)/,n=/(?:www\.)/,s=/[A-Za-z0-9\.\-]*[A-Za-z0-9\-]/,i=/\.(?:international|construction|contractors|enterprises|photography|productions|foundation|immobilien|industries|management|properties|technology|christmas|community|directory|education|equipment|institute|marketing|solutions|vacations|bargains|boutique|builders|catering|cleaning|clothing|computer|democrat|diamonds|graphics|holdings|lighting|partners|plumbing|supplies|training|ventures|academy|careers|company|cruises|domains|exposed|flights|florist|gallery|guitars|holiday|kitchen|neustar|okinawa|recipes|rentals|reviews|shiksha|singles|support|systems|agency|berlin|camera|center|coffee|condos|dating|estate|events|expert|futbol|kaufen|luxury|maison|monash|museum|nagoya|photos|repair|report|social|supply|tattoo|tienda|travel|viajes|villas|vision|voting|voyage|actor|build|cards|cheap|codes|dance|email|glass|house|mango|ninja|parts|photo|shoes|solar|today|tokyo|tools|watch|works|aero|arpa|asia|best|bike|blue|buzz|camp|club|cool|coop|farm|fish|gift|guru|info|jobs|kiwi|kred|land|limo|link|menu|mobi|moda|name|pics|pink|post|qpon|rich|ruhr|sexy|tips|vote|voto|wang|wien|wiki|zone|bar|bid|biz|cab|cat|ceo|com|edu|gov|int|kim|mil|net|onl|org|pro|pub|red|tel|uno|wed|xxx|xyz|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cw|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|za|zm|zw)\b/,o=/(?:[\-A-Za-z0-9+&@#\/%?=~_()|!:,.;]*[\-A-Za-z0-9+&@#\/%=~_()|])?/;return new RegExp(["(",e.source,")","|","(",r.source,s.source,i.source,")","|","(","(?:","(?:",t.source,s.source,")","|","(?:","(.?//)?",n.source,s.source,")","|","(?:","(.?//)?",s.source,i.source,")",")",o.source,")"].join(""),"gi")}(),invalidProtocolRelMatchRegex:/^[\w]\/\//,charBeforeProtocolRelMatchRegex:/^(.)?\/\//,link:function(r){var t=this,n=this.getHtmlParser(),s=this.htmlCharacterEntitiesRegex,i=0,o=[];return n.parse(r,{processHtmlNode:function(e,r,t){"a"===r&&(t?i=Math.max(i-1,0):i++),o.push(e)},processTextNode:function(r){if(0===i)for(var n=e.Util.splitAndCapture(r,s),l=0,a=n.length;a>l;l++){var c=n[l],u=t.processTextNode(c);o.push(u)}else o.push(r)}}),o.join("")},getHtmlParser:function(){var r=this.htmlParser;return r||(r=this.htmlParser=new e.HtmlParser),r},getTagBuilder:function(){var r=this.tagBuilder;return r||(r=this.tagBuilder=new e.AnchorTagBuilder({newWindow:this.newWindow,truncate:this.truncate,className:this.className})),r},processTextNode:function(r){var t=this,n=this.charBeforeProtocolRelMatchRegex;return r.replace(this.matcherRegex,function(r,s,i,o,l,a,c,u){var p,h=s,f=i,d=o,g=l,m=a,b=c||u,v="",k="";if(!t.isValidMatch(h,g,m,b))return r;if(t.matchHasUnbalancedClosingParen(r)&&(r=r.substr(0,r.length-1),k=")"),g)p=new e.match.Email({matchedText:r,email:g});else if(h)f&&(v=f,r=r.slice(1)),p=new e.match.Twitter({matchedText:r,twitterHandle:d});else{if(b){var y=b.match(n)[1]||"";y&&(v=y,r=r.slice(1))}p=new e.match.Url({matchedText:r,url:r,protocolRelativeMatch:b,stripPrefix:t.stripPrefix})}var x=t.createMatchReturnVal(p,r);return v+x+k})},isValidMatch:function(e,r,t,n){return e&&!this.twitter||r&&!this.email||t&&!this.urls||t&&-1===t.indexOf(".")||t&&/^[A-Za-z]{3,9}:/.test(t)&&!/:.*?[A-Za-z]/.test(t)||n&&this.invalidProtocolRelMatchRegex.test(n)?!1:!0},matchHasUnbalancedClosingParen:function(e){var r=e.charAt(e.length-1);if(")"===r){var t=e.match(/\(/g),n=e.match(/\)/g),s=t&&t.length||0,i=n&&n.length||0;if(i>s)return!0}return!1},createMatchReturnVal:function(r,t){var n;if(this.replaceFn&&(n=this.replaceFn.call(this,this,r)),"string"==typeof n)return n;if(n===!1)return t;if(n instanceof e.HtmlTag)return n.toString();var s=this.getTagBuilder(),i=s.build(r);return i.toString()}},e.link=function(r,t){var n=new e(t);return n.link(r)},e.match={},e.Util={abstractMethod:function(){throw"abstract"},assign:function(e,r){for(var t in r)r.hasOwnProperty(t)&&(e[t]=r[t]);return e},extend:function(r,t){var n=r.prototype,s=function(){};s.prototype=n;var i;i=t.hasOwnProperty("constructor")?t.constructor:function(){n.constructor.apply(this,arguments)};var o=i.prototype=new s;return o.constructor=i,o.superclass=n,delete t.constructor,e.Util.assign(o,t),i},ellipsis:function(e,r,t){return e.length>r&&(t=null==t?"..":t,e=e.substring(0,r-t.length)+t),e},indexOf:function(e,r){if(Array.prototype.indexOf)return e.indexOf(r);for(var t=0,n=e.length;n>t;t++)if(e[t]===r)return t;return-1},splitAndCapture:function(e,r){if(!r.global)throw new Error("`splitRegex` must have the 'g' flag set");for(var t,n=[],s=0;t=r.exec(e);)n.push(e.substring(s,t.index)),n.push(t[0]),s=t.index+t[0].length;return n.push(e.substring(s)),n}},e.HtmlParser=e.Util.extend(Object,{htmlRegex:function(){var e=/[0-9a-zA-Z:]+/,r=/[^\s\0"'>\/=\x01-\x1F\x7F]+/,t=/(?:".*?"|'.*?'|[^'"=<>`\s]+)/,n=r.source+"(?:\\s*=\\s*"+t.source+")?";return new RegExp(["<(?:!|(/))?","("+e.source+")","(?:","\\s+","(?:",n,"|",t.source+")",")*","\\s*/?",">"].join(""),"g")}(),parse:function(e,r){r=r||{};for(var t,n=r.processHtmlNode||function(){},s=r.processTextNode||function(){},i=this.htmlRegex,o=0;null!==(t=i.exec(e));){var l=t[0],a=t[2],c=!!t[1],u=e.substring(o,t.index);u&&s(u),n(l,a,c),o=t.index+l.length}if(o",this.getInnerHtml(),""].join("")},buildAttrsStr:function(){if(!this.attrs)return"";var e=this.getAttrs(),r=[];for(var t in e)e.hasOwnProperty(t)&&r.push(t+'="'+e[t]+'"');return r.join(" ")}}),e.AnchorTagBuilder=e.Util.extend(Object,{constructor:function(r){e.Util.assign(this,r)},build:function(r){var t=new e.HtmlTag({tagName:"a",attrs:this.createAttrs(r.getType(),r.getAnchorHref()),innerHtml:this.processAnchorText(r.getAnchorText())});return t},createAttrs:function(e,r){var t={href:r},n=this.createCssClass(e);return n&&(t["class"]=n),this.newWindow&&(t.target="_blank"),t},createCssClass:function(e){var r=this.className;return r?r+" "+r+"-"+e:""},processAnchorText:function(e){return e=this.doTruncate(e)},doTruncate:function(r){return e.Util.ellipsis(r,this.truncate||Number.POSITIVE_INFINITY)}}),e.match.Match=e.Util.extend(Object,{constructor:function(r){e.Util.assign(this,r)},getType:e.Util.abstractMethod,getMatchedText:function(){return this.matchedText},getAnchorHref:e.Util.abstractMethod,getAnchorText:e.Util.abstractMethod}),e.match.Email=e.Util.extend(e.match.Match,{getType:function(){return"email"},getEmail:function(){return this.email},getAnchorHref:function(){return"mailto:"+this.email},getAnchorText:function(){return this.email}}),e.match.Twitter=e.Util.extend(e.match.Match,{getType:function(){return"twitter"},getTwitterHandle:function(){return this.twitterHandle},getAnchorHref:function(){return"https://twitter.com/"+this.twitterHandle},getAnchorText:function(){return"@"+this.twitterHandle}}),e.match.Url=e.Util.extend(e.match.Match,{urlPrefixRegex:/^(https?:\/\/)?(www\.)?/i,protocolRelativeRegex:/^\/\//,checkForProtocolRegex:/^[A-Za-z]{3,9}:/,getType:function(){return"url"},getUrl:function(){var e=this.url;return this.protocolRelativeMatch||this.checkForProtocolRegex.test(e)||(e=this.url="http://"+e),e},getAnchorHref:function(){var e=this.getUrl();return e.replace(/&/g,"&")},getAnchorText:function(){var e=this.getUrl();return this.protocolRelativeMatch&&(e=this.stripProtocolRelativePrefix(e)),this.stripPrefix&&(e=this.stripUrlPrefix(e)),e=this.removeTrailingSlash(e)},stripUrlPrefix:function(e){return e.replace(this.urlPrefixRegex,"")},stripProtocolRelativePrefix:function(e){return e.replace(this.protocolRelativeRegex,"")},removeTrailingSlash:function(e){return"/"===e.charAt(e.length-1)&&(e=e.slice(0,-1)),e}}),e})},{}]},{},[])("./")}); \ No newline at end of file
    "+i+"