[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

title

Body

[close]

/wp-includes/js/dist/ -> blocks.js (source)

   1  this["wp"] = this["wp"] || {}; this["wp"]["blocks"] =
   2  /******/ (function(modules) { // webpackBootstrap
   3  /******/     // The module cache
   4  /******/     var installedModules = {};
   5  /******/
   6  /******/     // The require function
   7  /******/ 	function __webpack_require__(moduleId) {
   8  /******/
   9  /******/         // Check if module is in cache
  10  /******/         if(installedModules[moduleId]) {
  11  /******/             return installedModules[moduleId].exports;
  12  /******/         }
  13  /******/         // Create a new module (and put it into the cache)
  14  /******/         var module = installedModules[moduleId] = {
  15  /******/             i: moduleId,
  16  /******/             l: false,
  17  /******/             exports: {}
  18  /******/         };
  19  /******/
  20  /******/         // Execute the module function
  21  /******/         modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
  22  /******/
  23  /******/         // Flag the module as loaded
  24  /******/         module.l = true;
  25  /******/
  26  /******/         // Return the exports of the module
  27  /******/         return module.exports;
  28  /******/     }
  29  /******/
  30  /******/
  31  /******/     // expose the modules object (__webpack_modules__)
  32  /******/     __webpack_require__.m = modules;
  33  /******/
  34  /******/     // expose the module cache
  35  /******/     __webpack_require__.c = installedModules;
  36  /******/
  37  /******/     // define getter function for harmony exports
  38  /******/     __webpack_require__.d = function(exports, name, getter) {
  39  /******/         if(!__webpack_require__.o(exports, name)) {
  40  /******/             Object.defineProperty(exports, name, { enumerable: true, get: getter });
  41  /******/         }
  42  /******/     };
  43  /******/
  44  /******/     // define __esModule on exports
  45  /******/     __webpack_require__.r = function(exports) {
  46  /******/         if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
  47  /******/             Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
  48  /******/         }
  49  /******/         Object.defineProperty(exports, '__esModule', { value: true });
  50  /******/     };
  51  /******/
  52  /******/     // create a fake namespace object
  53  /******/     // mode & 1: value is a module id, require it
  54  /******/     // mode & 2: merge all properties of value into the ns
  55  /******/     // mode & 4: return value when already ns object
  56  /******/     // mode & 8|1: behave like require
  57  /******/     __webpack_require__.t = function(value, mode) {
  58  /******/         if(mode & 1) value = __webpack_require__(value);
  59  /******/         if(mode & 8) return value;
  60  /******/         if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
  61  /******/         var ns = Object.create(null);
  62  /******/         __webpack_require__.r(ns);
  63  /******/         Object.defineProperty(ns, 'default', { enumerable: true, value: value });
  64  /******/         if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
  65  /******/         return ns;
  66  /******/     };
  67  /******/
  68  /******/     // getDefaultExport function for compatibility with non-harmony modules
  69  /******/     __webpack_require__.n = function(module) {
  70  /******/         var getter = module && module.__esModule ?
  71  /******/ 			function getDefault() { return module['default']; } :
  72  /******/ 			function getModuleExports() { return module; };
  73  /******/         __webpack_require__.d(getter, 'a', getter);
  74  /******/         return getter;
  75  /******/     };
  76  /******/
  77  /******/     // Object.prototype.hasOwnProperty.call
  78  /******/     __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
  79  /******/
  80  /******/     // __webpack_public_path__
  81  /******/     __webpack_require__.p = "";
  82  /******/
  83  /******/
  84  /******/     // Load entry module and return exports
  85  /******/     return __webpack_require__(__webpack_require__.s = 347);
  86  /******/ })
  87  /************************************************************************/
  88  /******/ ({
  89  
  90  /***/ 0:
  91  /***/ (function(module, exports) {
  92  
  93  (function() { module.exports = this["wp"]["element"]; }());
  94  
  95  /***/ }),
  96  
  97  /***/ 1:
  98  /***/ (function(module, exports) {
  99  
 100  (function() { module.exports = this["wp"]["i18n"]; }());
 101  
 102  /***/ }),
 103  
 104  /***/ 10:
 105  /***/ (function(module, __webpack_exports__, __webpack_require__) {
 106  
 107  "use strict";
 108  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return _defineProperty; });
 109  function _defineProperty(obj, key, value) {
 110    if (key in obj) {
 111      Object.defineProperty(obj, key, {
 112        value: value,
 113        enumerable: true,
 114        configurable: true,
 115        writable: true
 116      });
 117    } else {
 118      obj[key] = value;
 119    }
 120  
 121    return obj;
 122  }
 123  
 124  /***/ }),
 125  
 126  /***/ 11:
 127  /***/ (function(module, __webpack_exports__, __webpack_require__) {
 128  
 129  "use strict";
 130  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return _createClass; });
 131  function _defineProperties(target, props) {
 132    for (var i = 0; i < props.length; i++) {
 133      var descriptor = props[i];
 134      descriptor.enumerable = descriptor.enumerable || false;
 135      descriptor.configurable = true;
 136      if ("value" in descriptor) descriptor.writable = true;
 137      Object.defineProperty(target, descriptor.key, descriptor);
 138    }
 139  }
 140  
 141  function _createClass(Constructor, protoProps, staticProps) {
 142    if (protoProps) _defineProperties(Constructor.prototype, protoProps);
 143    if (staticProps) _defineProperties(Constructor, staticProps);
 144    return Constructor;
 145  }
 146  
 147  /***/ }),
 148  
 149  /***/ 12:
 150  /***/ (function(module, __webpack_exports__, __webpack_require__) {
 151  
 152  "use strict";
 153  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return _classCallCheck; });
 154  function _classCallCheck(instance, Constructor) {
 155    if (!(instance instanceof Constructor)) {
 156      throw new TypeError("Cannot call a class as a function");
 157    }
 158  }
 159  
 160  /***/ }),
 161  
 162  /***/ 144:
 163  /***/ (function(module, exports) {
 164  
 165  (function() { module.exports = this["wp"]["shortcode"]; }());
 166  
 167  /***/ }),
 168  
 169  /***/ 17:
 170  /***/ (function(module, __webpack_exports__, __webpack_require__) {
 171  
 172  "use strict";
 173  
 174  // CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/arrayWithoutHoles.js
 175  function _arrayWithoutHoles(arr) {
 176    if (Array.isArray(arr)) {
 177      for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) {
 178        arr2[i] = arr[i];
 179      }
 180  
 181      return arr2;
 182    }
 183  }
 184  // EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/iterableToArray.js
 185  var iterableToArray = __webpack_require__(30);
 186  
 187  // CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/nonIterableSpread.js
 188  function _nonIterableSpread() {
 189    throw new TypeError("Invalid attempt to spread non-iterable instance");
 190  }
 191  // CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/toConsumableArray.js
 192  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return _toConsumableArray; });
 193  
 194  
 195  
 196  function _toConsumableArray(arr) {
 197    return _arrayWithoutHoles(arr) || Object(iterableToArray["a" /* default */])(arr) || _nonIterableSpread();
 198  }
 199  
 200  /***/ }),
 201  
 202  /***/ 18:
 203  /***/ (function(module, __webpack_exports__, __webpack_require__) {
 204  
 205  "use strict";
 206  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return _extends; });
 207  function _extends() {
 208    _extends = Object.assign || function (target) {
 209      for (var i = 1; i < arguments.length; i++) {
 210        var source = arguments[i];
 211  
 212        for (var key in source) {
 213          if (Object.prototype.hasOwnProperty.call(source, key)) {
 214            target[key] = source[key];
 215          }
 216        }
 217      }
 218  
 219      return target;
 220    };
 221  
 222    return _extends.apply(this, arguments);
 223  }
 224  
 225  /***/ }),
 226  
 227  /***/ 2:
 228  /***/ (function(module, exports) {
 229  
 230  (function() { module.exports = this["lodash"]; }());
 231  
 232  /***/ }),
 233  
 234  /***/ 222:
 235  /***/ (function(module, exports) {
 236  
 237  (function() { module.exports = this["wp"]["blockSerializationDefaultParser"]; }());
 238  
 239  /***/ }),
 240  
 241  /***/ 223:
 242  /***/ (function(module, exports, __webpack_require__) {
 243  
 244  var __WEBPACK_AMD_DEFINE_RESULT__;;/*! showdown v 1.9.0 - 10-11-2018 */
 245  (function(){
 246  /**
 247   * Created by Tivie on 13-07-2015.
 248   */
 249  
 250  function getDefaultOpts (simple) {
 251    'use strict';
 252  
 253    var defaultOptions = {
 254      omitExtraWLInCodeBlocks: {
 255        defaultValue: false,
 256        describe: 'Omit the default extra whiteline added to code blocks',
 257        type: 'boolean'
 258      },
 259      noHeaderId: {
 260        defaultValue: false,
 261        describe: 'Turn on/off generated header id',
 262        type: 'boolean'
 263      },
 264      prefixHeaderId: {
 265        defaultValue: false,
 266        describe: 'Add a prefix to the generated header ids. Passing a string will prefix that string to the header id. Setting to true will add a generic \'section-\' prefix',
 267        type: 'string'
 268      },
 269      rawPrefixHeaderId: {
 270        defaultValue: false,
 271        describe: 'Setting this option to true will prevent showdown from modifying the prefix. This might result in malformed IDs (if, for instance, the " char is used in the prefix)',
 272        type: 'boolean'
 273      },
 274      ghCompatibleHeaderId: {
 275        defaultValue: false,
 276        describe: 'Generate header ids compatible with github style (spaces are replaced with dashes, a bunch of non alphanumeric chars are removed)',
 277        type: 'boolean'
 278      },
 279      rawHeaderId: {
 280        defaultValue: false,
 281        describe: 'Remove only spaces, \' and " from generated header ids (including prefixes), replacing them with dashes (-). WARNING: This might result in malformed ids',
 282        type: 'boolean'
 283      },
 284      headerLevelStart: {
 285        defaultValue: false,
 286        describe: 'The header blocks level start',
 287        type: 'integer'
 288      },
 289      parseImgDimensions: {
 290        defaultValue: false,
 291        describe: 'Turn on/off image dimension parsing',
 292        type: 'boolean'
 293      },
 294      simplifiedAutoLink: {
 295        defaultValue: false,
 296        describe: 'Turn on/off GFM autolink style',
 297        type: 'boolean'
 298      },
 299      excludeTrailingPunctuationFromURLs: {
 300        defaultValue: false,
 301        describe: 'Excludes trailing punctuation from links generated with autoLinking',
 302        type: 'boolean'
 303      },
 304      literalMidWordUnderscores: {
 305        defaultValue: false,
 306        describe: 'Parse midword underscores as literal underscores',
 307        type: 'boolean'
 308      },
 309      literalMidWordAsterisks: {
 310        defaultValue: false,
 311        describe: 'Parse midword asterisks as literal asterisks',
 312        type: 'boolean'
 313      },
 314      strikethrough: {
 315        defaultValue: false,
 316        describe: 'Turn on/off strikethrough support',
 317        type: 'boolean'
 318      },
 319      tables: {
 320        defaultValue: false,
 321        describe: 'Turn on/off tables support',
 322        type: 'boolean'
 323      },
 324      tablesHeaderId: {
 325        defaultValue: false,
 326        describe: 'Add an id to table headers',
 327        type: 'boolean'
 328      },
 329      ghCodeBlocks: {
 330        defaultValue: true,
 331        describe: 'Turn on/off GFM fenced code blocks support',
 332        type: 'boolean'
 333      },
 334      tasklists: {
 335        defaultValue: false,
 336        describe: 'Turn on/off GFM tasklist support',
 337        type: 'boolean'
 338      },
 339      smoothLivePreview: {
 340        defaultValue: false,
 341        describe: 'Prevents weird effects in live previews due to incomplete input',
 342        type: 'boolean'
 343      },
 344      smartIndentationFix: {
 345        defaultValue: false,
 346        description: 'Tries to smartly fix indentation in es6 strings',
 347        type: 'boolean'
 348      },
 349      disableForced4SpacesIndentedSublists: {
 350        defaultValue: false,
 351        description: 'Disables the requirement of indenting nested sublists by 4 spaces',
 352        type: 'boolean'
 353      },
 354      simpleLineBreaks: {
 355        defaultValue: false,
 356        description: 'Parses simple line breaks as <br> (GFM Style)',
 357        type: 'boolean'
 358      },
 359      requireSpaceBeforeHeadingText: {
 360        defaultValue: false,
 361        description: 'Makes adding a space between `#` and the header text mandatory (GFM Style)',
 362        type: 'boolean'
 363      },
 364      ghMentions: {
 365        defaultValue: false,
 366        description: 'Enables github @mentions',
 367        type: 'boolean'
 368      },
 369      ghMentionsLink: {
 370        defaultValue: 'https://github.com/{u}',
 371        description: 'Changes the link generated by @mentions. Only applies if ghMentions option is enabled.',
 372        type: 'string'
 373      },
 374      encodeEmails: {
 375        defaultValue: true,
 376        description: 'Encode e-mail addresses through the use of Character Entities, transforming ASCII e-mail addresses into its equivalent decimal entities',
 377        type: 'boolean'
 378      },
 379      openLinksInNewWindow: {
 380        defaultValue: false,
 381        description: 'Open all links in new windows',
 382        type: 'boolean'
 383      },
 384      backslashEscapesHTMLTags: {
 385        defaultValue: false,
 386        description: 'Support for HTML Tag escaping. ex: \<div>foo\</div>',
 387        type: 'boolean'
 388      },
 389      emoji: {
 390        defaultValue: false,
 391        description: 'Enable emoji support. Ex: `this is a :smile: emoji`',
 392        type: 'boolean'
 393      },
 394      underline: {
 395        defaultValue: false,
 396        description: 'Enable support for underline. Syntax is double or triple underscores: `__underline word__`. With this option enabled, underscores no longer parses into `<em>` and `<strong>`',
 397        type: 'boolean'
 398      },
 399      completeHTMLDocument: {
 400        defaultValue: false,
 401        description: 'Outputs a complete html document, including `<html>`, `<head>` and `<body>` tags',
 402        type: 'boolean'
 403      },
 404      metadata: {
 405        defaultValue: false,
 406        description: 'Enable support for document metadata (defined at the top of the document between `«««` and `»»»` or between `---` and `---`).',
 407        type: 'boolean'
 408      },
 409      splitAdjacentBlockquotes: {
 410        defaultValue: false,
 411        description: 'Split adjacent blockquote blocks',
 412        type: 'boolean'
 413      }
 414    };
 415    if (simple === false) {
 416      return JSON.parse(JSON.stringify(defaultOptions));
 417    }
 418    var ret = {};
 419    for (var opt in defaultOptions) {
 420      if (defaultOptions.hasOwnProperty(opt)) {
 421        ret[opt] = defaultOptions[opt].defaultValue;
 422      }
 423    }
 424    return ret;
 425  }
 426  
 427  function allOptionsOn () {
 428    'use strict';
 429    var options = getDefaultOpts(true),
 430        ret = {};
 431    for (var opt in options) {
 432      if (options.hasOwnProperty(opt)) {
 433        ret[opt] = true;
 434      }
 435    }
 436    return ret;
 437  }
 438  
 439  /**
 440   * Created by Tivie on 06-01-2015.
 441   */
 442  
 443  // Private properties
 444  var showdown = {},
 445      parsers = {},
 446      extensions = {},
 447      globalOptions = getDefaultOpts(true),
 448      setFlavor = 'vanilla',
 449      flavor = {
 450        github: {
 451          omitExtraWLInCodeBlocks:              true,
 452          simplifiedAutoLink:                   true,
 453          excludeTrailingPunctuationFromURLs:   true,
 454          literalMidWordUnderscores:            true,
 455          strikethrough:                        true,
 456          tables:                               true,
 457          tablesHeaderId:                       true,
 458          ghCodeBlocks:                         true,
 459          tasklists:                            true,
 460          disableForced4SpacesIndentedSublists: true,
 461          simpleLineBreaks:                     true,
 462          requireSpaceBeforeHeadingText:        true,
 463          ghCompatibleHeaderId:                 true,
 464          ghMentions:                           true,
 465          backslashEscapesHTMLTags:             true,
 466          emoji:                                true,
 467          splitAdjacentBlockquotes:             true
 468        },
 469        original: {
 470          noHeaderId:                           true,
 471          ghCodeBlocks:                         false
 472        },
 473        ghost: {
 474          omitExtraWLInCodeBlocks:              true,
 475          parseImgDimensions:                   true,
 476          simplifiedAutoLink:                   true,
 477          excludeTrailingPunctuationFromURLs:   true,
 478          literalMidWordUnderscores:            true,
 479          strikethrough:                        true,
 480          tables:                               true,
 481          tablesHeaderId:                       true,
 482          ghCodeBlocks:                         true,
 483          tasklists:                            true,
 484          smoothLivePreview:                    true,
 485          simpleLineBreaks:                     true,
 486          requireSpaceBeforeHeadingText:        true,
 487          ghMentions:                           false,
 488          encodeEmails:                         true
 489        },
 490        vanilla: getDefaultOpts(true),
 491        allOn: allOptionsOn()
 492      };
 493  
 494  /**
 495   * helper namespace
 496   * @type {{}}
 497   */
 498  showdown.helper = {};
 499  
 500  /**
 501   * TODO LEGACY SUPPORT CODE
 502   * @type {{}}
 503   */
 504  showdown.extensions = {};
 505  
 506  /**
 507   * Set a global option
 508   * @static
 509   * @param {string} key
 510   * @param {*} value
 511   * @returns {showdown}
 512   */
 513  showdown.setOption = function (key, value) {
 514    'use strict';
 515    globalOptions[key] = value;
 516    return this;
 517  };
 518  
 519  /**
 520   * Get a global option
 521   * @static
 522   * @param {string} key
 523   * @returns {*}
 524   */
 525  showdown.getOption = function (key) {
 526    'use strict';
 527    return globalOptions[key];
 528  };
 529  
 530  /**
 531   * Get the global options
 532   * @static
 533   * @returns {{}}
 534   */
 535  showdown.getOptions = function () {
 536    'use strict';
 537    return globalOptions;
 538  };
 539  
 540  /**
 541   * Reset global options to the default values
 542   * @static
 543   */
 544  showdown.resetOptions = function () {
 545    'use strict';
 546    globalOptions = getDefaultOpts(true);
 547  };
 548  
 549  /**
 550   * Set the flavor showdown should use as default
 551   * @param {string} name
 552   */
 553  showdown.setFlavor = function (name) {
 554    'use strict';
 555    if (!flavor.hasOwnProperty(name)) {
 556      throw Error(name + ' flavor was not found');
 557    }
 558    showdown.resetOptions();
 559    var preset = flavor[name];
 560    setFlavor = name;
 561    for (var option in preset) {
 562      if (preset.hasOwnProperty(option)) {
 563        globalOptions[option] = preset[option];
 564      }
 565    }
 566  };
 567  
 568  /**
 569   * Get the currently set flavor
 570   * @returns {string}
 571   */
 572  showdown.getFlavor = function () {
 573    'use strict';
 574    return setFlavor;
 575  };
 576  
 577  /**
 578   * Get the options of a specified flavor. Returns undefined if the flavor was not found
 579   * @param {string} name Name of the flavor
 580   * @returns {{}|undefined}
 581   */
 582  showdown.getFlavorOptions = function (name) {
 583    'use strict';
 584    if (flavor.hasOwnProperty(name)) {
 585      return flavor[name];
 586    }
 587  };
 588  
 589  /**
 590   * Get the default options
 591   * @static
 592   * @param {boolean} [simple=true]
 593   * @returns {{}}
 594   */
 595  showdown.getDefaultOptions = function (simple) {
 596    'use strict';
 597    return getDefaultOpts(simple);
 598  };
 599  
 600  /**
 601   * Get or set a subParser
 602   *
 603   * subParser(name)       - Get a registered subParser
 604   * subParser(name, func) - Register a subParser
 605   * @static
 606   * @param {string} name
 607   * @param {function} [func]
 608   * @returns {*}
 609   */
 610  showdown.subParser = function (name, func) {
 611    'use strict';
 612    if (showdown.helper.isString(name)) {
 613      if (typeof func !== 'undefined') {
 614        parsers[name] = func;
 615      } else {
 616        if (parsers.hasOwnProperty(name)) {
 617          return parsers[name];
 618        } else {
 619          throw Error('SubParser named ' + name + ' not registered!');
 620        }
 621      }
 622    }
 623  };
 624  
 625  /**
 626   * Gets or registers an extension
 627   * @static
 628   * @param {string} name
 629   * @param {object|function=} ext
 630   * @returns {*}
 631   */
 632  showdown.extension = function (name, ext) {
 633    'use strict';
 634  
 635    if (!showdown.helper.isString(name)) {
 636      throw Error('Extension \'name\' must be a string');
 637    }
 638  
 639    name = showdown.helper.stdExtName(name);
 640  
 641    // Getter
 642    if (showdown.helper.isUndefined(ext)) {
 643      if (!extensions.hasOwnProperty(name)) {
 644        throw Error('Extension named ' + name + ' is not registered!');
 645      }
 646      return extensions[name];
 647  
 648      // Setter
 649    } else {
 650      // Expand extension if it's wrapped in a function
 651      if (typeof ext === 'function') {
 652        ext = ext();
 653      }
 654  
 655      // Ensure extension is an array
 656      if (!showdown.helper.isArray(ext)) {
 657        ext = [ext];
 658      }
 659  
 660      var validExtension = validate(ext, name);
 661  
 662      if (validExtension.valid) {
 663        extensions[name] = ext;
 664      } else {
 665        throw Error(validExtension.error);
 666      }
 667    }
 668  };
 669  
 670  /**
 671   * Gets all extensions registered
 672   * @returns {{}}
 673   */
 674  showdown.getAllExtensions = function () {
 675    'use strict';
 676    return extensions;
 677  };
 678  
 679  /**
 680   * Remove an extension
 681   * @param {string} name
 682   */
 683  showdown.removeExtension = function (name) {
 684    'use strict';
 685    delete extensions[name];
 686  };
 687  
 688  /**
 689   * Removes all extensions
 690   */
 691  showdown.resetExtensions = function () {
 692    'use strict';
 693    extensions = {};
 694  };
 695  
 696  /**
 697   * Validate extension
 698   * @param {array} extension
 699   * @param {string} name
 700   * @returns {{valid: boolean, error: string}}
 701   */
 702  function validate (extension, name) {
 703    'use strict';
 704  
 705    var errMsg = (name) ? 'Error in ' + name + ' extension->' : 'Error in unnamed extension',
 706        ret = {
 707          valid: true,
 708          error: ''
 709        };
 710  
 711    if (!showdown.helper.isArray(extension)) {
 712      extension = [extension];
 713    }
 714  
 715    for (var i = 0; i < extension.length; ++i) {
 716      var baseMsg = errMsg + ' sub-extension ' + i + ': ',
 717          ext = extension[i];
 718      if (typeof ext !== 'object') {
 719        ret.valid = false;
 720        ret.error = baseMsg + 'must be an object, but ' + typeof ext + ' given';
 721        return ret;
 722      }
 723  
 724      if (!showdown.helper.isString(ext.type)) {
 725        ret.valid = false;
 726        ret.error = baseMsg + 'property "type" must be a string, but ' + typeof ext.type + ' given';
 727        return ret;
 728      }
 729  
 730      var type = ext.type = ext.type.toLowerCase();
 731  
 732      // normalize extension type
 733      if (type === 'language') {
 734        type = ext.type = 'lang';
 735      }
 736  
 737      if (type === 'html') {
 738        type = ext.type = 'output';
 739      }
 740  
 741      if (type !== 'lang' && type !== 'output' && type !== 'listener') {
 742        ret.valid = false;
 743        ret.error = baseMsg + 'type ' + type + ' is not recognized. Valid values: "lang/language", "output/html" or "listener"';
 744        return ret;
 745      }
 746  
 747      if (type === 'listener') {
 748        if (showdown.helper.isUndefined(ext.listeners)) {
 749          ret.valid = false;
 750          ret.error = baseMsg + '. Extensions of type "listener" must have a property called "listeners"';
 751          return ret;
 752        }
 753      } else {
 754        if (showdown.helper.isUndefined(ext.filter) && showdown.helper.isUndefined(ext.regex)) {
 755          ret.valid = false;
 756          ret.error = baseMsg + type + ' extensions must define either a "regex" property or a "filter" method';
 757          return ret;
 758        }
 759      }
 760  
 761      if (ext.listeners) {
 762        if (typeof ext.listeners !== 'object') {
 763          ret.valid = false;
 764          ret.error = baseMsg + '"listeners" property must be an object but ' + typeof ext.listeners + ' given';
 765          return ret;
 766        }
 767        for (var ln in ext.listeners) {
 768          if (ext.listeners.hasOwnProperty(ln)) {
 769            if (typeof ext.listeners[ln] !== 'function') {
 770              ret.valid = false;
 771              ret.error = baseMsg + '"listeners" property must be an hash of [event name]: [callback]. listeners.' + ln +
 772                ' must be a function but ' + typeof ext.listeners[ln] + ' given';
 773              return ret;
 774            }
 775          }
 776        }
 777      }
 778  
 779      if (ext.filter) {
 780        if (typeof ext.filter !== 'function') {
 781          ret.valid = false;
 782          ret.error = baseMsg + '"filter" must be a function, but ' + typeof ext.filter + ' given';
 783          return ret;
 784        }
 785      } else if (ext.regex) {
 786        if (showdown.helper.isString(ext.regex)) {
 787          ext.regex = new RegExp(ext.regex, 'g');
 788        }
 789        if (!(ext.regex instanceof RegExp)) {
 790          ret.valid = false;
 791          ret.error = baseMsg + '"regex" property must either be a string or a RegExp object, but ' + typeof ext.regex + ' given';
 792          return ret;
 793        }
 794        if (showdown.helper.isUndefined(ext.replace)) {
 795          ret.valid = false;
 796          ret.error = baseMsg + '"regex" extensions must implement a replace string or function';
 797          return ret;
 798        }
 799      }
 800    }
 801    return ret;
 802  }
 803  
 804  /**
 805   * Validate extension
 806   * @param {object} ext
 807   * @returns {boolean}
 808   */
 809  showdown.validateExtension = function (ext) {
 810    'use strict';
 811  
 812    var validateExtension = validate(ext, null);
 813    if (!validateExtension.valid) {
 814      console.warn(validateExtension.error);
 815      return false;
 816    }
 817    return true;
 818  };
 819  
 820  /**
 821   * showdownjs helper functions
 822   */
 823  
 824  if (!showdown.hasOwnProperty('helper')) {
 825    showdown.helper = {};
 826  }
 827  
 828  /**
 829   * Check if var is string
 830   * @static
 831   * @param {string} a
 832   * @returns {boolean}
 833   */
 834  showdown.helper.isString = function (a) {
 835    'use strict';
 836    return (typeof a === 'string' || a instanceof String);
 837  };
 838  
 839  /**
 840   * Check if var is a function
 841   * @static
 842   * @param {*} a
 843   * @returns {boolean}
 844   */
 845  showdown.helper.isFunction = function (a) {
 846    'use strict';
 847    var getType = {};
 848    return a && getType.toString.call(a) === '[object Function]';
 849  };
 850  
 851  /**
 852   * isArray helper function
 853   * @static
 854   * @param {*} a
 855   * @returns {boolean}
 856   */
 857  showdown.helper.isArray = function (a) {
 858    'use strict';
 859    return Array.isArray(a);
 860  };
 861  
 862  /**
 863   * Check if value is undefined
 864   * @static
 865   * @param {*} value The value to check.
 866   * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
 867   */
 868  showdown.helper.isUndefined = function (value) {
 869    'use strict';
 870    return typeof value === 'undefined';
 871  };
 872  
 873  /**
 874   * ForEach helper function
 875   * Iterates over Arrays and Objects (own properties only)
 876   * @static
 877   * @param {*} obj
 878   * @param {function} callback Accepts 3 params: 1. value, 2. key, 3. the original array/object
 879   */
 880  showdown.helper.forEach = function (obj, callback) {
 881    'use strict';
 882    // check if obj is defined
 883    if (showdown.helper.isUndefined(obj)) {
 884      throw new Error('obj param is required');
 885    }
 886  
 887    if (showdown.helper.isUndefined(callback)) {
 888      throw new Error('callback param is required');
 889    }
 890  
 891    if (!showdown.helper.isFunction(callback)) {
 892      throw new Error('callback param must be a function/closure');
 893    }
 894  
 895    if (typeof obj.forEach === 'function') {
 896      obj.forEach(callback);
 897    } else if (showdown.helper.isArray(obj)) {
 898      for (var i = 0; i < obj.length; i++) {
 899        callback(obj[i], i, obj);
 900      }
 901    } else if (typeof (obj) === 'object') {
 902      for (var prop in obj) {
 903        if (obj.hasOwnProperty(prop)) {
 904          callback(obj[prop], prop, obj);
 905        }
 906      }
 907    } else {
 908      throw new Error('obj does not seem to be an array or an iterable object');
 909    }
 910  };
 911  
 912  /**
 913   * Standardidize extension name
 914   * @static
 915   * @param {string} s extension name
 916   * @returns {string}
 917   */
 918  showdown.helper.stdExtName = function (s) {
 919    'use strict';
 920    return s.replace(/[_?*+\/\\.^-]/g, '').replace(/\s/g, '').toLowerCase();
 921  };
 922  
 923  function escapeCharactersCallback (wholeMatch, m1) {
 924    'use strict';
 925    var charCodeToEscape = m1.charCodeAt(0);
 926    return '¨E' + charCodeToEscape + 'E';
 927  }
 928  
 929  /**
 930   * Callback used to escape characters when passing through String.replace
 931   * @static
 932   * @param {string} wholeMatch
 933   * @param {string} m1
 934   * @returns {string}
 935   */
 936  showdown.helper.escapeCharactersCallback = escapeCharactersCallback;
 937  
 938  /**
 939   * Escape characters in a string
 940   * @static
 941   * @param {string} text
 942   * @param {string} charsToEscape
 943   * @param {boolean} afterBackslash
 944   * @returns {XML|string|void|*}
 945   */
 946  showdown.helper.escapeCharacters = function (text, charsToEscape, afterBackslash) {
 947    'use strict';
 948    // First we have to escape the escape characters so that
 949    // we can build a character class out of them
 950    var regexString = '([' + charsToEscape.replace(/([\[\]\\])/g, '\\$1') + '])';
 951  
 952    if (afterBackslash) {
 953      regexString = '\\\\' + regexString;
 954    }
 955  
 956    var regex = new RegExp(regexString, 'g');
 957    text = text.replace(regex, escapeCharactersCallback);
 958  
 959    return text;
 960  };
 961  
 962  /**
 963   * Unescape HTML entities
 964   * @param txt
 965   * @returns {string}
 966   */
 967  showdown.helper.unescapeHTMLEntities = function (txt) {
 968    'use strict';
 969  
 970    return txt
 971      .replace(/&quot;/g, '"')
 972      .replace(/&lt;/g, '<')
 973      .replace(/&gt;/g, '>')
 974      .replace(/&amp;/g, '&');
 975  };
 976  
 977  var rgxFindMatchPos = function (str, left, right, flags) {
 978    'use strict';
 979    var f = flags || '',
 980        g = f.indexOf('g') > -1,
 981        x = new RegExp(left + '|' + right, 'g' + f.replace(/g/g, '')),
 982        l = new RegExp(left, f.replace(/g/g, '')),
 983        pos = [],
 984        t, s, m, start, end;
 985  
 986    do {
 987      t = 0;
 988      while ((m = x.exec(str))) {
 989        if (l.test(m[0])) {
 990          if (!(t++)) {
 991            s = x.lastIndex;
 992            start = s - m[0].length;
 993          }
 994        } else if (t) {
 995          if (!--t) {
 996            end = m.index + m[0].length;
 997            var obj = {
 998              left: {start: start, end: s},
 999              match: {start: s, end: m.index},
1000              right: {start: m.index, end: end},
1001              wholeMatch: {start: start, end: end}
1002            };
1003            pos.push(obj);
1004            if (!g) {
1005              return pos;
1006            }
1007          }
1008        }
1009      }
1010    } while (t && (x.lastIndex = s));
1011  
1012    return pos;
1013  };
1014  
1015  /**
1016   * matchRecursiveRegExp
1017   *
1018   * (c) 2007 Steven Levithan <stevenlevithan.com>
1019   * MIT License
1020   *
1021   * Accepts a string to search, a left and right format delimiter
1022   * as regex patterns, and optional regex flags. Returns an array
1023   * of matches, allowing nested instances of left/right delimiters.
1024   * Use the "g" flag to return all matches, otherwise only the
1025   * first is returned. Be careful to ensure that the left and
1026   * right format delimiters produce mutually exclusive matches.
1027   * Backreferences are not supported within the right delimiter
1028   * due to how it is internally combined with the left delimiter.
1029   * When matching strings whose format delimiters are unbalanced
1030   * to the left or right, the output is intentionally as a
1031   * conventional regex library with recursion support would
1032   * produce, e.g. "<<x>" and "<x>>" both produce ["x"] when using
1033   * "<" and ">" as the delimiters (both strings contain a single,
1034   * balanced instance of "<x>").
1035   *
1036   * examples:
1037   * matchRecursiveRegExp("test", "\\(", "\\)")
1038   * returns: []
1039   * matchRecursiveRegExp("<t<<e>><s>>t<>", "<", ">", "g")
1040   * returns: ["t<<e>><s>", ""]
1041   * matchRecursiveRegExp("<div id=\"x\">test</div>", "<div\\b[^>]*>", "</div>", "gi")
1042   * returns: ["test"]
1043   */
1044  showdown.helper.matchRecursiveRegExp = function (str, left, right, flags) {
1045    'use strict';
1046  
1047    var matchPos = rgxFindMatchPos (str, left, right, flags),
1048        results = [];
1049  
1050    for (var i = 0; i < matchPos.length; ++i) {
1051      results.push([
1052        str.slice(matchPos[i].wholeMatch.start, matchPos[i].wholeMatch.end),
1053        str.slice(matchPos[i].match.start, matchPos[i].match.end),
1054        str.slice(matchPos[i].left.start, matchPos[i].left.end),
1055        str.slice(matchPos[i].right.start, matchPos[i].right.end)
1056      ]);
1057    }
1058    return results;
1059  };
1060  
1061  /**
1062   *
1063   * @param {string} str
1064   * @param {string|function} replacement
1065   * @param {string} left
1066   * @param {string} right
1067   * @param {string} flags
1068   * @returns {string}
1069   */
1070  showdown.helper.replaceRecursiveRegExp = function (str, replacement, left, right, flags) {
1071    'use strict';
1072  
1073    if (!showdown.helper.isFunction(replacement)) {
1074      var repStr = replacement;
1075      replacement = function () {
1076        return repStr;
1077      };
1078    }
1079  
1080    var matchPos = rgxFindMatchPos(str, left, right, flags),
1081        finalStr = str,
1082        lng = matchPos.length;
1083  
1084    if (lng > 0) {
1085      var bits = [];
1086      if (matchPos[0].wholeMatch.start !== 0) {
1087        bits.push(str.slice(0, matchPos[0].wholeMatch.start));
1088      }
1089      for (var i = 0; i < lng; ++i) {
1090        bits.push(
1091          replacement(
1092            str.slice(matchPos[i].wholeMatch.start, matchPos[i].wholeMatch.end),
1093            str.slice(matchPos[i].match.start, matchPos[i].match.end),
1094            str.slice(matchPos[i].left.start, matchPos[i].left.end),
1095            str.slice(matchPos[i].right.start, matchPos[i].right.end)
1096          )
1097        );
1098        if (i < lng - 1) {
1099          bits.push(str.slice(matchPos[i].wholeMatch.end, matchPos[i + 1].wholeMatch.start));
1100        }
1101      }
1102      if (matchPos[lng - 1].wholeMatch.end < str.length) {
1103        bits.push(str.slice(matchPos[lng - 1].wholeMatch.end));
1104      }
1105      finalStr = bits.join('');
1106    }
1107    return finalStr;
1108  };
1109  
1110  /**
1111   * Returns the index within the passed String object of the first occurrence of the specified regex,
1112   * starting the search at fromIndex. Returns -1 if the value is not found.
1113   *
1114   * @param {string} str string to search
1115   * @param {RegExp} regex Regular expression to search
1116   * @param {int} [fromIndex = 0] Index to start the search
1117   * @returns {Number}
1118   * @throws InvalidArgumentError
1119   */
1120  showdown.helper.regexIndexOf = function (str, regex, fromIndex) {
1121    'use strict';
1122    if (!showdown.helper.isString(str)) {
1123      throw 'InvalidArgumentError: first parameter of showdown.helper.regexIndexOf function must be a string';
1124    }
1125    if (regex instanceof RegExp === false) {
1126      throw 'InvalidArgumentError: second parameter of showdown.helper.regexIndexOf function must be an instance of RegExp';
1127    }
1128    var indexOf = str.substring(fromIndex || 0).search(regex);
1129    return (indexOf >= 0) ? (indexOf + (fromIndex || 0)) : indexOf;
1130  };
1131  
1132  /**
1133   * Splits the passed string object at the defined index, and returns an array composed of the two substrings
1134   * @param {string} str string to split
1135   * @param {int} index index to split string at
1136   * @returns {[string,string]}
1137   * @throws InvalidArgumentError
1138   */
1139  showdown.helper.splitAtIndex = function (str, index) {
1140    'use strict';
1141    if (!showdown.helper.isString(str)) {
1142      throw 'InvalidArgumentError: first parameter of showdown.helper.regexIndexOf function must be a string';
1143    }
1144    return [str.substring(0, index), str.substring(index)];
1145  };
1146  
1147  /**
1148   * Obfuscate an e-mail address through the use of Character Entities,
1149   * transforming ASCII characters into their equivalent decimal or hex entities.
1150   *
1151   * Since it has a random component, subsequent calls to this function produce different results
1152   *
1153   * @param {string} mail
1154   * @returns {string}
1155   */
1156  showdown.helper.encodeEmailAddress = function (mail) {
1157    'use strict';
1158    var encode = [
1159      function (ch) {
1160        return '&#' + ch.charCodeAt(0) + ';';
1161      },
1162      function (ch) {
1163        return '&#x' + ch.charCodeAt(0).toString(16) + ';';
1164      },
1165      function (ch) {
1166        return ch;
1167      }
1168    ];
1169  
1170    mail = mail.replace(/./g, function (ch) {
1171      if (ch === '@') {
1172        // this *must* be encoded. I insist.
1173        ch = encode[Math.floor(Math.random() * 2)](ch);
1174      } else {
1175        var r = Math.random();
1176        // roughly 10% raw, 45% hex, 45% dec
1177        ch = (
1178          r > 0.9 ? encode[2](ch) : r > 0.45 ? encode[1](ch) : encode[0](ch)
1179        );
1180      }
1181      return ch;
1182    });
1183  
1184    return mail;
1185  };
1186  
1187  /**
1188   *
1189   * @param str
1190   * @param targetLength
1191   * @param padString
1192   * @returns {string}
1193   */
1194  showdown.helper.padEnd = function padEnd (str, targetLength, padString) {
1195    'use strict';
1196    /*jshint bitwise: false*/
1197    // eslint-disable-next-line space-infix-ops
1198    targetLength = targetLength>>0; //floor if number or convert non-number to 0;
1199    /*jshint bitwise: true*/
1200    padString = String(padString || ' ');
1201    if (str.length > targetLength) {
1202      return String(str);
1203    } else {
1204      targetLength = targetLength - str.length;
1205      if (targetLength > padString.length) {
1206        padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed
1207      }
1208      return String(str) + padString.slice(0,targetLength);
1209    }
1210  };
1211  
1212  /**
1213   * POLYFILLS
1214   */
1215  // use this instead of builtin is undefined for IE8 compatibility
1216  if (typeof(console) === 'undefined') {
1217    console = {
1218      warn: function (msg) {
1219        'use strict';
1220        alert(msg);
1221      },
1222      log: function (msg) {
1223        'use strict';
1224        alert(msg);
1225      },
1226      error: function (msg) {
1227        'use strict';
1228        throw msg;
1229      }
1230    };
1231  }
1232  
1233  /**
1234   * Common regexes.
1235   * We declare some common regexes to improve performance
1236   */
1237  showdown.helper.regexes = {
1238    asteriskDashAndColon: /([*_:~])/g
1239  };
1240  
1241  /**
1242   * EMOJIS LIST
1243   */
1244  showdown.helper.emojis = {
1245    '+1':'\ud83d\udc4d',
1246    '-1':'\ud83d\udc4e',
1247    '100':'\ud83d\udcaf',
1248    '1234':'\ud83d\udd22',
1249    '1st_place_medal':'\ud83e\udd47',
1250    '2nd_place_medal':'\ud83e\udd48',
1251    '3rd_place_medal':'\ud83e\udd49',
1252    '8ball':'\ud83c\udfb1',
1253    'a':'\ud83c\udd70\ufe0f',
1254    'ab':'\ud83c\udd8e',
1255    'abc':'\ud83d\udd24',
1256    'abcd':'\ud83d\udd21',
1257    'accept':'\ud83c\ude51',
1258    'aerial_tramway':'\ud83d\udea1',
1259    'airplane':'\u2708\ufe0f',
1260    'alarm_clock':'\u23f0',
1261    'alembic':'\u2697\ufe0f',
1262    'alien':'\ud83d\udc7d',
1263    'ambulance':'\ud83d\ude91',
1264    'amphora':'\ud83c\udffa',
1265    'anchor':'\u2693\ufe0f',
1266    'angel':'\ud83d\udc7c',
1267    'anger':'\ud83d\udca2',
1268    'angry':'\ud83d\ude20',
1269    'anguished':'\ud83d\ude27',
1270    'ant':'\ud83d\udc1c',
1271    'apple':'\ud83c\udf4e',
1272    'aquarius':'\u2652\ufe0f',
1273    'aries':'\u2648\ufe0f',
1274    'arrow_backward':'\u25c0\ufe0f',
1275    'arrow_double_down':'\u23ec',
1276    'arrow_double_up':'\u23eb',
1277    'arrow_down':'\u2b07\ufe0f',
1278    'arrow_down_small':'\ud83d\udd3d',
1279    'arrow_forward':'\u25b6\ufe0f',
1280    'arrow_heading_down':'\u2935\ufe0f',
1281    'arrow_heading_up':'\u2934\ufe0f',
1282    'arrow_left':'\u2b05\ufe0f',
1283    'arrow_lower_left':'\u2199\ufe0f',
1284    'arrow_lower_right':'\u2198\ufe0f',
1285    'arrow_right':'\u27a1\ufe0f',
1286    'arrow_right_hook':'\u21aa\ufe0f',
1287    'arrow_up':'\u2b06\ufe0f',
1288    'arrow_up_down':'\u2195\ufe0f',
1289    'arrow_up_small':'\ud83d\udd3c',
1290    'arrow_upper_left':'\u2196\ufe0f',
1291    'arrow_upper_right':'\u2197\ufe0f',
1292    'arrows_clockwise':'\ud83d\udd03',
1293    'arrows_counterclockwise':'\ud83d\udd04',
1294    'art':'\ud83c\udfa8',
1295    'articulated_lorry':'\ud83d\ude9b',
1296    'artificial_satellite':'\ud83d\udef0',
1297    'astonished':'\ud83d\ude32',
1298    'athletic_shoe':'\ud83d\udc5f',
1299    'atm':'\ud83c\udfe7',
1300    'atom_symbol':'\u269b\ufe0f',
1301    'avocado':'\ud83e\udd51',
1302    'b':'\ud83c\udd71\ufe0f',
1303    'baby':'\ud83d\udc76',
1304    'baby_bottle':'\ud83c\udf7c',
1305    'baby_chick':'\ud83d\udc24',
1306    'baby_symbol':'\ud83d\udebc',
1307    'back':'\ud83d\udd19',
1308    'bacon':'\ud83e\udd53',
1309    'badminton':'\ud83c\udff8',
1310    'baggage_claim':'\ud83d\udec4',
1311    'baguette_bread':'\ud83e\udd56',
1312    'balance_scale':'\u2696\ufe0f',
1313    'balloon':'\ud83c\udf88',
1314    'ballot_box':'\ud83d\uddf3',
1315    'ballot_box_with_check':'\u2611\ufe0f',
1316    'bamboo':'\ud83c\udf8d',
1317    'banana':'\ud83c\udf4c',
1318    'bangbang':'\u203c\ufe0f',
1319    'bank':'\ud83c\udfe6',
1320    'bar_chart':'\ud83d\udcca',
1321    'barber':'\ud83d\udc88',
1322    'baseball':'\u26be\ufe0f',
1323    'basketball':'\ud83c\udfc0',
1324    'basketball_man':'\u26f9\ufe0f',
1325    'basketball_woman':'\u26f9\ufe0f&zwj;\u2640\ufe0f',
1326    'bat':'\ud83e\udd87',
1327    'bath':'\ud83d\udec0',
1328    'bathtub':'\ud83d\udec1',
1329    'battery':'\ud83d\udd0b',
1330    'beach_umbrella':'\ud83c\udfd6',
1331    'bear':'\ud83d\udc3b',
1332    'bed':'\ud83d\udecf',
1333    'bee':'\ud83d\udc1d',
1334    'beer':'\ud83c\udf7a',
1335    'beers':'\ud83c\udf7b',
1336    'beetle':'\ud83d\udc1e',
1337    'beginner':'\ud83d\udd30',
1338    'bell':'\ud83d\udd14',
1339    'bellhop_bell':'\ud83d\udece',
1340    'bento':'\ud83c\udf71',
1341    'biking_man':'\ud83d\udeb4',
1342    'bike':'\ud83d\udeb2',
1343    'biking_woman':'\ud83d\udeb4&zwj;\u2640\ufe0f',
1344    'bikini':'\ud83d\udc59',
1345    'biohazard':'\u2623\ufe0f',
1346    'bird':'\ud83d\udc26',
1347    'birthday':'\ud83c\udf82',
1348    'black_circle':'\u26ab\ufe0f',
1349    'black_flag':'\ud83c\udff4',
1350    'black_heart':'\ud83d\udda4',
1351    'black_joker':'\ud83c\udccf',
1352    'black_large_square':'\u2b1b\ufe0f',
1353    'black_medium_small_square':'\u25fe\ufe0f',
1354    'black_medium_square':'\u25fc\ufe0f',
1355    'black_nib':'\u2712\ufe0f',
1356    'black_small_square':'\u25aa\ufe0f',
1357    'black_square_button':'\ud83d\udd32',
1358    'blonde_man':'\ud83d\udc71',
1359    'blonde_woman':'\ud83d\udc71&zwj;\u2640\ufe0f',
1360    'blossom':'\ud83c\udf3c',
1361    'blowfish':'\ud83d\udc21',
1362    'blue_book':'\ud83d\udcd8',
1363    'blue_car':'\ud83d\ude99',
1364    'blue_heart':'\ud83d\udc99',
1365    'blush':'\ud83d\ude0a',
1366    'boar':'\ud83d\udc17',
1367    'boat':'\u26f5\ufe0f',
1368    'bomb':'\ud83d\udca3',
1369    'book':'\ud83d\udcd6',
1370    'bookmark':'\ud83d\udd16',
1371    'bookmark_tabs':'\ud83d\udcd1',
1372    'books':'\ud83d\udcda',
1373    'boom':'\ud83d\udca5',
1374    'boot':'\ud83d\udc62',
1375    'bouquet':'\ud83d\udc90',
1376    'bowing_man':'\ud83d\ude47',
1377    'bow_and_arrow':'\ud83c\udff9',
1378    'bowing_woman':'\ud83d\ude47&zwj;\u2640\ufe0f',
1379    'bowling':'\ud83c\udfb3',
1380    'boxing_glove':'\ud83e\udd4a',
1381    'boy':'\ud83d\udc66',
1382    'bread':'\ud83c\udf5e',
1383    'bride_with_veil':'\ud83d\udc70',
1384    'bridge_at_night':'\ud83c\udf09',
1385    'briefcase':'\ud83d\udcbc',
1386    'broken_heart':'\ud83d\udc94',
1387    'bug':'\ud83d\udc1b',
1388    'building_construction':'\ud83c\udfd7',
1389    'bulb':'\ud83d\udca1',
1390    'bullettrain_front':'\ud83d\ude85',
1391    'bullettrain_side':'\ud83d\ude84',
1392    'burrito':'\ud83c\udf2f',
1393    'bus':'\ud83d\ude8c',
1394    'business_suit_levitating':'\ud83d\udd74',
1395    'busstop':'\ud83d\ude8f',
1396    'bust_in_silhouette':'\ud83d\udc64',
1397    'busts_in_silhouette':'\ud83d\udc65',
1398    'butterfly':'\ud83e\udd8b',
1399    'cactus':'\ud83c\udf35',
1400    'cake':'\ud83c\udf70',
1401    'calendar':'\ud83d\udcc6',
1402    'call_me_hand':'\ud83e\udd19',
1403    'calling':'\ud83d\udcf2',
1404    'camel':'\ud83d\udc2b',
1405    'camera':'\ud83d\udcf7',
1406    'camera_flash':'\ud83d\udcf8',
1407    'camping':'\ud83c\udfd5',
1408    'cancer':'\u264b\ufe0f',
1409    'candle':'\ud83d\udd6f',
1410    'candy':'\ud83c\udf6c',
1411    'canoe':'\ud83d\udef6',
1412    'capital_abcd':'\ud83d\udd20',
1413    'capricorn':'\u2651\ufe0f',
1414    'car':'\ud83d\ude97',
1415    'card_file_box':'\ud83d\uddc3',
1416    'card_index':'\ud83d\udcc7',
1417    'card_index_dividers':'\ud83d\uddc2',
1418    'carousel_horse':'\ud83c\udfa0',
1419    'carrot':'\ud83e\udd55',
1420    'cat':'\ud83d\udc31',
1421    'cat2':'\ud83d\udc08',
1422    'cd':'\ud83d\udcbf',
1423    'chains':'\u26d3',
1424    'champagne':'\ud83c\udf7e',
1425    'chart':'\ud83d\udcb9',
1426    'chart_with_downwards_trend':'\ud83d\udcc9',
1427    'chart_with_upwards_trend':'\ud83d\udcc8',
1428    'checkered_flag':'\ud83c\udfc1',
1429    'cheese':'\ud83e\uddc0',
1430    'cherries':'\ud83c\udf52',
1431    'cherry_blossom':'\ud83c\udf38',
1432    'chestnut':'\ud83c\udf30',
1433    'chicken':'\ud83d\udc14',
1434    'children_crossing':'\ud83d\udeb8',
1435    'chipmunk':'\ud83d\udc3f',
1436    'chocolate_bar':'\ud83c\udf6b',
1437    'christmas_tree':'\ud83c\udf84',
1438    'church':'\u26ea\ufe0f',
1439    'cinema':'\ud83c\udfa6',
1440    'circus_tent':'\ud83c\udfaa',
1441    'city_sunrise':'\ud83c\udf07',
1442    'city_sunset':'\ud83c\udf06',
1443    'cityscape':'\ud83c\udfd9',
1444    'cl':'\ud83c\udd91',
1445    'clamp':'\ud83d\udddc',
1446    'clap':'\ud83d\udc4f',
1447    'clapper':'\ud83c\udfac',
1448    'classical_building':'\ud83c\udfdb',
1449    'clinking_glasses':'\ud83e\udd42',
1450    'clipboard':'\ud83d\udccb',
1451    'clock1':'\ud83d\udd50',
1452    'clock10':'\ud83d\udd59',
1453    'clock1030':'\ud83d\udd65',
1454    'clock11':'\ud83d\udd5a',
1455    'clock1130':'\ud83d\udd66',
1456    'clock12':'\ud83d\udd5b',
1457    'clock1230':'\ud83d\udd67',
1458    'clock130':'\ud83d\udd5c',
1459    'clock2':'\ud83d\udd51',
1460    'clock230':'\ud83d\udd5d',
1461    'clock3':'\ud83d\udd52',
1462    'clock330':'\ud83d\udd5e',
1463    'clock4':'\ud83d\udd53',
1464    'clock430':'\ud83d\udd5f',
1465    'clock5':'\ud83d\udd54',
1466    'clock530':'\ud83d\udd60',
1467    'clock6':'\ud83d\udd55',
1468    'clock630':'\ud83d\udd61',
1469    'clock7':'\ud83d\udd56',
1470    'clock730':'\ud83d\udd62',
1471    'clock8':'\ud83d\udd57',
1472    'clock830':'\ud83d\udd63',
1473    'clock9':'\ud83d\udd58',
1474    'clock930':'\ud83d\udd64',
1475    'closed_book':'\ud83d\udcd5',
1476    'closed_lock_with_key':'\ud83d\udd10',
1477    'closed_umbrella':'\ud83c\udf02',
1478    'cloud':'\u2601\ufe0f',
1479    'cloud_with_lightning':'\ud83c\udf29',
1480    'cloud_with_lightning_and_rain':'\u26c8',
1481    'cloud_with_rain':'\ud83c\udf27',
1482    'cloud_with_snow':'\ud83c\udf28',
1483    'clown_face':'\ud83e\udd21',
1484    'clubs':'\u2663\ufe0f',
1485    'cocktail':'\ud83c\udf78',
1486    'coffee':'\u2615\ufe0f',
1487    'coffin':'\u26b0\ufe0f',
1488    'cold_sweat':'\ud83d\ude30',
1489    'comet':'\u2604\ufe0f',
1490    'computer':'\ud83d\udcbb',
1491    'computer_mouse':'\ud83d\uddb1',
1492    'confetti_ball':'\ud83c\udf8a',
1493    'confounded':'\ud83d\ude16',
1494    'confused':'\ud83d\ude15',
1495    'congratulations':'\u3297\ufe0f',
1496    'construction':'\ud83d\udea7',
1497    'construction_worker_man':'\ud83d\udc77',
1498    'construction_worker_woman':'\ud83d\udc77&zwj;\u2640\ufe0f',
1499    'control_knobs':'\ud83c\udf9b',
1500    'convenience_store':'\ud83c\udfea',
1501    'cookie':'\ud83c\udf6a',
1502    'cool':'\ud83c\udd92',
1503    'policeman':'\ud83d\udc6e',
1504    'copyright':'\u00a9\ufe0f',
1505    'corn':'\ud83c\udf3d',
1506    'couch_and_lamp':'\ud83d\udecb',
1507    'couple':'\ud83d\udc6b',
1508    'couple_with_heart_woman_man':'\ud83d\udc91',
1509    'couple_with_heart_man_man':'\ud83d\udc68&zwj;\u2764\ufe0f&zwj;\ud83d\udc68',
1510    'couple_with_heart_woman_woman':'\ud83d\udc69&zwj;\u2764\ufe0f&zwj;\ud83d\udc69',
1511    'couplekiss_man_man':'\ud83d\udc68&zwj;\u2764\ufe0f&zwj;\ud83d\udc8b&zwj;\ud83d\udc68',
1512    'couplekiss_man_woman':'\ud83d\udc8f',
1513    'couplekiss_woman_woman':'\ud83d\udc69&zwj;\u2764\ufe0f&zwj;\ud83d\udc8b&zwj;\ud83d\udc69',
1514    'cow':'\ud83d\udc2e',
1515    'cow2':'\ud83d\udc04',
1516    'cowboy_hat_face':'\ud83e\udd20',
1517    'crab':'\ud83e\udd80',
1518    'crayon':'\ud83d\udd8d',
1519    'credit_card':'\ud83d\udcb3',
1520    'crescent_moon':'\ud83c\udf19',
1521    'cricket':'\ud83c\udfcf',
1522    'crocodile':'\ud83d\udc0a',
1523    'croissant':'\ud83e\udd50',
1524    'crossed_fingers':'\ud83e\udd1e',
1525    'crossed_flags':'\ud83c\udf8c',
1526    'crossed_swords':'\u2694\ufe0f',
1527    'crown':'\ud83d\udc51',
1528    'cry':'\ud83d\ude22',
1529    'crying_cat_face':'\ud83d\ude3f',
1530    'crystal_ball':'\ud83d\udd2e',
1531    'cucumber':'\ud83e\udd52',
1532    'cupid':'\ud83d\udc98',
1533    'curly_loop':'\u27b0',
1534    'currency_exchange':'\ud83d\udcb1',
1535    'curry':'\ud83c\udf5b',
1536    'custard':'\ud83c\udf6e',
1537    'customs':'\ud83d\udec3',
1538    'cyclone':'\ud83c\udf00',
1539    'dagger':'\ud83d\udde1',
1540    'dancer':'\ud83d\udc83',
1541    'dancing_women':'\ud83d\udc6f',
1542    'dancing_men':'\ud83d\udc6f&zwj;\u2642\ufe0f',
1543    'dango':'\ud83c\udf61',
1544    'dark_sunglasses':'\ud83d\udd76',
1545    'dart':'\ud83c\udfaf',
1546    'dash':'\ud83d\udca8',
1547    'date':'\ud83d\udcc5',
1548    'deciduous_tree':'\ud83c\udf33',
1549    'deer':'\ud83e\udd8c',
1550    'department_store':'\ud83c\udfec',
1551    'derelict_house':'\ud83c\udfda',
1552    'desert':'\ud83c\udfdc',
1553    'desert_island':'\ud83c\udfdd',
1554    'desktop_computer':'\ud83d\udda5',
1555    'male_detective':'\ud83d\udd75\ufe0f',
1556    'diamond_shape_with_a_dot_inside':'\ud83d\udca0',
1557    'diamonds':'\u2666\ufe0f',
1558    'disappointed':'\ud83d\ude1e',
1559    'disappointed_relieved':'\ud83d\ude25',
1560    'dizzy':'\ud83d\udcab',
1561    'dizzy_face':'\ud83d\ude35',
1562    'do_not_litter':'\ud83d\udeaf',
1563    'dog':'\ud83d\udc36',
1564    'dog2':'\ud83d\udc15',
1565    'dollar':'\ud83d\udcb5',
1566    'dolls':'\ud83c\udf8e',
1567    'dolphin':'\ud83d\udc2c',
1568    'door':'\ud83d\udeaa',
1569    'doughnut':'\ud83c\udf69',
1570    'dove':'\ud83d\udd4a',
1571    'dragon':'\ud83d\udc09',
1572    'dragon_face':'\ud83d\udc32',
1573    'dress':'\ud83d\udc57',
1574    'dromedary_camel':'\ud83d\udc2a',
1575    'drooling_face':'\ud83e\udd24',
1576    'droplet':'\ud83d\udca7',
1577    'drum':'\ud83e\udd41',
1578    'duck':'\ud83e\udd86',
1579    'dvd':'\ud83d\udcc0',
1580    'e-mail':'\ud83d\udce7',
1581    'eagle':'\ud83e\udd85',
1582    'ear':'\ud83d\udc42',
1583    'ear_of_rice':'\ud83c\udf3e',
1584    'earth_africa':'\ud83c\udf0d',
1585    'earth_americas':'\ud83c\udf0e',
1586    'earth_asia':'\ud83c\udf0f',
1587    'egg':'\ud83e\udd5a',
1588    'eggplant':'\ud83c\udf46',
1589    'eight_pointed_black_star':'\u2734\ufe0f',
1590    'eight_spoked_asterisk':'\u2733\ufe0f',
1591    'electric_plug':'\ud83d\udd0c',
1592    'elephant':'\ud83d\udc18',
1593    'email':'\u2709\ufe0f',
1594    'end':'\ud83d\udd1a',
1595    'envelope_with_arrow':'\ud83d\udce9',
1596    'euro':'\ud83d\udcb6',
1597    'european_castle':'\ud83c\udff0',
1598    'european_post_office':'\ud83c\udfe4',
1599    'evergreen_tree':'\ud83c\udf32',
1600    'exclamation':'\u2757\ufe0f',
1601    'expressionless':'\ud83d\ude11',
1602    'eye':'\ud83d\udc41',
1603    'eye_speech_bubble':'\ud83d\udc41&zwj;\ud83d\udde8',
1604    'eyeglasses':'\ud83d\udc53',
1605    'eyes':'\ud83d\udc40',
1606    'face_with_head_bandage':'\ud83e\udd15',
1607    'face_with_thermometer':'\ud83e\udd12',
1608    'fist_oncoming':'\ud83d\udc4a',
1609    'factory':'\ud83c\udfed',
1610    'fallen_leaf':'\ud83c\udf42',
1611    'family_man_woman_boy':'\ud83d\udc6a',
1612    'family_man_boy':'\ud83d\udc68&zwj;\ud83d\udc66',
1613    'family_man_boy_boy':'\ud83d\udc68&zwj;\ud83d\udc66&zwj;\ud83d\udc66',
1614    'family_man_girl':'\ud83d\udc68&zwj;\ud83d\udc67',
1615    'family_man_girl_boy':'\ud83d\udc68&zwj;\ud83d\udc67&zwj;\ud83d\udc66',
1616    'family_man_girl_girl':'\ud83d\udc68&zwj;\ud83d\udc67&zwj;\ud83d\udc67',
1617    'family_man_man_boy':'\ud83d\udc68&zwj;\ud83d\udc68&zwj;\ud83d\udc66',
1618    'family_man_man_boy_boy':'\ud83d\udc68&zwj;\ud83d\udc68&zwj;\ud83d\udc66&zwj;\ud83d\udc66',
1619    'family_man_man_girl':'\ud83d\udc68&zwj;\ud83d\udc68&zwj;\ud83d\udc67',
1620    'family_man_man_girl_boy':'\ud83d\udc68&zwj;\ud83d\udc68&zwj;\ud83d\udc67&zwj;\ud83d\udc66',
1621    'family_man_man_girl_girl':'\ud83d\udc68&zwj;\ud83d\udc68&zwj;\ud83d\udc67&zwj;\ud83d\udc67',
1622    'family_man_woman_boy_boy':'\ud83d\udc68&zwj;\ud83d\udc69&zwj;\ud83d\udc66&zwj;\ud83d\udc66',
1623    'family_man_woman_girl':'\ud83d\udc68&zwj;\ud83d\udc69&zwj;\ud83d\udc67',
1624    'family_man_woman_girl_boy':'\ud83d\udc68&zwj;\ud83d\udc69&zwj;\ud83d\udc67&zwj;\ud83d\udc66',
1625    'family_man_woman_girl_girl':'\ud83d\udc68&zwj;\ud83d\udc69&zwj;\ud83d\udc67&zwj;\ud83d\udc67',
1626    'family_woman_boy':'\ud83d\udc69&zwj;\ud83d\udc66',
1627    'family_woman_boy_boy':'\ud83d\udc69&zwj;\ud83d\udc66&zwj;\ud83d\udc66',
1628    'family_woman_girl':'\ud83d\udc69&zwj;\ud83d\udc67',
1629    'family_woman_girl_boy':'\ud83d\udc69&zwj;\ud83d\udc67&zwj;\ud83d\udc66',
1630    'family_woman_girl_girl':'\ud83d\udc69&zwj;\ud83d\udc67&zwj;\ud83d\udc67',
1631    'family_woman_woman_boy':'\ud83d\udc69&zwj;\ud83d\udc69&zwj;\ud83d\udc66',
1632    'family_woman_woman_boy_boy':'\ud83d\udc69&zwj;\ud83d\udc69&zwj;\ud83d\udc66&zwj;\ud83d\udc66',
1633    'family_woman_woman_girl':'\ud83d\udc69&zwj;\ud83d\udc69&zwj;\ud83d\udc67',
1634    'family_woman_woman_girl_boy':'\ud83d\udc69&zwj;\ud83d\udc69&zwj;\ud83d\udc67&zwj;\ud83d\udc66',
1635    'family_woman_woman_girl_girl':'\ud83d\udc69&zwj;\ud83d\udc69&zwj;\ud83d\udc67&zwj;\ud83d\udc67',
1636    'fast_forward':'\u23e9',
1637    'fax':'\ud83d\udce0',
1638    'fearful':'\ud83d\ude28',
1639    'feet':'\ud83d\udc3e',
1640    'female_detective':'\ud83d\udd75\ufe0f&zwj;\u2640\ufe0f',
1641    'ferris_wheel':'\ud83c\udfa1',
1642    'ferry':'\u26f4',
1643    'field_hockey':'\ud83c\udfd1',
1644    'file_cabinet':'\ud83d\uddc4',
1645    'file_folder':'\ud83d\udcc1',
1646    'film_projector':'\ud83d\udcfd',
1647    'film_strip':'\ud83c\udf9e',
1648    'fire':'\ud83d\udd25',
1649    'fire_engine':'\ud83d\ude92',
1650    'fireworks':'\ud83c\udf86',
1651    'first_quarter_moon':'\ud83c\udf13',
1652    'first_quarter_moon_with_face':'\ud83c\udf1b',
1653    'fish':'\ud83d\udc1f',
1654    'fish_cake':'\ud83c\udf65',
1655    'fishing_pole_and_fish':'\ud83c\udfa3',
1656    'fist_raised':'\u270a',
1657    'fist_left':'\ud83e\udd1b',
1658    'fist_right':'\ud83e\udd1c',
1659    'flags':'\ud83c\udf8f',
1660    'flashlight':'\ud83d\udd26',
1661    'fleur_de_lis':'\u269c\ufe0f',
1662    'flight_arrival':'\ud83d\udeec',
1663    'flight_departure':'\ud83d\udeeb',
1664    'floppy_disk':'\ud83d\udcbe',
1665    'flower_playing_cards':'\ud83c\udfb4',
1666    'flushed':'\ud83d\ude33',
1667    'fog':'\ud83c\udf2b',
1668    'foggy':'\ud83c\udf01',
1669    'football':'\ud83c\udfc8',
1670    'footprints':'\ud83d\udc63',
1671    'fork_and_knife':'\ud83c\udf74',
1672    'fountain':'\u26f2\ufe0f',
1673    'fountain_pen':'\ud83d\udd8b',
1674    'four_leaf_clover':'\ud83c\udf40',
1675    'fox_face':'\ud83e\udd8a',
1676    'framed_picture':'\ud83d\uddbc',
1677    'free':'\ud83c\udd93',
1678    'fried_egg':'\ud83c\udf73',
1679    'fried_shrimp':'\ud83c\udf64',
1680    'fries':'\ud83c\udf5f',
1681    'frog':'\ud83d\udc38',
1682    'frowning':'\ud83d\ude26',
1683    'frowning_face':'\u2639\ufe0f',
1684    'frowning_man':'\ud83d\ude4d&zwj;\u2642\ufe0f',
1685    'frowning_woman':'\ud83d\ude4d',
1686    'middle_finger':'\ud83d\udd95',
1687    'fuelpump':'\u26fd\ufe0f',
1688    'full_moon':'\ud83c\udf15',
1689    'full_moon_with_face':'\ud83c\udf1d',
1690    'funeral_urn':'\u26b1\ufe0f',
1691    'game_die':'\ud83c\udfb2',
1692    'gear':'\u2699\ufe0f',
1693    'gem':'\ud83d\udc8e',
1694    'gemini':'\u264a\ufe0f',
1695    'ghost':'\ud83d\udc7b',
1696    'gift':'\ud83c\udf81',
1697    'gift_heart':'\ud83d\udc9d',
1698    'girl':'\ud83d\udc67',
1699    'globe_with_meridians':'\ud83c\udf10',
1700    'goal_net':'\ud83e\udd45',
1701    'goat':'\ud83d\udc10',
1702    'golf':'\u26f3\ufe0f',
1703    'golfing_man':'\ud83c\udfcc\ufe0f',
1704    'golfing_woman':'\ud83c\udfcc\ufe0f&zwj;\u2640\ufe0f',
1705    'gorilla':'\ud83e\udd8d',
1706    'grapes':'\ud83c\udf47',
1707    'green_apple':'\ud83c\udf4f',
1708    'green_book':'\ud83d\udcd7',
1709    'green_heart':'\ud83d\udc9a',
1710    'green_salad':'\ud83e\udd57',
1711    'grey_exclamation':'\u2755',
1712    'grey_question':'\u2754',
1713    'grimacing':'\ud83d\ude2c',
1714    'grin':'\ud83d\ude01',
1715    'grinning':'\ud83d\ude00',
1716    'guardsman':'\ud83d\udc82',
1717    'guardswoman':'\ud83d\udc82&zwj;\u2640\ufe0f',
1718    'guitar':'\ud83c\udfb8',
1719    'gun':'\ud83d\udd2b',
1720    'haircut_woman':'\ud83d\udc87',
1721    'haircut_man':'\ud83d\udc87&zwj;\u2642\ufe0f',
1722    'hamburger':'\ud83c\udf54',
1723    'hammer':'\ud83d\udd28',
1724    'hammer_and_pick':'\u2692',
1725    'hammer_and_wrench':'\ud83d\udee0',
1726    'hamster':'\ud83d\udc39',
1727    'hand':'\u270b',
1728    'handbag':'\ud83d\udc5c',
1729    'handshake':'\ud83e\udd1d',
1730    'hankey':'\ud83d\udca9',
1731    'hatched_chick':'\ud83d\udc25',
1732    'hatching_chick':'\ud83d\udc23',
1733    'headphones':'\ud83c\udfa7',
1734    'hear_no_evil':'\ud83d\ude49',
1735    'heart':'\u2764\ufe0f',
1736    'heart_decoration':'\ud83d\udc9f',
1737    'heart_eyes':'\ud83d\ude0d',
1738    'heart_eyes_cat':'\ud83d\ude3b',
1739    'heartbeat':'\ud83d\udc93',
1740    'heartpulse':'\ud83d\udc97',
1741    'hearts':'\u2665\ufe0f',
1742    'heavy_check_mark':'\u2714\ufe0f',
1743    'heavy_division_sign':'\u2797',
1744    'heavy_dollar_sign':'\ud83d\udcb2',
1745    'heavy_heart_exclamation':'\u2763\ufe0f',
1746    'heavy_minus_sign':'\u2796',
1747    'heavy_multiplication_x':'\u2716\ufe0f',
1748    'heavy_plus_sign':'\u2795',
1749    'helicopter':'\ud83d\ude81',
1750    'herb':'\ud83c\udf3f',
1751    'hibiscus':'\ud83c\udf3a',
1752    'high_brightness':'\ud83d\udd06',
1753    'high_heel':'\ud83d\udc60',
1754    'hocho':'\ud83d\udd2a',
1755    'hole':'\ud83d\udd73',
1756    'honey_pot':'\ud83c\udf6f',
1757    'horse':'\ud83d\udc34',
1758    'horse_racing':'\ud83c\udfc7',
1759    'hospital':'\ud83c\udfe5',
1760    'hot_pepper':'\ud83c\udf36',
1761    'hotdog':'\ud83c\udf2d',
1762    'hotel':'\ud83c\udfe8',
1763    'hotsprings':'\u2668\ufe0f',
1764    'hourglass':'\u231b\ufe0f',
1765    'hourglass_flowing_sand':'\u23f3',
1766    'house':'\ud83c\udfe0',
1767    'house_with_garden':'\ud83c\udfe1',
1768    'houses':'\ud83c\udfd8',
1769    'hugs':'\ud83e\udd17',
1770    'hushed':'\ud83d\ude2f',
1771    'ice_cream':'\ud83c\udf68',
1772    'ice_hockey':'\ud83c\udfd2',
1773    'ice_skate':'\u26f8',
1774    'icecream':'\ud83c\udf66',
1775    'id':'\ud83c\udd94',
1776    'ideograph_advantage':'\ud83c\ude50',
1777    'imp':'\ud83d\udc7f',
1778    'inbox_tray':'\ud83d\udce5',
1779    'incoming_envelope':'\ud83d\udce8',
1780    'tipping_hand_woman':'\ud83d\udc81',
1781    'information_source':'\u2139\ufe0f',
1782    'innocent':'\ud83d\ude07',
1783    'interrobang':'\u2049\ufe0f',
1784    'iphone':'\ud83d\udcf1',
1785    'izakaya_lantern':'\ud83c\udfee',
1786    'jack_o_lantern':'\ud83c\udf83',
1787    'japan':'\ud83d\uddfe',
1788    'japanese_castle':'\ud83c\udfef',
1789    'japanese_goblin':'\ud83d\udc7a',
1790    'japanese_ogre':'\ud83d\udc79',
1791    'jeans':'\ud83d\udc56',
1792    'joy':'\ud83d\ude02',
1793    'joy_cat':'\ud83d\ude39',
1794    'joystick':'\ud83d\udd79',
1795    'kaaba':'\ud83d\udd4b',
1796    'key':'\ud83d\udd11',
1797    'keyboard':'\u2328\ufe0f',
1798    'keycap_ten':'\ud83d\udd1f',
1799    'kick_scooter':'\ud83d\udef4',
1800    'kimono':'\ud83d\udc58',
1801    'kiss':'\ud83d\udc8b',
1802    'kissing':'\ud83d\ude17',
1803    'kissing_cat':'\ud83d\ude3d',
1804    'kissing_closed_eyes':'\ud83d\ude1a',
1805    'kissing_heart':'\ud83d\ude18',
1806    'kissing_smiling_eyes':'\ud83d\ude19',
1807    'kiwi_fruit':'\ud83e\udd5d',
1808    'koala':'\ud83d\udc28',
1809    'koko':'\ud83c\ude01',
1810    'label':'\ud83c\udff7',
1811    'large_blue_circle':'\ud83d\udd35',
1812    'large_blue_diamond':'\ud83d\udd37',
1813    'large_orange_diamond':'\ud83d\udd36',
1814    'last_quarter_moon':'\ud83c\udf17',
1815    'last_quarter_moon_with_face':'\ud83c\udf1c',
1816    'latin_cross':'\u271d\ufe0f',
1817    'laughing':'\ud83d\ude06',
1818    'leaves':'\ud83c\udf43',
1819    'ledger':'\ud83d\udcd2',
1820    'left_luggage':'\ud83d\udec5',
1821    'left_right_arrow':'\u2194\ufe0f',
1822    'leftwards_arrow_with_hook':'\u21a9\ufe0f',
1823    'lemon':'\ud83c\udf4b',
1824    'leo':'\u264c\ufe0f',
1825    'leopard':'\ud83d\udc06',
1826    'level_slider':'\ud83c\udf9a',
1827    'libra':'\u264e\ufe0f',
1828    'light_rail':'\ud83d\ude88',
1829    'link':'\ud83d\udd17',
1830    'lion':'\ud83e\udd81',
1831    'lips':'\ud83d\udc44',
1832    'lipstick':'\ud83d\udc84',
1833    'lizard':'\ud83e\udd8e',
1834    'lock':'\ud83d\udd12',
1835    'lock_with_ink_pen':'\ud83d\udd0f',
1836    'lollipop':'\ud83c\udf6d',
1837    'loop':'\u27bf',
1838    'loud_sound':'\ud83d\udd0a',
1839    'loudspeaker':'\ud83d\udce2',
1840    'love_hotel':'\ud83c\udfe9',
1841    'love_letter':'\ud83d\udc8c',
1842    'low_brightness':'\ud83d\udd05',
1843    'lying_face':'\ud83e\udd25',
1844    'm':'\u24c2\ufe0f',
1845    'mag':'\ud83d\udd0d',
1846    'mag_right':'\ud83d\udd0e',
1847    'mahjong':'\ud83c\udc04\ufe0f',
1848    'mailbox':'\ud83d\udceb',
1849    'mailbox_closed':'\ud83d\udcea',
1850    'mailbox_with_mail':'\ud83d\udcec',
1851    'mailbox_with_no_mail':'\ud83d\udced',
1852    'man':'\ud83d\udc68',
1853    'man_artist':'\ud83d\udc68&zwj;\ud83c\udfa8',
1854    'man_astronaut':'\ud83d\udc68&zwj;\ud83d\ude80',
1855    'man_cartwheeling':'\ud83e\udd38&zwj;\u2642\ufe0f',
1856    'man_cook':'\ud83d\udc68&zwj;\ud83c\udf73',
1857    'man_dancing':'\ud83d\udd7a',
1858    'man_facepalming':'\ud83e\udd26&zwj;\u2642\ufe0f',
1859    'man_factory_worker':'\ud83d\udc68&zwj;\ud83c\udfed',
1860    'man_farmer':'\ud83d\udc68&zwj;\ud83c\udf3e',
1861    'man_firefighter':'\ud83d\udc68&zwj;\ud83d\ude92',
1862    'man_health_worker':'\ud83d\udc68&zwj;\u2695\ufe0f',
1863    'man_in_tuxedo':'\ud83e\udd35',
1864    'man_judge':'\ud83d\udc68&zwj;\u2696\ufe0f',
1865    'man_juggling':'\ud83e\udd39&zwj;\u2642\ufe0f',
1866    'man_mechanic':'\ud83d\udc68&zwj;\ud83d\udd27',
1867    'man_office_worker':'\ud83d\udc68&zwj;\ud83d\udcbc',
1868    'man_pilot':'\ud83d\udc68&zwj;\u2708\ufe0f',
1869    'man_playing_handball':'\ud83e\udd3e&zwj;\u2642\ufe0f',
1870    'man_playing_water_polo':'\ud83e\udd3d&zwj;\u2642\ufe0f',
1871    'man_scientist':'\ud83d\udc68&zwj;\ud83d\udd2c',
1872    'man_shrugging':'\ud83e\udd37&zwj;\u2642\ufe0f',
1873    'man_singer':'\ud83d\udc68&zwj;\ud83c\udfa4',
1874    'man_student':'\ud83d\udc68&zwj;\ud83c\udf93',
1875    'man_teacher':'\ud83d\udc68&zwj;\ud83c\udfeb',
1876    'man_technologist':'\ud83d\udc68&zwj;\ud83d\udcbb',
1877    'man_with_gua_pi_mao':'\ud83d\udc72',
1878    'man_with_turban':'\ud83d\udc73',
1879    'tangerine':'\ud83c\udf4a',
1880    'mans_shoe':'\ud83d\udc5e',
1881    'mantelpiece_clock':'\ud83d\udd70',
1882    'maple_leaf':'\ud83c\udf41',
1883    'martial_arts_uniform':'\ud83e\udd4b',
1884    'mask':'\ud83d\ude37',
1885    'massage_woman':'\ud83d\udc86',
1886    'massage_man':'\ud83d\udc86&zwj;\u2642\ufe0f',
1887    'meat_on_bone':'\ud83c\udf56',
1888    'medal_military':'\ud83c\udf96',
1889    'medal_sports':'\ud83c\udfc5',
1890    'mega':'\ud83d\udce3',
1891    'melon':'\ud83c\udf48',
1892    'memo':'\ud83d\udcdd',
1893    'men_wrestling':'\ud83e\udd3c&zwj;\u2642\ufe0f',
1894    'menorah':'\ud83d\udd4e',
1895    'mens':'\ud83d\udeb9',
1896    'metal':'\ud83e\udd18',
1897    'metro':'\ud83d\ude87',
1898    'microphone':'\ud83c\udfa4',
1899    'microscope':'\ud83d\udd2c',
1900    'milk_glass':'\ud83e\udd5b',
1901    'milky_way':'\ud83c\udf0c',
1902    'minibus':'\ud83d\ude90',
1903    'minidisc':'\ud83d\udcbd',
1904    'mobile_phone_off':'\ud83d\udcf4',
1905    'money_mouth_face':'\ud83e\udd11',
1906    'money_with_wings':'\ud83d\udcb8',
1907    'moneybag':'\ud83d\udcb0',
1908    'monkey':'\ud83d\udc12',
1909    'monkey_face':'\ud83d\udc35',
1910    'monorail':'\ud83d\ude9d',
1911    'moon':'\ud83c\udf14',
1912    'mortar_board':'\ud83c\udf93',
1913    'mosque':'\ud83d\udd4c',
1914    'motor_boat':'\ud83d\udee5',
1915    'motor_scooter':'\ud83d\udef5',
1916    'motorcycle':'\ud83c\udfcd',
1917    'motorway':'\ud83d\udee3',
1918    'mount_fuji':'\ud83d\uddfb',
1919    'mountain':'\u26f0',
1920    'mountain_biking_man':'\ud83d\udeb5',
1921    'mountain_biking_woman':'\ud83d\udeb5&zwj;\u2640\ufe0f',
1922    'mountain_cableway':'\ud83d\udea0',
1923    'mountain_railway':'\ud83d\ude9e',
1924    'mountain_snow':'\ud83c\udfd4',
1925    'mouse':'\ud83d\udc2d',
1926    'mouse2':'\ud83d\udc01',
1927    'movie_camera':'\ud83c\udfa5',
1928    'moyai':'\ud83d\uddff',
1929    'mrs_claus':'\ud83e\udd36',
1930    'muscle':'\ud83d\udcaa',
1931    'mushroom':'\ud83c\udf44',
1932    'musical_keyboard':'\ud83c\udfb9',
1933    'musical_note':'\ud83c\udfb5',
1934    'musical_score':'\ud83c\udfbc',
1935    'mute':'\ud83d\udd07',
1936    'nail_care':'\ud83d\udc85',
1937    'name_badge':'\ud83d\udcdb',
1938    'national_park':'\ud83c\udfde',
1939    'nauseated_face':'\ud83e\udd22',
1940    'necktie':'\ud83d\udc54',
1941    'negative_squared_cross_mark':'\u274e',
1942    'nerd_face':'\ud83e\udd13',
1943    'neutral_face':'\ud83d\ude10',
1944    'new':'\ud83c\udd95',
1945    'new_moon':'\ud83c\udf11',
1946    'new_moon_with_face':'\ud83c\udf1a',
1947    'newspaper':'\ud83d\udcf0',
1948    'newspaper_roll':'\ud83d\uddde',
1949    'next_track_button':'\u23ed',
1950    'ng':'\ud83c\udd96',
1951    'no_good_man':'\ud83d\ude45&zwj;\u2642\ufe0f',
1952    'no_good_woman':'\ud83d\ude45',
1953    'night_with_stars':'\ud83c\udf03',
1954    'no_bell':'\ud83d\udd15',
1955    'no_bicycles':'\ud83d\udeb3',
1956    'no_entry':'\u26d4\ufe0f',
1957    'no_entry_sign':'\ud83d\udeab',
1958    'no_mobile_phones':'\ud83d\udcf5',
1959    'no_mouth':'\ud83d\ude36',
1960    'no_pedestrians':'\ud83d\udeb7',
1961    'no_smoking':'\ud83d\udead',
1962    'non-potable_water':'\ud83d\udeb1',
1963    'nose':'\ud83d\udc43',
1964    'notebook':'\ud83d\udcd3',
1965    'notebook_with_decorative_cover':'\ud83d\udcd4',
1966    'notes':'\ud83c\udfb6',
1967    'nut_and_bolt':'\ud83d\udd29',
1968    'o':'\u2b55\ufe0f',
1969    'o2':'\ud83c\udd7e\ufe0f',
1970    'ocean':'\ud83c\udf0a',
1971    'octopus':'\ud83d\udc19',
1972    'oden':'\ud83c\udf62',
1973    'office':'\ud83c\udfe2',
1974    'oil_drum':'\ud83d\udee2',
1975    'ok':'\ud83c\udd97',
1976    'ok_hand':'\ud83d\udc4c',
1977    'ok_man':'\ud83d\ude46&zwj;\u2642\ufe0f',
1978    'ok_woman':'\ud83d\ude46',
1979    'old_key':'\ud83d\udddd',
1980    'older_man':'\ud83d\udc74',
1981    'older_woman':'\ud83d\udc75',
1982    'om':'\ud83d\udd49',
1983    'on':'\ud83d\udd1b',
1984    'oncoming_automobile':'\ud83d\ude98',
1985    'oncoming_bus':'\ud83d\ude8d',
1986    'oncoming_police_car':'\ud83d\ude94',
1987    'oncoming_taxi':'\ud83d\ude96',
1988    'open_file_folder':'\ud83d\udcc2',
1989    'open_hands':'\ud83d\udc50',
1990    'open_mouth':'\ud83d\ude2e',
1991    'open_umbrella':'\u2602\ufe0f',
1992    'ophiuchus':'\u26ce',
1993    'orange_book':'\ud83d\udcd9',
1994    'orthodox_cross':'\u2626\ufe0f',
1995    'outbox_tray':'\ud83d\udce4',
1996    'owl':'\ud83e\udd89',
1997    'ox':'\ud83d\udc02',
1998    'package':'\ud83d\udce6',
1999    'page_facing_up':'\ud83d\udcc4',
2000    'page_with_curl':'\ud83d\udcc3',
2001    'pager':'\ud83d\udcdf',
2002    'paintbrush':'\ud83d\udd8c',
2003    'palm_tree':'\ud83c\udf34',
2004    'pancakes':'\ud83e\udd5e',
2005    'panda_face':'\ud83d\udc3c',
2006    'paperclip':'\ud83d\udcce',
2007    'paperclips':'\ud83d\udd87',
2008    'parasol_on_ground':'\u26f1',
2009    'parking':'\ud83c\udd7f\ufe0f',
2010    'part_alternation_mark':'\u303d\ufe0f',
2011    'partly_sunny':'\u26c5\ufe0f',
2012    'passenger_ship':'\ud83d\udef3',
2013    'passport_control':'\ud83d\udec2',
2014    'pause_button':'\u23f8',
2015    'peace_symbol':'\u262e\ufe0f',
2016    'peach':'\ud83c\udf51',
2017    'peanuts':'\ud83e\udd5c',
2018    'pear':'\ud83c\udf50',
2019    'pen':'\ud83d\udd8a',
2020    'pencil2':'\u270f\ufe0f',
2021    'penguin':'\ud83d\udc27',
2022    'pensive':'\ud83d\ude14',
2023    'performing_arts':'\ud83c\udfad',
2024    'persevere':'\ud83d\ude23',
2025    'person_fencing':'\ud83e\udd3a',
2026    'pouting_woman':'\ud83d\ude4e',
2027    'phone':'\u260e\ufe0f',
2028    'pick':'\u26cf',
2029    'pig':'\ud83d\udc37',
2030    'pig2':'\ud83d\udc16',
2031    'pig_nose':'\ud83d\udc3d',
2032    'pill':'\ud83d\udc8a',
2033    'pineapple':'\ud83c\udf4d',
2034    'ping_pong':'\ud83c\udfd3',
2035    'pisces':'\u2653\ufe0f',
2036    'pizza':'\ud83c\udf55',
2037    'place_of_worship':'\ud83d\uded0',
2038    'plate_with_cutlery':'\ud83c\udf7d',
2039    'play_or_pause_button':'\u23ef',
2040    'point_down':'\ud83d\udc47',
2041    'point_left':'\ud83d\udc48',
2042    'point_right':'\ud83d\udc49',
2043    'point_up':'\u261d\ufe0f',
2044    'point_up_2':'\ud83d\udc46',
2045    'police_car':'\ud83d\ude93',
2046    'policewoman':'\ud83d\udc6e&zwj;\u2640\ufe0f',
2047    'poodle':'\ud83d\udc29',
2048    'popcorn':'\ud83c\udf7f',
2049    'post_office':'\ud83c\udfe3',
2050    'postal_horn':'\ud83d\udcef',
2051    'postbox':'\ud83d\udcee',
2052    'potable_water':'\ud83d\udeb0',
2053    'potato':'\ud83e\udd54',
2054    'pouch':'\ud83d\udc5d',
2055    'poultry_leg':'\ud83c\udf57',
2056    'pound':'\ud83d\udcb7',
2057    'rage':'\ud83d\ude21',
2058    'pouting_cat':'\ud83d\ude3e',
2059    'pouting_man':'\ud83d\ude4e&zwj;\u2642\ufe0f',
2060    'pray':'\ud83d\ude4f',
2061    'prayer_beads':'\ud83d\udcff',
2062    'pregnant_woman':'\ud83e\udd30',
2063    'previous_track_button':'\u23ee',
2064    'prince':'\ud83e\udd34',
2065    'princess':'\ud83d\udc78',
2066    'printer':'\ud83d\udda8',
2067    'purple_heart':'\ud83d\udc9c',
2068    'purse':'\ud83d\udc5b',
2069    'pushpin':'\ud83d\udccc',
2070    'put_litter_in_its_place':'\ud83d\udeae',
2071    'question':'\u2753',
2072    'rabbit':'\ud83d\udc30',
2073    'rabbit2':'\ud83d\udc07',
2074    'racehorse':'\ud83d\udc0e',
2075    'racing_car':'\ud83c\udfce',
2076    'radio':'\ud83d\udcfb',
2077    'radio_button':'\ud83d\udd18',
2078    'radioactive':'\u2622\ufe0f',
2079    'railway_car':'\ud83d\ude83',
2080    'railway_track':'\ud83d\udee4',
2081    'rainbow':'\ud83c\udf08',
2082    'rainbow_flag':'\ud83c\udff3\ufe0f&zwj;\ud83c\udf08',
2083    'raised_back_of_hand':'\ud83e\udd1a',
2084    'raised_hand_with_fingers_splayed':'\ud83d\udd90',
2085    'raised_hands':'\ud83d\ude4c',
2086    'raising_hand_woman':'\ud83d\ude4b',
2087    'raising_hand_man':'\ud83d\ude4b&zwj;\u2642\ufe0f',
2088    'ram':'\ud83d\udc0f',
2089    'ramen':'\ud83c\udf5c',
2090    'rat':'\ud83d\udc00',
2091    'record_button':'\u23fa',
2092    'recycle':'\u267b\ufe0f',
2093    'red_circle':'\ud83d\udd34',
2094    'registered':'\u00ae\ufe0f',
2095    'relaxed':'\u263a\ufe0f',
2096    'relieved':'\ud83d\ude0c',
2097    'reminder_ribbon':'\ud83c\udf97',
2098    'repeat':'\ud83d\udd01',
2099    'repeat_one':'\ud83d\udd02',
2100    'rescue_worker_helmet':'\u26d1',
2101    'restroom':'\ud83d\udebb',
2102    'revolving_hearts':'\ud83d\udc9e',
2103    'rewind':'\u23ea',
2104    'rhinoceros':'\ud83e\udd8f',
2105    'ribbon':'\ud83c\udf80',
2106    'rice':'\ud83c\udf5a',
2107    'rice_ball':'\ud83c\udf59',
2108    'rice_cracker':'\ud83c\udf58',
2109    'rice_scene':'\ud83c\udf91',
2110    'right_anger_bubble':'\ud83d\uddef',
2111    'ring':'\ud83d\udc8d',
2112    'robot':'\ud83e\udd16',
2113    'rocket':'\ud83d\ude80',
2114    'rofl':'\ud83e\udd23',
2115    'roll_eyes':'\ud83d\ude44',
2116    'roller_coaster':'\ud83c\udfa2',
2117    'rooster':'\ud83d\udc13',
2118    'rose':'\ud83c\udf39',
2119    'rosette':'\ud83c\udff5',
2120    'rotating_light':'\ud83d\udea8',
2121    'round_pushpin':'\ud83d\udccd',
2122    'rowing_man':'\ud83d\udea3',
2123    'rowing_woman':'\ud83d\udea3&zwj;\u2640\ufe0f',
2124    'rugby_football':'\ud83c\udfc9',
2125    'running_man':'\ud83c\udfc3',
2126    'running_shirt_with_sash':'\ud83c\udfbd',
2127    'running_woman':'\ud83c\udfc3&zwj;\u2640\ufe0f',
2128    'sa':'\ud83c\ude02\ufe0f',
2129    'sagittarius':'\u2650\ufe0f',
2130    'sake':'\ud83c\udf76',
2131    'sandal':'\ud83d\udc61',
2132    'santa':'\ud83c\udf85',
2133    'satellite':'\ud83d\udce1',
2134    'saxophone':'\ud83c\udfb7',
2135    'school':'\ud83c\udfeb',
2136    'school_satchel':'\ud83c\udf92',
2137    'scissors':'\u2702\ufe0f',
2138    'scorpion':'\ud83e\udd82',
2139    'scorpius':'\u264f\ufe0f',
2140    'scream':'\ud83d\ude31',
2141    'scream_cat':'\ud83d\ude40',
2142    'scroll':'\ud83d\udcdc',
2143    'seat':'\ud83d\udcba',
2144    'secret':'\u3299\ufe0f',
2145    'see_no_evil':'\ud83d\ude48',
2146    'seedling':'\ud83c\udf31',
2147    'selfie':'\ud83e\udd33',
2148    'shallow_pan_of_food':'\ud83e\udd58',
2149    'shamrock':'\u2618\ufe0f',
2150    'shark':'\ud83e\udd88',
2151    'shaved_ice':'\ud83c\udf67',
2152    'sheep':'\ud83d\udc11',
2153    'shell':'\ud83d\udc1a',
2154    'shield':'\ud83d\udee1',
2155    'shinto_shrine':'\u26e9',
2156    'ship':'\ud83d\udea2',
2157    'shirt':'\ud83d\udc55',
2158    'shopping':'\ud83d\udecd',
2159    'shopping_cart':'\ud83d\uded2',
2160    'shower':'\ud83d\udebf',
2161    'shrimp':'\ud83e\udd90',
2162    'signal_strength':'\ud83d\udcf6',
2163    'six_pointed_star':'\ud83d\udd2f',
2164    'ski':'\ud83c\udfbf',
2165    'skier':'\u26f7',
2166    'skull':'\ud83d\udc80',
2167    'skull_and_crossbones':'\u2620\ufe0f',
2168    'sleeping':'\ud83d\ude34',
2169    'sleeping_bed':'\ud83d\udecc',
2170    'sleepy':'\ud83d\ude2a',
2171    'slightly_frowning_face':'\ud83d\ude41',
2172    'slightly_smiling_face':'\ud83d\ude42',
2173    'slot_machine':'\ud83c\udfb0',
2174    'small_airplane':'\ud83d\udee9',
2175    'small_blue_diamond':'\ud83d\udd39',
2176    'small_orange_diamond':'\ud83d\udd38',
2177    'small_red_triangle':'\ud83d\udd3a',
2178    'small_red_triangle_down':'\ud83d\udd3b',
2179    'smile':'\ud83d\ude04',
2180    'smile_cat':'\ud83d\ude38',
2181    'smiley':'\ud83d\ude03',
2182    'smiley_cat':'\ud83d\ude3a',
2183    'smiling_imp':'\ud83d\ude08',
2184    'smirk':'\ud83d\ude0f',
2185    'smirk_cat':'\ud83d\ude3c',
2186    'smoking':'\ud83d\udeac',
2187    'snail':'\ud83d\udc0c',
2188    'snake':'\ud83d\udc0d',
2189    'sneezing_face':'\ud83e\udd27',
2190    'snowboarder':'\ud83c\udfc2',
2191    'snowflake':'\u2744\ufe0f',
2192    'snowman':'\u26c4\ufe0f',
2193    'snowman_with_snow':'\u2603\ufe0f',
2194    'sob':'\ud83d\ude2d',
2195    'soccer':'\u26bd\ufe0f',
2196    'soon':'\ud83d\udd1c',
2197    'sos':'\ud83c\udd98',
2198    'sound':'\ud83d\udd09',
2199    'space_invader':'\ud83d\udc7e',
2200    'spades':'\u2660\ufe0f',
2201    'spaghetti':'\ud83c\udf5d',
2202    'sparkle':'\u2747\ufe0f',
2203    'sparkler':'\ud83c\udf87',
2204    'sparkles':'\u2728',
2205    'sparkling_heart':'\ud83d\udc96',
2206    'speak_no_evil':'\ud83d\ude4a',
2207    'speaker':'\ud83d\udd08',
2208    'speaking_head':'\ud83d\udde3',
2209    'speech_balloon':'\ud83d\udcac',
2210    'speedboat':'\ud83d\udea4',
2211    'spider':'\ud83d\udd77',
2212    'spider_web':'\ud83d\udd78',
2213    'spiral_calendar':'\ud83d\uddd3',
2214    'spiral_notepad':'\ud83d\uddd2',
2215    'spoon':'\ud83e\udd44',
2216    'squid':'\ud83e\udd91',
2217    'stadium':'\ud83c\udfdf',
2218    'star':'\u2b50\ufe0f',
2219    'star2':'\ud83c\udf1f',
2220    'star_and_crescent':'\u262a\ufe0f',
2221    'star_of_david':'\u2721\ufe0f',
2222    'stars':'\ud83c\udf20',
2223    'station':'\ud83d\ude89',
2224    'statue_of_liberty':'\ud83d\uddfd',
2225    'steam_locomotive':'\ud83d\ude82',
2226    'stew':'\ud83c\udf72',
2227    'stop_button':'\u23f9',
2228    'stop_sign':'\ud83d\uded1',
2229    'stopwatch':'\u23f1',
2230    'straight_ruler':'\ud83d\udccf',
2231    'strawberry':'\ud83c\udf53',
2232    'stuck_out_tongue':'\ud83d\ude1b',
2233    'stuck_out_tongue_closed_eyes':'\ud83d\ude1d',
2234    'stuck_out_tongue_winking_eye':'\ud83d\ude1c',
2235    'studio_microphone':'\ud83c\udf99',
2236    'stuffed_flatbread':'\ud83e\udd59',
2237    'sun_behind_large_cloud':'\ud83c\udf25',
2238    'sun_behind_rain_cloud':'\ud83c\udf26',
2239    'sun_behind_small_cloud':'\ud83c\udf24',
2240    'sun_with_face':'\ud83c\udf1e',
2241    'sunflower':'\ud83c\udf3b',
2242    'sunglasses':'\ud83d\ude0e',
2243    'sunny':'\u2600\ufe0f',
2244    'sunrise':'\ud83c\udf05',
2245    'sunrise_over_mountains':'\ud83c\udf04',
2246    'surfing_man':'\ud83c\udfc4',
2247    'surfing_woman':'\ud83c\udfc4&zwj;\u2640\ufe0f',
2248    'sushi':'\ud83c\udf63',
2249    'suspension_railway':'\ud83d\ude9f',
2250    'sweat':'\ud83d\ude13',
2251    'sweat_drops':'\ud83d\udca6',
2252    'sweat_smile':'\ud83d\ude05',
2253    'sweet_potato':'\ud83c\udf60',
2254    'swimming_man':'\ud83c\udfca',
2255    'swimming_woman':'\ud83c\udfca&zwj;\u2640\ufe0f',
2256    'symbols':'\ud83d\udd23',
2257    'synagogue':'\ud83d\udd4d',
2258    'syringe':'\ud83d\udc89',
2259    'taco':'\ud83c\udf2e',
2260    'tada':'\ud83c\udf89',
2261    'tanabata_tree':'\ud83c\udf8b',
2262    'taurus':'\u2649\ufe0f',
2263    'taxi':'\ud83d\ude95',
2264    'tea':'\ud83c\udf75',
2265    'telephone_receiver':'\ud83d\udcde',
2266    'telescope':'\ud83d\udd2d',
2267    'tennis':'\ud83c\udfbe',
2268    'tent':'\u26fa\ufe0f',
2269    'thermometer':'\ud83c\udf21',
2270    'thinking':'\ud83e\udd14',
2271    'thought_balloon':'\ud83d\udcad',
2272    'ticket':'\ud83c\udfab',
2273    'tickets':'\ud83c\udf9f',
2274    'tiger':'\ud83d\udc2f',
2275    'tiger2':'\ud83d\udc05',
2276    'timer_clock':'\u23f2',
2277    'tipping_hand_man':'\ud83d\udc81&zwj;\u2642\ufe0f',
2278    'tired_face':'\ud83d\ude2b',
2279    'tm':'\u2122\ufe0f',
2280    'toilet':'\ud83d\udebd',
2281    'tokyo_tower':'\ud83d\uddfc',
2282    'tomato':'\ud83c\udf45',
2283    'tongue':'\ud83d\udc45',
2284    'top':'\ud83d\udd1d',
2285    'tophat':'\ud83c\udfa9',
2286    'tornado':'\ud83c\udf2a',
2287    'trackball':'\ud83d\uddb2',
2288    'tractor':'\ud83d\ude9c',
2289    'traffic_light':'\ud83d\udea5',
2290    'train':'\ud83d\ude8b',
2291    'train2':'\ud83d\ude86',
2292    'tram':'\ud83d\ude8a',
2293    'triangular_flag_on_post':'\ud83d\udea9',
2294    'triangular_ruler':'\ud83d\udcd0',
2295    'trident':'\ud83d\udd31',
2296    'triumph':'\ud83d\ude24',
2297    'trolleybus':'\ud83d\ude8e',
2298    'trophy':'\ud83c\udfc6',
2299    'tropical_drink':'\ud83c\udf79',
2300    'tropical_fish':'\ud83d\udc20',
2301    'truck':'\ud83d\ude9a',
2302    'trumpet':'\ud83c\udfba',
2303    'tulip':'\ud83c\udf37',
2304    'tumbler_glass':'\ud83e\udd43',
2305    'turkey':'\ud83e\udd83',
2306    'turtle':'\ud83d\udc22',
2307    'tv':'\ud83d\udcfa',
2308    'twisted_rightwards_arrows':'\ud83d\udd00',
2309    'two_hearts':'\ud83d\udc95',
2310    'two_men_holding_hands':'\ud83d\udc6c',
2311    'two_women_holding_hands':'\ud83d\udc6d',
2312    'u5272':'\ud83c\ude39',
2313    'u5408':'\ud83c\ude34',
2314    'u55b6':'\ud83c\ude3a',
2315    'u6307':'\ud83c\ude2f\ufe0f',
2316    'u6708':'\ud83c\ude37\ufe0f',
2317    'u6709':'\ud83c\ude36',
2318    'u6e80':'\ud83c\ude35',
2319    'u7121':'\ud83c\ude1a\ufe0f',
2320    'u7533':'\ud83c\ude38',
2321    'u7981':'\ud83c\ude32',
2322    'u7a7a':'\ud83c\ude33',
2323    'umbrella':'\u2614\ufe0f',
2324    'unamused':'\ud83d\ude12',
2325    'underage':'\ud83d\udd1e',
2326    'unicorn':'\ud83e\udd84',
2327    'unlock':'\ud83d\udd13',
2328    'up':'\ud83c\udd99',
2329    'upside_down_face':'\ud83d\ude43',
2330    'v':'\u270c\ufe0f',
2331    'vertical_traffic_light':'\ud83d\udea6',
2332    'vhs':'\ud83d\udcfc',
2333    'vibration_mode':'\ud83d\udcf3',
2334    'video_camera':'\ud83d\udcf9',
2335    'video_game':'\ud83c\udfae',
2336    'violin':'\ud83c\udfbb',
2337    'virgo':'\u264d\ufe0f',
2338    'volcano':'\ud83c\udf0b',
2339    'volleyball':'\ud83c\udfd0',
2340    'vs':'\ud83c\udd9a',
2341    'vulcan_salute':'\ud83d\udd96',
2342    'walking_man':'\ud83d\udeb6',
2343    'walking_woman':'\ud83d\udeb6&zwj;\u2640\ufe0f',
2344    'waning_crescent_moon':'\ud83c\udf18',
2345    'waning_gibbous_moon':'\ud83c\udf16',
2346    'warning':'\u26a0\ufe0f',
2347    'wastebasket':'\ud83d\uddd1',
2348    'watch':'\u231a\ufe0f',
2349    'water_buffalo':'\ud83d\udc03',
2350    'watermelon':'\ud83c\udf49',
2351    'wave':'\ud83d\udc4b',
2352    'wavy_dash':'\u3030\ufe0f',
2353    'waxing_crescent_moon':'\ud83c\udf12',
2354    'wc':'\ud83d\udebe',
2355    'weary':'\ud83d\ude29',
2356    'wedding':'\ud83d\udc92',
2357    'weight_lifting_man':'\ud83c\udfcb\ufe0f',
2358    'weight_lifting_woman':'\ud83c\udfcb\ufe0f&zwj;\u2640\ufe0f',
2359    'whale':'\ud83d\udc33',
2360    'whale2':'\ud83d\udc0b',
2361    'wheel_of_dharma':'\u2638\ufe0f',
2362    'wheelchair':'\u267f\ufe0f',
2363    'white_check_mark':'\u2705',
2364    'white_circle':'\u26aa\ufe0f',
2365    'white_flag':'\ud83c\udff3\ufe0f',
2366    'white_flower':'\ud83d\udcae',
2367    'white_large_square':'\u2b1c\ufe0f',
2368    'white_medium_small_square':'\u25fd\ufe0f',
2369    'white_medium_square':'\u25fb\ufe0f',
2370    'white_small_square':'\u25ab\ufe0f',
2371    'white_square_button':'\ud83d\udd33',
2372    'wilted_flower':'\ud83e\udd40',
2373    'wind_chime':'\ud83c\udf90',
2374    'wind_face':'\ud83c\udf2c',
2375    'wine_glass':'\ud83c\udf77',
2376    'wink':'\ud83d\ude09',
2377    'wolf':'\ud83d\udc3a',
2378    'woman':'\ud83d\udc69',
2379    'woman_artist':'\ud83d\udc69&zwj;\ud83c\udfa8',
2380    'woman_astronaut':'\ud83d\udc69&zwj;\ud83d\ude80',
2381    'woman_cartwheeling':'\ud83e\udd38&zwj;\u2640\ufe0f',
2382    'woman_cook':'\ud83d\udc69&zwj;\ud83c\udf73',
2383    'woman_facepalming':'\ud83e\udd26&zwj;\u2640\ufe0f',
2384    'woman_factory_worker':'\ud83d\udc69&zwj;\ud83c\udfed',
2385    'woman_farmer':'\ud83d\udc69&zwj;\ud83c\udf3e',
2386    'woman_firefighter':'\ud83d\udc69&zwj;\ud83d\ude92',
2387    'woman_health_worker':'\ud83d\udc69&zwj;\u2695\ufe0f',
2388    'woman_judge':'\ud83d\udc69&zwj;\u2696\ufe0f',
2389    'woman_juggling':'\ud83e\udd39&zwj;\u2640\ufe0f',
2390    'woman_mechanic':'\ud83d\udc69&zwj;\ud83d\udd27',
2391    'woman_office_worker':'\ud83d\udc69&zwj;\ud83d\udcbc',
2392    'woman_pilot':'\ud83d\udc69&zwj;\u2708\ufe0f',
2393    'woman_playing_handball':'\ud83e\udd3e&zwj;\u2640\ufe0f',
2394    'woman_playing_water_polo':'\ud83e\udd3d&zwj;\u2640\ufe0f',
2395    'woman_scientist':'\ud83d\udc69&zwj;\ud83d\udd2c',
2396    'woman_shrugging':'\ud83e\udd37&zwj;\u2640\ufe0f',
2397    'woman_singer':'\ud83d\udc69&zwj;\ud83c\udfa4',
2398    'woman_student':'\ud83d\udc69&zwj;\ud83c\udf93',
2399    'woman_teacher':'\ud83d\udc69&zwj;\ud83c\udfeb',
2400    'woman_technologist':'\ud83d\udc69&zwj;\ud83d\udcbb',
2401    'woman_with_turban':'\ud83d\udc73&zwj;\u2640\ufe0f',
2402    'womans_clothes':'\ud83d\udc5a',
2403    'womans_hat':'\ud83d\udc52',
2404    'women_wrestling':'\ud83e\udd3c&zwj;\u2640\ufe0f',
2405    'womens':'\ud83d\udeba',
2406    'world_map':'\ud83d\uddfa',
2407    'worried':'\ud83d\ude1f',
2408    'wrench':'\ud83d\udd27',
2409    'writing_hand':'\u270d\ufe0f',
2410    'x':'\u274c',
2411    'yellow_heart':'\ud83d\udc9b',
2412    'yen':'\ud83d\udcb4',
2413    'yin_yang':'\u262f\ufe0f',
2414    'yum':'\ud83d\ude0b',
2415    'zap':'\u26a1\ufe0f',
2416    'zipper_mouth_face':'\ud83e\udd10',
2417    'zzz':'\ud83d\udca4',
2418  
2419    /* special emojis :P */
2420    'octocat':  '<img alt=":octocat:" height="20" width="20" align="absmiddle" src="https://assets-cdn.github.com/images/icons/emoji/octocat.png">',
2421    'showdown': '<span style="font-family: \'Anonymous Pro\', monospace; text-decoration: underline; text-decoration-style: dashed; text-decoration-color: #3e8b8a;text-underline-position: under;">S</span>'
2422  };
2423  
2424  /**
2425   * Created by Estevao on 31-05-2015.
2426   */
2427  
2428  /**
2429   * Showdown Converter class
2430   * @class
2431   * @param {object} [converterOptions]
2432   * @returns {Converter}
2433   */
2434  showdown.Converter = function (converterOptions) {
2435    'use strict';
2436  
2437    var
2438        /**
2439         * Options used by this converter
2440         * @private
2441         * @type {{}}
2442         */
2443        options = {},
2444  
2445        /**
2446         * Language extensions used by this converter
2447         * @private
2448         * @type {Array}
2449         */
2450        langExtensions = [],
2451  
2452        /**
2453         * Output modifiers extensions used by this converter
2454         * @private
2455         * @type {Array}
2456         */
2457        outputModifiers = [],
2458  
2459        /**
2460         * Event listeners
2461         * @private
2462         * @type {{}}
2463         */
2464        listeners = {},
2465  
2466        /**
2467         * The flavor set in this converter
2468         */
2469        setConvFlavor = setFlavor,
2470  
2471      /**
2472       * Metadata of the document
2473       * @type {{parsed: {}, raw: string, format: string}}
2474       */
2475        metadata = {
2476          parsed: {},
2477          raw: '',
2478          format: ''
2479        };
2480  
2481    _constructor();
2482  
2483    /**
2484     * Converter constructor
2485     * @private
2486     */
2487    function _constructor () {
2488      converterOptions = converterOptions || {};
2489  
2490      for (var gOpt in globalOptions) {
2491        if (globalOptions.hasOwnProperty(gOpt)) {
2492          options[gOpt] = globalOptions[gOpt];
2493        }
2494      }
2495  
2496      // Merge options
2497      if (typeof converterOptions === 'object') {
2498        for (var opt in converterOptions) {
2499          if (converterOptions.hasOwnProperty(opt)) {
2500            options[opt] = converterOptions[opt];
2501          }
2502        }
2503      } else {
2504        throw Error('Converter expects the passed parameter to be an object, but ' + typeof converterOptions +
2505        ' was passed instead.');
2506      }
2507  
2508      if (options.extensions) {
2509        showdown.helper.forEach(options.extensions, _parseExtension);
2510      }
2511    }
2512  
2513    /**
2514     * Parse extension
2515     * @param {*} ext
2516     * @param {string} [name='']
2517     * @private
2518     */
2519    function _parseExtension (ext, name) {
2520  
2521      name = name || null;
2522      // If it's a string, the extension was previously loaded
2523      if (showdown.helper.isString(ext)) {
2524        ext = showdown.helper.stdExtName(ext);
2525        name = ext;
2526  
2527        // LEGACY_SUPPORT CODE
2528        if (showdown.extensions[ext]) {
2529          console.warn('DEPRECATION WARNING: ' + ext + ' is an old extension that uses a deprecated loading method.' +
2530            'Please inform the developer that the extension should be updated!');
2531          legacyExtensionLoading(showdown.extensions[ext], ext);
2532          return;
2533        // END LEGACY SUPPORT CODE
2534  
2535        } else if (!showdown.helper.isUndefined(extensions[ext])) {
2536          ext = extensions[ext];
2537  
2538        } else {
2539          throw Error('Extension "' + ext + '" could not be loaded. It was either not found or is not a valid extension.');
2540        }
2541      }
2542  
2543      if (typeof ext === 'function') {
2544        ext = ext();
2545      }
2546  
2547      if (!showdown.helper.isArray(ext)) {
2548        ext = [ext];
2549      }
2550  
2551      var validExt = validate(ext, name);
2552      if (!validExt.valid) {
2553        throw Error(validExt.error);
2554      }
2555  
2556      for (var i = 0; i < ext.length; ++i) {
2557        switch (ext[i].type) {
2558  
2559          case 'lang':
2560            langExtensions.push(ext[i]);
2561            break;
2562  
2563          case 'output':
2564            outputModifiers.push(ext[i]);
2565            break;
2566        }
2567        if (ext[i].hasOwnProperty('listeners')) {
2568          for (var ln in ext[i].listeners) {
2569            if (ext[i].listeners.hasOwnProperty(ln)) {
2570              listen(ln, ext[i].listeners[ln]);
2571            }
2572          }
2573        }
2574      }
2575  
2576    }
2577  
2578    /**
2579     * LEGACY_SUPPORT
2580     * @param {*} ext
2581     * @param {string} name
2582     */
2583    function legacyExtensionLoading (ext, name) {
2584      if (typeof ext === 'function') {
2585        ext = ext(new showdown.Converter());
2586      }
2587      if (!showdown.helper.isArray(ext)) {
2588        ext = [ext];
2589      }
2590      var valid = validate(ext, name);
2591  
2592      if (!valid.valid) {
2593        throw Error(valid.error);
2594      }
2595  
2596      for (var i = 0; i < ext.length; ++i) {
2597        switch (ext[i].type) {
2598          case 'lang':
2599            langExtensions.push(ext[i]);
2600            break;
2601          case 'output':
2602            outputModifiers.push(ext[i]);
2603            break;
2604          default:// should never reach here
2605            throw Error('Extension loader error: Type unrecognized!!!');
2606        }
2607      }
2608    }
2609  
2610    /**
2611     * Listen to an event
2612     * @param {string} name
2613     * @param {function} callback
2614     */
2615    function listen (name, callback) {
2616      if (!showdown.helper.isString(name)) {
2617        throw Error('Invalid argument in converter.listen() method: name must be a string, but ' + typeof name + ' given');
2618      }
2619  
2620      if (typeof callback !== 'function') {
2621        throw Error('Invalid argument in converter.listen() method: callback must be a function, but ' + typeof callback + ' given');
2622      }
2623  
2624      if (!listeners.hasOwnProperty(name)) {
2625        listeners[name] = [];
2626      }
2627      listeners[name].push(callback);
2628    }
2629  
2630    function rTrimInputText (text) {
2631      var rsp = text.match(/^\s*/)[0].length,
2632          rgx = new RegExp('^\\s{0,' + rsp + '}', 'gm');
2633      return text.replace(rgx, '');
2634    }
2635  
2636    /**
2637     * Dispatch an event
2638     * @private
2639     * @param {string} evtName Event name
2640     * @param {string} text Text
2641     * @param {{}} options Converter Options
2642     * @param {{}} globals
2643     * @returns {string}
2644     */
2645    this._dispatch = function dispatch (evtName, text, options, globals) {
2646      if (listeners.hasOwnProperty(evtName)) {
2647        for (var ei = 0; ei < listeners[evtName].length; ++ei) {
2648          var nText = listeners[evtName][ei](evtName, text, this, options, globals);
2649          if (nText && typeof nText !== 'undefined') {
2650            text = nText;
2651          }
2652        }
2653      }
2654      return text;
2655    };
2656  
2657    /**
2658     * Listen to an event
2659     * @param {string} name
2660     * @param {function} callback
2661     * @returns {showdown.Converter}
2662     */
2663    this.listen = function (name, callback) {
2664      listen(name, callback);
2665      return this;
2666    };
2667  
2668    /**
2669     * Converts a markdown string into HTML
2670     * @param {string} text
2671     * @returns {*}
2672     */
2673    this.makeHtml = function (text) {
2674      //check if text is not falsy
2675      if (!text) {
2676        return text;
2677      }
2678  
2679      var globals = {
2680        gHtmlBlocks:     [],
2681        gHtmlMdBlocks:   [],
2682        gHtmlSpans:      [],
2683        gUrls:           {},
2684        gTitles:         {},
2685        gDimensions:     {},
2686        gListLevel:      0,
2687        hashLinkCounts:  {},
2688        langExtensions:  langExtensions,
2689        outputModifiers: outputModifiers,
2690        converter:       this,
2691        ghCodeBlocks:    [],
2692        metadata: {
2693          parsed: {},
2694          raw: '',
2695          format: ''
2696        }
2697      };
2698  
2699      // This lets us use ¨ trema as an escape char to avoid md5 hashes
2700      // The choice of character is arbitrary; anything that isn't
2701      // magic in Markdown will work.
2702      text = text.replace(/¨/g, '¨T');
2703  
2704      // Replace $ with ¨D
2705      // RegExp interprets $ as a special character
2706      // when it's in a replacement string
2707      text = text.replace(/\$/g, '¨D');
2708  
2709      // Standardize line endings
2710      text = text.replace(/\r\n/g, '\n'); // DOS to Unix
2711      text = text.replace(/\r/g, '\n'); // Mac to Unix
2712  
2713      // Stardardize line spaces
2714      text = text.replace(/\u00A0/g, '&nbsp;');
2715  
2716      if (options.smartIndentationFix) {
2717        text = rTrimInputText(text);
2718      }
2719  
2720      // Make sure text begins and ends with a couple of newlines:
2721      text = '\n\n' + text + '\n\n';
2722  
2723      // detab
2724      text = showdown.subParser('detab')(text, options, globals);
2725  
2726      /**
2727       * Strip any lines consisting only of spaces and tabs.
2728       * This makes subsequent regexs easier to write, because we can
2729       * match consecutive blank lines with /\n+/ instead of something
2730       * contorted like /[ \t]*\n+/
2731       */
2732      text = text.replace(/^[ \t]+$/mg, '');
2733  
2734      //run languageExtensions
2735      showdown.helper.forEach(langExtensions, function (ext) {
2736        text = showdown.subParser('runExtension')(ext, text, options, globals);
2737      });
2738  
2739      // run the sub parsers
2740      text = showdown.subParser('metadata')(text, options, globals);
2741      text = showdown.subParser('hashPreCodeTags')(text, options, globals);
2742      text = showdown.subParser('githubCodeBlocks')(text, options, globals);
2743      text = showdown.subParser('hashHTMLBlocks')(text, options, globals);
2744      text = showdown.subParser('hashCodeTags')(text, options, globals);
2745      text = showdown.subParser('stripLinkDefinitions')(text, options, globals);
2746      text = showdown.subParser('blockGamut')(text, options, globals);
2747      text = showdown.subParser('unhashHTMLSpans')(text, options, globals);
2748      text = showdown.subParser('unescapeSpecialChars')(text, options, globals);
2749  
2750      // attacklab: Restore dollar signs
2751      text = text.replace(/¨D/g, '$$');
2752  
2753      // attacklab: Restore tremas
2754      text = text.replace(/¨T/g, '¨');
2755  
2756      // render a complete html document instead of a partial if the option is enabled
2757      text = showdown.subParser('completeHTMLDocument')(text, options, globals);
2758  
2759      // Run output modifiers
2760      showdown.helper.forEach(outputModifiers, function (ext) {
2761        text = showdown.subParser('runExtension')(ext, text, options, globals);
2762      });
2763  
2764      // update metadata
2765      metadata = globals.metadata;
2766      return text;
2767    };
2768  
2769    /**
2770     * Converts an HTML string into a markdown string
2771     * @param src
2772     * @param [HTMLParser] A WHATWG DOM and HTML parser, such as JSDOM. If none is supplied, window.document will be used.
2773     * @returns {string}
2774     */
2775    this.makeMarkdown = this.makeMd = function (src, HTMLParser) {
2776  
2777      // replace \r\n with \n
2778      src = src.replace(/\r\n/g, '\n');
2779      src = src.replace(/\r/g, '\n'); // old macs
2780  
2781      // due to an edge case, we need to find this: > <
2782      // to prevent removing of non silent white spaces
2783      // ex: <em>this is</em> <strong>sparta</strong>
2784      src = src.replace(/>[ \t]+</, '>¨NBSP;<');
2785  
2786      if (!HTMLParser) {
2787        if (window && window.document) {
2788          HTMLParser = window.document;
2789        } else {
2790          throw new Error('HTMLParser is undefined. If in a webworker or nodejs environment, you need to provide a WHATWG DOM and HTML such as JSDOM');
2791        }
2792      }
2793  
2794      var doc = HTMLParser.createElement('div');
2795      doc.innerHTML = src;
2796  
2797      var globals = {
2798        preList: substitutePreCodeTags(doc)
2799      };
2800  
2801      // remove all newlines and collapse spaces
2802      clean(doc);
2803  
2804      // some stuff, like accidental reference links must now be escaped
2805      // TODO
2806      // doc.innerHTML = doc.innerHTML.replace(/\[[\S\t ]]/);
2807  
2808      var nodes = doc.childNodes,
2809          mdDoc = '';
2810  
2811      for (var i = 0; i < nodes.length; i++) {
2812        mdDoc += showdown.subParser('makeMarkdown.node')(nodes[i], globals);
2813      }
2814  
2815      function clean (node) {
2816        for (var n = 0; n < node.childNodes.length; ++n) {
2817          var child = node.childNodes[n];
2818          if (child.nodeType === 3) {
2819            if (!/\S/.test(child.nodeValue)) {
2820              node.removeChild(child);
2821              --n;
2822            } else {
2823              child.nodeValue = child.nodeValue.split('\n').join(' ');
2824              child.nodeValue = child.nodeValue.replace(/(\s)+/g, '$1');
2825            }
2826          } else if (child.nodeType === 1) {
2827            clean(child);
2828          }
2829        }
2830      }
2831  
2832      // find all pre tags and replace contents with placeholder
2833      // we need this so that we can remove all indentation from html
2834      // to ease up parsing
2835      function substitutePreCodeTags (doc) {
2836  
2837        var pres = doc.querySelectorAll('pre'),
2838            presPH = [];
2839  
2840        for (var i = 0; i < pres.length; ++i) {
2841  
2842          if (pres[i].childElementCount === 1 && pres[i].firstChild.tagName.toLowerCase() === 'code') {
2843            var content = pres[i].firstChild.innerHTML.trim(),
2844                language = pres[i].firstChild.getAttribute('data-language') || '';
2845  
2846            // if data-language attribute is not defined, then we look for class language-*
2847            if (language === '') {
2848              var classes = pres[i].firstChild.className.split(' ');
2849              for (var c = 0; c < classes.length; ++c) {
2850                var matches = classes[c].match(/^language-(.+)$/);
2851                if (matches !== null) {
2852                  language = matches[1];
2853                  break;
2854                }
2855              }
2856            }
2857  
2858            // unescape html entities in content
2859            content = showdown.helper.unescapeHTMLEntities(content);
2860  
2861            presPH.push(content);
2862            pres[i].outerHTML = '<precode language="' + language + '" precodenum="' + i.toString() + '"></precode>';
2863          } else {
2864            presPH.push(pres[i].innerHTML);
2865            pres[i].innerHTML = '';
2866            pres[i].setAttribute('prenum', i.toString());
2867          }
2868        }
2869        return presPH;
2870      }
2871  
2872      return mdDoc;
2873    };
2874  
2875    /**
2876     * Set an option of this Converter instance
2877     * @param {string} key
2878     * @param {*} value
2879     */
2880    this.setOption = function (key, value) {
2881      options[key] = value;
2882    };
2883  
2884    /**
2885     * Get the option of this Converter instance
2886     * @param {string} key
2887     * @returns {*}
2888     */
2889    this.getOption = function (key) {
2890      return options[key];
2891    };
2892  
2893    /**
2894     * Get the options of this Converter instance
2895     * @returns {{}}
2896     */
2897    this.getOptions = function () {
2898      return options;
2899    };
2900  
2901    /**
2902     * Add extension to THIS converter
2903     * @param {{}} extension
2904     * @param {string} [name=null]
2905     */
2906    this.addExtension = function (extension, name) {
2907      name = name || null;
2908      _parseExtension(extension, name);
2909    };
2910  
2911    /**
2912     * Use a global registered extension with THIS converter
2913     * @param {string} extensionName Name of the previously registered extension
2914     */
2915    this.useExtension = function (extensionName) {
2916      _parseExtension(extensionName);
2917    };
2918  
2919    /**
2920     * Set the flavor THIS converter should use
2921     * @param {string} name
2922     */
2923    this.setFlavor = function (name) {
2924      if (!flavor.hasOwnProperty(name)) {
2925        throw Error(name + ' flavor was not found');
2926      }
2927      var preset = flavor[name];
2928      setConvFlavor = name;
2929      for (var option in preset) {
2930        if (preset.hasOwnProperty(option)) {
2931          options[option] = preset[option];
2932        }
2933      }
2934    };
2935  
2936    /**
2937     * Get the currently set flavor of this converter
2938     * @returns {string}
2939     */
2940    this.getFlavor = function () {
2941      return setConvFlavor;
2942    };
2943  
2944    /**
2945     * Remove an extension from THIS converter.
2946     * Note: This is a costly operation. It's better to initialize a new converter
2947     * and specify the extensions you wish to use
2948     * @param {Array} extension
2949     */
2950    this.removeExtension = function (extension) {
2951      if (!showdown.helper.isArray(extension)) {
2952        extension = [extension];
2953      }
2954      for (var a = 0; a < extension.length; ++a) {
2955        var ext = extension[a];
2956        for (var i = 0; i < langExtensions.length; ++i) {
2957          if (langExtensions[i] === ext) {
2958            langExtensions[i].splice(i, 1);
2959          }
2960        }
2961        for (var ii = 0; ii < outputModifiers.length; ++i) {
2962          if (outputModifiers[ii] === ext) {
2963            outputModifiers[ii].splice(i, 1);
2964          }
2965        }
2966      }
2967    };
2968  
2969    /**
2970     * Get all extension of THIS converter
2971     * @returns {{language: Array, output: Array}}
2972     */
2973    this.getAllExtensions = function () {
2974      return {
2975        language: langExtensions,
2976        output: outputModifiers
2977      };
2978    };
2979  
2980    /**
2981     * Get the metadata of the previously parsed document
2982     * @param raw
2983     * @returns {string|{}}
2984     */
2985    this.getMetadata = function (raw) {
2986      if (raw) {
2987        return metadata.raw;
2988      } else {
2989        return metadata.parsed;
2990      }
2991    };
2992  
2993    /**
2994     * Get the metadata format of the previously parsed document
2995     * @returns {string}
2996     */
2997    this.getMetadataFormat = function () {
2998      return metadata.format;
2999    };
3000  
3001    /**
3002     * Private: set a single key, value metadata pair
3003     * @param {string} key
3004     * @param {string} value
3005     */
3006    this._setMetadataPair = function (key, value) {
3007      metadata.parsed[key] = value;
3008    };
3009  
3010    /**
3011     * Private: set metadata format
3012     * @param {string} format
3013     */
3014    this._setMetadataFormat = function (format) {
3015      metadata.format = format;
3016    };
3017  
3018    /**
3019     * Private: set metadata raw text
3020     * @param {string} raw
3021     */
3022    this._setMetadataRaw = function (raw) {
3023      metadata.raw = raw;
3024    };
3025  };
3026  
3027  /**
3028   * Turn Markdown link shortcuts into XHTML <a> tags.
3029   */
3030  showdown.subParser('anchors', function (text, options, globals) {
3031    'use strict';
3032  
3033    text = globals.converter._dispatch('anchors.before', text, options, globals);
3034  
3035    var writeAnchorTag = function (wholeMatch, linkText, linkId, url, m5, m6, title) {
3036      if (showdown.helper.isUndefined(title)) {
3037        title = '';
3038      }
3039      linkId = linkId.toLowerCase();
3040  
3041      // Special case for explicit empty url
3042      if (wholeMatch.search(/\(<?\s*>? ?(['"].*['"])?\)$/m) > -1) {
3043        url = '';
3044      } else if (!url) {
3045        if (!linkId) {
3046          // lower-case and turn embedded newlines into spaces
3047          linkId = linkText.toLowerCase().replace(/ ?\n/g, ' ');
3048        }
3049        url = '#' + linkId;
3050  
3051        if (!showdown.helper.isUndefined(globals.gUrls[linkId])) {
3052          url = globals.gUrls[linkId];
3053          if (!showdown.helper.isUndefined(globals.gTitles[linkId])) {
3054            title = globals.gTitles[linkId];
3055          }
3056        } else {
3057          return wholeMatch;
3058        }
3059      }
3060  
3061      //url = showdown.helper.escapeCharacters(url, '*_', false); // replaced line to improve performance
3062      url = url.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback);
3063  
3064      var result = '<a href="' + url + '"';
3065  
3066      if (title !== '' && title !== null) {
3067        title = title.replace(/"/g, '&quot;');
3068        //title = showdown.helper.escapeCharacters(title, '*_', false); // replaced line to improve performance
3069        title = title.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback);
3070        result += ' title="' + title + '"';
3071      }
3072  
3073      // optionLinksInNewWindow only applies
3074      // to external links. Hash links (#) open in same page
3075      if (options.openLinksInNewWindow && !/^#/.test(url)) {
3076        // escaped _
3077        result += ' target="¨E95Eblank"';
3078      }
3079  
3080      result += '>' + linkText + '</a>';
3081  
3082      return result;
3083    };
3084  
3085    // First, handle reference-style links: [link text] [id]
3086    text = text.replace(/\[((?:\[[^\]]*]|[^\[\]])*)] ?(?:\n *)?\[(.*?)]()()()()/g, writeAnchorTag);
3087  
3088    // Next, inline-style links: [link text](url "optional title")
3089    // cases with crazy urls like ./image/cat1).png
3090    text = text.replace(/\[((?:\[[^\]]*]|[^\[\]])*)]()[ \t]*\([ \t]?<([^>]*)>(?:[ \t]*((["'])([^"]*?)\5))?[ \t]?\)/g,
3091      writeAnchorTag);
3092  
3093    // normal cases
3094    text = text.replace(/\[((?:\[[^\]]*]|[^\[\]])*)]()[ \t]*\([ \t]?<?([\S]+?(?:\([\S]*?\)[\S]*?)?)>?(?:[ \t]*((["'])([^"]*?)\5))?[ \t]?\)/g,
3095                        writeAnchorTag);
3096  
3097    // handle reference-style shortcuts: [link text]
3098    // These must come last in case you've also got [link test][1]
3099    // or [link test](/foo)
3100    text = text.replace(/\[([^\[\]]+)]()()()()()/g, writeAnchorTag);
3101  
3102    // Lastly handle GithubMentions if option is enabled
3103    if (options.ghMentions) {
3104      text = text.replace(/(^|\s)(\\)?(@([a-z\d]+(?:[a-z\d.-]+?[a-z\d]+)*))/gmi, function (wm, st, escape, mentions, username) {
3105        if (escape === '\\') {
3106          return st + mentions;
3107        }
3108  
3109        //check if options.ghMentionsLink is a string
3110        if (!showdown.helper.isString(options.ghMentionsLink)) {
3111          throw new Error('ghMentionsLink option must be a string');
3112        }
3113        var lnk = options.ghMentionsLink.replace(/\{u}/g, username),
3114            target = '';
3115        if (options.openLinksInNewWindow) {
3116          target = ' target="¨E95Eblank"';
3117        }
3118        return st + '<a href="' + lnk + '"' + target + '>' + mentions + '</a>';
3119      });
3120    }
3121  
3122    text = globals.converter._dispatch('anchors.after', text, options, globals);
3123    return text;
3124  });
3125  
3126  // url allowed chars [a-z\d_.~:/?#[]@!$&'()*+,;=-]
3127  
3128  var simpleURLRegex  = /([*~_]+|\b)(((https?|ftp|dict):\/\/|www\.)[^'">\s]+?\.[^'">\s]+?)()(\1)?(?=\s|$)(?!["<>])/gi,
3129      simpleURLRegex2 = /([*~_]+|\b)(((https?|ftp|dict):\/\/|www\.)[^'">\s]+\.[^'">\s]+?)([.!?,()\[\]])?(\1)?(?=\s|$)(?!["<>])/gi,
3130      delimUrlRegex   = /()<(((https?|ftp|dict):\/\/|www\.)[^'">\s]+)()>()/gi,
3131      simpleMailRegex = /(^|\s)(?:mailto:)?([A-Za-z0-9!#$%&'*+-/=?^_`{|}~.]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)(?=$|\s)/gmi,
3132      delimMailRegex  = /<()(?:mailto:)?([-.\w]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi,
3133  
3134      replaceLink = function (options) {
3135        'use strict';
3136        return function (wm, leadingMagicChars, link, m2, m3, trailingPunctuation, trailingMagicChars) {
3137          link = link.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback);
3138          var lnkTxt = link,
3139              append = '',
3140              target = '',
3141              lmc    = leadingMagicChars || '',
3142              tmc    = trailingMagicChars || '';
3143          if (/^www\./i.test(link)) {
3144            link = link.replace(/^www\./i, 'http://www.');
3145          }
3146          if (options.excludeTrailingPunctuationFromURLs && trailingPunctuation) {
3147            append = trailingPunctuation;
3148          }
3149          if (options.openLinksInNewWindow) {
3150            target = ' target="¨E95Eblank"';
3151          }
3152          return lmc + '<a href="' + link + '"' + target + '>' + lnkTxt + '</a>' + append + tmc;
3153        };
3154      },
3155  
3156      replaceMail = function (options, globals) {
3157        'use strict';
3158        return function (wholeMatch, b, mail) {
3159          var href = 'mailto:';
3160          b = b || '';
3161          mail = showdown.subParser('unescapeSpecialChars')(mail, options, globals);
3162          if (options.encodeEmails) {
3163            href = showdown.helper.encodeEmailAddress(href + mail);
3164            mail = showdown.helper.encodeEmailAddress(mail);
3165          } else {
3166            href = href + mail;
3167          }
3168          return b + '<a href="' + href + '">' + mail + '</a>';
3169        };
3170      };
3171  
3172  showdown.subParser('autoLinks', function (text, options, globals) {
3173    'use strict';
3174  
3175    text = globals.converter._dispatch('autoLinks.before', text, options, globals);
3176  
3177    text = text.replace(delimUrlRegex, replaceLink(options));
3178    text = text.replace(delimMailRegex, replaceMail(options, globals));
3179  
3180    text = globals.converter._dispatch('autoLinks.after', text, options, globals);
3181  
3182    return text;
3183  });
3184  
3185  showdown.subParser('simplifiedAutoLinks', function (text, options, globals) {
3186    'use strict';
3187  
3188    if (!options.simplifiedAutoLink) {
3189      return text;
3190    }
3191  
3192    text = globals.converter._dispatch('simplifiedAutoLinks.before', text, options, globals);
3193  
3194    if (options.excludeTrailingPunctuationFromURLs) {
3195      text = text.replace(simpleURLRegex2, replaceLink(options));
3196    } else {
3197      text = text.replace(simpleURLRegex, replaceLink(options));
3198    }
3199    text = text.replace(simpleMailRegex, replaceMail(options, globals));
3200  
3201    text = globals.converter._dispatch('simplifiedAutoLinks.after', text, options, globals);
3202  
3203    return text;
3204  });
3205  
3206  /**
3207   * These are all the transformations that form block-level
3208   * tags like paragraphs, headers, and list items.
3209   */
3210  showdown.subParser('blockGamut', function (text, options, globals) {
3211    'use strict';
3212  
3213    text = globals.converter._dispatch('blockGamut.before', text, options, globals);
3214  
3215    // we parse blockquotes first so that we can have headings and hrs
3216    // inside blockquotes
3217    text = showdown.subParser('blockQuotes')(text, options, globals);
3218    text = showdown.subParser('headers')(text, options, globals);
3219  
3220    // Do Horizontal Rules:
3221    text = showdown.subParser('horizontalRule')(text, options, globals);
3222  
3223    text = showdown.subParser('lists')(text, options, globals);
3224    text = showdown.subParser('codeBlocks')(text, options, globals);
3225    text = showdown.subParser('tables')(text, options, globals);
3226  
3227    // We already ran _HashHTMLBlocks() before, in Markdown(), but that
3228    // was to escape raw HTML in the original Markdown source. This time,
3229    // we're escaping the markup we've just created, so that we don't wrap
3230    // <p> tags around block-level tags.
3231    text = showdown.subParser('hashHTMLBlocks')(text, options, globals);
3232    text = showdown.subParser('paragraphs')(text, options, globals);
3233  
3234    text = globals.converter._dispatch('blockGamut.after', text, options, globals);
3235  
3236    return text;
3237  });
3238  
3239  showdown.subParser('blockQuotes', function (text, options, globals) {
3240    'use strict';
3241  
3242    text = globals.converter._dispatch('blockQuotes.before', text, options, globals);
3243  
3244    // add a couple extra lines after the text and endtext mark
3245    text = text + '\n\n';
3246  
3247    var rgx = /(^ {0,3}>[ \t]?.+\n(.+\n)*\n*)+/gm;
3248  
3249    if (options.splitAdjacentBlockquotes) {
3250      rgx = /^ {0,3}>[\s\S]*?(?:\n\n)/gm;
3251    }
3252  
3253    text = text.replace(rgx, function (bq) {
3254      // attacklab: hack around Konqueror 3.5.4 bug:
3255      // "----------bug".replace(/^-/g,"") == "bug"
3256      bq = bq.replace(/^[ \t]*>[ \t]?/gm, ''); // trim one level of quoting
3257  
3258      // attacklab: clean up hack
3259      bq = bq.replace(/¨0/g, '');
3260  
3261      bq = bq.replace(/^[ \t]+$/gm, ''); // trim whitespace-only lines
3262      bq = showdown.subParser('githubCodeBlocks')(bq, options, globals);
3263      bq = showdown.subParser('blockGamut')(bq, options, globals); // recurse
3264  
3265      bq = bq.replace(/(^|\n)/g, '$1  ');
3266      // These leading spaces screw with <pre> content, so we need to fix that:
3267      bq = bq.replace(/(\s*<pre>[^\r]+?<\/pre>)/gm, function (wholeMatch, m1) {
3268        var pre = m1;
3269        // attacklab: hack around Konqueror 3.5.4 bug:
3270        pre = pre.replace(/^  /mg, '¨0');
3271        pre = pre.replace(/¨0/g, '');
3272        return pre;
3273      });
3274  
3275      return showdown.subParser('hashBlock')('<blockquote>\n' + bq + '\n</blockquote>', options, globals);
3276    });
3277  
3278    text = globals.converter._dispatch('blockQuotes.after', text, options, globals);
3279    return text;
3280  });
3281  
3282  /**
3283   * Process Markdown `<pre><code>` blocks.
3284   */
3285  showdown.subParser('codeBlocks', function (text, options, globals) {
3286    'use strict';
3287  
3288    text = globals.converter._dispatch('codeBlocks.before', text, options, globals);
3289  
3290    // sentinel workarounds for lack of \A and \Z, safari\khtml bug
3291    text += '¨0';
3292  
3293    var pattern = /(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=¨0))/g;
3294    text = text.replace(pattern, function (wholeMatch, m1, m2) {
3295      var codeblock = m1,
3296          nextChar = m2,
3297          end = '\n';
3298  
3299      codeblock = showdown.subParser('outdent')(codeblock, options, globals);
3300      codeblock = showdown.subParser('encodeCode')(codeblock, options, globals);
3301      codeblock = showdown.subParser('detab')(codeblock, options, globals);
3302      codeblock = codeblock.replace(/^\n+/g, ''); // trim leading newlines
3303      codeblock = codeblock.replace(/\n+$/g, ''); // trim trailing newlines
3304  
3305      if (options.omitExtraWLInCodeBlocks) {
3306        end = '';
3307      }
3308  
3309      codeblock = '<pre><code>' + codeblock + end + '</code></pre>';
3310  
3311      return showdown.subParser('hashBlock')(codeblock, options, globals) + nextChar;
3312    });
3313  
3314    // strip sentinel
3315    text = text.replace(/¨0/, '');
3316  
3317    text = globals.converter._dispatch('codeBlocks.after', text, options, globals);
3318    return text;
3319  });
3320  
3321  /**
3322   *
3323   *   *  Backtick quotes are used for <code></code> spans.
3324   *
3325   *   *  You can use multiple backticks as the delimiters if you want to
3326   *     include literal backticks in the code span. So, this input:
3327   *
3328   *         Just type ``foo `bar` baz`` at the prompt.
3329   *
3330   *       Will translate to:
3331   *
3332   *         <p>Just type <code>foo `bar` baz</code> at the prompt.</p>
3333   *
3334   *    There's no arbitrary limit to the number of backticks you
3335   *    can use as delimters. If you need three consecutive backticks
3336   *    in your code, use four for delimiters, etc.
3337   *
3338   *  *  You can use spaces to get literal backticks at the edges:
3339   *
3340   *         ... type `` `bar` `` ...
3341   *
3342   *       Turns to:
3343   *
3344   *         ... type <code>`bar`</code> ...
3345   */
3346  showdown.subParser('codeSpans', function (text, options, globals) {
3347    'use strict';
3348  
3349    text = globals.converter._dispatch('codeSpans.before', text, options, globals);
3350  
3351    if (typeof(text) === 'undefined') {
3352      text = '';
3353    }
3354    text = text.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm,
3355      function (wholeMatch, m1, m2, m3) {
3356        var c = m3;
3357        c = c.replace(/^([ \t]*)/g, '');    // leading whitespace
3358        c = c.replace(/[ \t]*$/g, '');    // trailing whitespace
3359        c = showdown.subParser('encodeCode')(c, options, globals);
3360        c = m1 + '<code>' + c + '</code>';
3361        c = showdown.subParser('hashHTMLSpans')(c, options, globals);
3362        return c;
3363      }
3364    );
3365  
3366    text = globals.converter._dispatch('codeSpans.after', text, options, globals);
3367    return text;
3368  });
3369  
3370  /**
3371   * Create a full HTML document from the processed markdown
3372   */
3373  showdown.subParser('completeHTMLDocument', function (text, options, globals) {
3374    'use strict';
3375  
3376    if (!options.completeHTMLDocument) {
3377      return text;
3378    }
3379  
3380    text = globals.converter._dispatch('completeHTMLDocument.before', text, options, globals);
3381  
3382    var doctype = 'html',
3383        doctypeParsed = '<!DOCTYPE HTML>\n',
3384        title = '',
3385        charset = '<meta charset="utf-8">\n',
3386        lang = '',
3387        metadata = '';
3388  
3389    if (typeof globals.metadata.parsed.doctype !== 'undefined') {
3390      doctypeParsed = '<!DOCTYPE ' +  globals.metadata.parsed.doctype + '>\n';
3391      doctype = globals.metadata.parsed.doctype.toString().toLowerCase();
3392      if (doctype === 'html' || doctype === 'html5') {
3393        charset = '<meta charset="utf-8">';
3394      }
3395    }
3396  
3397    for (var meta in globals.metadata.parsed) {
3398      if (globals.metadata.parsed.hasOwnProperty(meta)) {
3399        switch (meta.toLowerCase()) {
3400          case 'doctype':
3401            break;
3402  
3403          case 'title':
3404            title = '<title>' +  globals.metadata.parsed.title + '</title>\n';
3405            break;
3406  
3407          case 'charset':
3408            if (doctype === 'html' || doctype === 'html5') {
3409              charset = '<meta charset="' + globals.metadata.parsed.charset + '">\n';
3410            } else {
3411              charset = '<meta name="charset" content="' + globals.metadata.parsed.charset + '">\n';
3412            }
3413            break;
3414  
3415          case 'language':
3416          case 'lang':
3417            lang = ' lang="' + globals.metadata.parsed[meta] + '"';
3418            metadata += '<meta name="' + meta + '" content="' + globals.metadata.parsed[meta] + '">\n';
3419            break;
3420  
3421          default:
3422            metadata += '<meta name="' + meta + '" content="' + globals.metadata.parsed[meta] + '">\n';
3423        }
3424      }
3425    }
3426  
3427    text = doctypeParsed + '<html' + lang + '>\n<head>\n' + title + charset + metadata + '</head>\n<body>\n' + text.trim() + '\n</body>\n</html>';
3428  
3429    text = globals.converter._dispatch('completeHTMLDocument.after', text, options, globals);
3430    return text;
3431  });
3432  
3433  /**
3434   * Convert all tabs to spaces
3435   */
3436  showdown.subParser('detab', function (text, options, globals) {
3437    'use strict';
3438    text = globals.converter._dispatch('detab.before', text, options, globals);
3439  
3440    // expand first n-1 tabs
3441    text = text.replace(/\t(?=\t)/g, '    '); // g_tab_width
3442  
3443    // replace the nth with two sentinels
3444    text = text.replace(/\t/g, '¨A¨B');
3445  
3446    // use the sentinel to anchor our regex so it doesn't explode
3447    text = text.replace(/¨B(.+?)¨A/g, function (wholeMatch, m1) {
3448      var leadingText = m1,
3449          numSpaces = 4 - leadingText.length % 4;  // g_tab_width
3450  
3451      // there *must* be a better way to do this:
3452      for (var i = 0; i < numSpaces; i++) {
3453        leadingText += ' ';
3454      }
3455  
3456      return leadingText;
3457    });
3458  
3459    // clean up sentinels
3460    text = text.replace(/¨A/g, '    ');  // g_tab_width
3461    text = text.replace(/¨B/g, '');
3462  
3463    text = globals.converter._dispatch('detab.after', text, options, globals);
3464    return text;
3465  });
3466  
3467  showdown.subParser('ellipsis', function (text, options, globals) {
3468    'use strict';
3469  
3470    text = globals.converter._dispatch('ellipsis.before', text, options, globals);
3471  
3472    text = text.replace(/\.\.\./g, '…');
3473  
3474    text = globals.converter._dispatch('ellipsis.after', text, options, globals);
3475  
3476    return text;
3477  });
3478  
3479  /**
3480   * Turn emoji codes into emojis
3481   *
3482   * List of supported emojis: https://github.com/showdownjs/showdown/wiki/Emojis
3483   */
3484  showdown.subParser('emoji', function (text, options, globals) {
3485    'use strict';
3486  
3487    if (!options.emoji) {
3488      return text;
3489    }
3490  
3491    text = globals.converter._dispatch('emoji.before', text, options, globals);
3492  
3493    var emojiRgx = /:([\S]+?):/g;
3494  
3495    text = text.replace(emojiRgx, function (wm, emojiCode) {
3496      if (showdown.helper.emojis.hasOwnProperty(emojiCode)) {
3497        return showdown.helper.emojis[emojiCode];
3498      }
3499      return wm;
3500    });
3501  
3502    text = globals.converter._dispatch('emoji.after', text, options, globals);
3503  
3504    return text;
3505  });
3506  
3507  /**
3508   * Smart processing for ampersands and angle brackets that need to be encoded.
3509   */
3510  showdown.subParser('encodeAmpsAndAngles', function (text, options, globals) {
3511    'use strict';
3512    text = globals.converter._dispatch('encodeAmpsAndAngles.before', text, options, globals);
3513  
3514    // Ampersand-encoding based entirely on Nat Irons's Amputator MT plugin:
3515    // http://bumppo.net/projects/amputator/
3516    text = text.replace(/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/g, '&amp;');
3517  
3518    // Encode naked <'s
3519    text = text.replace(/<(?![a-z\/?$!])/gi, '&lt;');
3520  
3521    // Encode <
3522    text = text.replace(/</g, '&lt;');
3523  
3524    // Encode >
3525    text = text.replace(/>/g, '&gt;');
3526  
3527    text = globals.converter._dispatch('encodeAmpsAndAngles.after', text, options, globals);
3528    return text;
3529  });
3530  
3531  /**
3532   * Returns the string, with after processing the following backslash escape sequences.
3533   *
3534   * attacklab: The polite way to do this is with the new escapeCharacters() function:
3535   *
3536   *    text = escapeCharacters(text,"\\",true);
3537   *    text = escapeCharacters(text,"`*_{}[]()>#+-.!",true);
3538   *
3539   * ...but we're sidestepping its use of the (slow) RegExp constructor
3540   * as an optimization for Firefox.  This function gets called a LOT.
3541   */
3542  showdown.subParser('encodeBackslashEscapes', function (text, options, globals) {
3543    'use strict';
3544    text = globals.converter._dispatch('encodeBackslashEscapes.before', text, options, globals);
3545  
3546    text = text.replace(/\\(\\)/g, showdown.helper.escapeCharactersCallback);
3547    text = text.replace(/\\([`*_{}\[\]()>#+.!~=|-])/g, showdown.helper.escapeCharactersCallback);
3548  
3549    text = globals.converter._dispatch('encodeBackslashEscapes.after', text, options, globals);
3550    return text;
3551  });
3552  
3553  /**
3554   * Encode/escape certain characters inside Markdown code runs.
3555   * The point is that in code, these characters are literals,
3556   * and lose their special Markdown meanings.
3557   */
3558  showdown.subParser('encodeCode', function (text, options, globals) {
3559    'use strict';
3560  
3561    text = globals.converter._dispatch('encodeCode.before', text, options, globals);
3562  
3563    // Encode all ampersands; HTML entities are not
3564    // entities within a Markdown code span.
3565    text = text
3566      .replace(/&/g, '&amp;')
3567    // Do the angle bracket song and dance:
3568      .replace(/</g, '&lt;')
3569      .replace(/>/g, '&gt;')
3570    // Now, escape characters that are magic in Markdown:
3571      .replace(/([*_{}\[\]\\=~-])/g, showdown.helper.escapeCharactersCallback);
3572  
3573    text = globals.converter._dispatch('encodeCode.after', text, options, globals);
3574    return text;
3575  });
3576  
3577  /**
3578   * Within tags -- meaning between < and > -- encode [\ ` * _ ~ =] so they
3579   * don't conflict with their use in Markdown for code, italics and strong.
3580   */
3581  showdown.subParser('escapeSpecialCharsWithinTagAttributes', function (text, options, globals) {
3582    'use strict';
3583    text = globals.converter._dispatch('escapeSpecialCharsWithinTagAttributes.before', text, options, globals);
3584  
3585    // Build a regex to find HTML tags.
3586    var tags     = /<\/?[a-z\d_:-]+(?:[\s]+[\s\S]+?)?>/gi,
3587        comments = /<!(--(?:(?:[^>-]|-[^>])(?:[^-]|-[^-])*)--)>/gi;
3588  
3589    text = text.replace(tags, function (wholeMatch) {
3590      return wholeMatch
3591        .replace(/(.)<\/?code>(?=.)/g, '$1`')
3592        .replace(/([\\`*_~=|])/g, showdown.helper.escapeCharactersCallback);
3593    });
3594  
3595    text = text.replace(comments, function (wholeMatch) {
3596      return wholeMatch
3597        .replace(/([\\`*_~=|])/g, showdown.helper.escapeCharactersCallback);
3598    });
3599  
3600    text = globals.converter._dispatch('escapeSpecialCharsWithinTagAttributes.after', text, options, globals);
3601    return text;
3602  });
3603  
3604  /**
3605   * Handle github codeblocks prior to running HashHTML so that
3606   * HTML contained within the codeblock gets escaped properly
3607   * Example:
3608   * ```ruby
3609   *     def hello_world(x)
3610   *       puts "Hello, #{x}"
3611   *     end
3612   * ```
3613   */
3614  showdown.subParser('githubCodeBlocks', function (text, options, globals) {
3615    'use strict';
3616  
3617    // early exit if option is not enabled
3618    if (!options.ghCodeBlocks) {
3619      return text;
3620    }
3621  
3622    text = globals.converter._dispatch('githubCodeBlocks.before', text, options, globals);
3623  
3624    text += '¨0';
3625  
3626    text = text.replace(/(?:^|\n)(?: {0,3})(```+|~~~+)(?: *)([^\s`~]*)\n([\s\S]*?)\n(?: {0,3})\1/g, function (wholeMatch, delim, language, codeblock) {
3627      var end = (options.omitExtraWLInCodeBlocks) ? '' : '\n';
3628  
3629      // First parse the github code block
3630      codeblock = showdown.subParser('encodeCode')(codeblock, options, globals);
3631      codeblock = showdown.subParser('detab')(codeblock, options, globals);
3632      codeblock = codeblock.replace(/^\n+/g, ''); // trim leading newlines
3633      codeblock = codeblock.replace(/\n+$/g, ''); // trim trailing whitespace
3634  
3635      codeblock = '<pre><code' + (language ? ' class="' + language + ' language-' + language + '"' : '') + '>' + codeblock + end + '</code></pre>';
3636  
3637      codeblock = showdown.subParser('hashBlock')(codeblock, options, globals);
3638  
3639      // Since GHCodeblocks can be false positives, we need to
3640      // store the primitive text and the parsed text in a global var,
3641      // and then return a token
3642      return '\n\n¨G' + (globals.ghCodeBlocks.push({text: wholeMatch, codeblock: codeblock}) - 1) + 'G\n\n';
3643    });
3644  
3645    // attacklab: strip sentinel
3646    text = text.replace(/¨0/, '');
3647  
3648    return globals.converter._dispatch('githubCodeBlocks.after', text, options, globals);
3649  });
3650  
3651  showdown.subParser('hashBlock', function (text, options, globals) {
3652    'use strict';
3653    text = globals.converter._dispatch('hashBlock.before', text, options, globals);
3654    text = text.replace(/(^\n+|\n+$)/g, '');
3655    text = '\n\n¨K' + (globals.gHtmlBlocks.push(text) - 1) + 'K\n\n';
3656    text = globals.converter._dispatch('hashBlock.after', text, options, globals);
3657    return text;
3658  });
3659  
3660  /**
3661   * Hash and escape <code> elements that should not be parsed as markdown
3662   */
3663  showdown.subParser('hashCodeTags', function (text, options, globals) {
3664    'use strict';
3665    text = globals.converter._dispatch('hashCodeTags.before', text, options, globals);
3666  
3667    var repFunc = function (wholeMatch, match, left, right) {
3668      var codeblock = left + showdown.subParser('encodeCode')(match, options, globals) + right;
3669      return '¨C' + (globals.gHtmlSpans.push(codeblock) - 1) + 'C';
3670    };
3671  
3672    // Hash naked <code>
3673    text = showdown.helper.replaceRecursiveRegExp(text, repFunc, '<code\\b[^>]*>', '</code>', 'gim');
3674  
3675    text = globals.converter._dispatch('hashCodeTags.after', text, options, globals);
3676    return text;
3677  });
3678  
3679  showdown.subParser('hashElement', function (text, options, globals) {
3680    'use strict';
3681  
3682    return function (wholeMatch, m1) {
3683      var blockText = m1;
3684  
3685      // Undo double lines
3686      blockText = blockText.replace(/\n\n/g, '\n');
3687      blockText = blockText.replace(/^\n/, '');
3688  
3689      // strip trailing blank lines
3690      blockText = blockText.replace(/\n+$/g, '');
3691  
3692      // Replace the element text with a marker ("¨KxK" where x is its key)
3693      blockText = '\n\n¨K' + (globals.gHtmlBlocks.push(blockText) - 1) + 'K\n\n';
3694  
3695      return blockText;
3696    };
3697  });
3698  
3699  showdown.subParser('hashHTMLBlocks', function (text, options, globals) {
3700    'use strict';
3701    text = globals.converter._dispatch('hashHTMLBlocks.before', text, options, globals);
3702  
3703    var blockTags = [
3704          'pre',
3705          'div',
3706          'h1',
3707          'h2',
3708          'h3',
3709          'h4',
3710          'h5',
3711          'h6',
3712          'blockquote',
3713          'table',
3714          'dl',
3715          'ol',
3716          'ul',
3717          'script',
3718          'noscript',
3719          'form',
3720          'fieldset',
3721          'iframe',
3722          'math',
3723          'style',
3724          'section',
3725          'header',
3726          'footer',
3727          'nav',
3728          'article',
3729          'aside',
3730          'address',
3731          'audio',
3732          'canvas',
3733          'figure',
3734          'hgroup',
3735          'output',
3736          'video',
3737          'p'
3738        ],
3739        repFunc = function (wholeMatch, match, left, right) {
3740          var txt = wholeMatch;
3741          // check if this html element is marked as markdown
3742          // if so, it's contents should be parsed as markdown
3743          if (left.search(/\bmarkdown\b/) !== -1) {
3744            txt = left + globals.converter.makeHtml(match) + right;
3745          }
3746          return '\n\n¨K' + (globals.gHtmlBlocks.push(txt) - 1) + 'K\n\n';
3747        };
3748  
3749    if (options.backslashEscapesHTMLTags) {
3750      // encode backslash escaped HTML tags
3751      text = text.replace(/\\<(\/?[^>]+?)>/g, function (wm, inside) {
3752        return '&lt;' + inside + '&gt;';
3753      });
3754    }
3755  
3756    // hash HTML Blocks
3757    for (var i = 0; i < blockTags.length; ++i) {
3758  
3759      var opTagPos,
3760          rgx1     = new RegExp('^ {0,3}(<' + blockTags[i] + '\\b[^>]*>)', 'im'),
3761          patLeft  = '<' + blockTags[i] + '\\b[^>]*>',
3762          patRight = '</' + blockTags[i] + '>';
3763      // 1. Look for the first position of the first opening HTML tag in the text
3764      while ((opTagPos = showdown.helper.regexIndexOf(text, rgx1)) !== -1) {
3765  
3766        // if the HTML tag is \ escaped, we need to escape it and break
3767  
3768  
3769        //2. Split the text in that position
3770        var subTexts = showdown.helper.splitAtIndex(text, opTagPos),
3771        //3. Match recursively
3772            newSubText1 = showdown.helper.replaceRecursiveRegExp(subTexts[1], repFunc, patLeft, patRight, 'im');
3773  
3774        // prevent an infinite loop
3775        if (newSubText1 === subTexts[1]) {
3776          break;
3777        }
3778        text = subTexts[0].concat(newSubText1);
3779      }
3780    }
3781    // HR SPECIAL CASE
3782    text = text.replace(/(\n {0,3}(<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g,
3783      showdown.subParser('hashElement')(text, options, globals));
3784  
3785    // Special case for standalone HTML comments
3786    text = showdown.helper.replaceRecursiveRegExp(text, function (txt) {
3787      return '\n\n¨K' + (globals.gHtmlBlocks.push(txt) - 1) + 'K\n\n';
3788    }, '^ {0,3}<!--', '-->', 'gm');
3789  
3790    // PHP and ASP-style processor instructions (<?...?> and <%...%>)
3791    text = text.replace(/(?:\n\n)( {0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g,
3792      showdown.subParser('hashElement')(text, options, globals));
3793  
3794    text = globals.converter._dispatch('hashHTMLBlocks.after', text, options, globals);
3795    return text;
3796  });
3797  
3798  /**
3799   * Hash span elements that should not be parsed as markdown
3800   */
3801  showdown.subParser('hashHTMLSpans', function (text, options, globals) {
3802    'use strict';
3803    text = globals.converter._dispatch('hashHTMLSpans.before', text, options, globals);
3804  
3805    function hashHTMLSpan (html) {
3806      return '¨C' + (globals.gHtmlSpans.push(html) - 1) + 'C';
3807    }
3808  
3809    // Hash Self Closing tags
3810    text = text.replace(/<[^>]+?\/>/gi, function (wm) {
3811      return hashHTMLSpan(wm);
3812    });
3813  
3814    // Hash tags without properties
3815    text = text.replace(/<([^>]+?)>[\s\S]*?<\/\1>/g, function (wm) {
3816      return hashHTMLSpan(wm);
3817    });
3818  
3819    // Hash tags with properties
3820    text = text.replace(/<([^>]+?)\s[^>]+?>[\s\S]*?<\/\1>/g, function (wm) {
3821      return hashHTMLSpan(wm);
3822    });
3823  
3824    // Hash self closing tags without />
3825    text = text.replace(/<[^>]+?>/gi, function (wm) {
3826      return hashHTMLSpan(wm);
3827    });
3828  
3829    /*showdown.helper.matchRecursiveRegExp(text, '<code\\b[^>]*>', '</code>', 'gi');*/
3830  
3831    text = globals.converter._dispatch('hashHTMLSpans.after', text, options, globals);
3832    return text;
3833  });
3834  
3835  /**
3836   * Unhash HTML spans
3837   */
3838  showdown.subParser('unhashHTMLSpans', function (text, options, globals) {
3839    'use strict';
3840    text = globals.converter._dispatch('unhashHTMLSpans.before', text, options, globals);
3841  
3842    for (var i = 0; i < globals.gHtmlSpans.length; ++i) {
3843      var repText = globals.gHtmlSpans[i],
3844          // limiter to prevent infinite loop (assume 10 as limit for recurse)
3845          limit = 0;
3846  
3847      while (/¨C(\d+)C/.test(repText)) {
3848        var num = RegExp.$1;
3849        repText = repText.replace('¨C' + num + 'C', globals.gHtmlSpans[num]);
3850        if (limit === 10) {
3851          console.error('maximum nesting of 10 spans reached!!!');
3852          break;
3853        }
3854        ++limit;
3855      }
3856      text = text.replace('¨C' + i + 'C', repText);
3857    }
3858  
3859    text = globals.converter._dispatch('unhashHTMLSpans.after', text, options, globals);
3860    return text;
3861  });
3862  
3863  /**
3864   * Hash and escape <pre><code> elements that should not be parsed as markdown
3865   */
3866  showdown.subParser('hashPreCodeTags', function (text, options, globals) {
3867    'use strict';
3868    text = globals.converter._dispatch('hashPreCodeTags.before', text, options, globals);
3869  
3870    var repFunc = function (wholeMatch, match, left, right) {
3871      // encode html entities
3872      var codeblock = left + showdown.subParser('encodeCode')(match, options, globals) + right;
3873      return '\n\n¨G' + (globals.ghCodeBlocks.push({text: wholeMatch, codeblock: codeblock}) - 1) + 'G\n\n';
3874    };
3875  
3876    // Hash <pre><code>
3877    text = showdown.helper.replaceRecursiveRegExp(text, repFunc, '^ {0,3}<pre\\b[^>]*>\\s*<code\\b[^>]*>', '^ {0,3}</code>\\s*</pre>', 'gim');
3878  
3879    text = globals.converter._dispatch('hashPreCodeTags.after', text, options, globals);
3880    return text;
3881  });
3882  
3883  showdown.subParser('headers', function (text, options, globals) {
3884    'use strict';
3885  
3886    text = globals.converter._dispatch('headers.before', text, options, globals);
3887  
3888    var headerLevelStart = (isNaN(parseInt(options.headerLevelStart))) ? 1 : parseInt(options.headerLevelStart),
3889  
3890    // Set text-style headers:
3891    //    Header 1
3892    //    ========
3893    //
3894    //    Header 2
3895    //    --------
3896    //
3897        setextRegexH1 = (options.smoothLivePreview) ? /^(.+)[ \t]*\n={2,}[ \t]*\n+/gm : /^(.+)[ \t]*\n=+[ \t]*\n+/gm,
3898        setextRegexH2 = (options.smoothLivePreview) ? /^(.+)[ \t]*\n-{2,}[ \t]*\n+/gm : /^(.+)[ \t]*\n-+[ \t]*\n+/gm;
3899  
3900    text = text.replace(setextRegexH1, function (wholeMatch, m1) {
3901  
3902      var spanGamut = showdown.subParser('spanGamut')(m1, options, globals),
3903          hID = (options.noHeaderId) ? '' : ' id="' + headerId(m1) + '"',
3904          hLevel = headerLevelStart,
3905          hashBlock = '<h' + hLevel + hID + '>' + spanGamut + '</h' + hLevel + '>';
3906      return showdown.subParser('hashBlock')(hashBlock, options, globals);
3907    });
3908  
3909    text = text.replace(setextRegexH2, function (matchFound, m1) {
3910      var spanGamut = showdown.subParser('spanGamut')(m1, options, globals),
3911          hID = (options.noHeaderId) ? '' : ' id="' + headerId(m1) + '"',
3912          hLevel = headerLevelStart + 1,
3913          hashBlock = '<h' + hLevel + hID + '>' + spanGamut + '</h' + hLevel + '>';
3914      return showdown.subParser('hashBlock')(hashBlock, options, globals);
3915    });
3916  
3917    // atx-style headers:
3918    //  # Header 1
3919    //  ## Header 2
3920    //  ## Header 2 with closing hashes ##
3921    //  ...
3922    //  ###### Header 6
3923    //
3924    var atxStyle = (options.requireSpaceBeforeHeadingText) ? /^(#{1,6})[ \t]+(.+?)[ \t]*#*\n+/gm : /^(#{1,6})[ \t]*(.+?)[ \t]*#*\n+/gm;
3925  
3926    text = text.replace(atxStyle, function (wholeMatch, m1, m2) {
3927      var hText = m2;
3928      if (options.customizedHeaderId) {
3929        hText = m2.replace(/\s?\{([^{]+?)}\s*$/, '');
3930      }
3931  
3932      var span = showdown.subParser('spanGamut')(hText, options, globals),
3933          hID = (options.noHeaderId) ? '' : ' id="' + headerId(m2) + '"',
3934          hLevel = headerLevelStart - 1 + m1.length,
3935          header = '<h' + hLevel + hID + '>' + span + '</h' + hLevel + '>';
3936  
3937      return showdown.subParser('hashBlock')(header, options, globals);
3938    });
3939  
3940    function headerId (m) {
3941      var title,
3942          prefix;
3943  
3944      // It is separate from other options to allow combining prefix and customized
3945      if (options.customizedHeaderId) {
3946        var match = m.match(/\{([^{]+?)}\s*$/);
3947        if (match && match[1]) {
3948          m = match[1];
3949        }
3950      }
3951  
3952      title = m;
3953  
3954      // Prefix id to prevent causing inadvertent pre-existing style matches.
3955      if (showdown.helper.isString(options.prefixHeaderId)) {
3956        prefix = options.prefixHeaderId;
3957      } else if (options.prefixHeaderId === true) {
3958        prefix = 'section-';
3959      } else {
3960        prefix = '';
3961      }
3962  
3963      if (!options.rawPrefixHeaderId) {
3964        title = prefix + title;
3965      }
3966  
3967      if (options.ghCompatibleHeaderId) {
3968        title = title
3969          .replace(/ /g, '-')
3970          // replace previously escaped chars (&, ¨ and $)
3971          .replace(/&amp;/g, '')
3972          .replace(/¨T/g, '')
3973          .replace(/¨D/g, '')
3974          // replace rest of the chars (&~$ are repeated as they might have been escaped)
3975          // borrowed from github's redcarpet (some they should produce similar results)
3976          .replace(/[&+$,\/:;=?@"#{}|^¨~\[\]`\\*)(%.!'<>]/g, '')
3977          .toLowerCase();
3978      } else if (options.rawHeaderId) {
3979        title = title
3980          .replace(/ /g, '-')
3981          // replace previously escaped chars (&, ¨ and $)
3982          .replace(/&amp;/g, '&')
3983          .replace(/¨T/g, '¨')
3984          .replace(/¨D/g, '$')
3985          // replace " and '
3986          .replace(/["']/g, '-')
3987          .toLowerCase();
3988      } else {
3989        title = title
3990          .replace(/[^\w]/g, '')
3991          .toLowerCase();
3992      }
3993  
3994      if (options.rawPrefixHeaderId) {
3995        title = prefix + title;
3996      }
3997  
3998      if (globals.hashLinkCounts[title]) {
3999        title = title + '-' + (globals.hashLinkCounts[title]++);
4000      } else {
4001        globals.hashLinkCounts[title] = 1;
4002      }
4003      return title;
4004    }
4005  
4006    text = globals.converter._dispatch('headers.after', text, options, globals);
4007    return text;
4008  });
4009  
4010  /**
4011   * Turn Markdown link shortcuts into XHTML <a> tags.
4012   */
4013  showdown.subParser('horizontalRule', function (text, options, globals) {
4014    'use strict';
4015    text = globals.converter._dispatch('horizontalRule.before', text, options, globals);
4016  
4017    var key = showdown.subParser('hashBlock')('<hr />', options, globals);
4018    text = text.replace(/^ {0,2}( ?-){3,}[ \t]*$/gm, key);
4019    text = text.replace(/^ {0,2}( ?\*){3,}[ \t]*$/gm, key);
4020    text = text.replace(/^ {0,2}( ?_){3,}[ \t]*$/gm, key);
4021  
4022    text = globals.converter._dispatch('horizontalRule.after', text, options, globals);
4023    return text;
4024  });
4025  
4026  /**
4027   * Turn Markdown image shortcuts into <img> tags.
4028   */
4029  showdown.subParser('images', function (text, options, globals) {
4030    'use strict';
4031  
4032    text = globals.converter._dispatch('images.before', text, options, globals);
4033  
4034    var inlineRegExp      = /!\[([^\]]*?)][ \t]*()\([ \t]?<?([\S]+?(?:\([\S]*?\)[\S]*?)?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(["'])([^"]*?)\6)?[ \t]?\)/g,
4035        crazyRegExp       = /!\[([^\]]*?)][ \t]*()\([ \t]?<([^>]*)>(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(?:(["'])([^"]*?)\6))?[ \t]?\)/g,
4036        base64RegExp      = /!\[([^\]]*?)][ \t]*()\([ \t]?<?(data:.+?\/.+?;base64,[A-Za-z0-9+/=\n]+?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(["'])([^"]*?)\6)?[ \t]?\)/g,
4037        referenceRegExp   = /!\[([^\]]*?)] ?(?:\n *)?\[([\s\S]*?)]()()()()()/g,
4038        refShortcutRegExp = /!\[([^\[\]]+)]()()()()()/g;
4039  
4040    function writeImageTagBase64 (wholeMatch, altText, linkId, url, width, height, m5, title) {
4041      url = url.replace(/\s/g, '');
4042      return writeImageTag (wholeMatch, altText, linkId, url, width, height, m5, title);
4043    }
4044  
4045    function writeImageTag (wholeMatch, altText, linkId, url, width, height, m5, title) {
4046  
4047      var gUrls   = globals.gUrls,
4048          gTitles = globals.gTitles,
4049          gDims   = globals.gDimensions;
4050  
4051      linkId = linkId.toLowerCase();
4052  
4053      if (!title) {
4054        title = '';
4055      }
4056      // Special case for explicit empty url
4057      if (wholeMatch.search(/\(<?\s*>? ?(['"].*['"])?\)$/m) > -1) {
4058        url = '';
4059  
4060      } else if (url === '' || url === null) {
4061        if (linkId === '' || linkId === null) {
4062          // lower-case and turn embedded newlines into spaces
4063          linkId = altText.toLowerCase().replace(/ ?\n/g, ' ');
4064        }
4065        url = '#' + linkId;
4066  
4067        if (!showdown.helper.isUndefined(gUrls[linkId])) {
4068          url = gUrls[linkId];
4069          if (!showdown.helper.isUndefined(gTitles[linkId])) {
4070            title = gTitles[linkId];
4071          }
4072          if (!showdown.helper.isUndefined(gDims[linkId])) {
4073            width = gDims[linkId].width;
4074            height = gDims[linkId].height;
4075          }
4076        } else {
4077          return wholeMatch;
4078        }
4079      }
4080  
4081      altText = altText
4082        .replace(/"/g, '&quot;')
4083      //altText = showdown.helper.escapeCharacters(altText, '*_', false);
4084        .replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback);
4085      //url = showdown.helper.escapeCharacters(url, '*_', false);
4086      url = url.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback);
4087      var result = '<img src="' + url + '" alt="' + altText + '"';
4088  
4089      if (title && showdown.helper.isString(title)) {
4090        title = title
4091          .replace(/"/g, '&quot;')
4092        //title = showdown.helper.escapeCharacters(title, '*_', false);
4093          .replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback);
4094        result += ' title="' + title + '"';
4095      }
4096  
4097      if (width && height) {
4098        width  = (width === '*') ? 'auto' : width;
4099        height = (height === '*') ? 'auto' : height;
4100  
4101        result += ' width="' + width + '"';
4102        result += ' height="' + height + '"';
4103      }
4104  
4105      result += ' />';
4106  
4107      return result;
4108    }
4109  
4110    // First, handle reference-style labeled images: ![alt text][id]
4111    text = text.replace(referenceRegExp, writeImageTag);
4112  
4113    // Next, handle inline images:  ![alt text](url =<width>x<height> "optional title")
4114  
4115    // base64 encoded images
4116    text = text.replace(base64RegExp, writeImageTagBase64);
4117  
4118    // cases with crazy urls like ./image/cat1).png
4119    text = text.replace(crazyRegExp, writeImageTag);
4120  
4121    // normal cases
4122    text = text.replace(inlineRegExp, writeImageTag);
4123  
4124    // handle reference-style shortcuts: ![img text]
4125    text = text.replace(refShortcutRegExp, writeImageTag);
4126  
4127    text = globals.converter._dispatch('images.after', text, options, globals);
4128    return text;
4129  });
4130  
4131  showdown.subParser('italicsAndBold', function (text, options, globals) {
4132    'use strict';
4133  
4134    text = globals.converter._dispatch('italicsAndBold.before', text, options, globals);
4135  
4136    // it's faster to have 3 separate regexes for each case than have just one
4137    // because of backtracing, in some cases, it could lead to an exponential effect
4138    // called "catastrophic backtrace". Ominous!
4139  
4140    function parseInside (txt, left, right) {
4141      /*
4142      if (options.simplifiedAutoLink) {
4143        txt = showdown.subParser('simplifiedAutoLinks')(txt, options, globals);
4144      }
4145      */
4146      return left + txt + right;
4147    }
4148  
4149    // Parse underscores
4150    if (options.literalMidWordUnderscores) {
4151      text = text.replace(/\b___(\S[\s\S]*?)___\b/g, function (wm, txt) {
4152        return parseInside (txt, '<strong><em>', '</em></strong>');
4153      });
4154      text = text.replace(/\b__(\S[\s\S]*?)__\b/g, function (wm, txt) {
4155        return parseInside (txt, '<strong>', '</strong>');
4156      });
4157      text = text.replace(/\b_(\S[\s\S]*?)_\b/g, function (wm, txt) {
4158        return parseInside (txt, '<em>', '</em>');
4159      });
4160    } else {
4161      text = text.replace(/___(\S[\s\S]*?)___/g, function (wm, m) {
4162        return (/\S$/.test(m)) ? parseInside (m, '<strong><em>', '</em></strong>') : wm;
4163      });
4164      text = text.replace(/__(\S[\s\S]*?)__/g, function (wm, m) {
4165        return (/\S$/.test(m)) ? parseInside (m, '<strong>', '</strong>') : wm;
4166      });
4167      text = text.replace(/_([^\s_][\s\S]*?)_/g, function (wm, m) {
4168        // !/^_[^_]/.test(m) - test if it doesn't start with __ (since it seems redundant, we removed it)
4169        return (/\S$/.test(m)) ? parseInside (m, '<em>', '</em>') : wm;
4170      });
4171    }
4172  
4173    // Now parse asterisks
4174    if (options.literalMidWordAsterisks) {
4175      text = text.replace(/([^*]|^)\B\*\*\*(\S[\s\S]*?)\*\*\*\B(?!\*)/g, function (wm, lead, txt) {
4176        return parseInside (txt, lead + '<strong><em>', '</em></strong>');
4177      });
4178      text = text.replace(/([^*]|^)\B\*\*(\S[\s\S]*?)\*\*\B(?!\*)/g, function (wm, lead, txt) {
4179        return parseInside (txt, lead + '<strong>', '</strong>');
4180      });
4181      text = text.replace(/([^*]|^)\B\*(\S[\s\S]*?)\*\B(?!\*)/g, function (wm, lead, txt) {
4182        return parseInside (txt, lead + '<em>', '</em>');
4183      });
4184    } else {
4185      text = text.replace(/\*\*\*(\S[\s\S]*?)\*\*\*/g, function (wm, m) {
4186        return (/\S$/.test(m)) ? parseInside (m, '<strong><em>', '</em></strong>') : wm;
4187      });
4188      text = text.replace(/\*\*(\S[\s\S]*?)\*\*/g, function (wm, m) {
4189        return (/\S$/.test(m)) ? parseInside (m, '<strong>', '</strong>') : wm;
4190      });
4191      text = text.replace(/\*([^\s*][\s\S]*?)\*/g, function (wm, m) {
4192        // !/^\*[^*]/.test(m) - test if it doesn't start with ** (since it seems redundant, we removed it)
4193        return (/\S$/.test(m)) ? parseInside (m, '<em>', '</em>') : wm;
4194      });
4195    }
4196  
4197  
4198    text = globals.converter._dispatch('italicsAndBold.after', text, options, globals);
4199    return text;
4200  });
4201  
4202  /**
4203   * Form HTML ordered (numbered) and unordered (bulleted) lists.
4204   */
4205  showdown.subParser('lists', function (text, options, globals) {
4206    'use strict';
4207  
4208    /**
4209     * Process the contents of a single ordered or unordered list, splitting it
4210     * into individual list items.
4211     * @param {string} listStr
4212     * @param {boolean} trimTrailing
4213     * @returns {string}
4214     */
4215    function processListItems (listStr, trimTrailing) {
4216      // The $g_list_level global keeps track of when we're inside a list.
4217      // Each time we enter a list, we increment it; when we leave a list,
4218      // we decrement. If it's zero, we're not in a list anymore.
4219      //
4220      // We do this because when we're not inside a list, we want to treat
4221      // something like this:
4222      //
4223      //    I recommend upgrading to version
4224      //    8. Oops, now this line is treated
4225      //    as a sub-list.
4226      //
4227      // As a single paragraph, despite the fact that the second line starts
4228      // with a digit-period-space sequence.
4229      //
4230      // Whereas when we're inside a list (or sub-list), that line will be
4231      // treated as the start of a sub-list. What a kludge, huh? This is
4232      // an aspect of Markdown's syntax that's hard to parse perfectly
4233      // without resorting to mind-reading. Perhaps the solution is to
4234      // change the syntax rules such that sub-lists must start with a
4235      // starting cardinal number; e.g. "1." or "a.".
4236      globals.gListLevel++;
4237  
4238      // trim trailing blank lines:
4239      listStr = listStr.replace(/\n{2,}$/, '\n');
4240  
4241      // attacklab: add sentinel to emulate \z
4242      listStr += '¨0';
4243  
4244      var rgx = /(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0| {0,3}([*+-]|\d+[.])[ \t]+))/gm,
4245          isParagraphed = (/\n[ \t]*\n(?!¨0)/.test(listStr));
4246  
4247      // Since version 1.5, nesting sublists requires 4 spaces (or 1 tab) indentation,
4248      // which is a syntax breaking change
4249      // activating this option reverts to old behavior
4250      if (options.disableForced4SpacesIndentedSublists) {
4251        rgx = /(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0|\2([*+-]|\d+[.])[ \t]+))/gm;
4252      }
4253  
4254      listStr = listStr.replace(rgx, function (wholeMatch, m1, m2, m3, m4, taskbtn, checked) {
4255        checked = (checked && checked.trim() !== '');
4256  
4257        var item = showdown.subParser('outdent')(m4, options, globals),
4258            bulletStyle = '';
4259  
4260        // Support for github tasklists
4261        if (taskbtn && options.tasklists) {
4262          bulletStyle = ' class="task-list-item" style="list-style-type: none;"';
4263          item = item.replace(/^[ \t]*\[(x|X| )?]/m, function () {
4264            var otp = '<input type="checkbox" disabled style="margin: 0px 0.35em 0.25em -1.6em; vertical-align: middle;"';
4265            if (checked) {
4266              otp += ' checked';
4267            }
4268            otp += '>';
4269            return otp;
4270          });
4271        }
4272  
4273        // ISSUE #312
4274        // This input: - - - a
4275        // causes trouble to the parser, since it interprets it as:
4276        // <ul><li><li><li>a</li></li></li></ul>
4277        // instead of:
4278        // <ul><li>- - a</li></ul>
4279        // So, to prevent it, we will put a marker (¨A)in the beginning of the line
4280        // Kind of hackish/monkey patching, but seems more effective than overcomplicating the list parser
4281        item = item.replace(/^([-*+]|\d\.)[ \t]+[\S\n ]*/g, function (wm2) {
4282          return '¨A' + wm2;
4283        });
4284  
4285        // m1 - Leading line or
4286        // Has a double return (multi paragraph) or
4287        // Has sublist
4288        if (m1 || (item.search(/\n{2,}/) > -1)) {
4289          item = showdown.subParser('githubCodeBlocks')(item, options, globals);
4290          item = showdown.subParser('blockGamut')(item, options, globals);
4291        } else {
4292          // Recursion for sub-lists:
4293          item = showdown.subParser('lists')(item, options, globals);
4294          item = item.replace(/\n$/, ''); // chomp(item)
4295          item = showdown.subParser('hashHTMLBlocks')(item, options, globals);
4296  
4297          // Colapse double linebreaks
4298          item = item.replace(/\n\n+/g, '\n\n');
4299          if (isParagraphed) {
4300            item = showdown.subParser('paragraphs')(item, options, globals);
4301          } else {
4302            item = showdown.subParser('spanGamut')(item, options, globals);
4303          }
4304        }
4305  
4306        // now we need to remove the marker (¨A)
4307        item = item.replace('¨A', '');
4308        // we can finally wrap the line in list item tags
4309        item =  '<li' + bulletStyle + '>' + item + '</li>\n';
4310  
4311        return item;
4312      });
4313  
4314      // attacklab: strip sentinel
4315      listStr = listStr.replace(/¨0/g, '');
4316  
4317      globals.gListLevel--;
4318  
4319      if (trimTrailing) {
4320        listStr = listStr.replace(/\s+$/, '');
4321      }
4322  
4323      return listStr;
4324    }
4325  
4326    function styleStartNumber (list, listType) {
4327      // check if ol and starts by a number different than 1
4328      if (listType === 'ol') {
4329        var res = list.match(/^ *(\d+)\./);
4330        if (res && res[1] !== '1') {
4331          return ' start="' + res[1] + '"';
4332        }
4333      }
4334      return '';
4335    }
4336  
4337    /**
4338     * Check and parse consecutive lists (better fix for issue #142)
4339     * @param {string} list
4340     * @param {string} listType
4341     * @param {boolean} trimTrailing
4342     * @returns {string}
4343     */
4344    function parseConsecutiveLists (list, listType, trimTrailing) {
4345      // check if we caught 2 or more consecutive lists by mistake
4346      // we use the counterRgx, meaning if listType is UL we look for OL and vice versa
4347      var olRgx = (options.disableForced4SpacesIndentedSublists) ? /^ ?\d+\.[ \t]/gm : /^ {0,3}\d+\.[ \t]/gm,
4348          ulRgx = (options.disableForced4SpacesIndentedSublists) ? /^ ?[*+-][ \t]/gm : /^ {0,3}[*+-][ \t]/gm,
4349          counterRxg = (listType === 'ul') ? olRgx : ulRgx,
4350          result = '';
4351  
4352      if (list.search(counterRxg) !== -1) {
4353        (function parseCL (txt) {
4354          var pos = txt.search(counterRxg),
4355              style = styleStartNumber(list, listType);
4356          if (pos !== -1) {
4357            // slice
4358            result += '\n\n<' + listType + style + '>\n' + processListItems(txt.slice(0, pos), !!trimTrailing) + '</' + listType + '>\n';
4359  
4360            // invert counterType and listType
4361            listType = (listType === 'ul') ? 'ol' : 'ul';
4362            counterRxg = (listType === 'ul') ? olRgx : ulRgx;
4363  
4364            //recurse
4365            parseCL(txt.slice(pos));
4366          } else {
4367            result += '\n\n<' + listType + style + '>\n' + processListItems(txt, !!trimTrailing) + '</' + listType + '>\n';
4368          }
4369        })(list);
4370      } else {
4371        var style = styleStartNumber(list, listType);
4372        result = '\n\n<' + listType + style + '>\n' + processListItems(list, !!trimTrailing) + '</' + listType + '>\n';
4373      }
4374  
4375      return result;
4376    }
4377  
4378    /** Start of list parsing **/
4379    text = globals.converter._dispatch('lists.before', text, options, globals);
4380    // add sentinel to hack around khtml/safari bug:
4381    // http://bugs.webkit.org/show_bug.cgi?id=11231
4382    text += '¨0';
4383  
4384    if (globals.gListLevel) {
4385      text = text.replace(/^(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(¨0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm,
4386        function (wholeMatch, list, m2) {
4387          var listType = (m2.search(/[*+-]/g) > -1) ? 'ul' : 'ol';
4388          return parseConsecutiveLists(list, listType, true);
4389        }
4390      );
4391    } else {
4392      text = text.replace(/(\n\n|^\n?)(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(¨0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm,
4393        function (wholeMatch, m1, list, m3) {
4394          var listType = (m3.search(/[*+-]/g) > -1) ? 'ul' : 'ol';
4395          return parseConsecutiveLists(list, listType, false);
4396        }
4397      );
4398    }
4399  
4400    // strip sentinel
4401    text = text.replace(/¨0/, '');
4402    text = globals.converter._dispatch('lists.after', text, options, globals);
4403    return text;
4404  });
4405  
4406  /**
4407   * Parse metadata at the top of the document
4408   */
4409  showdown.subParser('metadata', function (text, options, globals) {
4410    'use strict';
4411  
4412    if (!options.metadata) {
4413      return text;
4414    }
4415  
4416    text = globals.converter._dispatch('metadata.before', text, options, globals);
4417  
4418    function parseMetadataContents (content) {
4419      // raw is raw so it's not changed in any way
4420      globals.metadata.raw = content;
4421  
4422      // escape chars forbidden in html attributes
4423      // double quotes
4424      content = content
4425        // ampersand first
4426        .replace(/&/g, '&amp;')
4427        // double quotes
4428        .replace(/"/g, '&quot;');
4429  
4430      content = content.replace(/\n {4}/g, ' ');
4431      content.replace(/^([\S ]+): +([\s\S]+?)$/gm, function (wm, key, value) {
4432        globals.metadata.parsed[key] = value;
4433        return '';
4434      });
4435    }
4436  
4437    text = text.replace(/^\s*«««+(\S*?)\n([\s\S]+?)\n»»»+\n/, function (wholematch, format, content) {
4438      parseMetadataContents(content);
4439      return '¨M';
4440    });
4441  
4442    text = text.replace(/^\s*---+(\S*?)\n([\s\S]+?)\n---+\n/, function (wholematch, format, content) {
4443      if (format) {
4444        globals.metadata.format = format;
4445      }
4446      parseMetadataContents(content);
4447      return '¨M';
4448    });
4449  
4450    text = text.replace(/¨M/g, '');
4451  
4452    text = globals.converter._dispatch('metadata.after', text, options, globals);
4453    return text;
4454  });
4455  
4456  /**
4457   * Remove one level of line-leading tabs or spaces
4458   */
4459  showdown.subParser('outdent', function (text, options, globals) {
4460    'use strict';
4461    text = globals.converter._dispatch('outdent.before', text, options, globals);
4462  
4463    // attacklab: hack around Konqueror 3.5.4 bug:
4464    // "----------bug".replace(/^-/g,"") == "bug"
4465    text = text.replace(/^(\t|[ ]{1,4})/gm, '¨0'); // attacklab: g_tab_width
4466  
4467    // attacklab: clean up hack
4468    text = text.replace(/¨0/g, '');
4469  
4470    text = globals.converter._dispatch('outdent.after', text, options, globals);
4471    return text;
4472  });
4473  
4474  /**
4475   *
4476   */
4477  showdown.subParser('paragraphs', function (text, options, globals) {
4478    'use strict';
4479  
4480    text = globals.converter._dispatch('paragraphs.before', text, options, globals);
4481    // Strip leading and trailing lines:
4482    text = text.replace(/^\n+/g, '');
4483    text = text.replace(/\n+$/g, '');
4484  
4485    var grafs = text.split(/\n{2,}/g),
4486        grafsOut = [],
4487        end = grafs.length; // Wrap <p> tags
4488  
4489    for (var i = 0; i < end; i++) {
4490      var str = grafs[i];
4491      // if this is an HTML marker, copy it
4492      if (str.search(/¨(K|G)(\d+)\1/g) >= 0) {
4493        grafsOut.push(str);
4494  
4495      // test for presence of characters to prevent empty lines being parsed
4496      // as paragraphs (resulting in undesired extra empty paragraphs)
4497      } else if (str.search(/\S/) >= 0) {
4498        str = showdown.subParser('spanGamut')(str, options, globals);
4499        str = str.replace(/^([ \t]*)/g, '<p>');
4500        str += '</p>';
4501        grafsOut.push(str);
4502      }
4503    }
4504  
4505    /** Unhashify HTML blocks */
4506    end = grafsOut.length;
4507    for (i = 0; i < end; i++) {
4508      var blockText = '',
4509          grafsOutIt = grafsOut[i],
4510          codeFlag = false;
4511      // if this is a marker for an html block...
4512      // use RegExp.test instead of string.search because of QML bug
4513      while (/¨(K|G)(\d+)\1/.test(grafsOutIt)) {
4514        var delim = RegExp.$1,
4515            num   = RegExp.$2;
4516  
4517        if (delim === 'K') {
4518          blockText = globals.gHtmlBlocks[num];
4519        } else {
4520          // we need to check if ghBlock is a false positive
4521          if (codeFlag) {
4522            // use encoded version of all text
4523            blockText = showdown.subParser('encodeCode')(globals.ghCodeBlocks[num].text, options, globals);
4524          } else {
4525            blockText = globals.ghCodeBlocks[num].codeblock;
4526          }
4527        }
4528        blockText = blockText.replace(/\$/g, '$$$$'); // Escape any dollar signs
4529  
4530        grafsOutIt = grafsOutIt.replace(/(\n\n)?¨(K|G)\d+\2(\n\n)?/, blockText);
4531        // Check if grafsOutIt is a pre->code
4532        if (/^<pre\b[^>]*>\s*<code\b[^>]*>/.test(grafsOutIt)) {
4533          codeFlag = true;
4534        }
4535      }
4536      grafsOut[i] = grafsOutIt;
4537    }
4538    text = grafsOut.join('\n');
4539    // Strip leading and trailing lines:
4540    text = text.replace(/^\n+/g, '');
4541    text = text.replace(/\n+$/g, '');
4542    return globals.converter._dispatch('paragraphs.after', text, options, globals);
4543  });
4544  
4545  /**
4546   * Run extension
4547   */
4548  showdown.subParser('runExtension', function (ext, text, options, globals) {
4549    'use strict';
4550  
4551    if (ext.filter) {
4552      text = ext.filter(text, globals.converter, options);
4553  
4554    } else if (ext.regex) {
4555      // TODO remove this when old extension loading mechanism is deprecated
4556      var re = ext.regex;
4557      if (!(re instanceof RegExp)) {
4558        re = new RegExp(re, 'g');
4559      }
4560      text = text.replace(re, ext.replace);
4561    }
4562  
4563    return text;
4564  });
4565  
4566  /**
4567   * These are all the transformations that occur *within* block-level
4568   * tags like paragraphs, headers, and list items.
4569   */
4570  showdown.subParser('spanGamut', function (text, options, globals) {
4571    'use strict';
4572  
4573    text = globals.converter._dispatch('spanGamut.before', text, options, globals);
4574    text = showdown.subParser('codeSpans')(text, options, globals);
4575    text = showdown.subParser('escapeSpecialCharsWithinTagAttributes')(text, options, globals);
4576    text = showdown.subParser('encodeBackslashEscapes')(text, options, globals);
4577  
4578    // Process anchor and image tags. Images must come first,
4579    // because ![foo][f] looks like an anchor.
4580    text = showdown.subParser('images')(text, options, globals);
4581    text = showdown.subParser('anchors')(text, options, globals);
4582  
4583    // Make links out of things like `<http://example.com/>`
4584    // Must come after anchors, because you can use < and >
4585    // delimiters in inline links like [this](<url>).
4586    text = showdown.subParser('autoLinks')(text, options, globals);
4587    text = showdown.subParser('simplifiedAutoLinks')(text, options, globals);
4588    text = showdown.subParser('emoji')(text, options, globals);
4589    text = showdown.subParser('underline')(text, options, globals);
4590    text = showdown.subParser('italicsAndBold')(text, options, globals);
4591    text = showdown.subParser('strikethrough')(text, options, globals);
4592    text = showdown.subParser('ellipsis')(text, options, globals);
4593  
4594    // we need to hash HTML tags inside spans
4595    text = showdown.subParser('hashHTMLSpans')(text, options, globals);
4596  
4597    // now we encode amps and angles
4598    text = showdown.subParser('encodeAmpsAndAngles')(text, options, globals);
4599  
4600    // Do hard breaks
4601    if (options.simpleLineBreaks) {
4602      // GFM style hard breaks
4603      // only add line breaks if the text does not contain a block (special case for lists)
4604      if (!/\n\n¨K/.test(text)) {
4605        text = text.replace(/\n+/g, '<br />\n');
4606      }
4607    } else {
4608      // Vanilla hard breaks
4609      text = text.replace(/  +\n/g, '<br />\n');
4610    }
4611  
4612    text = globals.converter._dispatch('spanGamut.after', text, options, globals);
4613    return text;
4614  });
4615  
4616  showdown.subParser('strikethrough', function (text, options, globals) {
4617    'use strict';
4618  
4619    function parseInside (txt) {
4620      if (options.simplifiedAutoLink) {
4621        txt = showdown.subParser('simplifiedAutoLinks')(txt, options, globals);
4622      }
4623      return '<del>' + txt + '</del>';
4624    }
4625  
4626    if (options.strikethrough) {
4627      text = globals.converter._dispatch('strikethrough.before', text, options, globals);
4628      text = text.replace(/(?:~){2}([\s\S]+?)(?:~){2}/g, function (wm, txt) { return parseInside(txt); });
4629      text = globals.converter._dispatch('strikethrough.after', text, options, globals);
4630    }
4631  
4632    return text;
4633  });
4634  
4635  /**
4636   * Strips link definitions from text, stores the URLs and titles in
4637   * hash references.
4638   * Link defs are in the form: ^[id]: url "optional title"
4639   */
4640  showdown.subParser('stripLinkDefinitions', function (text, options, globals) {
4641    'use strict';
4642  
4643    var regex       = /^ {0,3}\[(.+)]:[ \t]*\n?[ \t]*<?([^>\s]+)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*\n?[ \t]*(?:(\n*)["|'(](.+?)["|')][ \t]*)?(?:\n+|(?=¨0))/gm,
4644        base64Regex = /^ {0,3}\[(.+)]:[ \t]*\n?[ \t]*<?(data:.+?\/.+?;base64,[A-Za-z0-9+/=\n]+?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*\n?[ \t]*(?:(\n*)["|'(](.+?)["|')][ \t]*)?(?:\n\n|(?=¨0)|(?=\n\[))/gm;
4645  
4646    // attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug
4647    text += '¨0';
4648  
4649    var replaceFunc = function (wholeMatch, linkId, url, width, height, blankLines, title) {
4650      linkId = linkId.toLowerCase();
4651      if (url.match(/^data:.+?\/.+?;base64,/)) {
4652        // remove newlines
4653        globals.gUrls[linkId] = url.replace(/\s/g, '');
4654      } else {
4655        globals.gUrls[linkId] = showdown.subParser('encodeAmpsAndAngles')(url, options, globals);  // Link IDs are case-insensitive
4656      }
4657  
4658      if (blankLines) {
4659        // Oops, found blank lines, so it's not a title.
4660        // Put back the parenthetical statement we stole.
4661        return blankLines + title;
4662  
4663      } else {
4664        if (title) {
4665          globals.gTitles[linkId] = title.replace(/"|'/g, '&quot;');
4666        }
4667        if (options.parseImgDimensions && width && height) {
4668          globals.gDimensions[linkId] = {
4669            width:  width,
4670            height: height
4671          };
4672        }
4673      }
4674      // Completely remove the definition from the text
4675      return '';
4676    };
4677  
4678    // first we try to find base64 link references
4679    text = text.replace(base64Regex, replaceFunc);
4680  
4681    text = text.replace(regex, replaceFunc);
4682  
4683    // attacklab: strip sentinel
4684    text = text.replace(/¨0/, '');
4685  
4686    return text;
4687  });
4688  
4689  showdown.subParser('tables', function (text, options, globals) {
4690    'use strict';
4691  
4692    if (!options.tables) {
4693      return text;
4694    }
4695  
4696    var tableRgx       = /^ {0,3}\|?.+\|.+\n {0,3}\|?[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*:?[ \t]*(?:[-=]){2,}[\s\S]+?(?:\n\n|¨0)/gm,
4697      //singeColTblRgx = /^ {0,3}\|.+\|\n {0,3}\|[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*\n(?: {0,3}\|.+\|\n)+(?:\n\n|¨0)/gm;
4698        singeColTblRgx = /^ {0,3}\|.+\|[ \t]*\n {0,3}\|[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*\n( {0,3}\|.+\|[ \t]*\n)*(?:\n|¨0)/gm;
4699  
4700    function parseStyles (sLine) {
4701      if (/^:[ \t]*--*$/.test(sLine)) {
4702        return ' style="text-align:left;"';
4703      } else if (/^--*[ \t]*:[ \t]*$/.test(sLine)) {
4704        return ' style="text-align:right;"';
4705      } else if (/^:[ \t]*--*[ \t]*:$/.test(sLine)) {
4706        return ' style="text-align:center;"';
4707      } else {
4708        return '';
4709      }
4710    }
4711  
4712    function parseHeaders (header, style) {
4713      var id = '';
4714      header = header.trim();
4715      // support both tablesHeaderId and tableHeaderId due to error in documentation so we don't break backwards compatibility
4716      if (options.tablesHeaderId || options.tableHeaderId) {
4717        id = ' id="' + header.replace(/ /g, '_').toLowerCase() + '"';
4718      }
4719      header = showdown.subParser('spanGamut')(header, options, globals);
4720  
4721      return '<th' + id + style + '>' + header + '</th>\n';
4722    }
4723  
4724    function parseCells (cell, style) {
4725      var subText = showdown.subParser('spanGamut')(cell, options, globals);
4726      return '<td' + style + '>' + subText + '</td>\n';
4727    }
4728  
4729    function buildTable (headers, cells) {
4730      var tb = '<table>\n<thead>\n<tr>\n',
4731          tblLgn = headers.length;
4732  
4733      for (var i = 0; i < tblLgn; ++i) {
4734        tb += headers[i];
4735      }
4736      tb += '</tr>\n</thead>\n<tbody>\n';
4737  
4738      for (i = 0; i < cells.length; ++i) {
4739        tb += '<tr>\n';
4740        for (var ii = 0; ii < tblLgn; ++ii) {
4741          tb += cells[i][ii];
4742        }
4743        tb += '</tr>\n';
4744      }
4745      tb += '</tbody>\n</table>\n';
4746      return tb;
4747    }
4748  
4749    function parseTable (rawTable) {
4750      var i, tableLines = rawTable.split('\n');
4751  
4752      for (i = 0; i < tableLines.length; ++i) {
4753        // strip wrong first and last column if wrapped tables are used
4754        if (/^ {0,3}\|/.test(tableLines[i])) {
4755          tableLines[i] = tableLines[i].replace(/^ {0,3}\|/, '');
4756        }
4757        if (/\|[ \t]*$/.test(tableLines[i])) {
4758          tableLines[i] = tableLines[i].replace(/\|[ \t]*$/, '');
4759        }
4760        // parse code spans first, but we only support one line code spans
4761        tableLines[i] = showdown.subParser('codeSpans')(tableLines[i], options, globals);
4762      }
4763  
4764      var rawHeaders = tableLines[0].split('|').map(function (s) { return s.trim();}),
4765          rawStyles = tableLines[1].split('|').map(function (s) { return s.trim();}),
4766          rawCells = [],
4767          headers = [],
4768          styles = [],
4769          cells = [];
4770  
4771      tableLines.shift();
4772      tableLines.shift();
4773  
4774      for (i = 0; i < tableLines.length; ++i) {
4775        if (tableLines[i].trim() === '') {
4776          continue;
4777        }
4778        rawCells.push(
4779          tableLines[i]
4780            .split('|')
4781            .map(function (s) {
4782              return s.trim();
4783            })
4784        );
4785      }
4786  
4787      if (rawHeaders.length < rawStyles.length) {
4788        return rawTable;
4789      }
4790  
4791      for (i = 0; i < rawStyles.length; ++i) {
4792        styles.push(parseStyles(rawStyles[i]));
4793      }
4794  
4795      for (i = 0; i < rawHeaders.length; ++i) {
4796        if (showdown.helper.isUndefined(styles[i])) {
4797          styles[i] = '';
4798        }
4799        headers.push(parseHeaders(rawHeaders[i], styles[i]));
4800      }
4801  
4802      for (i = 0; i < rawCells.length; ++i) {
4803        var row = [];
4804        for (var ii = 0; ii < headers.length; ++ii) {
4805          if (showdown.helper.isUndefined(rawCells[i][ii])) {
4806  
4807          }
4808          row.push(parseCells(rawCells[i][ii], styles[ii]));
4809        }
4810        cells.push(row);
4811      }
4812  
4813      return buildTable(headers, cells);
4814    }
4815  
4816    text = globals.converter._dispatch('tables.before', text, options, globals);
4817  
4818    // find escaped pipe characters
4819    text = text.replace(/\\(\|)/g, showdown.helper.escapeCharactersCallback);
4820  
4821    // parse multi column tables
4822    text = text.replace(tableRgx, parseTable);
4823  
4824    // parse one column tables
4825    text = text.replace(singeColTblRgx, parseTable);
4826  
4827    text = globals.converter._dispatch('tables.after', text, options, globals);
4828  
4829    return text;
4830  });
4831  
4832  showdown.subParser('underline', function (text, options, globals) {
4833    'use strict';
4834  
4835    if (!options.underline) {
4836      return text;
4837    }
4838  
4839    text = globals.converter._dispatch('underline.before', text, options, globals);
4840  
4841    if (options.literalMidWordUnderscores) {
4842      text = text.replace(/\b___(\S[\s\S]*?)___\b/g, function (wm, txt) {
4843        return '<u>' + txt + '</u>';
4844      });
4845      text = text.replace(/\b__(\S[\s\S]*?)__\b/g, function (wm, txt) {
4846        return '<u>' + txt + '</u>';
4847      });
4848    } else {
4849      text = text.replace(/___(\S[\s\S]*?)___/g, function (wm, m) {
4850        return (/\S$/.test(m)) ? '<u>' + m + '</u>' : wm;
4851      });
4852      text = text.replace(/__(\S[\s\S]*?)__/g, function (wm, m) {
4853        return (/\S$/.test(m)) ? '<u>' + m + '</u>' : wm;
4854      });
4855    }
4856  
4857    // escape remaining underscores to prevent them being parsed by italic and bold
4858    text = text.replace(/(_)/g, showdown.helper.escapeCharactersCallback);
4859  
4860    text = globals.converter._dispatch('underline.after', text, options, globals);
4861  
4862    return text;
4863  });
4864  
4865  /**
4866   * Swap back in all the special characters we've hidden.
4867   */
4868  showdown.subParser('unescapeSpecialChars', function (text, options, globals) {
4869    'use strict';
4870    text = globals.converter._dispatch('unescapeSpecialChars.before', text, options, globals);
4871  
4872    text = text.replace(/¨E(\d+)E/g, function (wholeMatch, m1) {
4873      var charCodeToReplace = parseInt(m1);
4874      return String.fromCharCode(charCodeToReplace);
4875    });
4876  
4877    text = globals.converter._dispatch('unescapeSpecialChars.after', text, options, globals);
4878    return text;
4879  });
4880  
4881  showdown.subParser('makeMarkdown.blockquote', function (node, globals) {
4882    'use strict';
4883  
4884    var txt = '';
4885    if (node.hasChildNodes()) {
4886      var children = node.childNodes,
4887          childrenLength = children.length;
4888  
4889      for (var i = 0; i < childrenLength; ++i) {
4890        var innerTxt = showdown.subParser('makeMarkdown.node')(children[i], globals);
4891  
4892        if (innerTxt === '') {
4893          continue;
4894        }
4895        txt += innerTxt;
4896      }
4897    }
4898    // cleanup
4899    txt = txt.trim();
4900    txt = '> ' + txt.split('\n').join('\n> ');
4901    return txt;
4902  });
4903  
4904  showdown.subParser('makeMarkdown.codeBlock', function (node, globals) {
4905    'use strict';
4906  
4907    var lang = node.getAttribute('language'),
4908        num  = node.getAttribute('precodenum');
4909    return '```' + lang + '\n' + globals.preList[num] + '\n```';
4910  });
4911  
4912  showdown.subParser('makeMarkdown.codeSpan', function (node) {
4913    'use strict';
4914  
4915    return '`' + node.innerHTML + '`';
4916  });
4917  
4918  showdown.subParser('makeMarkdown.emphasis', function (node, globals) {
4919    'use strict';
4920  
4921    var txt = '';
4922    if (node.hasChildNodes()) {
4923      txt += '*';
4924      var children = node.childNodes,
4925          childrenLength = children.length;
4926      for (var i = 0; i < childrenLength; ++i) {
4927        txt += showdown.subParser('makeMarkdown.node')(children[i], globals);
4928      }
4929      txt += '*';
4930    }
4931    return txt;
4932  });
4933  
4934  showdown.subParser('makeMarkdown.header', function (node, globals, headerLevel) {
4935    'use strict';
4936  
4937    var headerMark = new Array(headerLevel + 1).join('#'),
4938        txt = '';
4939  
4940    if (node.hasChildNodes()) {
4941      txt = headerMark + ' ';
4942      var children = node.childNodes,
4943          childrenLength = children.length;
4944  
4945      for (var i = 0; i < childrenLength; ++i) {
4946        txt += showdown.subParser('makeMarkdown.node')(children[i], globals);
4947      }
4948    }
4949    return txt;
4950  });
4951  
4952  showdown.subParser('makeMarkdown.hr', function () {
4953    'use strict';
4954  
4955    return '---';
4956  });
4957  
4958  showdown.subParser('makeMarkdown.image', function (node) {
4959    'use strict';
4960  
4961    var txt = '';
4962    if (node.hasAttribute('src')) {
4963      txt += '![' + node.getAttribute('alt') + '](';
4964      txt += '<' + node.getAttribute('src') + '>';
4965      if (node.hasAttribute('width') && node.hasAttribute('height')) {
4966        txt += ' =' + node.getAttribute('width') + 'x' + node.getAttribute('height');
4967      }
4968  
4969      if (node.hasAttribute('title')) {
4970        txt += ' "' + node.getAttribute('title') + '"';
4971      }
4972      txt += ')';
4973    }
4974    return txt;
4975  });
4976  
4977  showdown.subParser('makeMarkdown.links', function (node, globals) {
4978    'use strict';
4979  
4980    var txt = '';
4981    if (node.hasChildNodes() && node.hasAttribute('href')) {
4982      var children = node.childNodes,
4983          childrenLength = children.length;
4984      txt = '[';
4985      for (var i = 0; i < childrenLength; ++i) {
4986        txt += showdown.subParser('makeMarkdown.node')(children[i], globals);
4987      }
4988      txt += '](';
4989      txt += '<' + node.getAttribute('href') + '>';
4990      if (node.hasAttribute('title')) {
4991        txt += ' "' + node.getAttribute('title') + '"';
4992      }
4993      txt += ')';
4994    }
4995    return txt;
4996  });
4997  
4998  showdown.subParser('makeMarkdown.list', function (node, globals, type) {
4999    'use strict';
5000  
5001    var txt = '';
5002    if (!node.hasChildNodes()) {
5003      return '';
5004    }
5005    var listItems       = node.childNodes,
5006        listItemsLenght = listItems.length,
5007        listNum = node.getAttribute('start') || 1;
5008  
5009    for (var i = 0; i < listItemsLenght; ++i) {
5010      if (typeof listItems[i].tagName === 'undefined' || listItems[i].tagName.toLowerCase() !== 'li') {
5011        continue;
5012      }
5013  
5014      // define the bullet to use in list
5015      var bullet = '';
5016      if (type === 'ol') {
5017        bullet = listNum.toString() + '. ';
5018      } else {
5019        bullet = '- ';
5020      }
5021  
5022      // parse list item
5023      txt += bullet + showdown.subParser('makeMarkdown.listItem')(listItems[i], globals);
5024      ++listNum;
5025    }
5026  
5027    // add comment at the end to prevent consecutive lists to be parsed as one
5028    txt += '\n<!-- -->\n';
5029    return txt.trim();
5030  });
5031  
5032  showdown.subParser('makeMarkdown.listItem', function (node, globals) {
5033    'use strict';
5034  
5035    var listItemTxt = '';
5036  
5037    var children = node.childNodes,
5038        childrenLenght = children.length;
5039  
5040    for (var i = 0; i < childrenLenght; ++i) {
5041      listItemTxt += showdown.subParser('makeMarkdown.node')(children[i], globals);
5042    }
5043    // if it's only one liner, we need to add a newline at the end
5044    if (!/\n$/.test(listItemTxt)) {
5045      listItemTxt += '\n';
5046    } else {
5047      // it's multiparagraph, so we need to indent
5048      listItemTxt = listItemTxt
5049        .split('\n')
5050        .join('\n    ')
5051        .replace(/^ {4}$/gm, '')
5052        .replace(/\n\n+/g, '\n\n');
5053    }
5054  
5055    return listItemTxt;
5056  });
5057  
5058  
5059  
5060  showdown.subParser('makeMarkdown.node', function (node, globals, spansOnly) {
5061    'use strict';
5062  
5063    spansOnly = spansOnly || false;
5064  
5065    var txt = '';
5066  
5067    // edge case of text without wrapper paragraph
5068    if (node.nodeType === 3) {
5069      return showdown.subParser('makeMarkdown.txt')(node, globals);
5070    }
5071  
5072    // HTML comment
5073    if (node.nodeType === 8) {
5074      return '<!--' + node.data + '-->\n\n';
5075    }
5076  
5077    // process only node elements
5078    if (node.nodeType !== 1) {
5079      return '';
5080    }
5081  
5082    var tagName = node.tagName.toLowerCase();
5083  
5084    switch (tagName) {
5085  
5086      //
5087      // BLOCKS
5088      //
5089      case 'h1':
5090        if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 1) + '\n\n'; }
5091        break;
5092      case 'h2':
5093        if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 2) + '\n\n'; }
5094        break;
5095      case 'h3':
5096        if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 3) + '\n\n'; }
5097        break;
5098      case 'h4':
5099        if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 4) + '\n\n'; }
5100        break;
5101      case 'h5':
5102        if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 5) + '\n\n'; }
5103        break;
5104      case 'h6':
5105        if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 6) + '\n\n'; }
5106        break;
5107  
5108      case 'p':
5109        if (!spansOnly) { txt = showdown.subParser('makeMarkdown.paragraph')(node, globals) + '\n\n'; }
5110        break;
5111  
5112      case 'blockquote':
5113        if (!spansOnly) { txt = showdown.subParser('makeMarkdown.blockquote')(node, globals) + '\n\n'; }
5114        break;
5115  
5116      case 'hr':
5117        if (!spansOnly) { txt = showdown.subParser('makeMarkdown.hr')(node, globals) + '\n\n'; }
5118        break;
5119  
5120      case 'ol':
5121        if (!spansOnly) { txt = showdown.subParser('makeMarkdown.list')(node, globals, 'ol') + '\n\n'; }
5122        break;
5123  
5124      case 'ul':
5125        if (!spansOnly) { txt = showdown.subParser('makeMarkdown.list')(node, globals, 'ul') + '\n\n'; }
5126        break;
5127  
5128      case 'precode':
5129        if (!spansOnly) { txt = showdown.subParser('makeMarkdown.codeBlock')(node, globals) + '\n\n'; }
5130        break;
5131  
5132      case 'pre':
5133        if (!spansOnly) { txt = showdown.subParser('makeMarkdown.pre')(node, globals) + '\n\n'; }
5134        break;
5135  
5136      case 'table':
5137        if (!spansOnly) { txt = showdown.subParser('makeMarkdown.table')(node, globals) + '\n\n'; }
5138        break;
5139  
5140      //
5141      // SPANS
5142      //
5143      case 'code':
5144        txt = showdown.subParser('makeMarkdown.codeSpan')(node, globals);
5145        break;
5146  
5147      case 'em':
5148      case 'i':
5149        txt = showdown.subParser('makeMarkdown.emphasis')(node, globals);
5150        break;
5151  
5152      case 'strong':
5153      case 'b':
5154        txt = showdown.subParser('makeMarkdown.strong')(node, globals);
5155        break;
5156  
5157      case 'del':
5158        txt = showdown.subParser('makeMarkdown.strikethrough')(node, globals);
5159        break;
5160  
5161      case 'a':
5162        txt = showdown.subParser('makeMarkdown.links')(node, globals);
5163        break;
5164  
5165      case 'img':
5166        txt = showdown.subParser('makeMarkdown.image')(node, globals);
5167        break;
5168  
5169      default:
5170        txt = node.outerHTML + '\n\n';
5171    }
5172  
5173    // common normalization
5174    // TODO eventually
5175  
5176    return txt;
5177  });
5178  
5179  showdown.subParser('makeMarkdown.paragraph', function (node, globals) {
5180    'use strict';
5181  
5182    var txt = '';
5183    if (node.hasChildNodes()) {
5184      var children = node.childNodes,
5185          childrenLength = children.length;
5186      for (var i = 0; i < childrenLength; ++i) {
5187        txt += showdown.subParser('makeMarkdown.node')(children[i], globals);
5188      }
5189    }
5190  
5191    // some text normalization
5192    txt = txt.trim();
5193  
5194    return txt;
5195  });
5196  
5197  showdown.subParser('makeMarkdown.pre', function (node, globals) {
5198    'use strict';
5199  
5200    var num  = node.getAttribute('prenum');
5201    return '<pre>' + globals.preList[num] + '</pre>';
5202  });
5203  
5204  showdown.subParser('makeMarkdown.strikethrough', function (node, globals) {
5205    'use strict';
5206  
5207    var txt = '';
5208    if (node.hasChildNodes()) {
5209      txt += '~~';
5210      var children = node.childNodes,
5211          childrenLength = children.length;
5212      for (var i = 0; i < childrenLength; ++i) {
5213        txt += showdown.subParser('makeMarkdown.node')(children[i], globals);
5214      }
5215      txt += '~~';
5216    }
5217    return txt;
5218  });
5219  
5220  showdown.subParser('makeMarkdown.strong', function (node, globals) {
5221    'use strict';
5222  
5223    var txt = '';
5224    if (node.hasChildNodes()) {
5225      txt += '**';
5226      var children = node.childNodes,
5227          childrenLength = children.length;
5228      for (var i = 0; i < childrenLength; ++i) {
5229        txt += showdown.subParser('makeMarkdown.node')(children[i], globals);
5230      }
5231      txt += '**';
5232    }
5233    return txt;
5234  });
5235  
5236  showdown.subParser('makeMarkdown.table', function (node, globals) {
5237    'use strict';
5238  
5239    var txt = '',
5240        tableArray = [[], []],
5241        headings   = node.querySelectorAll('thead>tr>th'),
5242        rows       = node.querySelectorAll('tbody>tr'),
5243        i, ii;
5244    for (i = 0; i < headings.length; ++i) {
5245      var headContent = showdown.subParser('makeMarkdown.tableCell')(headings[i], globals),
5246          allign = '---';
5247  
5248      if (headings[i].hasAttribute('style')) {
5249        var style = headings[i].getAttribute('style').toLowerCase().replace(/\s/g, '');
5250        switch (style) {
5251          case 'text-align:left;':
5252            allign = ':---';
5253            break;
5254          case 'text-align:right;':
5255            allign = '---:';
5256            break;
5257          case 'text-align:center;':
5258            allign = ':---:';
5259            break;
5260        }
5261      }
5262      tableArray[0][i] = headContent.trim();
5263      tableArray[1][i] = allign;
5264    }
5265  
5266    for (i = 0; i < rows.length; ++i) {
5267      var r = tableArray.push([]) - 1,
5268          cols = rows[i].getElementsByTagName('td');
5269  
5270      for (ii = 0; ii < headings.length; ++ii) {
5271        var cellContent = ' ';
5272        if (typeof cols[ii] !== 'undefined') {
5273          cellContent = showdown.subParser('makeMarkdown.tableCell')(cols[ii], globals);
5274        }
5275        tableArray[r].push(cellContent);
5276      }
5277    }
5278  
5279    var cellSpacesCount = 3;
5280    for (i = 0; i < tableArray.length; ++i) {
5281      for (ii = 0; ii < tableArray[i].length; ++ii) {
5282        var strLen = tableArray[i][ii].length;
5283        if (strLen > cellSpacesCount) {
5284          cellSpacesCount = strLen;
5285        }
5286      }
5287    }
5288  
5289    for (i = 0; i < tableArray.length; ++i) {
5290      for (ii = 0; ii < tableArray[i].length; ++ii) {
5291        if (i === 1) {
5292          if (tableArray[i][ii].slice(-1) === ':') {
5293            tableArray[i][ii] = showdown.helper.padEnd(tableArray[i][ii].slice(-1), cellSpacesCount - 1, '-') + ':';
5294          } else {
5295            tableArray[i][ii] = showdown.helper.padEnd(tableArray[i][ii], cellSpacesCount, '-');
5296          }
5297        } else {
5298          tableArray[i][ii] = showdown.helper.padEnd(tableArray[i][ii], cellSpacesCount);
5299        }
5300      }
5301      txt += '| ' + tableArray[i].join(' | ') + ' |\n';
5302    }
5303  
5304    return txt.trim();
5305  });
5306  
5307  showdown.subParser('makeMarkdown.tableCell', function (node, globals) {
5308    'use strict';
5309  
5310    var txt = '';
5311    if (!node.hasChildNodes()) {
5312      return '';
5313    }
5314    var children = node.childNodes,
5315        childrenLength = children.length;
5316  
5317    for (var i = 0; i < childrenLength; ++i) {
5318      txt += showdown.subParser('makeMarkdown.node')(children[i], globals, true);
5319    }
5320    return txt.trim();
5321  });
5322  
5323  showdown.subParser('makeMarkdown.txt', function (node) {
5324    'use strict';
5325  
5326    var txt = node.nodeValue;
5327  
5328    // multiple spaces are collapsed
5329    txt = txt.replace(/ +/g, ' ');
5330  
5331    // replace the custom ¨NBSP; with a space
5332    txt = txt.replace(/¨NBSP;/g, ' ');
5333  
5334    // ", <, > and & should replace escaped html entities
5335    txt = showdown.helper.unescapeHTMLEntities(txt);
5336  
5337    // escape markdown magic characters
5338    // emphasis, strong and strikethrough - can appear everywhere
5339    // we also escape pipe (|) because of tables
5340    // and escape ` because of code blocks and spans
5341    txt = txt.replace(/([*_~|`])/g, '\\$1');
5342  
5343    // escape > because of blockquotes
5344    txt = txt.replace(/^(\s*)>/g, '\\$1>');
5345  
5346    // hash character, only troublesome at the beginning of a line because of headers
5347    txt = txt.replace(/^#/gm, '\\#');
5348  
5349    // horizontal rules
5350    txt = txt.replace(/^(\s*)([-=]{3,})(\s*)$/, '$1\\$2$3');
5351  
5352    // dot, because of ordered lists, only troublesome at the beginning of a line when preceded by an integer
5353    txt = txt.replace(/^( {0,3}\d+)\./gm, '$1\\.');
5354  
5355    // +, * and -, at the beginning of a line becomes a list, so we need to escape them also (asterisk was already escaped)
5356    txt = txt.replace(/^( {0,3})([+-])/gm, '$1\\$2');
5357  
5358    // images and links, ] followed by ( is problematic, so we escape it
5359    txt = txt.replace(/]([\s]*)\(/g, '\\]$1\\(');
5360  
5361    // reference URIs must also be escaped
5362    txt = txt.replace(/^ {0,3}\[([\S \t]*?)]:/gm, '\\[$1]:');
5363  
5364    return txt;
5365  });
5366  
5367  var root = this;
5368  
5369  // AMD Loader
5370  if (true) {
5371    !(__WEBPACK_AMD_DEFINE_RESULT__ = (function () {
5372      'use strict';
5373      return showdown;
5374    }).call(exports, __webpack_require__, exports, module),
5375                  __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
5376  
5377  // CommonJS/nodeJS Loader
5378  } else {}
5379  }).call(this);
5380  
5381  
5382  
5383  /***/ }),
5384  
5385  /***/ 23:
5386  /***/ (function(module, __webpack_exports__, __webpack_require__) {
5387  
5388  "use strict";
5389  
5390  // EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/arrayWithHoles.js
5391  var arrayWithHoles = __webpack_require__(38);
5392  
5393  // CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/iterableToArrayLimit.js
5394  function _iterableToArrayLimit(arr, i) {
5395    var _arr = [];
5396    var _n = true;
5397    var _d = false;
5398    var _e = undefined;
5399  
5400    try {
5401      for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
5402        _arr.push(_s.value);
5403  
5404        if (i && _arr.length === i) break;
5405      }
5406    } catch (err) {
5407      _d = true;
5408      _e = err;
5409    } finally {
5410      try {
5411        if (!_n && _i["return"] != null) _i["return"]();
5412      } finally {
5413        if (_d) throw _e;
5414      }
5415    }
5416  
5417    return _arr;
5418  }
5419  // EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/nonIterableRest.js
5420  var nonIterableRest = __webpack_require__(39);
5421  
5422  // CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/slicedToArray.js
5423  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return _slicedToArray; });
5424  
5425  
5426  
5427  function _slicedToArray(arr, i) {
5428    return Object(arrayWithHoles["a" /* default */])(arr) || _iterableToArrayLimit(arr, i) || Object(nonIterableRest["a" /* default */])();
5429  }
5430  
5431  /***/ }),
5432  
5433  /***/ 25:
5434  /***/ (function(module, exports) {
5435  
5436  (function() { module.exports = this["wp"]["dom"]; }());
5437  
5438  /***/ }),
5439  
5440  /***/ 27:
5441  /***/ (function(module, exports) {
5442  
5443  (function() { module.exports = this["wp"]["hooks"]; }());
5444  
5445  /***/ }),
5446  
5447  /***/ 30:
5448  /***/ (function(module, __webpack_exports__, __webpack_require__) {
5449  
5450  "use strict";
5451  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return _iterableToArray; });
5452  function _iterableToArray(iter) {
5453    if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
5454  }
5455  
5456  /***/ }),
5457  
5458  /***/ 347:
5459  /***/ (function(module, __webpack_exports__, __webpack_require__) {
5460  
5461  "use strict";
5462  __webpack_require__.r(__webpack_exports__);
5463  var selectors_namespaceObject = {};
5464  __webpack_require__.r(selectors_namespaceObject);
5465  __webpack_require__.d(selectors_namespaceObject, "getBlockTypes", function() { return getBlockTypes; });
5466  __webpack_require__.d(selectors_namespaceObject, "getBlockType", function() { return getBlockType; });
5467  __webpack_require__.d(selectors_namespaceObject, "getBlockStyles", function() { return getBlockStyles; });
5468  __webpack_require__.d(selectors_namespaceObject, "getCategories", function() { return getCategories; });
5469  __webpack_require__.d(selectors_namespaceObject, "getDefaultBlockName", function() { return getDefaultBlockName; });
5470  __webpack_require__.d(selectors_namespaceObject, "getFreeformFallbackBlockName", function() { return getFreeformFallbackBlockName; });
5471  __webpack_require__.d(selectors_namespaceObject, "getUnregisteredFallbackBlockName", function() { return getUnregisteredFallbackBlockName; });
5472  __webpack_require__.d(selectors_namespaceObject, "getGroupingBlockName", function() { return getGroupingBlockName; });
5473  __webpack_require__.d(selectors_namespaceObject, "getChildBlockNames", function() { return selectors_getChildBlockNames; });
5474  __webpack_require__.d(selectors_namespaceObject, "getBlockSupport", function() { return selectors_getBlockSupport; });
5475  __webpack_require__.d(selectors_namespaceObject, "hasBlockSupport", function() { return hasBlockSupport; });
5476  __webpack_require__.d(selectors_namespaceObject, "isMatchingSearchTerm", function() { return isMatchingSearchTerm; });
5477  __webpack_require__.d(selectors_namespaceObject, "hasChildBlocks", function() { return selectors_hasChildBlocks; });
5478  __webpack_require__.d(selectors_namespaceObject, "hasChildBlocksWithInserterSupport", function() { return selectors_hasChildBlocksWithInserterSupport; });
5479  var actions_namespaceObject = {};
5480  __webpack_require__.r(actions_namespaceObject);
5481  __webpack_require__.d(actions_namespaceObject, "addBlockTypes", function() { return addBlockTypes; });
5482  __webpack_require__.d(actions_namespaceObject, "removeBlockTypes", function() { return removeBlockTypes; });
5483  __webpack_require__.d(actions_namespaceObject, "addBlockStyles", function() { return addBlockStyles; });
5484  __webpack_require__.d(actions_namespaceObject, "removeBlockStyles", function() { return removeBlockStyles; });
5485  __webpack_require__.d(actions_namespaceObject, "setDefaultBlockName", function() { return setDefaultBlockName; });
5486  __webpack_require__.d(actions_namespaceObject, "setFreeformFallbackBlockName", function() { return setFreeformFallbackBlockName; });
5487  __webpack_require__.d(actions_namespaceObject, "setUnregisteredFallbackBlockName", function() { return setUnregisteredFallbackBlockName; });
5488  __webpack_require__.d(actions_namespaceObject, "setGroupingBlockName", function() { return setGroupingBlockName; });
5489  __webpack_require__.d(actions_namespaceObject, "setCategories", function() { return setCategories; });
5490  __webpack_require__.d(actions_namespaceObject, "updateCategory", function() { return updateCategory; });
5491  
5492  // EXTERNAL MODULE: external {"this":["wp","data"]}
5493  var external_this_wp_data_ = __webpack_require__(4);
5494  
5495  // EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/defineProperty.js
5496  var defineProperty = __webpack_require__(10);
5497  
5498  // EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/toConsumableArray.js + 2 modules
5499  var toConsumableArray = __webpack_require__(17);
5500  
5501  // EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/objectSpread.js
5502  var objectSpread = __webpack_require__(7);
5503  
5504  // EXTERNAL MODULE: external "lodash"
5505  var external_lodash_ = __webpack_require__(2);
5506  
5507  // EXTERNAL MODULE: external {"this":["wp","i18n"]}
5508  var external_this_wp_i18n_ = __webpack_require__(1);
5509  
5510  // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/store/reducer.js
5511  
5512  
5513  
5514  
5515  /**
5516   * External dependencies
5517   */
5518  
5519  /**
5520   * WordPress dependencies
5521   */
5522  
5523  
5524  
5525  /**
5526   * Module Constants
5527   */
5528  
5529  var DEFAULT_CATEGORIES = [{
5530    slug: 'common',
5531    title: Object(external_this_wp_i18n_["__"])('Common Blocks')
5532  }, {
5533    slug: 'formatting',
5534    title: Object(external_this_wp_i18n_["__"])('Formatting')
5535  }, {
5536    slug: 'layout',
5537    title: Object(external_this_wp_i18n_["__"])('Layout Elements')
5538  }, {
5539    slug: 'widgets',
5540    title: Object(external_this_wp_i18n_["__"])('Widgets')
5541  }, {
5542    slug: 'embed',
5543    title: Object(external_this_wp_i18n_["__"])('Embeds')
5544  }, {
5545    slug: 'reusable',
5546    title: Object(external_this_wp_i18n_["__"])('Reusable Blocks')
5547  }];
5548  /**
5549   * Reducer managing the block types
5550   *
5551   * @param {Object} state  Current state.
5552   * @param {Object} action Dispatched action.
5553   *
5554   * @return {Object} Updated state.
5555   */
5556  
5557  function reducer_blockTypes() {
5558    var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
5559    var action = arguments.length > 1 ? arguments[1] : undefined;
5560  
5561    switch (action.type) {
5562      case 'ADD_BLOCK_TYPES':
5563        return Object(objectSpread["a" /* default */])({}, state, Object(external_lodash_["keyBy"])(Object(external_lodash_["map"])(action.blockTypes, function (blockType) {
5564          return Object(external_lodash_["omit"])(blockType, 'styles ');
5565        }), 'name'));
5566  
5567      case 'REMOVE_BLOCK_TYPES':
5568        return Object(external_lodash_["omit"])(state, action.names);
5569    }
5570  
5571    return state;
5572  }
5573  /**
5574   * Reducer managing the block style variations.
5575   *
5576   * @param {Object} state  Current state.
5577   * @param {Object} action Dispatched action.
5578   *
5579   * @return {Object} Updated state.
5580   */
5581  
5582  function blockStyles() {
5583    var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
5584    var action = arguments.length > 1 ? arguments[1] : undefined;
5585  
5586    switch (action.type) {
5587      case 'ADD_BLOCK_TYPES':
5588        return Object(objectSpread["a" /* default */])({}, state, Object(external_lodash_["mapValues"])(Object(external_lodash_["keyBy"])(action.blockTypes, 'name'), function (blockType) {
5589          return Object(external_lodash_["uniqBy"])([].concat(Object(toConsumableArray["a" /* default */])(Object(external_lodash_["get"])(blockType, ['styles'], [])), Object(toConsumableArray["a" /* default */])(Object(external_lodash_["get"])(state, [blockType.name], []))), function (style) {
5590            return style.name;
5591          });
5592        }));
5593  
5594      case 'ADD_BLOCK_STYLES':
5595        return Object(objectSpread["a" /* default */])({}, state, Object(defineProperty["a" /* default */])({}, action.blockName, Object(external_lodash_["uniqBy"])([].concat(Object(toConsumableArray["a" /* default */])(Object(external_lodash_["get"])(state, [action.blockName], [])), Object(toConsumableArray["a" /* default */])(action.styles)), function (style) {
5596          return style.name;
5597        })));
5598  
5599      case 'REMOVE_BLOCK_STYLES':
5600        return Object(objectSpread["a" /* default */])({}, state, Object(defineProperty["a" /* default */])({}, action.blockName, Object(external_lodash_["filter"])(Object(external_lodash_["get"])(state, [action.blockName], []), function (style) {
5601          return action.styleNames.indexOf(style.name) === -1;
5602        })));
5603    }
5604  
5605    return state;
5606  }
5607  /**
5608   * Higher-order Reducer creating a reducer keeping track of given block name.
5609   *
5610   * @param {string} setActionType  Action type.
5611   *
5612   * @return {Function} Reducer.
5613   */
5614  
5615  function createBlockNameSetterReducer(setActionType) {
5616    return function () {
5617      var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
5618      var action = arguments.length > 1 ? arguments[1] : undefined;
5619  
5620      switch (action.type) {
5621        case 'REMOVE_BLOCK_TYPES':
5622          if (action.names.indexOf(state) !== -1) {
5623            return null;
5624          }
5625  
5626          return state;
5627  
5628        case setActionType:
5629          return action.name || null;
5630      }
5631  
5632      return state;
5633    };
5634  }
5635  var reducer_defaultBlockName = createBlockNameSetterReducer('SET_DEFAULT_BLOCK_NAME');
5636  var freeformFallbackBlockName = createBlockNameSetterReducer('SET_FREEFORM_FALLBACK_BLOCK_NAME');
5637  var unregisteredFallbackBlockName = createBlockNameSetterReducer('SET_UNREGISTERED_FALLBACK_BLOCK_NAME');
5638  var groupingBlockName = createBlockNameSetterReducer('SET_GROUPING_BLOCK_NAME');
5639  /**
5640   * Reducer managing the categories
5641   *
5642   * @param {Object} state  Current state.
5643   * @param {Object} action Dispatched action.
5644   *
5645   * @return {Object} Updated state.
5646   */
5647  
5648  function reducer_categories() {
5649    var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : DEFAULT_CATEGORIES;
5650    var action = arguments.length > 1 ? arguments[1] : undefined;
5651  
5652    switch (action.type) {
5653      case 'SET_CATEGORIES':
5654        return action.categories || [];
5655  
5656      case 'UPDATE_CATEGORY':
5657        {
5658          if (!action.category || Object(external_lodash_["isEmpty"])(action.category)) {
5659            return state;
5660          }
5661  
5662          var categoryToChange = Object(external_lodash_["find"])(state, ['slug', action.slug]);
5663  
5664          if (categoryToChange) {
5665            return Object(external_lodash_["map"])(state, function (category) {
5666              if (category.slug === action.slug) {
5667                return Object(objectSpread["a" /* default */])({}, category, action.category);
5668              }
5669  
5670              return category;
5671            });
5672          }
5673        }
5674    }
5675  
5676    return state;
5677  }
5678  /* harmony default export */ var reducer = (Object(external_this_wp_data_["combineReducers"])({
5679    blockTypes: reducer_blockTypes,
5680    blockStyles: blockStyles,
5681    defaultBlockName: reducer_defaultBlockName,
5682    freeformFallbackBlockName: freeformFallbackBlockName,
5683    unregisteredFallbackBlockName: unregisteredFallbackBlockName,
5684    groupingBlockName: groupingBlockName,
5685    categories: reducer_categories
5686  }));
5687  
5688  // EXTERNAL MODULE: ./node_modules/rememo/es/rememo.js
5689  var rememo = __webpack_require__(36);
5690  
5691  // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/store/selectors.js
5692  /**
5693   * External dependencies
5694   */
5695  
5696  
5697  /**
5698   * Given a block name or block type object, returns the corresponding
5699   * normalized block type object.
5700   *
5701   * @param {Object}          state      Blocks state.
5702   * @param {(string|Object)} nameOrType Block name or type object
5703   *
5704   * @return {Object} Block type object.
5705   */
5706  
5707  var getNormalizedBlockType = function getNormalizedBlockType(state, nameOrType) {
5708    return 'string' === typeof nameOrType ? getBlockType(state, nameOrType) : nameOrType;
5709  };
5710  /**
5711   * Returns all the available block types.
5712   *
5713   * @param {Object} state Data state.
5714   *
5715   * @return {Array} Block Types.
5716   */
5717  
5718  
5719  var getBlockTypes = Object(rememo["a" /* default */])(function (state) {
5720    return Object.values(state.blockTypes);
5721  }, function (state) {
5722    return [state.blockTypes];
5723  });
5724  /**
5725   * Returns a block type by name.
5726   *
5727   * @param {Object} state Data state.
5728   * @param {string} name Block type name.
5729   *
5730   * @return {Object?} Block Type.
5731   */
5732  
5733  function getBlockType(state, name) {
5734    return state.blockTypes[name];
5735  }
5736  /**
5737   * Returns block styles by block name.
5738   *
5739   * @param {Object} state Data state.
5740   * @param {string} name  Block type name.
5741   *
5742   * @return {Array?} Block Styles.
5743   */
5744  
5745  function getBlockStyles(state, name) {
5746    return state.blockStyles[name];
5747  }
5748  /**
5749   * Returns all the available categories.
5750   *
5751   * @param {Object} state Data state.
5752   *
5753   * @return {Array} Categories list.
5754   */
5755  
5756  function getCategories(state) {
5757    return state.categories;
5758  }
5759  /**
5760   * Returns the name of the default block name.
5761   *
5762   * @param {Object} state Data state.
5763   *
5764   * @return {string?} Default block name.
5765   */
5766  
5767  function getDefaultBlockName(state) {
5768    return state.defaultBlockName;
5769  }
5770  /**
5771   * Returns the name of the block for handling non-block content.
5772   *
5773   * @param {Object} state Data state.
5774   *
5775   * @return {string?} Name of the block for handling non-block content.
5776   */
5777  
5778  function getFreeformFallbackBlockName(state) {
5779    return state.freeformFallbackBlockName;
5780  }
5781  /**
5782   * Returns the name of the block for handling unregistered blocks.
5783   *
5784   * @param {Object} state Data state.
5785   *
5786   * @return {string?} Name of the block for handling unregistered blocks.
5787   */
5788  
5789  function getUnregisteredFallbackBlockName(state) {
5790    return state.unregisteredFallbackBlockName;
5791  }
5792  /**
5793   * Returns the name of the block for handling unregistered blocks.
5794   *
5795   * @param {Object} state Data state.
5796   *
5797   * @return {string?} Name of the block for handling unregistered blocks.
5798   */
5799  
5800  function getGroupingBlockName(state) {
5801    return state.groupingBlockName;
5802  }
5803  /**
5804   * Returns an array with the child blocks of a given block.
5805   *
5806   * @param {Object} state     Data state.
5807   * @param {string} blockName Block type name.
5808   *
5809   * @return {Array} Array of child block names.
5810   */
5811  
5812  var selectors_getChildBlockNames = Object(rememo["a" /* default */])(function (state, blockName) {
5813    return Object(external_lodash_["map"])(Object(external_lodash_["filter"])(state.blockTypes, function (blockType) {
5814      return Object(external_lodash_["includes"])(blockType.parent, blockName);
5815    }), function (_ref) {
5816      var name = _ref.name;
5817      return name;
5818    });
5819  }, function (state) {
5820    return [state.blockTypes];
5821  });
5822  /**
5823   * Returns the block support value for a feature, if defined.
5824   *
5825   * @param  {Object}          state           Data state.
5826   * @param  {(string|Object)} nameOrType      Block name or type object
5827   * @param  {string}          feature         Feature to retrieve
5828   * @param  {*}               defaultSupports Default value to return if not
5829   *                                           explicitly defined
5830   *
5831   * @return {?*} Block support value
5832   */
5833  
5834  var selectors_getBlockSupport = function getBlockSupport(state, nameOrType, feature, defaultSupports) {
5835    var blockType = getNormalizedBlockType(state, nameOrType);
5836    return Object(external_lodash_["get"])(blockType, ['supports', feature], defaultSupports);
5837  };
5838  /**
5839   * Returns true if the block defines support for a feature, or false otherwise.
5840   *
5841   * @param  {Object}         state           Data state.
5842   * @param {(string|Object)} nameOrType      Block name or type object.
5843   * @param {string}          feature         Feature to test.
5844   * @param {boolean}         defaultSupports Whether feature is supported by
5845   *                                          default if not explicitly defined.
5846   *
5847   * @return {boolean} Whether block supports feature.
5848   */
5849  
5850  function hasBlockSupport(state, nameOrType, feature, defaultSupports) {
5851    return !!selectors_getBlockSupport(state, nameOrType, feature, defaultSupports);
5852  }
5853  /**
5854   * Returns true if the block type by the given name or object value matches a
5855   * search term, or false otherwise.
5856   *
5857   * @param {Object}          state      Blocks state.
5858   * @param {(string|Object)} nameOrType Block name or type object.
5859   * @param {string}          searchTerm Search term by which to filter.
5860   *
5861   * @return {Object[]} Whether block type matches search term.
5862   */
5863  
5864  function isMatchingSearchTerm(state, nameOrType, searchTerm) {
5865    var blockType = getNormalizedBlockType(state, nameOrType);
5866    var getNormalizedSearchTerm = Object(external_lodash_["flow"])([// Disregard diacritics.
5867    //  Input: "média"
5868    external_lodash_["deburr"], // Lowercase.
5869    //  Input: "MEDIA"
5870    function (term) {
5871      return term.toLowerCase();
5872    }, // Strip leading and trailing whitespace.
5873    //  Input: " media "
5874    function (term) {
5875      return term.trim();
5876    }]);
5877    var normalizedSearchTerm = getNormalizedSearchTerm(searchTerm);
5878    var isSearchMatch = Object(external_lodash_["flow"])([getNormalizedSearchTerm, function (normalizedCandidate) {
5879      return Object(external_lodash_["includes"])(normalizedCandidate, normalizedSearchTerm);
5880    }]);
5881    return isSearchMatch(blockType.title) || Object(external_lodash_["some"])(blockType.keywords, isSearchMatch) || isSearchMatch(blockType.category);
5882  }
5883  /**
5884   * Returns a boolean indicating if a block has child blocks or not.
5885   *
5886   * @param {Object} state     Data state.
5887   * @param {string} blockName Block type name.
5888   *
5889   * @return {boolean} True if a block contains child blocks and false otherwise.
5890   */
5891  
5892  var selectors_hasChildBlocks = function hasChildBlocks(state, blockName) {
5893    return selectors_getChildBlockNames(state, blockName).length > 0;
5894  };
5895  /**
5896   * Returns a boolean indicating if a block has at least one child block with inserter support.
5897   *
5898   * @param {Object} state     Data state.
5899   * @param {string} blockName Block type name.
5900   *
5901   * @return {boolean} True if a block contains at least one child blocks with inserter support
5902   *                   and false otherwise.
5903   */
5904  
5905  var selectors_hasChildBlocksWithInserterSupport = function hasChildBlocksWithInserterSupport(state, blockName) {
5906    return Object(external_lodash_["some"])(selectors_getChildBlockNames(state, blockName), function (childBlockName) {
5907      return hasBlockSupport(state, childBlockName, 'inserter', true);
5908    });
5909  };
5910  
5911  // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/store/actions.js
5912  /**
5913   * External dependencies
5914   */
5915  
5916  /**
5917   * Returns an action object used in signalling that block types have been added.
5918   *
5919   * @param {Array|Object} blockTypes Block types received.
5920   *
5921   * @return {Object} Action object.
5922   */
5923  
5924  function addBlockTypes(blockTypes) {
5925    return {
5926      type: 'ADD_BLOCK_TYPES',
5927      blockTypes: Object(external_lodash_["castArray"])(blockTypes)
5928    };
5929  }
5930  /**
5931   * Returns an action object used to remove a registered block type.
5932   *
5933   * @param {string|Array} names Block name.
5934   *
5935   * @return {Object} Action object.
5936   */
5937  
5938  function removeBlockTypes(names) {
5939    return {
5940      type: 'REMOVE_BLOCK_TYPES',
5941      names: Object(external_lodash_["castArray"])(names)
5942    };
5943  }
5944  /**
5945   * Returns an action object used in signalling that new block styles have been added.
5946   *
5947   * @param {string}       blockName  Block name.
5948   * @param {Array|Object} styles     Block styles.
5949   *
5950   * @return {Object} Action object.
5951   */
5952  
5953  function addBlockStyles(blockName, styles) {
5954    return {
5955      type: 'ADD_BLOCK_STYLES',
5956      styles: Object(external_lodash_["castArray"])(styles),
5957      blockName: blockName
5958    };
5959  }
5960  /**
5961   * Returns an action object used in signalling that block styles have been removed.
5962   *
5963   * @param {string}       blockName  Block name.
5964   * @param {Array|string} styleNames Block style names.
5965   *
5966   * @return {Object} Action object.
5967   */
5968  
5969  function removeBlockStyles(blockName, styleNames) {
5970    return {
5971      type: 'REMOVE_BLOCK_STYLES',
5972      styleNames: Object(external_lodash_["castArray"])(styleNames),
5973      blockName: blockName
5974    };
5975  }
5976  /**
5977   * Returns an action object used to set the default block name.
5978   *
5979   * @param {string} name Block name.
5980   *
5981   * @return {Object} Action object.
5982   */
5983  
5984  function setDefaultBlockName(name) {
5985    return {
5986      type: 'SET_DEFAULT_BLOCK_NAME',
5987      name: name
5988    };
5989  }
5990  /**
5991   * Returns an action object used to set the name of the block used as a fallback
5992   * for non-block content.
5993   *
5994   * @param {string} name Block name.
5995   *
5996   * @return {Object} Action object.
5997   */
5998  
5999  function setFreeformFallbackBlockName(name) {
6000    return {
6001      type: 'SET_FREEFORM_FALLBACK_BLOCK_NAME',
6002      name: name
6003    };
6004  }
6005  /**
6006   * Returns an action object used to set the name of the block used as a fallback
6007   * for unregistered blocks.
6008   *
6009   * @param {string} name Block name.
6010   *
6011   * @return {Object} Action object.
6012   */
6013  
6014  function setUnregisteredFallbackBlockName(name) {
6015    return {
6016      type: 'SET_UNREGISTERED_FALLBACK_BLOCK_NAME',
6017      name: name
6018    };
6019  }
6020  /**
6021   * Returns an action object used to set the name of the block used
6022   * when grouping other blocks
6023   * eg: in "Group/Ungroup" interactions
6024   *
6025   * @param {string} name Block name.
6026   *
6027   * @return {Object} Action object.
6028   */
6029  
6030  function setGroupingBlockName(name) {
6031    return {
6032      type: 'SET_GROUPING_BLOCK_NAME',
6033      name: name
6034    };
6035  }
6036  /**
6037   * Returns an action object used to set block categories.
6038   *
6039   * @param {Object[]} categories Block categories.
6040   *
6041   * @return {Object} Action object.
6042   */
6043  
6044  function setCategories(categories) {
6045    return {
6046      type: 'SET_CATEGORIES',
6047      categories: categories
6048    };
6049  }
6050  /**
6051   * Returns an action object used to update a category.
6052   *
6053   * @param {string} slug     Block category slug.
6054   * @param {Object} category Object containing the category properties that should be updated.
6055   *
6056   * @return {Object} Action object.
6057   */
6058  
6059  function updateCategory(slug, category) {
6060    return {
6061      type: 'UPDATE_CATEGORY',
6062      slug: slug,
6063      category: category
6064    };
6065  }
6066  
6067  // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/store/index.js
6068  /**
6069   * WordPress dependencies
6070   */
6071  
6072  /**
6073   * Internal dependencies
6074   */
6075  
6076  
6077  
6078  
6079  Object(external_this_wp_data_["registerStore"])('core/blocks', {
6080    reducer: reducer,
6081    selectors: selectors_namespaceObject,
6082    actions: actions_namespaceObject
6083  });
6084  
6085  // EXTERNAL MODULE: ./node_modules/uuid/v4.js
6086  var v4 = __webpack_require__(67);
6087  var v4_default = /*#__PURE__*/__webpack_require__.n(v4);
6088  
6089  // EXTERNAL MODULE: external {"this":["wp","hooks"]}
6090  var external_this_wp_hooks_ = __webpack_require__(27);
6091  
6092  // EXTERNAL MODULE: ./node_modules/tinycolor2/tinycolor.js
6093  var tinycolor = __webpack_require__(48);
6094  var tinycolor_default = /*#__PURE__*/__webpack_require__.n(tinycolor);
6095  
6096  // EXTERNAL MODULE: external {"this":["wp","element"]}
6097  var external_this_wp_element_ = __webpack_require__(0);
6098  
6099  // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/utils.js
6100  
6101  
6102  /**
6103   * External dependencies
6104   */
6105  
6106  
6107  /**
6108   * WordPress dependencies
6109   */
6110  
6111  
6112  /**
6113   * Internal dependencies
6114   */
6115  
6116  
6117  
6118  /**
6119   * Array of icon colors containing a color to be used if the icon color
6120   * was not explicitly set but the icon background color was.
6121   *
6122   * @type {Object}
6123   */
6124  
6125  var ICON_COLORS = ['#191e23', '#f8f9f9'];
6126  /**
6127   * Determines whether the block is a default block
6128   * and its attributes are equal to the default attributes
6129   * which means the block is unmodified.
6130   *
6131   * @param  {WPBlock} block Block Object
6132   *
6133   * @return {boolean}       Whether the block is an unmodified default block
6134   */
6135  
6136  function isUnmodifiedDefaultBlock(block) {
6137    var defaultBlockName = registration_getDefaultBlockName();
6138  
6139    if (block.name !== defaultBlockName) {
6140      return false;
6141    } // Cache a created default block if no cache exists or the default block
6142    // name changed.
6143  
6144  
6145    if (!isUnmodifiedDefaultBlock.block || isUnmodifiedDefaultBlock.block.name !== defaultBlockName) {
6146      isUnmodifiedDefaultBlock.block = createBlock(defaultBlockName);
6147    }
6148  
6149    var newDefaultBlock = isUnmodifiedDefaultBlock.block;
6150    var blockType = registration_getBlockType(defaultBlockName);
6151    return Object(external_lodash_["every"])(blockType.attributes, function (value, key) {
6152      return newDefaultBlock.attributes[key] === block.attributes[key];
6153    });
6154  }
6155  /**
6156   * Function that checks if the parameter is a valid icon.
6157   *
6158   * @param {*} icon  Parameter to be checked.
6159   *
6160   * @return {boolean} True if the parameter is a valid icon and false otherwise.
6161   */
6162  
6163  function isValidIcon(icon) {
6164    return !!icon && (Object(external_lodash_["isString"])(icon) || Object(external_this_wp_element_["isValidElement"])(icon) || Object(external_lodash_["isFunction"])(icon) || icon instanceof external_this_wp_element_["Component"]);
6165  }
6166  /**
6167   * Function that receives an icon as set by the blocks during the registration
6168   * and returns a new icon object that is normalized so we can rely on just on possible icon structure
6169   * in the codebase.
6170   *
6171   * @param {WPBlockTypeIconRender} icon Render behavior of a block type icon;
6172   *                                     one of a Dashicon slug, an element, or a
6173   *                                     component.
6174   *
6175   * @return {WPBlockTypeIconDescriptor} Object describing the icon.
6176   */
6177  
6178  function normalizeIconObject(icon) {
6179    if (isValidIcon(icon)) {
6180      return {
6181        src: icon
6182      };
6183    }
6184  
6185    if (Object(external_lodash_["has"])(icon, ['background'])) {
6186      var tinyBgColor = tinycolor_default()(icon.background);
6187      return Object(objectSpread["a" /* default */])({}, icon, {
6188        foreground: icon.foreground ? icon.foreground : Object(tinycolor["mostReadable"])(tinyBgColor, ICON_COLORS, {
6189          includeFallbackColors: true,
6190          level: 'AA',
6191          size: 'large'
6192        }).toHexString(),
6193        shadowColor: tinyBgColor.setAlpha(0.3).toRgbString()
6194      });
6195    }
6196  
6197    return icon;
6198  }
6199  /**
6200   * Normalizes block type passed as param. When string is passed then
6201   * it converts it to the matching block type object.
6202   * It passes the original object otherwise.
6203   *
6204   * @param {string|Object} blockTypeOrName  Block type or name.
6205   *
6206   * @return {?Object} Block type.
6207   */
6208  
6209  function normalizeBlockType(blockTypeOrName) {
6210    if (Object(external_lodash_["isString"])(blockTypeOrName)) {
6211      return registration_getBlockType(blockTypeOrName);
6212    }
6213  
6214    return blockTypeOrName;
6215  }
6216  
6217  // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/constants.js
6218  /**
6219   * Array of valid keys in a block type settings deprecation object.
6220   *
6221   * @type {string[]}
6222   */
6223  var DEPRECATED_ENTRY_KEYS = ['attributes', 'supports', 'save', 'migrate', 'isEligible'];
6224  
6225  // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/registration.js
6226  
6227  
6228  /* eslint no-console: [ 'error', { allow: [ 'error' ] } ] */
6229  
6230  /**
6231   * External dependencies
6232   */
6233  
6234  /**
6235   * WordPress dependencies
6236   */
6237  
6238  
6239  
6240  /**
6241   * Internal dependencies
6242   */
6243  
6244  
6245  
6246  /**
6247   * Render behavior of a block type icon; one of a Dashicon slug, an element,
6248   * or a component.
6249   *
6250   * @typedef {(string|WPElement|WPComponent)} WPBlockTypeIconRender
6251   *
6252   * @see https://developer.wordpress.org/resource/dashicons/
6253   */
6254  
6255  /**
6256   * An object describing a normalized block type icon.
6257   *
6258   * @typedef {Object} WPBlockTypeIconDescriptor
6259   *
6260   * @property {WPBlockTypeIconRender} src         Render behavior of the icon,
6261   *                                               one of a Dashicon slug, an
6262   *                                               element, or a component.
6263   * @property {string}                background  Optimal background hex string
6264   *                                               color when displaying icon.
6265   * @property {string}                foreground  Optimal foreground hex string
6266   *                                               color when displaying icon.
6267   * @property {string}                shadowColor Optimal shadow hex string
6268   *                                               color when displaying icon.
6269   */
6270  
6271  /**
6272   * Value to use to render the icon for a block type in an editor interface,
6273   * either a Dashicon slug, an element, a component, or an object describing
6274   * the icon.
6275   *
6276   * @typedef {(WPBlockTypeIconDescriptor|WPBlockTypeIconRender)} WPBlockTypeIcon
6277   */
6278  
6279  /**
6280   * Defined behavior of a block type.
6281   *
6282   * @typedef {Object} WPBlockType
6283   *
6284   * @property {string}           name        Block type's namespaced name.
6285   * @property {string}           title       Human-readable block type label.
6286   * @property {string}           category    Block type category classification,
6287   *                                          used in search interfaces to arrange
6288   *                                          block types by category.
6289   * @property {WPBlockTypeIcon} [icon]       Block type icon.
6290   * @property {string[]}        [keywords]   Additional keywords to produce block
6291   *                                          type as result in search interfaces.
6292   * @property {Object}          [attributes] Block type attributes.
6293   * @property {WPComponent}     [save]       Optional component describing
6294   *                                          serialized markup structure of a
6295   *                                          block type.
6296   * @property {WPComponent}      edit        Component rendering an element to
6297   *                                          manipulate the attributes of a block
6298   *                                          in the context of an editor.
6299   */
6300  
6301  /**
6302   * Default values to assign for omitted optional block type settings.
6303   *
6304   * @type {Object}
6305   */
6306  
6307  var DEFAULT_BLOCK_TYPE_SETTINGS = {
6308    icon: 'block-default',
6309    attributes: {},
6310    keywords: [],
6311    save: function save() {
6312      return null;
6313    }
6314  };
6315  var serverSideBlockDefinitions = {};
6316  /**
6317   * Sets the server side block definition of blocks.
6318   *
6319   * @param {Object} definitions Server-side block definitions
6320   */
6321  
6322  function unstable__bootstrapServerSideBlockDefinitions(definitions) {
6323    // eslint-disable-line camelcase
6324    serverSideBlockDefinitions = Object(objectSpread["a" /* default */])({}, serverSideBlockDefinitions, definitions);
6325  }
6326  /**
6327   * Registers a new block provided a unique name and an object defining its
6328   * behavior. Once registered, the block is made available as an option to any
6329   * editor interface where blocks are implemented.
6330   *
6331   * @param {string} name     Block name.
6332   * @param {Object} settings Block settings.
6333   *
6334   * @return {?WPBlock} The block, if it has been successfully registered;
6335   *                     otherwise `undefined`.
6336   */
6337  
6338  function registerBlockType(name, settings) {
6339    settings = Object(objectSpread["a" /* default */])({
6340      name: name
6341    }, DEFAULT_BLOCK_TYPE_SETTINGS, Object(external_lodash_["get"])(serverSideBlockDefinitions, name), settings);
6342  
6343    if (typeof name !== 'string') {
6344      console.error('Block names must be strings.');
6345      return;
6346    }
6347  
6348    if (!/^[a-z][a-z0-9-]*\/[a-z][a-z0-9-]*$/.test(name)) {
6349      console.error('Block names must contain a namespace prefix, include only lowercase alphanumeric characters or dashes, and start with a letter. Example: my-plugin/my-custom-block');
6350      return;
6351    }
6352  
6353    if (Object(external_this_wp_data_["select"])('core/blocks').getBlockType(name)) {
6354      console.error('Block "' + name + '" is already registered.');
6355      return;
6356    }
6357  
6358    var preFilterSettings = Object(objectSpread["a" /* default */])({}, settings);
6359  
6360    settings = Object(external_this_wp_hooks_["applyFilters"])('blocks.registerBlockType', settings, name);
6361  
6362    if (settings.deprecated) {
6363      settings.deprecated = settings.deprecated.map(function (deprecation) {
6364        return Object(external_lodash_["pick"])( // Only keep valid deprecation keys.
6365        Object(external_this_wp_hooks_["applyFilters"])('blocks.registerBlockType', // Merge deprecation keys with pre-filter settings
6366        // so that filters that depend on specific keys being
6367        // present don't fail.
6368        Object(objectSpread["a" /* default */])({}, Object(external_lodash_["omit"])(preFilterSettings, DEPRECATED_ENTRY_KEYS), deprecation), name), DEPRECATED_ENTRY_KEYS);
6369      });
6370    }
6371  
6372    if (!Object(external_lodash_["isPlainObject"])(settings)) {
6373      console.error('Block settings must be a valid object.');
6374      return;
6375    }
6376  
6377    if (!Object(external_lodash_["isFunction"])(settings.save)) {
6378      console.error('The "save" property must be a valid function.');
6379      return;
6380    }
6381  
6382    if ('edit' in settings && !Object(external_lodash_["isFunction"])(settings.edit)) {
6383      console.error('The "edit" property must be a valid function.');
6384      return;
6385    }
6386  
6387    if (!('category' in settings)) {
6388      console.error('The block "' + name + '" must have a category.');
6389      return;
6390    }
6391  
6392    if ('category' in settings && !Object(external_lodash_["some"])(Object(external_this_wp_data_["select"])('core/blocks').getCategories(), {
6393      slug: settings.category
6394    })) {
6395      console.error('The block "' + name + '" must have a registered category.');
6396      return;
6397    }
6398  
6399    if (!('title' in settings) || settings.title === '') {
6400      console.error('The block "' + name + '" must have a title.');
6401      return;
6402    }
6403  
6404    if (typeof settings.title !== 'string') {
6405      console.error('Block titles must be strings.');
6406      return;
6407    }
6408  
6409    settings.icon = normalizeIconObject(settings.icon);
6410  
6411    if (!isValidIcon(settings.icon.src)) {
6412      console.error('The icon passed is invalid. ' + 'The icon should be a string, an element, a function, or an object following the specifications documented in https://developer.wordpress.org/block-editor/developers/block-api/block-registration/#icon-optional');
6413      return;
6414    }
6415  
6416    Object(external_this_wp_data_["dispatch"])('core/blocks').addBlockTypes(settings);
6417    return settings;
6418  }
6419  /**
6420   * Unregisters a block.
6421   *
6422   * @param {string} name Block name.
6423   *
6424   * @return {?WPBlock} The previous block value, if it has been successfully
6425   *                     unregistered; otherwise `undefined`.
6426   */
6427  
6428  function unregisterBlockType(name) {
6429    var oldBlock = Object(external_this_wp_data_["select"])('core/blocks').getBlockType(name);
6430  
6431    if (!oldBlock) {
6432      console.error('Block "' + name + '" is not registered.');
6433      return;
6434    }
6435  
6436    Object(external_this_wp_data_["dispatch"])('core/blocks').removeBlockTypes(name);
6437    return oldBlock;
6438  }
6439  /**
6440   * Assigns name of block for handling non-block content.
6441   *
6442   * @param {string} blockName Block name.
6443   */
6444  
6445  function setFreeformContentHandlerName(blockName) {
6446    Object(external_this_wp_data_["dispatch"])('core/blocks').setFreeformFallbackBlockName(blockName);
6447  }
6448  /**
6449   * Retrieves name of block handling non-block content, or undefined if no
6450   * handler has been defined.
6451   *
6452   * @return {?string} Block name.
6453   */
6454  
6455  function getFreeformContentHandlerName() {
6456    return Object(external_this_wp_data_["select"])('core/blocks').getFreeformFallbackBlockName();
6457  }
6458  /**
6459   * Retrieves name of block used for handling grouping interactions.
6460   *
6461   * @return {?string} Block name.
6462   */
6463  
6464  function registration_getGroupingBlockName() {
6465    return Object(external_this_wp_data_["select"])('core/blocks').getGroupingBlockName();
6466  }
6467  /**
6468   * Assigns name of block handling unregistered block types.
6469   *
6470   * @param {string} blockName Block name.
6471   */
6472  
6473  function setUnregisteredTypeHandlerName(blockName) {
6474    Object(external_this_wp_data_["dispatch"])('core/blocks').setUnregisteredFallbackBlockName(blockName);
6475  }
6476  /**
6477   * Retrieves name of block handling unregistered block types, or undefined if no
6478   * handler has been defined.
6479   *
6480   * @return {?string} Block name.
6481   */
6482  
6483  function getUnregisteredTypeHandlerName() {
6484    return Object(external_this_wp_data_["select"])('core/blocks').getUnregisteredFallbackBlockName();
6485  }
6486  /**
6487   * Assigns the default block name.
6488   *
6489   * @param {string} name Block name.
6490   */
6491  
6492  function registration_setDefaultBlockName(name) {
6493    Object(external_this_wp_data_["dispatch"])('core/blocks').setDefaultBlockName(name);
6494  }
6495  /**
6496   * Assigns name of block for handling block grouping interactions.
6497   *
6498   * @param {string} name Block name.
6499   */
6500  
6501  function registration_setGroupingBlockName(name) {
6502    Object(external_this_wp_data_["dispatch"])('core/blocks').setGroupingBlockName(name);
6503  }
6504  /**
6505   * Retrieves the default block name.
6506   *
6507   * @return {?string} Block name.
6508   */
6509  
6510  function registration_getDefaultBlockName() {
6511    return Object(external_this_wp_data_["select"])('core/blocks').getDefaultBlockName();
6512  }
6513  /**
6514   * Returns a registered block type.
6515   *
6516   * @param {string} name Block name.
6517   *
6518   * @return {?Object} Block type.
6519   */
6520  
6521  function registration_getBlockType(name) {
6522    return Object(external_this_wp_data_["select"])('core/blocks').getBlockType(name);
6523  }
6524  /**
6525   * Returns all registered blocks.
6526   *
6527   * @return {Array} Block settings.
6528   */
6529  
6530  function registration_getBlockTypes() {
6531    return Object(external_this_wp_data_["select"])('core/blocks').getBlockTypes();
6532  }
6533  /**
6534   * Returns the block support value for a feature, if defined.
6535   *
6536   * @param  {(string|Object)} nameOrType      Block name or type object
6537   * @param  {string}          feature         Feature to retrieve
6538   * @param  {*}               defaultSupports Default value to return if not
6539   *                                           explicitly defined
6540   *
6541   * @return {?*} Block support value
6542   */
6543  
6544  function registration_getBlockSupport(nameOrType, feature, defaultSupports) {
6545    return Object(external_this_wp_data_["select"])('core/blocks').getBlockSupport(nameOrType, feature, defaultSupports);
6546  }
6547  /**
6548   * Returns true if the block defines support for a feature, or false otherwise.
6549   *
6550   * @param {(string|Object)} nameOrType      Block name or type object.
6551   * @param {string}          feature         Feature to test.
6552   * @param {boolean}         defaultSupports Whether feature is supported by
6553   *                                          default if not explicitly defined.
6554   *
6555   * @return {boolean} Whether block supports feature.
6556   */
6557  
6558  function registration_hasBlockSupport(nameOrType, feature, defaultSupports) {
6559    return Object(external_this_wp_data_["select"])('core/blocks').hasBlockSupport(nameOrType, feature, defaultSupports);
6560  }
6561  /**
6562   * Determines whether or not the given block is a reusable block. This is a
6563   * special block type that is used to point to a global block stored via the
6564   * API.
6565   *
6566   * @param {Object} blockOrType Block or Block Type to test.
6567   *
6568   * @return {boolean} Whether the given block is a reusable block.
6569   */
6570  
6571  function isReusableBlock(blockOrType) {
6572    return blockOrType.name === 'core/block';
6573  }
6574  /**
6575   * Returns an array with the child blocks of a given block.
6576   *
6577   * @param {string} blockName Name of block (example: “latest-posts”).
6578   *
6579   * @return {Array} Array of child block names.
6580   */
6581  
6582  var registration_getChildBlockNames = function getChildBlockNames(blockName) {
6583    return Object(external_this_wp_data_["select"])('core/blocks').getChildBlockNames(blockName);
6584  };
6585  /**
6586   * Returns a boolean indicating if a block has child blocks or not.
6587   *
6588   * @param {string} blockName Name of block (example: “latest-posts”).
6589   *
6590   * @return {boolean} True if a block contains child blocks and false otherwise.
6591   */
6592  
6593  var registration_hasChildBlocks = function hasChildBlocks(blockName) {
6594    return Object(external_this_wp_data_["select"])('core/blocks').hasChildBlocks(blockName);
6595  };
6596  /**
6597   * Returns a boolean indicating if a block has at least one child block with inserter support.
6598   *
6599   * @param {string} blockName Block type name.
6600   *
6601   * @return {boolean} True if a block contains at least one child blocks with inserter support
6602   *                   and false otherwise.
6603   */
6604  
6605  var registration_hasChildBlocksWithInserterSupport = function hasChildBlocksWithInserterSupport(blockName) {
6606    return Object(external_this_wp_data_["select"])('core/blocks').hasChildBlocksWithInserterSupport(blockName);
6607  };
6608  /**
6609   * Registers a new block style variation for the given block.
6610   *
6611   * @param {string} blockName      Name of block (example: “core/latest-posts”).
6612   * @param {Object} styleVariation Object containing `name` which is the class name applied to the block and `label` which identifies the variation to the user.
6613   */
6614  
6615  var registration_registerBlockStyle = function registerBlockStyle(blockName, styleVariation) {
6616    Object(external_this_wp_data_["dispatch"])('core/blocks').addBlockStyles(blockName, styleVariation);
6617  };
6618  /**
6619   * Unregisters a block style variation for the given block.
6620   *
6621   * @param {string} blockName          Name of block (example: “core/latest-posts”).
6622   * @param {string} styleVariationName Name of class applied to the block.
6623   */
6624  
6625  var registration_unregisterBlockStyle = function unregisterBlockStyle(blockName, styleVariationName) {
6626    Object(external_this_wp_data_["dispatch"])('core/blocks').removeBlockStyles(blockName, styleVariationName);
6627  };
6628  
6629  // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/factory.js
6630  
6631  
6632  
6633  /**
6634   * External dependencies
6635   */
6636  
6637  
6638  /**
6639   * WordPress dependencies
6640   */
6641  
6642  
6643  /**
6644   * Internal dependencies
6645   */
6646  
6647  
6648  
6649  /**
6650   * Returns a block object given its type and attributes.
6651   *
6652   * @param {string} name        Block name.
6653   * @param {Object} attributes  Block attributes.
6654   * @param {?Array} innerBlocks Nested blocks.
6655   *
6656   * @return {Object} Block object.
6657   */
6658  
6659  function createBlock(name) {
6660    var attributes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
6661    var innerBlocks = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
6662    // Get the type definition associated with a registered block.
6663    var blockType = registration_getBlockType(name); // Ensure attributes contains only values defined by block type, and merge
6664    // default values for missing attributes.
6665  
6666    var sanitizedAttributes = Object(external_lodash_["reduce"])(blockType.attributes, function (result, schema, key) {
6667      var value = attributes[key];
6668  
6669      if (undefined !== value) {
6670        result[key] = value;
6671      } else if (schema.hasOwnProperty('default')) {
6672        result[key] = schema.default;
6673      }
6674  
6675      if (['node', 'children'].indexOf(schema.source) !== -1) {
6676        // Ensure value passed is always an array, which we're expecting in
6677        // the RichText component to handle the deprecated value.
6678        if (typeof result[key] === 'string') {
6679          result[key] = [result[key]];
6680        } else if (!Array.isArray(result[key])) {
6681          result[key] = [];
6682        }
6683      }
6684  
6685      return result;
6686    }, {});
6687    var clientId = v4_default()(); // Blocks are stored with a unique ID, the assigned type name, the block
6688    // attributes, and their inner blocks.
6689  
6690    return {
6691      clientId: clientId,
6692      name: name,
6693      isValid: true,
6694      attributes: sanitizedAttributes,
6695      innerBlocks: innerBlocks
6696    };
6697  }
6698  /**
6699   * Given a block object, returns a copy of the block object, optionally merging
6700   * new attributes and/or replacing its inner blocks.
6701   *
6702   * @param {Object} block              Block instance.
6703   * @param {Object} mergeAttributes    Block attributes.
6704   * @param {?Array} newInnerBlocks     Nested blocks.
6705   *
6706   * @return {Object} A cloned block.
6707   */
6708  
6709  function cloneBlock(block) {
6710    var mergeAttributes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
6711    var newInnerBlocks = arguments.length > 2 ? arguments[2] : undefined;
6712    var clientId = v4_default()();
6713    return Object(objectSpread["a" /* default */])({}, block, {
6714      clientId: clientId,
6715      attributes: Object(objectSpread["a" /* default */])({}, block.attributes, mergeAttributes),
6716      innerBlocks: newInnerBlocks || block.innerBlocks.map(function (innerBlock) {
6717        return cloneBlock(innerBlock);
6718      })
6719    });
6720  }
6721  /**
6722   * Returns a boolean indicating whether a transform is possible based on
6723   * various bits of context.
6724   *
6725   * @param {Object} transform The transform object to validate.
6726   * @param {string} direction Is this a 'from' or 'to' transform.
6727   * @param {Array} blocks The blocks to transform from.
6728   *
6729   * @return {boolean} Is the transform possible?
6730   */
6731  
6732  var factory_isPossibleTransformForSource = function isPossibleTransformForSource(transform, direction, blocks) {
6733    if (Object(external_lodash_["isEmpty"])(blocks)) {
6734      return false;
6735    } // If multiple blocks are selected, only multi block transforms
6736    // or wildcard transforms are allowed.
6737  
6738  
6739    var isMultiBlock = blocks.length > 1;
6740    var firstBlockName = Object(external_lodash_["first"])(blocks).name;
6741    var isValidForMultiBlocks = isWildcardBlockTransform(transform) || !isMultiBlock || transform.isMultiBlock;
6742  
6743    if (!isValidForMultiBlocks) {
6744      return false;
6745    } // Check non-wildcard transforms to ensure that transform is valid
6746    // for a block selection of multiple blocks of different types
6747  
6748  
6749    if (!isWildcardBlockTransform(transform) && !Object(external_lodash_["every"])(blocks, {
6750      name: firstBlockName
6751    })) {
6752      return false;
6753    } // Only consider 'block' type transforms as valid.
6754  
6755  
6756    var isBlockType = transform.type === 'block';
6757  
6758    if (!isBlockType) {
6759      return false;
6760    } // Check if the transform's block name matches the source block (or is a wildcard)
6761    // only if this is a transform 'from'.
6762  
6763  
6764    var sourceBlock = Object(external_lodash_["first"])(blocks);
6765    var hasMatchingName = direction !== 'from' || transform.blocks.indexOf(sourceBlock.name) !== -1 || isWildcardBlockTransform(transform);
6766  
6767    if (!hasMatchingName) {
6768      return false;
6769    } // Don't allow single Grouping blocks to be transformed into
6770    // a Grouping block.
6771  
6772  
6773    if (!isMultiBlock && factory_isContainerGroupBlock(sourceBlock.name) && factory_isContainerGroupBlock(transform.blockName)) {
6774      return false;
6775    } // If the transform has a `isMatch` function specified, check that it returns true.
6776  
6777  
6778    if (Object(external_lodash_["isFunction"])(transform.isMatch)) {
6779      var attributes = transform.isMultiBlock ? blocks.map(function (block) {
6780        return block.attributes;
6781      }) : sourceBlock.attributes;
6782  
6783      if (!transform.isMatch(attributes)) {
6784        return false;
6785      }
6786    }
6787  
6788    return true;
6789  };
6790  /**
6791   * Returns block types that the 'blocks' can be transformed into, based on
6792   * 'from' transforms on other blocks.
6793   *
6794   * @param {Array}  blocks  The blocks to transform from.
6795   *
6796   * @return {Array} Block types that the blocks can be transformed into.
6797   */
6798  
6799  
6800  var factory_getBlockTypesForPossibleFromTransforms = function getBlockTypesForPossibleFromTransforms(blocks) {
6801    if (Object(external_lodash_["isEmpty"])(blocks)) {
6802      return [];
6803    }
6804  
6805    var allBlockTypes = registration_getBlockTypes(); // filter all blocks to find those with a 'from' transform.
6806  
6807    var blockTypesWithPossibleFromTransforms = Object(external_lodash_["filter"])(allBlockTypes, function (blockType) {
6808      var fromTransforms = getBlockTransforms('from', blockType.name);
6809      return !!findTransform(fromTransforms, function (transform) {
6810        return factory_isPossibleTransformForSource(transform, 'from', blocks);
6811      });
6812    });
6813    return blockTypesWithPossibleFromTransforms;
6814  };
6815  /**
6816   * Returns block types that the 'blocks' can be transformed into, based on
6817   * the source block's own 'to' transforms.
6818   *
6819   * @param {Array} blocks The blocks to transform from.
6820   *
6821   * @return {Array} Block types that the source can be transformed into.
6822   */
6823  
6824  
6825  var factory_getBlockTypesForPossibleToTransforms = function getBlockTypesForPossibleToTransforms(blocks) {
6826    if (Object(external_lodash_["isEmpty"])(blocks)) {
6827      return [];
6828    }
6829  
6830    var sourceBlock = Object(external_lodash_["first"])(blocks);
6831    var blockType = registration_getBlockType(sourceBlock.name);
6832    var transformsTo = getBlockTransforms('to', blockType.name); // filter all 'to' transforms to find those that are possible.
6833  
6834    var possibleTransforms = Object(external_lodash_["filter"])(transformsTo, function (transform) {
6835      return transform && factory_isPossibleTransformForSource(transform, 'to', blocks);
6836    }); // Build a list of block names using the possible 'to' transforms.
6837  
6838    var blockNames = Object(external_lodash_["flatMap"])(possibleTransforms, function (transformation) {
6839      return transformation.blocks;
6840    }); // Map block names to block types.
6841  
6842    return blockNames.map(function (name) {
6843      return registration_getBlockType(name);
6844    });
6845  };
6846  /**
6847   * Determines whether transform is a "block" type
6848   * and if so whether it is a "wildcard" transform
6849   * ie: targets "any" block type
6850   *
6851   * @param {Object} t the Block transform object
6852   *
6853   * @return {boolean} whether transform is a wildcard transform
6854   */
6855  
6856  
6857  var isWildcardBlockTransform = function isWildcardBlockTransform(t) {
6858    return t && t.type === 'block' && Array.isArray(t.blocks) && t.blocks.includes('*');
6859  };
6860  /**
6861   * Determines whether the given Block is the core Block which
6862   * acts as a container Block for other Blocks as part of the
6863   * Grouping mechanics
6864   *
6865   * @param  {string} name the name of the Block to test against
6866   *
6867   * @return {boolean} whether or not the Block is the container Block type
6868   */
6869  
6870  var factory_isContainerGroupBlock = function isContainerGroupBlock(name) {
6871    return name === registration_getGroupingBlockName();
6872  };
6873  /**
6874   * Determines whether the provided Blocks are of the same type
6875   * (eg: all `core/paragraph`).
6876   *
6877   * @param  {Array}  blocksArray the Block definitions
6878   *
6879   * @return {boolean} whether or not the given Blocks pass the criteria
6880   */
6881  
6882  var factory_isBlockSelectionOfSameType = function isBlockSelectionOfSameType() {
6883    var blocksArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
6884  
6885    if (!blocksArray.length) {
6886      return false;
6887    }
6888  
6889    var sourceName = blocksArray[0].name;
6890    return Object(external_lodash_["every"])(blocksArray, ['name', sourceName]);
6891  };
6892  /**
6893   * Returns an array of block types that the set of blocks received as argument
6894   * can be transformed into.
6895   *
6896   * @param {Array} blocks Blocks array.
6897   *
6898   * @return {Array} Block types that the blocks argument can be transformed to.
6899   */
6900  
6901  function getPossibleBlockTransformations(blocks) {
6902    if (Object(external_lodash_["isEmpty"])(blocks)) {
6903      return [];
6904    }
6905  
6906    var blockTypesForFromTransforms = factory_getBlockTypesForPossibleFromTransforms(blocks);
6907    var blockTypesForToTransforms = factory_getBlockTypesForPossibleToTransforms(blocks);
6908    return Object(external_lodash_["uniq"])([].concat(Object(toConsumableArray["a" /* default */])(blockTypesForFromTransforms), Object(toConsumableArray["a" /* default */])(blockTypesForToTransforms)));
6909  }
6910  /**
6911   * Given an array of transforms, returns the highest-priority transform where
6912   * the predicate function returns a truthy value. A higher-priority transform
6913   * is one with a lower priority value (i.e. first in priority order). Returns
6914   * null if the transforms set is empty or the predicate function returns a
6915   * falsey value for all entries.
6916   *
6917   * @param {Object[]} transforms Transforms to search.
6918   * @param {Function} predicate  Function returning true on matching transform.
6919   *
6920   * @return {?Object} Highest-priority transform candidate.
6921   */
6922  
6923  function findTransform(transforms, predicate) {
6924    // The hooks library already has built-in mechanisms for managing priority
6925    // queue, so leverage via locally-defined instance.
6926    var hooks = Object(external_this_wp_hooks_["createHooks"])();
6927  
6928    var _loop = function _loop(i) {
6929      var candidate = transforms[i];
6930  
6931      if (predicate(candidate)) {
6932        hooks.addFilter('transform', 'transform/' + i.toString(), function (result) {
6933          return result ? result : candidate;
6934        }, candidate.priority);
6935      }
6936    };
6937  
6938    for (var i = 0; i < transforms.length; i++) {
6939      _loop(i);
6940    } // Filter name is arbitrarily chosen but consistent with above aggregation.
6941  
6942  
6943    return hooks.applyFilters('transform', null);
6944  }
6945  /**
6946   * Returns normal block transforms for a given transform direction, optionally
6947   * for a specific block by name, or an empty array if there are no transforms.
6948   * If no block name is provided, returns transforms for all blocks. A normal
6949   * transform object includes `blockName` as a property.
6950   *
6951   * @param {string}  direction Transform direction ("to", "from").
6952   * @param {string|Object} blockTypeOrName  Block type or name.
6953   *
6954   * @return {Array} Block transforms for direction.
6955   */
6956  
6957  function getBlockTransforms(direction, blockTypeOrName) {
6958    // When retrieving transforms for all block types, recurse into self.
6959    if (blockTypeOrName === undefined) {
6960      return Object(external_lodash_["flatMap"])(registration_getBlockTypes(), function (_ref) {
6961        var name = _ref.name;
6962        return getBlockTransforms(direction, name);
6963      });
6964    } // Validate that block type exists and has array of direction.
6965  
6966  
6967    var blockType = normalizeBlockType(blockTypeOrName);
6968  
6969    var _ref2 = blockType || {},
6970        blockName = _ref2.name,
6971        transforms = _ref2.transforms;
6972  
6973    if (!transforms || !Array.isArray(transforms[direction])) {
6974      return [];
6975    } // Map transforms to normal form.
6976  
6977  
6978    return transforms[direction].map(function (transform) {
6979      return Object(objectSpread["a" /* default */])({}, transform, {
6980        blockName: blockName
6981      });
6982    });
6983  }
6984  /**
6985   * Switch one or more blocks into one or more blocks of the new block type.
6986   *
6987   * @param {Array|Object} blocks Blocks array or block object.
6988   * @param {string}       name   Block name.
6989   *
6990   * @return {?Array} Array of blocks or null.
6991   */
6992  
6993  function switchToBlockType(blocks, name) {
6994    var blocksArray = Object(external_lodash_["castArray"])(blocks);
6995    var isMultiBlock = blocksArray.length > 1;
6996    var firstBlock = blocksArray[0];
6997    var sourceName = firstBlock.name; // Unless it's a Grouping Block then for multi block selections
6998    // check that all Blocks are of the same type otherwise
6999    // we can't run a conversion
7000  
7001    if (!factory_isContainerGroupBlock(name) && isMultiBlock && !factory_isBlockSelectionOfSameType(blocksArray)) {
7002      return null;
7003    } // Find the right transformation by giving priority to the "to"
7004    // transformation.
7005  
7006  
7007    var transformationsFrom = getBlockTransforms('from', name);
7008    var transformationsTo = getBlockTransforms('to', sourceName);
7009    var transformation = findTransform(transformationsTo, function (t) {
7010      return t.type === 'block' && (isWildcardBlockTransform(t) || t.blocks.indexOf(name) !== -1) && (!isMultiBlock || t.isMultiBlock);
7011    }) || findTransform(transformationsFrom, function (t) {
7012      return t.type === 'block' && (isWildcardBlockTransform(t) || t.blocks.indexOf(sourceName) !== -1) && (!isMultiBlock || t.isMultiBlock);
7013    }); // Stop if there is no valid transformation.
7014  
7015    if (!transformation) {
7016      return null;
7017    }
7018  
7019    var transformationResults;
7020  
7021    if (transformation.isMultiBlock) {
7022      if (Object(external_lodash_["has"])(transformation, '__experimentalConvert')) {
7023        transformationResults = transformation.__experimentalConvert(blocksArray);
7024      } else {
7025        transformationResults = transformation.transform(blocksArray.map(function (currentBlock) {
7026          return currentBlock.attributes;
7027        }), blocksArray.map(function (currentBlock) {
7028          return currentBlock.innerBlocks;
7029        }));
7030      }
7031    } else if (Object(external_lodash_["has"])(transformation, '__experimentalConvert')) {
7032      transformationResults = transformation.__experimentalConvert(firstBlock);
7033    } else {
7034      transformationResults = transformation.transform(firstBlock.attributes, firstBlock.innerBlocks);
7035    } // Ensure that the transformation function returned an object or an array
7036    // of objects.
7037  
7038  
7039    if (!Object(external_lodash_["isObjectLike"])(transformationResults)) {
7040      return null;
7041    } // If the transformation function returned a single object, we want to work
7042    // with an array instead.
7043  
7044  
7045    transformationResults = Object(external_lodash_["castArray"])(transformationResults); // Ensure that every block object returned by the transformation has a
7046    // valid block type.
7047  
7048    if (transformationResults.some(function (result) {
7049      return !registration_getBlockType(result.name);
7050    })) {
7051      return null;
7052    }
7053  
7054    var firstSwitchedBlock = Object(external_lodash_["findIndex"])(transformationResults, function (result) {
7055      return result.name === name;
7056    }); // Ensure that at least one block object returned by the transformation has
7057    // the expected "destination" block type.
7058  
7059    if (firstSwitchedBlock < 0) {
7060      return null;
7061    }
7062  
7063    return transformationResults.map(function (result, index) {
7064      var transformedBlock = Object(objectSpread["a" /* default */])({}, result, {
7065        // The first transformed block whose type matches the "destination"
7066        // type gets to keep the existing client ID of the first block.
7067        clientId: index === firstSwitchedBlock ? firstBlock.clientId : result.clientId
7068      });
7069      /**
7070       * Filters an individual transform result from block transformation.
7071       * All of the original blocks are passed, since transformations are
7072       * many-to-many, not one-to-one.
7073       *
7074       * @param {Object}   transformedBlock The transformed block.
7075       * @param {Object[]} blocks           Original blocks transformed.
7076       */
7077  
7078  
7079      return Object(external_this_wp_hooks_["applyFilters"])('blocks.switchToBlockType.transformedBlock', transformedBlock, blocks);
7080    });
7081  }
7082  /**
7083   * Create a block object from the example API.
7084   *
7085   * @param {string} name
7086   * @param {Object} example
7087   *
7088   * @return {Object} block.
7089   */
7090  
7091  var factory_getBlockFromExample = function getBlockFromExample(name, example) {
7092    return createBlock(name, example.attributes, Object(external_lodash_["map"])(example.innerBlocks, function (innerBlock) {
7093      return getBlockFromExample(innerBlock.name, innerBlock);
7094    }));
7095  };
7096  
7097  // EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/slicedToArray.js + 1 modules
7098  var slicedToArray = __webpack_require__(23);
7099  
7100  // CONCATENATED MODULE: ./node_modules/hpq/es/get-path.js
7101  /**
7102   * Given object and string of dot-delimited path segments, returns value at
7103   * path or undefined if path cannot be resolved.
7104   *
7105   * @param  {Object} object Lookup object
7106   * @param  {string} path   Path to resolve
7107   * @return {?*}            Resolved value
7108   */
7109  function getPath(object, path) {
7110    var segments = path.split('.');
7111    var segment;
7112  
7113    while (segment = segments.shift()) {
7114      if (!(segment in object)) {
7115        return;
7116      }
7117  
7118      object = object[segment];
7119    }
7120  
7121    return object;
7122  }
7123  // CONCATENATED MODULE: ./node_modules/hpq/es/index.js
7124  /**
7125   * Internal dependencies
7126   */
7127  
7128  /**
7129   * Function returning a DOM document created by `createHTMLDocument`. The same
7130   * document is returned between invocations.
7131   *
7132   * @return {Document} DOM document.
7133   */
7134  
7135  var getDocument = function () {
7136    var doc;
7137    return function () {
7138      if (!doc) {
7139        doc = document.implementation.createHTMLDocument('');
7140      }
7141  
7142      return doc;
7143    };
7144  }();
7145  /**
7146   * Given a markup string or DOM element, creates an object aligning with the
7147   * shape of the matchers object, or the value returned by the matcher.
7148   *
7149   * @param  {(string|Element)}  source   Source content
7150   * @param  {(Object|Function)} matchers Matcher function or object of matchers
7151   * @return {(Object|*)}                 Matched value(s), shaped by object
7152   */
7153  
7154  
7155  function es_parse(source, matchers) {
7156    if (!matchers) {
7157      return;
7158    } // Coerce to element
7159  
7160  
7161    if ('string' === typeof source) {
7162      var doc = getDocument();
7163      doc.body.innerHTML = source;
7164      source = doc.body;
7165    } // Return singular value
7166  
7167  
7168    if ('function' === typeof matchers) {
7169      return matchers(source);
7170    } // Bail if we can't handle matchers
7171  
7172  
7173    if (Object !== matchers.constructor) {
7174      return;
7175    } // Shape result by matcher object
7176  
7177  
7178    return Object.keys(matchers).reduce(function (memo, key) {
7179      memo[key] = es_parse(source, matchers[key]);
7180      return memo;
7181    }, {});
7182  }
7183  /**
7184   * Generates a function which matches node of type selector, returning an
7185   * attribute by property if the attribute exists. If no selector is passed,
7186   * returns property of the query element.
7187   *
7188   * @param  {?string} selector Optional selector
7189   * @param  {string}  name     Property name
7190   * @return {*}                Property value
7191   */
7192  
7193  function prop(selector, name) {
7194    if (1 === arguments.length) {
7195      name = selector;
7196      selector = undefined;
7197    }
7198  
7199    return function (node) {
7200      var match = node;
7201  
7202      if (selector) {
7203        match = node.querySelector(selector);
7204      }
7205  
7206      if (match) {
7207        return getPath(match, name);
7208      }
7209    };
7210  }
7211  /**
7212   * Generates a function which matches node of type selector, returning an
7213   * attribute by name if the attribute exists. If no selector is passed,
7214   * returns attribute of the query element.
7215   *
7216   * @param  {?string} selector Optional selector
7217   * @param  {string}  name     Attribute name
7218   * @return {?string}          Attribute value
7219   */
7220  
7221  function attr(selector, name) {
7222    if (1 === arguments.length) {
7223      name = selector;
7224      selector = undefined;
7225    }
7226  
7227    return function (node) {
7228      var attributes = prop(selector, 'attributes')(node);
7229  
7230      if (attributes && attributes.hasOwnProperty(name)) {
7231        return attributes[name].value;
7232      }
7233    };
7234  }
7235  /**
7236   * Convenience for `prop( selector, 'innerHTML' )`.
7237   *
7238   * @see prop()
7239   *
7240   * @param  {?string} selector Optional selector
7241   * @return {string}           Inner HTML
7242   */
7243  
7244  function es_html(selector) {
7245    return prop(selector, 'innerHTML');
7246  }
7247  /**
7248   * Convenience for `prop( selector, 'textContent' )`.
7249   *
7250   * @see prop()
7251   *
7252   * @param  {?string} selector Optional selector
7253   * @return {string}           Text content
7254   */
7255  
7256  function es_text(selector) {
7257    return prop(selector, 'textContent');
7258  }
7259  /**
7260   * Creates a new matching context by first finding elements matching selector
7261   * using querySelectorAll before then running another `parse` on `matchers`
7262   * scoped to the matched elements.
7263   *
7264   * @see parse()
7265   *
7266   * @param  {string}            selector Selector to match
7267   * @param  {(Object|Function)} matchers Matcher function or object of matchers
7268   * @return {Array.<*,Object>}           Array of matched value(s)
7269   */
7270  
7271  function query(selector, matchers) {
7272    return function (node) {
7273      var matches = node.querySelectorAll(selector);
7274      return [].map.call(matches, function (match) {
7275        return es_parse(match, matchers);
7276      });
7277    };
7278  }
7279  // EXTERNAL MODULE: external {"this":["wp","autop"]}
7280  var external_this_wp_autop_ = __webpack_require__(69);
7281  
7282  // EXTERNAL MODULE: external {"this":["wp","blockSerializationDefaultParser"]}
7283  var external_this_wp_blockSerializationDefaultParser_ = __webpack_require__(222);
7284  
7285  // EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/arrayWithHoles.js
7286  var arrayWithHoles = __webpack_require__(38);
7287  
7288  // EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/iterableToArray.js
7289  var iterableToArray = __webpack_require__(30);
7290  
7291  // EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/nonIterableRest.js
7292  var nonIterableRest = __webpack_require__(39);
7293  
7294  // CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/toArray.js
7295  
7296  
7297  
7298  function _toArray(arr) {
7299    return Object(arrayWithHoles["a" /* default */])(arr) || Object(iterableToArray["a" /* default */])(arr) || Object(nonIterableRest["a" /* default */])();
7300  }
7301  // EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/classCallCheck.js
7302  var classCallCheck = __webpack_require__(12);
7303  
7304  // EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/createClass.js
7305  var createClass = __webpack_require__(11);
7306  
7307  // CONCATENATED MODULE: ./node_modules/simple-html-tokenizer/dist/es6/index.js
7308  /**
7309   * generated from https://raw.githubusercontent.com/w3c/html/26b5126f96f736f796b9e29718138919dd513744/entities.json
7310   * do not edit
7311   */
7312  var namedCharRefs = {
7313      Aacute: "Á", aacute: "á", Abreve: "Ă", abreve: "ă", ac: "∾", acd: "∿", acE: "∾̳", Acirc: "Â", acirc: "â", acute: "´", Acy: "А", acy: "а", AElig: "Æ", aelig: "æ", af: "\u2061", Afr: "𝔄", afr: "𝔞", Agrave: "À", agrave: "à", alefsym: "ℵ", aleph: "ℵ", Alpha: "Α", alpha: "α", Amacr: "Ā", amacr: "ā", amalg: "⨿", amp: "&", AMP: "&", andand: "⩕", And: "⩓", and: "∧", andd: "⩜", andslope: "⩘", andv: "⩚", ang: "∠", ange: "⦤", angle: "∠", angmsdaa: "⦨", angmsdab: "⦩", angmsdac: "⦪", angmsdad: "⦫", angmsdae: "⦬", angmsdaf: "⦭", angmsdag: "⦮", angmsdah: "⦯", angmsd: "∡", angrt: "∟", angrtvb: "⊾", angrtvbd: "⦝", angsph: "∢", angst: "Å", angzarr: "⍼", Aogon: "Ą", aogon: "ą", Aopf: "𝔸", aopf: "𝕒", apacir: "⩯", ap: "≈", apE: "⩰", ape: "≊", apid: "≋", apos: "'", ApplyFunction: "\u2061", approx: "≈", approxeq: "≊", Aring: "Å", aring: "å", Ascr: "𝒜", ascr: "𝒶", Assign: "≔", ast: "*", asymp: "≈", asympeq: "≍", Atilde: "Ã", atilde: "ã", Auml: "Ä", auml: "ä", awconint: "∳", awint: "⨑", backcong: "≌", backepsilon: "϶", backprime: "‵", backsim: "∽", backsimeq: "⋍", Backslash: "∖", Barv: "⫧", barvee: "⊽", barwed: "⌅", Barwed: "⌆", barwedge: "⌅", bbrk: "⎵", bbrktbrk: "⎶", bcong: "≌", Bcy: "Б", bcy: "б", bdquo: "„", becaus: "∵", because: "∵", Because: "∵", bemptyv: "⦰", bepsi: "϶", bernou: "ℬ", Bernoullis: "ℬ", Beta: "Β", beta: "β", beth: "ℶ", between: "≬", Bfr: "𝔅", bfr: "𝔟", bigcap: "⋂", bigcirc: "◯", bigcup: "⋃", bigodot: "⨀", bigoplus: "⨁", bigotimes: "⨂", bigsqcup: "⨆", bigstar: "★", bigtriangledown: "▽", bigtriangleup: "△", biguplus: "⨄", bigvee: "⋁", bigwedge: "⋀", bkarow: "⤍", blacklozenge: "⧫", blacksquare: "▪", blacktriangle: "▴", blacktriangledown: "▾", blacktriangleleft: "◂", blacktriangleright: "▸", blank: "␣", blk12: "▒", blk14: "░", blk34: "▓", block: "█", bne: "=⃥", bnequiv: "≡⃥", bNot: "⫭", bnot: "⌐", Bopf: "𝔹", bopf: "𝕓", bot: "⊥", bottom: "⊥", bowtie: "⋈", boxbox: "⧉", boxdl: "┐", boxdL: "╕", boxDl: "╖", boxDL: "╗", boxdr: "┌", boxdR: "╒", boxDr: "╓", boxDR: "╔", boxh: "─", boxH: "═", boxhd: "┬", boxHd: "╤", boxhD: "╥", boxHD: "╦", boxhu: "┴", boxHu: "╧", boxhU: "╨", boxHU: "╩", boxminus: "⊟", boxplus: "⊞", boxtimes: "⊠", boxul: "┘", boxuL: "╛", boxUl: "╜", boxUL: "╝", boxur: "└", boxuR: "╘", boxUr: "╙", boxUR: "╚", boxv: "│", boxV: "║", boxvh: "┼", boxvH: "╪", boxVh: "╫", boxVH: "╬", boxvl: "┤", boxvL: "╡", boxVl: "╢", boxVL: "╣", boxvr: "├", boxvR: "╞", boxVr: "╟", boxVR: "╠", bprime: "‵", breve: "˘", Breve: "˘", brvbar: "¦", bscr: "𝒷", Bscr: "ℬ", bsemi: "⁏", bsim: "∽", bsime: "⋍", bsolb: "⧅", bsol: "\\", bsolhsub: "⟈", bull: "•", bullet: "•", bump: "≎", bumpE: "⪮", bumpe: "≏", Bumpeq: "≎", bumpeq: "≏", Cacute: "Ć", cacute: "ć", capand: "⩄", capbrcup: "⩉", capcap: "⩋", cap: "∩", Cap: "⋒", capcup: "⩇", capdot: "⩀", CapitalDifferentialD: "ⅅ", caps: "∩︀", caret: "⁁", caron: "ˇ", Cayleys: "ℭ", ccaps: "⩍", Ccaron: "Č", ccaron: "č", Ccedil: "Ç", ccedil: "ç", Ccirc: "Ĉ", ccirc: "ĉ", Cconint: "∰", ccups: "⩌", ccupssm: "⩐", Cdot: "Ċ", cdot: "ċ", cedil: "¸", Cedilla: "¸", cemptyv: "⦲", cent: "¢", centerdot: "·", CenterDot: "·", cfr: "𝔠", Cfr: "ℭ", CHcy: "Ч", chcy: "ч", check: "✓", checkmark: "✓", Chi: "Χ", chi: "χ", circ: "ˆ", circeq: "≗", circlearrowleft: "↺", circlearrowright: "↻", circledast: "⊛", circledcirc: "⊚", circleddash: "⊝", CircleDot: "⊙", circledR: "®", circledS: "Ⓢ", CircleMinus: "⊖", CirclePlus: "⊕", CircleTimes: "⊗", cir: "○", cirE: "⧃", cire: "≗", cirfnint: "⨐", cirmid: "⫯", cirscir: "⧂", ClockwiseContourIntegral: "∲", CloseCurlyDoubleQuote: "”", CloseCurlyQuote: "’", clubs: "♣", clubsuit: "♣", colon: ":", Colon: "∷", Colone: "⩴", colone: "≔", coloneq: "≔", comma: ",", commat: "@", comp: "∁", compfn: "∘", complement: "∁", complexes: "ℂ", cong: "≅", congdot: "⩭", Congruent: "≡", conint: "∮", Conint: "∯", ContourIntegral: "∮", copf: "𝕔", Copf: "ℂ", coprod: "∐", Coproduct: "∐", copy: "©", COPY: "©", copysr: "℗", CounterClockwiseContourIntegral: "∳", crarr: "↵", cross: "✗", Cross: "⨯", Cscr: "𝒞", cscr: "𝒸", csub: "⫏", csube: "⫑", csup: "⫐", csupe: "⫒", ctdot: "⋯", cudarrl: "⤸", cudarrr: "⤵", cuepr: "⋞", cuesc: "⋟", cularr: "↶", cularrp: "⤽", cupbrcap: "⩈", cupcap: "⩆", CupCap: "≍", cup: "∪", Cup: "⋓", cupcup: "⩊", cupdot: "⊍", cupor: "⩅", cups: "∪︀", curarr: "↷", curarrm: "⤼", curlyeqprec: "⋞", curlyeqsucc: "⋟", curlyvee: "⋎", curlywedge: "⋏", curren: "¤", curvearrowleft: "↶", curvearrowright: "↷", cuvee: "⋎", cuwed: "⋏", cwconint: "∲", cwint: "∱", cylcty: "⌭", dagger: "†", Dagger: "‡", daleth: "ℸ", darr: "↓", Darr: "↡", dArr: "⇓", dash: "‐", Dashv: "⫤", dashv: "⊣", dbkarow: "⤏", dblac: "˝", Dcaron: "Ď", dcaron: "ď", Dcy: "Д", dcy: "д", ddagger: "‡", ddarr: "⇊", DD: "ⅅ", dd: "ⅆ", DDotrahd: "⤑", ddotseq: "⩷", deg: "°", Del: "∇", Delta: "Δ", delta: "δ", demptyv: "⦱", dfisht: "⥿", Dfr: "𝔇", dfr: "𝔡", dHar: "⥥", dharl: "⇃", dharr: "⇂", DiacriticalAcute: "´", DiacriticalDot: "˙", DiacriticalDoubleAcute: "˝", DiacriticalGrave: "`", DiacriticalTilde: "˜", diam: "⋄", diamond: "⋄", Diamond: "⋄", diamondsuit: "♦", diams: "♦", die: "¨", DifferentialD: "ⅆ", digamma: "ϝ", disin: "⋲", div: "÷", divide: "÷", divideontimes: "⋇", divonx: "⋇", DJcy: "Ђ", djcy: "ђ", dlcorn: "⌞", dlcrop: "⌍", dollar: "$", Dopf: "𝔻", dopf: "𝕕", Dot: "¨", dot: "˙", DotDot: "⃜", doteq: "≐", doteqdot: "≑", DotEqual: "≐", dotminus: "∸", dotplus: "∔", dotsquare: "⊡", doublebarwedge: "⌆", DoubleContourIntegral: "∯", DoubleDot: "¨", DoubleDownArrow: "⇓", DoubleLeftArrow: "⇐", DoubleLeftRightArrow: "⇔", DoubleLeftTee: "⫤", DoubleLongLeftArrow: "⟸", DoubleLongLeftRightArrow: "⟺", DoubleLongRightArrow: "⟹", DoubleRightArrow: "⇒", DoubleRightTee: "⊨", DoubleUpArrow: "⇑", DoubleUpDownArrow: "⇕", DoubleVerticalBar: "∥", DownArrowBar: "⤓", downarrow: "↓", DownArrow: "↓", Downarrow: "⇓", DownArrowUpArrow: "⇵", DownBreve: "̑", downdownarrows: "⇊", downharpoonleft: "⇃", downharpoonright: "⇂", DownLeftRightVector: "⥐", DownLeftTeeVector: "⥞", DownLeftVectorBar: "⥖", DownLeftVector: "↽", DownRightTeeVector: "⥟", DownRightVectorBar: "⥗", DownRightVector: "⇁", DownTeeArrow: "↧", DownTee: "⊤", drbkarow: "⤐", drcorn: "⌟", drcrop: "⌌", Dscr: "𝒟", dscr: "𝒹", DScy: "Ѕ", dscy: "ѕ", dsol: "⧶", Dstrok: "Đ", dstrok: "đ", dtdot: "⋱", dtri: "▿", dtrif: "▾", duarr: "⇵", duhar: "⥯", dwangle: "⦦", DZcy: "Џ", dzcy: "џ", dzigrarr: "⟿", Eacute: "É", eacute: "é", easter: "⩮", Ecaron: "Ě", ecaron: "ě", Ecirc: "Ê", ecirc: "ê", ecir: "≖", ecolon: "≕", Ecy: "Э", ecy: "э", eDDot: "⩷", Edot: "Ė", edot: "ė", eDot: "≑", ee: "ⅇ", efDot: "≒", Efr: "𝔈", efr: "𝔢", eg: "⪚", Egrave: "È", egrave: "è", egs: "⪖", egsdot: "⪘", el: "⪙", Element: "∈", elinters: "⏧", ell: "ℓ", els: "⪕", elsdot: "⪗", Emacr: "Ē", emacr: "ē", empty: "∅", emptyset: "∅", EmptySmallSquare: "◻", emptyv: "∅", EmptyVerySmallSquare: "▫", emsp13: " ", emsp14: " ", emsp: " ", ENG: "Ŋ", eng: "ŋ", ensp: " ", Eogon: "Ę", eogon: "ę", Eopf: "𝔼", eopf: "𝕖", epar: "⋕", eparsl: "⧣", eplus: "⩱", epsi: "ε", Epsilon: "Ε", epsilon: "ε", epsiv: "ϵ", eqcirc: "≖", eqcolon: "≕", eqsim: "≂", eqslantgtr: "⪖", eqslantless: "⪕", Equal: "⩵", equals: "=", EqualTilde: "≂", equest: "≟", Equilibrium: "⇌", equiv: "≡", equivDD: "⩸", eqvparsl: "⧥", erarr: "⥱", erDot: "≓", escr: "ℯ", Escr: "ℰ", esdot: "≐", Esim: "⩳", esim: "≂", Eta: "Η", eta: "η", ETH: "Ð", eth: "ð", Euml: "Ë", euml: "ë", euro: "€", excl: "!", exist: "∃", Exists: "∃", expectation: "ℰ", exponentiale: "ⅇ", ExponentialE: "ⅇ", fallingdotseq: "≒", Fcy: "Ф", fcy: "ф", female: "♀", ffilig: "ffi", fflig: "ff", ffllig: "ffl", Ffr: "𝔉", ffr: "𝔣", filig: "fi", FilledSmallSquare: "◼", FilledVerySmallSquare: "▪", fjlig: "fj", flat: "♭", fllig: "fl", fltns: "▱", fnof: "ƒ", Fopf: "𝔽", fopf: "𝕗", forall: "∀", ForAll: "∀", fork: "⋔", forkv: "⫙", Fouriertrf: "ℱ", fpartint: "⨍", frac12: "½", frac13: "⅓", frac14: "¼", frac15: "⅕", frac16: "⅙", frac18: "⅛", frac23: "⅔", frac25: "⅖", frac34: "¾", frac35: "⅗", frac38: "⅜", frac45: "⅘", frac56: "⅚", frac58: "⅝", frac78: "⅞", frasl: "⁄", frown: "⌢", fscr: "𝒻", Fscr: "ℱ", gacute: "ǵ", Gamma: "Γ", gamma: "γ", Gammad: "Ϝ", gammad: "ϝ", gap: "⪆", Gbreve: "Ğ", gbreve: "ğ", Gcedil: "Ģ", Gcirc: "Ĝ", gcirc: "ĝ", Gcy: "Г", gcy: "г", Gdot: "Ġ", gdot: "ġ", ge: "≥", gE: "≧", gEl: "⪌", gel: "⋛", geq: "≥", geqq: "≧", geqslant: "⩾", gescc: "⪩", ges: "⩾", gesdot: "⪀", gesdoto: "⪂", gesdotol: "⪄", gesl: "⋛︀", gesles: "⪔", Gfr: "𝔊", gfr: "𝔤", gg: "≫", Gg: "⋙", ggg: "⋙", gimel: "ℷ", GJcy: "Ѓ", gjcy: "ѓ", gla: "⪥", gl: "≷", glE: "⪒", glj: "⪤", gnap: "⪊", gnapprox: "⪊", gne: "⪈", gnE: "≩", gneq: "⪈", gneqq: "≩", gnsim: "⋧", Gopf: "𝔾", gopf: "𝕘", grave: "`", GreaterEqual: "≥", GreaterEqualLess: "⋛", GreaterFullEqual: "≧", GreaterGreater: "⪢", GreaterLess: "≷", GreaterSlantEqual: "⩾", GreaterTilde: "≳", Gscr: "𝒢", gscr: "ℊ", gsim: "≳", gsime: "⪎", gsiml: "⪐", gtcc: "⪧", gtcir: "⩺", gt: ">", GT: ">", Gt: "≫", gtdot: "⋗", gtlPar: "⦕", gtquest: "⩼", gtrapprox: "⪆", gtrarr: "⥸", gtrdot: "⋗", gtreqless: "⋛", gtreqqless: "⪌", gtrless: "≷", gtrsim: "≳", gvertneqq: "≩︀", gvnE: "≩︀", Hacek: "ˇ", hairsp: " ", half: "½", hamilt: "ℋ", HARDcy: "Ъ", hardcy: "ъ", harrcir: "⥈", harr: "↔", hArr: "⇔", 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: "\u2063", Icirc: "Î", icirc: "î", Icy: "И", icy: "и", Idot: "İ", IEcy: "Е", iecy: "е", iexcl: "¡", iff: "⇔", ifr: "𝔦", Ifr: "ℑ", Igrave: "Ì", igrave: "ì", ii: "ⅈ", iiiint: "⨌", iiint: "∭", iinfin: "⧜", iiota: "℩", IJlig: "IJ", ijlig: "ij", Imacr: "Ī", imacr: "ī", image: "ℑ", ImaginaryI: "ⅈ", imagline: "ℐ", imagpart: "ℑ", imath: "ı", Im: "ℑ", imof: "⊷", imped: "Ƶ", Implies: "⇒", incare: "℅", in: "∈", infin: "∞", infintie: "⧝", inodot: "ı", intcal: "⊺", int: "∫", Int: "∬", integers: "ℤ", Integral: "∫", intercal: "⊺", Intersection: "⋂", intlarhk: "⨗", intprod: "⨼", InvisibleComma: "\u2063", InvisibleTimes: "\u2062", IOcy: "Ё", iocy: "ё", Iogon: "Į", iogon: "į", Iopf: "𝕀", iopf: "𝕚", Iota: "Ι", iota: "ι", iprod: "⨼", iquest: "¿", iscr: "𝒾", Iscr: "ℐ", isin: "∈", isindot: "⋵", isinE: "⋹", isins: "⋴", isinsv: "⋳", isinv: "∈", it: "\u2062", 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: "«", larrb: "⇤", larrbfs: "⤟", larr: "←", Larr: "↞", lArr: "⇐", larrfs: "⤝", larrhk: "↩", larrlp: "↫", larrpl: "⤹", larrsim: "⥳", larrtl: "↢", latail: "⤙", lAtail: "⤛", lat: "⪫", 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: "⟨", LeftArrowBar: "⇤", leftarrow: "←", LeftArrow: "←", Leftarrow: "⇐", LeftArrowRightArrow: "⇆", leftarrowtail: "↢", LeftCeiling: "⌈", LeftDoubleBracket: "⟦", LeftDownTeeVector: "⥡", LeftDownVectorBar: "⥙", LeftDownVector: "⇃", LeftFloor: "⌊", leftharpoondown: "↽", leftharpoonup: "↼", leftleftarrows: "⇇", leftrightarrow: "↔", LeftRightArrow: "↔", Leftrightarrow: "⇔", leftrightarrows: "⇆", leftrightharpoons: "⇋", leftrightsquigarrow: "↭", LeftRightVector: "⥎", LeftTeeArrow: "↤", LeftTee: "⊣", LeftTeeVector: "⥚", leftthreetimes: "⋋", LeftTriangleBar: "⧏", LeftTriangle: "⊲", LeftTriangleEqual: "⊴", LeftUpDownVector: "⥑", LeftUpTeeVector: "⥠", LeftUpVectorBar: "⥘", LeftUpVector: "↿", LeftVectorBar: "⥒", LeftVector: "↼", lEg: "⪋", leg: "⋚", leq: "≤", leqq: "≦", leqslant: "⩽", lescc: "⪨", les: "⩽", 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: "љ", llarr: "⇇", ll: "≪", Ll: "⋘", llcorner: "⌞", Lleftarrow: "⇚", llhard: "⥫", lltri: "◺", Lmidot: "Ŀ", lmidot: "ŀ", lmoustache: "⎰", lmoust: "⎰", 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: "\u200e", lrtri: "⊿", lsaquo: "‹", lscr: "𝓁", Lscr: "ℒ", lsh: "↰", Lsh: "↰", lsim: "≲", lsime: "⪍", lsimg: "⪏", lsqb: "[", lsquo: "‘", lsquor: "‚", Lstrok: "Ł", lstrok: "ł", ltcc: "⪦", ltcir: "⩹", lt: "<", LT: "<", Lt: "≪", 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: "µ", midast: "*", midcir: "⫰", mid: "∣", middot: "·", minusb: "⊟", minus: "−", 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: "≉", natural: "♮", naturals: "ℕ", natur: "♮", nbsp: " ", nbump: "≎̸", nbumpe: "≏̸", ncap: "⩃", Ncaron: "Ň", ncaron: "ň", Ncedil: "Ņ", ncedil: "ņ", ncong: "≇", ncongdot: "⩭̸", ncup: "⩂", Ncy: "Н", ncy: "н", ndash: "–", nearhk: "⤤", nearr: "↗", neArr: "⇗", nearrow: "↗", ne: "≠", nedot: "≐̸", NegativeMediumSpace: "​", NegativeThickSpace: "​", NegativeThinSpace: "​", NegativeVeryThinSpace: "​", nequiv: "≢", nesear: "⤨", nesim: "≂̸", NestedGreaterGreater: "≫", NestedLessLess: "≪", NewLine: "\u000a", 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: "\u2060", 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: "⋶", NotLeftTriangleBar: "⧏̸", NotLeftTriangle: "⋪", NotLeftTriangleEqual: "⋬", NotLess: "≮", NotLessEqual: "≰", NotLessGreater: "≸", NotLessLess: "≪̸", NotLessSlantEqual: "⩽̸", NotLessTilde: "≴", NotNestedGreaterGreater: "⪢̸", NotNestedLessLess: "⪡̸", notni: "∌", notniva: "∌", notnivb: "⋾", notnivc: "⋽", NotPrecedes: "⊀", NotPrecedesEqual: "⪯̸", NotPrecedesSlantEqual: "⋠", NotReverseElement: "∌", NotRightTriangleBar: "⧐̸", NotRightTriangle: "⋫", NotRightTriangleEqual: "⋭", NotSquareSubset: "⊏̸", NotSquareSubsetEqual: "⋢", NotSquareSuperset: "⊐̸", NotSquareSupersetEqual: "⋣", NotSubset: "⊂⃒", NotSubsetEqual: "⊈", NotSucceeds: "⊁", NotSucceedsEqual: "⪰̸", NotSucceedsSlantEqual: "⋡", NotSucceedsTilde: "≿̸", NotSuperset: "⊃⃒", NotSupersetEqual: "⊉", NotTilde: "≁", NotTildeEqual: "≄", NotTildeFullEqual: "≇", NotTildeTilde: "≉", NotVerticalBar: "∤", nparallel: "∦", npar: "∦", nparsl: "⫽⃥", npart: "∂̸", npolint: "⨔", npr: "⊀", nprcue: "⋠", nprec: "⊀", npreceq: "⪯̸", npre: "⪯̸", nrarrc: "⤳̸", nrarr: "↛", nrArr: "⇏", 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: "⊛", Ocirc: "Ô", ocirc: "ô", ocir: "⊚", 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: "⊕", orarr: "↻", Or: "⩔", or: "∨", ord: "⩝", order: "ℴ", orderof: "ℴ", ordf: "ª", ordm: "º", origof: "⊶", oror: "⩖", orslope: "⩗", orv: "⩛", oS: "Ⓢ", Oscr: "𝒪", oscr: "ℴ", Oslash: "Ø", oslash: "ø", osol: "⊘", Otilde: "Õ", otilde: "õ", otimesas: "⨶", Otimes: "⨷", otimes: "⊗", Ouml: "Ö", ouml: "ö", ovbar: "⌽", OverBar: "‾", OverBrace: "⏞", OverBracket: "⎴", OverParenthesis: "⏜", para: "¶", parallel: "∥", par: "∥", 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: "ℏ", plusacir: "⨣", plusb: "⊞", pluscir: "⨢", plus: "+", plusdo: "∔", plusdu: "⨥", pluse: "⩲", PlusMinus: "±", plusmn: "±", plussim: "⨦", plustwo: "⨧", pm: "±", Poincareplane: "ℌ", pointint: "⨕", popf: "𝕡", Popf: "ℙ", pound: "£", prap: "⪷", Pr: "⪻", pr: "≺", prcue: "≼", precapprox: "⪷", prec: "≺", preccurlyeq: "≼", Precedes: "≺", PrecedesEqual: "⪯", PrecedesSlantEqual: "≼", PrecedesTilde: "≾", preceq: "⪯", precnapprox: "⪹", precneqq: "⪵", precnsim: "⋨", pre: "⪯", prE: "⪳", precsim: "≾", prime: "′", Prime: "″", primes: "ℙ", prnap: "⪹", prnE: "⪵", prnsim: "⋨", prod: "∏", Product: "∏", profalar: "⌮", profline: "⌒", profsurf: "⌓", prop: "∝", Proportional: "∝", Proportion: "∷", 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: "»", rarrap: "⥵", rarrb: "⇥", rarrbfs: "⤠", rarrc: "⤳", rarr: "→", Rarr: "↠", rArr: "⇒", 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: "↳", real: "ℜ", realine: "ℛ", realpart: "ℜ", reals: "ℝ", Re: "ℜ", rect: "▭", reg: "®", REG: "®", ReverseElement: "∋", ReverseEquilibrium: "⇋", ReverseUpEquilibrium: "⥯", rfisht: "⥽", rfloor: "⌋", rfr: "𝔯", Rfr: "ℜ", rHar: "⥤", rhard: "⇁", rharu: "⇀", rharul: "⥬", Rho: "Ρ", rho: "ρ", rhov: "ϱ", RightAngleBracket: "⟩", RightArrowBar: "⇥", rightarrow: "→", RightArrow: "→", Rightarrow: "⇒", RightArrowLeftArrow: "⇄", rightarrowtail: "↣", RightCeiling: "⌉", RightDoubleBracket: "⟧", RightDownTeeVector: "⥝", RightDownVectorBar: "⥕", RightDownVector: "⇂", RightFloor: "⌋", rightharpoondown: "⇁", rightharpoonup: "⇀", rightleftarrows: "⇄", rightleftharpoons: "⇌", rightrightarrows: "⇉", rightsquigarrow: "↝", RightTeeArrow: "↦", RightTee: "⊢", RightTeeVector: "⥛", rightthreetimes: "⋌", RightTriangleBar: "⧐", RightTriangle: "⊳", RightTriangleEqual: "⊵", RightUpDownVector: "⥏", RightUpTeeVector: "⥜", RightUpVectorBar: "⥔", RightUpVector: "↾", RightVectorBar: "⥓", RightVector: "⇀", ring: "˚", risingdotseq: "≓", rlarr: "⇄", rlhar: "⇌", rlm: "\u200f", rmoustache: "⎱", rmoust: "⎱", 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: "‚", scap: "⪸", Scaron: "Š", scaron: "š", Sc: "⪼", sc: "≻", sccue: "≽", sce: "⪰", scE: "⪴", Scedil: "Ş", scedil: "ş", Scirc: "Ŝ", scirc: "ŝ", scnap: "⪺", scnE: "⪶", scnsim: "⋩", scpolint: "⨓", scsim: "≿", Scy: "С", scy: "с", sdotb: "⊡", sdot: "⋅", 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: "\u00ad", 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: "ь", solbar: "⌿", solb: "⧄", sol: "/", Sopf: "𝕊", sopf: "𝕤", spades: "♠", spadesuit: "♠", spar: "∥", sqcap: "⊓", sqcaps: "⊓︀", sqcup: "⊔", sqcups: "⊔︀", Sqrt: "√", sqsub: "⊏", sqsube: "⊑", sqsubset: "⊏", sqsubseteq: "⊑", sqsup: "⊐", sqsupe: "⊒", sqsupset: "⊐", sqsupseteq: "⊒", square: "□", Square: "□", SquareIntersection: "⊓", SquareSubset: "⊏", SquareSubsetEqual: "⊑", SquareSuperset: "⊐", SquareSupersetEqual: "⊒", SquareUnion: "⊔", squarf: "▪", squ: "□", 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: "⫓", succapprox: "⪸", succ: "≻", succcurlyeq: "≽", Succeeds: "≻", SucceedsEqual: "⪰", SucceedsSlantEqual: "≽", SucceedsTilde: "≿", succeq: "⪰", succnapprox: "⪺", succneqq: "⪶", succnsim: "⋩", succsim: "≿", SuchThat: "∋", sum: "∑", Sum: "∑", sung: "♪", sup1: "¹", sup2: "²", sup3: "³", sup: "⊃", Sup: "⋑", 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: "\u0009", target: "⌖", Tau: "Τ", tau: "τ", tbrk: "⎴", Tcaron: "Ť", tcaron: "ť", Tcedil: "Ţ", tcedil: "ţ", Tcy: "Т", tcy: "т", tdot: "⃛", telrec: "⌕", Tfr: "𝔗", tfr: "𝔱", there4: "∴", therefore: "∴", Therefore: "∴", Theta: "Θ", theta: "θ", thetasym: "ϑ", thetav: "ϑ", thickapprox: "≈", thicksim: "∼", ThickSpace: "  ", ThinSpace: " ", thinsp: " ", thkap: "≈", thksim: "∼", THORN: "Þ", thorn: "þ", tilde: "˜", Tilde: "∼", TildeEqual: "≃", TildeFullEqual: "≅", TildeTilde: "≈", timesbar: "⨱", timesb: "⊠", times: "×", timesd: "⨰", tint: "∭", toea: "⤨", topbot: "⌶", topcir: "⫱", top: "⊤", 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: "𝕦", UpArrowBar: "⤒", uparrow: "↑", UpArrow: "↑", Uparrow: "⇑", UpArrowDownArrow: "⇅", updownarrow: "↕", UpDownArrow: "↕", Updownarrow: "⇕", UpEquilibrium: "⥮", upharpoonleft: "↿", upharpoonright: "↾", uplus: "⊎", UpperLeftArrow: "↖", UpperRightArrow: "↗", upsi: "υ", Upsi: "ϒ", upsih: "ϒ", Upsilon: "Υ", upsilon: "υ", UpTeeArrow: "↥", UpTee: "⊥", 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: "⫦", veebar: "⊻", vee: "∨", Vee: "⋁", 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: "\u200d", zwnj: "\u200c"
7314  };
7315  
7316  var HEXCHARCODE = /^#[xX]([A-Fa-f0-9]+)$/;
7317  var CHARCODE = /^#([0-9]+)$/;
7318  var NAMED = /^([A-Za-z0-9]+)$/;
7319  var EntityParser = /** @class */ (function () {
7320      function EntityParser(named) {
7321          this.named = named;
7322      }
7323      EntityParser.prototype.parse = function (entity) {
7324          if (!entity) {
7325              return;
7326          }
7327          var matches = entity.match(HEXCHARCODE);
7328          if (matches) {
7329              return String.fromCharCode(parseInt(matches[1], 16));
7330          }
7331          matches = entity.match(CHARCODE);
7332          if (matches) {
7333              return String.fromCharCode(parseInt(matches[1], 10));
7334          }
7335          matches = entity.match(NAMED);
7336          if (matches) {
7337              return this.named[matches[1]];
7338          }
7339      };
7340      return EntityParser;
7341  }());
7342  
7343  var WSP = /[\t\n\f ]/;
7344  var ALPHA = /[A-Za-z]/;
7345  var CRLF = /\r\n?/g;
7346  function isSpace(char) {
7347      return WSP.test(char);
7348  }
7349  function isAlpha(char) {
7350      return ALPHA.test(char);
7351  }
7352  function preprocessInput(input) {
7353      return input.replace(CRLF, '\n');
7354  }
7355  
7356  var EventedTokenizer = /** @class */ (function () {
7357      function EventedTokenizer(delegate, entityParser) {
7358          this.delegate = delegate;
7359          this.entityParser = entityParser;
7360          this.state = "beforeData" /* beforeData */;
7361          this.line = -1;
7362          this.column = -1;
7363          this.input = '';
7364          this.index = -1;
7365          this.tagNameBuffer = '';
7366          this.states = {
7367              beforeData: function () {
7368                  var char = this.peek();
7369                  if (char === '<' && !this.isIgnoredEndTag()) {
7370                      this.transitionTo("tagOpen" /* tagOpen */);
7371                      this.markTagStart();
7372                      this.consume();
7373                  }
7374                  else {
7375                      if (char === '\n') {
7376                          var tag = this.tagNameBuffer.toLowerCase();
7377                          if (tag === 'pre' || tag === 'textarea') {
7378                              this.consume();
7379                          }
7380                      }
7381                      this.transitionTo("data" /* data */);
7382                      this.delegate.beginData();
7383                  }
7384              },
7385              data: function () {
7386                  var char = this.peek();
7387                  var tag = this.tagNameBuffer.toLowerCase();
7388                  if (char === '<' && !this.isIgnoredEndTag()) {
7389                      this.delegate.finishData();
7390                      this.transitionTo("tagOpen" /* tagOpen */);
7391                      this.markTagStart();
7392                      this.consume();
7393                  }
7394                  else if (char === '&' && tag !== 'script' && tag !== 'style') {
7395                      this.consume();
7396                      this.delegate.appendToData(this.consumeCharRef() || '&');
7397                  }
7398                  else {
7399                      this.consume();
7400                      this.delegate.appendToData(char);
7401                  }
7402              },
7403              tagOpen: function () {
7404                  var char = this.consume();
7405                  if (char === '!') {
7406                      this.transitionTo("markupDeclarationOpen" /* markupDeclarationOpen */);
7407                  }
7408                  else if (char === '/') {
7409                      this.transitionTo("endTagOpen" /* endTagOpen */);
7410                  }
7411                  else if (char === '@' || char === ':' || isAlpha(char)) {
7412                      this.transitionTo("tagName" /* tagName */);
7413                      this.tagNameBuffer = '';
7414                      this.delegate.beginStartTag();
7415                      this.appendToTagName(char);
7416                  }
7417              },
7418              markupDeclarationOpen: function () {
7419                  var char = this.consume();
7420                  if (char === '-' && this.peek() === '-') {
7421                      this.consume();
7422                      this.transitionTo("commentStart" /* commentStart */);
7423                      this.delegate.beginComment();
7424                  }
7425              },
7426              commentStart: function () {
7427                  var char = this.consume();
7428                  if (char === '-') {
7429                      this.transitionTo("commentStartDash" /* commentStartDash */);
7430                  }
7431                  else if (char === '>') {
7432                      this.delegate.finishComment();
7433                      this.transitionTo("beforeData" /* beforeData */);
7434                  }
7435                  else {
7436                      this.delegate.appendToCommentData(char);
7437                      this.transitionTo("comment" /* comment */);
7438                  }
7439              },
7440              commentStartDash: function () {
7441                  var char = this.consume();
7442                  if (char === '-') {
7443                      this.transitionTo("commentEnd" /* commentEnd */);
7444                  }
7445                  else if (char === '>') {
7446                      this.delegate.finishComment();
7447                      this.transitionTo("beforeData" /* beforeData */);
7448                  }
7449                  else {
7450                      this.delegate.appendToCommentData('-');
7451                      this.transitionTo("comment" /* comment */);
7452                  }
7453              },
7454              comment: function () {
7455                  var char = this.consume();
7456                  if (char === '-') {
7457                      this.transitionTo("commentEndDash" /* commentEndDash */);
7458                  }
7459                  else {
7460                      this.delegate.appendToCommentData(char);
7461                  }
7462              },
7463              commentEndDash: function () {
7464                  var char = this.consume();
7465                  if (char === '-') {
7466                      this.transitionTo("commentEnd" /* commentEnd */);
7467                  }
7468                  else {
7469                      this.delegate.appendToCommentData('-' + char);
7470                      this.transitionTo("comment" /* comment */);
7471                  }
7472              },
7473              commentEnd: function () {
7474                  var char = this.consume();
7475                  if (char === '>') {
7476                      this.delegate.finishComment();
7477                      this.transitionTo("beforeData" /* beforeData */);
7478                  }
7479                  else {
7480                      this.delegate.appendToCommentData('--' + char);
7481                      this.transitionTo("comment" /* comment */);
7482                  }
7483              },
7484              tagName: function () {
7485                  var char = this.consume();
7486                  if (isSpace(char)) {
7487                      this.transitionTo("beforeAttributeName" /* beforeAttributeName */);
7488                  }
7489                  else if (char === '/') {
7490                      this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */);
7491                  }
7492                  else if (char === '>') {
7493                      this.delegate.finishTag();
7494                      this.transitionTo("beforeData" /* beforeData */);
7495                  }
7496                  else {
7497                      this.appendToTagName(char);
7498                  }
7499              },
7500              endTagName: function () {
7501                  var char = this.consume();
7502                  if (isSpace(char)) {
7503                      this.transitionTo("beforeAttributeName" /* beforeAttributeName */);
7504                      this.tagNameBuffer = '';
7505                  }
7506                  else if (char === '/') {
7507                      this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */);
7508                      this.tagNameBuffer = '';
7509                  }
7510                  else if (char === '>') {
7511                      this.delegate.finishTag();
7512                      this.transitionTo("beforeData" /* beforeData */);
7513                      this.tagNameBuffer = '';
7514                  }
7515                  else {
7516                      this.appendToTagName(char);
7517                  }
7518              },
7519              beforeAttributeName: function () {
7520                  var char = this.peek();
7521                  if (isSpace(char)) {
7522                      this.consume();
7523                      return;
7524                  }
7525                  else if (char === '/') {
7526                      this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */);
7527                      this.consume();
7528                  }
7529                  else if (char === '>') {
7530                      this.consume();
7531                      this.delegate.finishTag();
7532                      this.transitionTo("beforeData" /* beforeData */);
7533                  }
7534                  else if (char === '=') {
7535                      this.delegate.reportSyntaxError('attribute name cannot start with equals sign');
7536                      this.transitionTo("attributeName" /* attributeName */);
7537                      this.delegate.beginAttribute();
7538                      this.consume();
7539                      this.delegate.appendToAttributeName(char);
7540                  }
7541                  else {
7542                      this.transitionTo("attributeName" /* attributeName */);
7543                      this.delegate.beginAttribute();
7544                  }
7545              },
7546              attributeName: function () {
7547                  var char = this.peek();
7548                  if (isSpace(char)) {
7549                      this.transitionTo("afterAttributeName" /* afterAttributeName */);
7550                      this.consume();
7551                  }
7552                  else if (char === '/') {
7553                      this.delegate.beginAttributeValue(false);
7554                      this.delegate.finishAttributeValue();
7555                      this.consume();
7556                      this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */);
7557                  }
7558                  else if (char === '=') {
7559                      this.transitionTo("beforeAttributeValue" /* beforeAttributeValue */);
7560                      this.consume();
7561                  }
7562                  else if (char === '>') {
7563                      this.delegate.beginAttributeValue(false);
7564                      this.delegate.finishAttributeValue();
7565                      this.consume();
7566                      this.delegate.finishTag();
7567                      this.transitionTo("beforeData" /* beforeData */);
7568                  }
7569                  else if (char === '"' || char === "'" || char === '<') {
7570                      this.delegate.reportSyntaxError(char + ' is not a valid character within attribute names');
7571                      this.consume();
7572                      this.delegate.appendToAttributeName(char);
7573                  }
7574                  else {
7575                      this.consume();
7576                      this.delegate.appendToAttributeName(char);
7577                  }
7578              },
7579              afterAttributeName: function () {
7580                  var char = this.peek();
7581                  if (isSpace(char)) {
7582                      this.consume();
7583                      return;
7584                  }
7585                  else if (char === '/') {
7586                      this.delegate.beginAttributeValue(false);
7587                      this.delegate.finishAttributeValue();
7588                      this.consume();
7589                      this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */);
7590                  }
7591                  else if (char === '=') {
7592                      this.consume();
7593                      this.transitionTo("beforeAttributeValue" /* beforeAttributeValue */);
7594                  }
7595                  else if (char === '>') {
7596                      this.delegate.beginAttributeValue(false);
7597                      this.delegate.finishAttributeValue();
7598                      this.consume();
7599                      this.delegate.finishTag();
7600                      this.transitionTo("beforeData" /* beforeData */);
7601                  }
7602                  else {
7603                      this.delegate.beginAttributeValue(false);
7604                      this.delegate.finishAttributeValue();
7605                      this.transitionTo("attributeName" /* attributeName */);
7606                      this.delegate.beginAttribute();
7607                      this.consume();
7608                      this.delegate.appendToAttributeName(char);
7609                  }
7610              },
7611              beforeAttributeValue: function () {
7612                  var char = this.peek();
7613                  if (isSpace(char)) {
7614                      this.consume();
7615                  }
7616                  else if (char === '"') {
7617                      this.transitionTo("attributeValueDoubleQuoted" /* attributeValueDoubleQuoted */);
7618                      this.delegate.beginAttributeValue(true);
7619                      this.consume();
7620                  }
7621                  else if (char === "'") {
7622                      this.transitionTo("attributeValueSingleQuoted" /* attributeValueSingleQuoted */);
7623                      this.delegate.beginAttributeValue(true);
7624                      this.consume();
7625                  }
7626                  else if (char === '>') {
7627                      this.delegate.beginAttributeValue(false);
7628                      this.delegate.finishAttributeValue();
7629                      this.consume();
7630                      this.delegate.finishTag();
7631                      this.transitionTo("beforeData" /* beforeData */);
7632                  }
7633                  else {
7634                      this.transitionTo("attributeValueUnquoted" /* attributeValueUnquoted */);
7635                      this.delegate.beginAttributeValue(false);
7636                      this.consume();
7637                      this.delegate.appendToAttributeValue(char);
7638                  }
7639              },
7640              attributeValueDoubleQuoted: function () {
7641                  var char = this.consume();
7642                  if (char === '"') {
7643                      this.delegate.finishAttributeValue();
7644                      this.transitionTo("afterAttributeValueQuoted" /* afterAttributeValueQuoted */);
7645                  }
7646                  else if (char === '&') {
7647                      this.delegate.appendToAttributeValue(this.consumeCharRef() || '&');
7648                  }
7649                  else {
7650                      this.delegate.appendToAttributeValue(char);
7651                  }
7652              },
7653              attributeValueSingleQuoted: function () {
7654                  var char = this.consume();
7655                  if (char === "'") {
7656                      this.delegate.finishAttributeValue();
7657                      this.transitionTo("afterAttributeValueQuoted" /* afterAttributeValueQuoted */);
7658                  }
7659                  else if (char === '&') {
7660                      this.delegate.appendToAttributeValue(this.consumeCharRef() || '&');
7661                  }
7662                  else {
7663                      this.delegate.appendToAttributeValue(char);
7664                  }
7665              },
7666              attributeValueUnquoted: function () {
7667                  var char = this.peek();
7668                  if (isSpace(char)) {
7669                      this.delegate.finishAttributeValue();
7670                      this.consume();
7671                      this.transitionTo("beforeAttributeName" /* beforeAttributeName */);
7672                  }
7673                  else if (char === '/') {
7674                      this.delegate.finishAttributeValue();
7675                      this.consume();
7676                      this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */);
7677                  }
7678                  else if (char === '&') {
7679                      this.consume();
7680                      this.delegate.appendToAttributeValue(this.consumeCharRef() || '&');
7681                  }
7682                  else if (char === '>') {
7683                      this.delegate.finishAttributeValue();
7684                      this.consume();
7685                      this.delegate.finishTag();
7686                      this.transitionTo("beforeData" /* beforeData */);
7687                  }
7688                  else {
7689                      this.consume();
7690                      this.delegate.appendToAttributeValue(char);
7691                  }
7692              },
7693              afterAttributeValueQuoted: function () {
7694                  var char = this.peek();
7695                  if (isSpace(char)) {
7696                      this.consume();
7697                      this.transitionTo("beforeAttributeName" /* beforeAttributeName */);
7698                  }
7699                  else if (char === '/') {
7700                      this.consume();
7701                      this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */);
7702                  }
7703                  else if (char === '>') {
7704                      this.consume();
7705                      this.delegate.finishTag();
7706                      this.transitionTo("beforeData" /* beforeData */);
7707                  }
7708                  else {
7709                      this.transitionTo("beforeAttributeName" /* beforeAttributeName */);
7710                  }
7711              },
7712              selfClosingStartTag: function () {
7713                  var char = this.peek();
7714                  if (char === '>') {
7715                      this.consume();
7716                      this.delegate.markTagAsSelfClosing();
7717                      this.delegate.finishTag();
7718                      this.transitionTo("beforeData" /* beforeData */);
7719                  }
7720                  else {
7721                      this.transitionTo("beforeAttributeName" /* beforeAttributeName */);
7722                  }
7723              },
7724              endTagOpen: function () {
7725                  var char = this.consume();
7726                  if (char === '@' || char === ':' || isAlpha(char)) {
7727                      this.transitionTo("endTagName" /* endTagName */);
7728                      this.tagNameBuffer = '';
7729                      this.delegate.beginEndTag();
7730                      this.appendToTagName(char);
7731                  }
7732              }
7733          };
7734          this.reset();
7735      }
7736      EventedTokenizer.prototype.reset = function () {
7737          this.transitionTo("beforeData" /* beforeData */);
7738          this.input = '';
7739          this.tagNameBuffer = '';
7740          this.index = 0;
7741          this.line = 1;
7742          this.column = 0;
7743          this.delegate.reset();
7744      };
7745      EventedTokenizer.prototype.transitionTo = function (state) {
7746          this.state = state;
7747      };
7748      EventedTokenizer.prototype.tokenize = function (input) {
7749          this.reset();
7750          this.tokenizePart(input);
7751          this.tokenizeEOF();
7752      };
7753      EventedTokenizer.prototype.tokenizePart = function (input) {
7754          this.input += preprocessInput(input);
7755          while (this.index < this.input.length) {
7756              var handler = this.states[this.state];
7757              if (handler !== undefined) {
7758                  handler.call(this);
7759              }
7760              else {
7761                  throw new Error("unhandled state " + this.state);
7762              }
7763          }
7764      };
7765      EventedTokenizer.prototype.tokenizeEOF = function () {
7766          this.flushData();
7767      };
7768      EventedTokenizer.prototype.flushData = function () {
7769          if (this.state === 'data') {
7770              this.delegate.finishData();
7771              this.transitionTo("beforeData" /* beforeData */);
7772          }
7773      };
7774      EventedTokenizer.prototype.peek = function () {
7775          return this.input.charAt(this.index);
7776      };
7777      EventedTokenizer.prototype.consume = function () {
7778          var char = this.peek();
7779          this.index++;
7780          if (char === '\n') {
7781              this.line++;
7782              this.column = 0;
7783          }
7784          else {
7785              this.column++;
7786          }
7787          return char;
7788      };
7789      EventedTokenizer.prototype.consumeCharRef = function () {
7790          var endIndex = this.input.indexOf(';', this.index);
7791          if (endIndex === -1) {
7792              return;
7793          }
7794          var entity = this.input.slice(this.index, endIndex);
7795          var chars = this.entityParser.parse(entity);
7796          if (chars) {
7797              var count = entity.length;
7798              // consume the entity chars
7799              while (count) {
7800                  this.consume();
7801                  count--;
7802              }
7803              // consume the `;`
7804              this.consume();
7805              return chars;
7806          }
7807      };
7808      EventedTokenizer.prototype.markTagStart = function () {
7809          this.delegate.tagOpen();
7810      };
7811      EventedTokenizer.prototype.appendToTagName = function (char) {
7812          this.tagNameBuffer += char;
7813          this.delegate.appendToTagName(char);
7814      };
7815      EventedTokenizer.prototype.isIgnoredEndTag = function () {
7816          var tag = this.tagNameBuffer.toLowerCase();
7817          return (tag === 'title' && this.input.substring(this.index, this.index + 8) !== '</title>') ||
7818              (tag === 'style' && this.input.substring(this.index, this.index + 8) !== '</style>') ||
7819              (tag === 'script' && this.input.substring(this.index, this.index + 9) !== '</script>');
7820      };
7821      return EventedTokenizer;
7822  }());
7823  
7824  var Tokenizer = /** @class */ (function () {
7825      function Tokenizer(entityParser, options) {
7826          if (options === void 0) { options = {}; }
7827          this.options = options;
7828          this.token = null;
7829          this.startLine = 1;
7830          this.startColumn = 0;
7831          this.tokens = [];
7832          this.tokenizer = new EventedTokenizer(this, entityParser);
7833          this._currentAttribute = undefined;
7834      }
7835      Tokenizer.prototype.tokenize = function (input) {
7836          this.tokens = [];
7837          this.tokenizer.tokenize(input);
7838          return this.tokens;
7839      };
7840      Tokenizer.prototype.tokenizePart = function (input) {
7841          this.tokens = [];
7842          this.tokenizer.tokenizePart(input);
7843          return this.tokens;
7844      };
7845      Tokenizer.prototype.tokenizeEOF = function () {
7846          this.tokens = [];
7847          this.tokenizer.tokenizeEOF();
7848          return this.tokens[0];
7849      };
7850      Tokenizer.prototype.reset = function () {
7851          this.token = null;
7852          this.startLine = 1;
7853          this.startColumn = 0;
7854      };
7855      Tokenizer.prototype.current = function () {
7856          var token = this.token;
7857          if (token === null) {
7858              throw new Error('token was unexpectedly null');
7859          }
7860          if (arguments.length === 0) {
7861              return token;
7862          }
7863          for (var i = 0; i < arguments.length; i++) {
7864              if (token.type === arguments[i]) {
7865                  return token;
7866              }
7867          }
7868          throw new Error("token type was unexpectedly " + token.type);
7869      };
7870      Tokenizer.prototype.push = function (token) {
7871          this.token = token;
7872          this.tokens.push(token);
7873      };
7874      Tokenizer.prototype.currentAttribute = function () {
7875          return this._currentAttribute;
7876      };
7877      Tokenizer.prototype.addLocInfo = function () {
7878          if (this.options.loc) {
7879              this.current().loc = {
7880                  start: {
7881                      line: this.startLine,
7882                      column: this.startColumn
7883                  },
7884                  end: {
7885                      line: this.tokenizer.line,
7886                      column: this.tokenizer.column
7887                  }
7888              };
7889          }
7890          this.startLine = this.tokenizer.line;
7891          this.startColumn = this.tokenizer.column;
7892      };
7893      // Data
7894      Tokenizer.prototype.beginData = function () {
7895          this.push({
7896              type: "Chars" /* Chars */,
7897              chars: ''
7898          });
7899      };
7900      Tokenizer.prototype.appendToData = function (char) {
7901          this.current("Chars" /* Chars */).chars += char;
7902      };
7903      Tokenizer.prototype.finishData = function () {
7904          this.addLocInfo();
7905      };
7906      // Comment
7907      Tokenizer.prototype.beginComment = function () {
7908          this.push({
7909              type: "Comment" /* Comment */,
7910              chars: ''
7911          });
7912      };
7913      Tokenizer.prototype.appendToCommentData = function (char) {
7914          this.current("Comment" /* Comment */).chars += char;
7915      };
7916      Tokenizer.prototype.finishComment = function () {
7917          this.addLocInfo();
7918      };
7919      // Tags - basic
7920      Tokenizer.prototype.tagOpen = function () { };
7921      Tokenizer.prototype.beginStartTag = function () {
7922          this.push({
7923              type: "StartTag" /* StartTag */,
7924              tagName: '',
7925              attributes: [],
7926              selfClosing: false
7927          });
7928      };
7929      Tokenizer.prototype.beginEndTag = function () {
7930          this.push({
7931              type: "EndTag" /* EndTag */,
7932              tagName: ''
7933          });
7934      };
7935      Tokenizer.prototype.finishTag = function () {
7936          this.addLocInfo();
7937      };
7938      Tokenizer.prototype.markTagAsSelfClosing = function () {
7939          this.current("StartTag" /* StartTag */).selfClosing = true;
7940      };
7941      // Tags - name
7942      Tokenizer.prototype.appendToTagName = function (char) {
7943          this.current("StartTag" /* StartTag */, "EndTag" /* EndTag */).tagName += char;
7944      };
7945      // Tags - attributes
7946      Tokenizer.prototype.beginAttribute = function () {
7947          this._currentAttribute = ['', '', false];
7948      };
7949      Tokenizer.prototype.appendToAttributeName = function (char) {
7950          this.currentAttribute()[0] += char;
7951      };
7952      Tokenizer.prototype.beginAttributeValue = function (isQuoted) {
7953          this.currentAttribute()[2] = isQuoted;
7954      };
7955      Tokenizer.prototype.appendToAttributeValue = function (char) {
7956          this.currentAttribute()[1] += char;
7957      };
7958      Tokenizer.prototype.finishAttributeValue = function () {
7959          this.current("StartTag" /* StartTag */).attributes.push(this._currentAttribute);
7960      };
7961      Tokenizer.prototype.reportSyntaxError = function (message) {
7962          this.current().syntaxError = message;
7963      };
7964      return Tokenizer;
7965  }());
7966  
7967  function tokenize(input, options) {
7968      var tokenizer = new Tokenizer(new EntityParser(namedCharRefs), options);
7969      return tokenizer.tokenize(input);
7970  }
7971  
7972  
7973  
7974  // EXTERNAL MODULE: external {"this":["wp","htmlEntities"]}
7975  var external_this_wp_htmlEntities_ = __webpack_require__(52);
7976  
7977  // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/validation/logger.js
7978  function createLogger() {
7979    /**
7980     * Creates a log handler with block validation prefix.
7981     *
7982     * @param {Function} logger Original logger function.
7983     *
7984     * @return {Function} Augmented logger function.
7985     */
7986    function createLogHandler(logger) {
7987      var log = function log(message) {
7988        for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
7989          args[_key - 1] = arguments[_key];
7990        }
7991  
7992        return logger.apply(void 0, ['Block validation: ' + message].concat(args));
7993      }; // In test environments, pre-process the sprintf message to improve
7994      // readability of error messages. We'd prefer to avoid pulling in this
7995      // dependency in runtime environments, and it can be dropped by a combo
7996      // of Webpack env substitution + UglifyJS dead code elimination.
7997  
7998  
7999      if (false) {}
8000  
8001      return log;
8002    }
8003  
8004    return {
8005      // eslint-disable-next-line no-console
8006      error: createLogHandler(console.error),
8007      // eslint-disable-next-line no-console
8008      warning: createLogHandler(console.warn),
8009      getItems: function getItems() {
8010        return [];
8011      }
8012    };
8013  }
8014  function createQueuedLogger() {
8015    /**
8016     * The list of enqueued log actions to print.
8017     *
8018     * @type {Array}
8019     */
8020    var queue = [];
8021    var logger = createLogger();
8022    return {
8023      error: function error() {
8024        for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
8025          args[_key2] = arguments[_key2];
8026        }
8027  
8028        queue.push({
8029          log: logger.error,
8030          args: args
8031        });
8032      },
8033      warning: function warning() {
8034        for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
8035          args[_key3] = arguments[_key3];
8036        }
8037  
8038        queue.push({
8039          log: logger.warning,
8040          args: args
8041        });
8042      },
8043      getItems: function getItems() {
8044        return queue;
8045      }
8046    };
8047  }
8048  
8049  // EXTERNAL MODULE: external {"this":["wp","isShallowEqual"]}
8050  var external_this_wp_isShallowEqual_ = __webpack_require__(41);
8051  var external_this_wp_isShallowEqual_default = /*#__PURE__*/__webpack_require__.n(external_this_wp_isShallowEqual_);
8052  
8053  // EXTERNAL MODULE: ./node_modules/@babel/runtime/helpers/esm/extends.js
8054  var esm_extends = __webpack_require__(18);
8055  
8056  // EXTERNAL MODULE: external {"this":["wp","compose"]}
8057  var external_this_wp_compose_ = __webpack_require__(8);
8058  
8059  // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/block-content-provider/index.js
8060  
8061  
8062  
8063  /**
8064   * WordPress dependencies
8065   */
8066  
8067  
8068  /**
8069   * Internal dependencies
8070   */
8071  
8072  
8073  
8074  var _createContext = Object(external_this_wp_element_["createContext"])(function () {}),
8075      Consumer = _createContext.Consumer,
8076      Provider = _createContext.Provider;
8077  /**
8078   * An internal block component used in block content serialization to inject
8079   * nested block content within the `save` implementation of the ancestor
8080   * component in which it is nested. The component provides a pre-bound
8081   * `BlockContent` component via context, which is used by the developer-facing
8082   * `InnerBlocks.Content` component to render block content.
8083   *
8084   * @example
8085   *
8086   * ```jsx
8087   * <BlockContentProvider innerBlocks={ innerBlocks }>
8088   *     { blockSaveElement }
8089   * </BlockContentProvider>
8090   * ```
8091   *
8092   * @return {WPElement} Element with BlockContent injected via context.
8093   */
8094  
8095  
8096  var block_content_provider_BlockContentProvider = function BlockContentProvider(_ref) {
8097    var children = _ref.children,
8098        innerBlocks = _ref.innerBlocks;
8099  
8100    var BlockContent = function BlockContent() {
8101      // Value is an array of blocks, so defer to block serializer
8102      var html = serialize(innerBlocks, {
8103        isInnerBlocks: true
8104      }); // Use special-cased raw HTML tag to avoid default escaping
8105  
8106      return Object(external_this_wp_element_["createElement"])(external_this_wp_element_["RawHTML"], null, html);
8107    };
8108  
8109    return Object(external_this_wp_element_["createElement"])(Provider, {
8110      value: BlockContent
8111    }, children);
8112  };
8113  /**
8114   * A Higher Order Component used to inject BlockContent using context to the
8115   * wrapped component.
8116   *
8117   * @return {Component} Enhanced component with injected BlockContent as prop.
8118   */
8119  
8120  
8121  var withBlockContentContext = Object(external_this_wp_compose_["createHigherOrderComponent"])(function (OriginalComponent) {
8122    return function (props) {
8123      return Object(external_this_wp_element_["createElement"])(Consumer, null, function (context) {
8124        return Object(external_this_wp_element_["createElement"])(OriginalComponent, Object(esm_extends["a" /* default */])({}, props, {
8125          BlockContent: context
8126        }));
8127      });
8128    };
8129  }, 'withBlockContentContext');
8130  /* harmony default export */ var block_content_provider = (block_content_provider_BlockContentProvider);
8131  
8132  // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/serializer.js
8133  
8134  
8135  
8136  /**
8137   * External dependencies
8138   */
8139  
8140  /**
8141   * WordPress dependencies
8142   */
8143  
8144  
8145  
8146  
8147  /**
8148   * Internal dependencies
8149   */
8150  
8151  
8152  
8153  
8154  /**
8155   * @typedef {Object} WPBlockSerializationOptions Serialization Options.
8156   *
8157   * @property {boolean} isInnerBlocks Whether we are serializing inner blocks.
8158   */
8159  
8160  /**
8161   * Returns the block's default classname from its name.
8162   *
8163   * @param {string} blockName The block name.
8164   *
8165   * @return {string} The block's default class.
8166   */
8167  
8168  function getBlockDefaultClassName(blockName) {
8169    // Generated HTML classes for blocks follow the `wp-block-{name}` nomenclature.
8170    // Blocks provided by WordPress drop the prefixes 'core/' or 'core-' (used in 'core-embed/').
8171    var className = 'wp-block-' + blockName.replace(/\//, '-').replace(/^core-/, '');
8172    return Object(external_this_wp_hooks_["applyFilters"])('blocks.getBlockDefaultClassName', className, blockName);
8173  }
8174  /**
8175   * Returns the block's default menu item classname from its name.
8176   *
8177   * @param {string} blockName The block name.
8178   *
8179   * @return {string} The block's default menu item class.
8180   */
8181  
8182  function getBlockMenuDefaultClassName(blockName) {
8183    // Generated HTML classes for blocks follow the `editor-block-list-item-{name}` nomenclature.
8184    // Blocks provided by WordPress drop the prefixes 'core/' or 'core-' (used in 'core-embed/').
8185    var className = 'editor-block-list-item-' + blockName.replace(/\//, '-').replace(/^core-/, '');
8186    return Object(external_this_wp_hooks_["applyFilters"])('blocks.getBlockMenuDefaultClassName', className, blockName);
8187  }
8188  /**
8189   * Given a block type containing a save render implementation and attributes, returns the
8190   * enhanced element to be saved or string when raw HTML expected.
8191   *
8192   * @param {string|Object} blockTypeOrName   Block type or name.
8193   * @param {Object}        attributes        Block attributes.
8194   * @param {?Array}        innerBlocks       Nested blocks.
8195   *
8196   * @return {Object|string} Save element or raw HTML string.
8197   */
8198  
8199  function getSaveElement(blockTypeOrName, attributes) {
8200    var innerBlocks = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
8201    var blockType = normalizeBlockType(blockTypeOrName);
8202    var save = blockType.save; // Component classes are unsupported for save since serialization must
8203    // occur synchronously. For improved interoperability with higher-order
8204    // components which often return component class, emulate basic support.
8205  
8206    if (save.prototype instanceof external_this_wp_element_["Component"]) {
8207      var instance = new save({
8208        attributes: attributes
8209      });
8210      save = instance.render.bind(instance);
8211    }
8212  
8213    var element = save({
8214      attributes: attributes,
8215      innerBlocks: innerBlocks
8216    });
8217  
8218    if (Object(external_lodash_["isObject"])(element) && Object(external_this_wp_hooks_["hasFilter"])('blocks.getSaveContent.extraProps')) {
8219      /**
8220       * Filters the props applied to the block save result element.
8221       *
8222       * @param {Object}      props      Props applied to save element.
8223       * @param {WPBlockType} blockType  Block type definition.
8224       * @param {Object}      attributes Block attributes.
8225       */
8226      var props = Object(external_this_wp_hooks_["applyFilters"])('blocks.getSaveContent.extraProps', Object(objectSpread["a" /* default */])({}, element.props), blockType, attributes);
8227  
8228      if (!external_this_wp_isShallowEqual_default()(props, element.props)) {
8229        element = Object(external_this_wp_element_["cloneElement"])(element, props);
8230      }
8231    }
8232    /**
8233     * Filters the save result of a block during serialization.
8234     *
8235     * @param {WPElement}   element    Block save result.
8236     * @param {WPBlockType} blockType  Block type definition.
8237     * @param {Object}      attributes Block attributes.
8238     */
8239  
8240  
8241    element = Object(external_this_wp_hooks_["applyFilters"])('blocks.getSaveElement', element, blockType, attributes);
8242    return Object(external_this_wp_element_["createElement"])(block_content_provider, {
8243      innerBlocks: innerBlocks
8244    }, element);
8245  }
8246  /**
8247   * Given a block type containing a save render implementation and attributes, returns the
8248   * static markup to be saved.
8249   *
8250   * @param {string|Object} blockTypeOrName Block type or name.
8251   * @param {Object}        attributes      Block attributes.
8252   * @param {?Array}        innerBlocks     Nested blocks.
8253   *
8254   * @return {string} Save content.
8255   */
8256  
8257  function getSaveContent(blockTypeOrName, attributes, innerBlocks) {
8258    var blockType = normalizeBlockType(blockTypeOrName);
8259    return Object(external_this_wp_element_["renderToString"])(getSaveElement(blockType, attributes, innerBlocks));
8260  }
8261  /**
8262   * Returns attributes which are to be saved and serialized into the block
8263   * comment delimiter.
8264   *
8265   * When a block exists in memory it contains as its attributes both those
8266   * parsed the block comment delimiter _and_ those which matched from the
8267   * contents of the block.
8268   *
8269   * This function returns only those attributes which are needed to persist and
8270   * which cannot be matched from the block content.
8271   *
8272   * @param {Object<string,*>} blockType     Block type.
8273   * @param {Object<string,*>} attributes Attributes from in-memory block data.
8274   *
8275   * @return {Object<string,*>} Subset of attributes for comment serialization.
8276   */
8277  
8278  function getCommentAttributes(blockType, attributes) {
8279    return Object(external_lodash_["reduce"])(blockType.attributes, function (result, attributeSchema, key) {
8280      var value = attributes[key]; // Ignore undefined values.
8281  
8282      if (undefined === value) {
8283        return result;
8284      } // Ignore all attributes but the ones with an "undefined" source
8285      // "undefined" source refers to attributes saved in the block comment.
8286  
8287  
8288      if (attributeSchema.source !== undefined) {
8289        return result;
8290      } // Ignore default value.
8291  
8292  
8293      if ('default' in attributeSchema && attributeSchema.default === value) {
8294        return result;
8295      } // Otherwise, include in comment set.
8296  
8297  
8298      result[key] = value;
8299      return result;
8300    }, {});
8301  }
8302  /**
8303   * Given an attributes object, returns a string in the serialized attributes
8304   * format prepared for post content.
8305   *
8306   * @param {Object} attributes Attributes object.
8307   *
8308   * @return {string} Serialized attributes.
8309   */
8310  
8311  function serializeAttributes(attributes) {
8312    return JSON.stringify(attributes) // Don't break HTML comments.
8313    .replace(/--/g, "\\u002d\\u002d") // Don't break non-standard-compliant tools.
8314    .replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/&/g, "\\u0026") // Bypass server stripslashes behavior which would unescape stringify's
8315    // escaping of quotation mark.
8316    //
8317    // See: https://developer.wordpress.org/reference/functions/wp_kses_stripslashes/
8318    .replace(/\\"/g, "\\u0022");
8319  }
8320  /**
8321   * Given a block object, returns the Block's Inner HTML markup.
8322   *
8323   * @param {Object} block Block instance.
8324   *
8325   * @return {string} HTML.
8326   */
8327  
8328  function getBlockContent(block) {
8329    // @todo why not getBlockInnerHtml?
8330    // If block was parsed as invalid or encounters an error while generating
8331    // save content, use original content instead to avoid content loss. If a
8332    // block contains nested content, exempt it from this condition because we
8333    // otherwise have no access to its original content and content loss would
8334    // still occur.
8335    var saveContent = block.originalContent;
8336  
8337    if (block.isValid || block.innerBlocks.length) {
8338      try {
8339        saveContent = getSaveContent(block.name, block.attributes, block.innerBlocks);
8340      } catch (error) {}
8341    }
8342  
8343    return saveContent;
8344  }
8345  /**
8346   * Returns the content of a block, including comment delimiters.
8347   *
8348   * @param {string} rawBlockName Block name.
8349   * @param {Object} attributes   Block attributes.
8350   * @param {string} content      Block save content.
8351   *
8352   * @return {string} Comment-delimited block content.
8353   */
8354  
8355  function getCommentDelimitedContent(rawBlockName, attributes, content) {
8356    var serializedAttributes = !Object(external_lodash_["isEmpty"])(attributes) ? serializeAttributes(attributes) + ' ' : ''; // Strip core blocks of their namespace prefix.
8357  
8358    var blockName = Object(external_lodash_["startsWith"])(rawBlockName, 'core/') ? rawBlockName.slice(5) : rawBlockName; // @todo make the `wp:` prefix potentially configurable.
8359  
8360    if (!content) {
8361      return "<!-- wp:".concat(blockName, " ").concat(serializedAttributes, "/-->");
8362    }
8363  
8364    return "<!-- wp:".concat(blockName, " ").concat(serializedAttributes, "-->\n") + content + "\n<!-- /wp:".concat(blockName, " -->");
8365  }
8366  /**
8367   * Returns the content of a block, including comment delimiters, determining
8368   * serialized attributes and content form from the current state of the block.
8369   *
8370   * @param {Object}                      block   Block instance.
8371   * @param {WPBlockSerializationOptions} options Serialization options.
8372   *
8373   * @return {string} Serialized block.
8374   */
8375  
8376  function serializeBlock(block) {
8377    var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
8378        _ref$isInnerBlocks = _ref.isInnerBlocks,
8379        isInnerBlocks = _ref$isInnerBlocks === void 0 ? false : _ref$isInnerBlocks;
8380  
8381    var blockName = block.name;
8382    var saveContent = getBlockContent(block);
8383  
8384    if (blockName === getUnregisteredTypeHandlerName() || !isInnerBlocks && blockName === getFreeformContentHandlerName()) {
8385      return saveContent;
8386    }
8387  
8388    var blockType = registration_getBlockType(blockName);
8389    var saveAttributes = getCommentAttributes(blockType, block.attributes);
8390    return getCommentDelimitedContent(blockName, saveAttributes, saveContent);
8391  }
8392  /**
8393   * Takes a block or set of blocks and returns the serialized post content.
8394   *
8395   * @param {Array}                       blocks  Block(s) to serialize.
8396   * @param {WPBlockSerializationOptions} options Serialization options.
8397   *
8398   * @return {string} The post content.
8399   */
8400  
8401  function serialize(blocks, options) {
8402    return Object(external_lodash_["castArray"])(blocks).map(function (block) {
8403      return serializeBlock(block, options);
8404    }).join('\n\n');
8405  }
8406  
8407  // CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/validation/index.js
8408  
8409  
8410  
8411  
8412  
8413  
8414  
8415  /**
8416   * External dependencies
8417   */
8418  
8419  
8420  /**
8421   * WordPress dependencies
8422   */
8423  
8424  
8425  /**
8426   * Internal dependencies
8427   */
8428  
8429  
8430  
8431  
8432  /**
8433   * Globally matches any consecutive whitespace
8434   *
8435   * @type {RegExp}
8436   */
8437  
8438  var REGEXP_WHITESPACE = /[\t\n\r\v\f ]+/g;
8439  /**
8440   * Matches a string containing only whitespace
8441   *
8442   * @type {RegExp}
8443   */
8444  
8445  var REGEXP_ONLY_WHITESPACE = /^[\t\n\r\v\f ]*$/;
8446  /**
8447   * Matches a CSS URL type value
8448   *
8449   * @type {RegExp}
8450   */
8451  
8452  var REGEXP_STYLE_URL_TYPE = /^url\s*\(['"\s]*(.*?)['"\s]*\)$/;
8453  /**
8454   * Boolean attributes are attributes whose presence as being assigned is
8455   * meaningful, even if only empty.
8456   *
8457   * See: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#boolean-attributes
8458   * Extracted from: https://html.spec.whatwg.org/multipage/indices.html#attributes-3
8459   *
8460   * Object.keys( [ ...document.querySelectorAll( '#attributes-1 > tbody > tr' ) ]
8461   *     .filter( ( tr ) => tr.lastChild.textContent.indexOf( 'Boolean attribute' ) !== -1 )
8462   *     .reduce( ( result, tr ) => Object.assign( result, {
8463   *         [ tr.firstChild.textContent.trim() ]: true
8464   *     } ), {} ) ).sort();
8465   *
8466   * @type {Array}
8467   */
8468  
8469  var BOOLEAN_ATTRIBUTES = ['allowfullscreen', 'allowpaymentrequest', 'allowusermedia', 'async', 'autofocus', 'autoplay', 'checked', 'controls', 'default', 'defer', 'disabled', 'download', 'formnovalidate', 'hidden', 'ismap', 'itemscope', 'loop', 'multiple', 'muted', 'nomodule', 'novalidate', 'open', 'playsinline', 'readonly', 'required', 'reversed', 'selected', 'typemustmatch'];
8470  /**
8471   * Enumerated attributes are attributes which must be of a specific value form.
8472   * Like boolean attributes, these are meaningful if specified, even if not of a
8473   * valid enumerated value.
8474   *
8475   * See: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#enumerated-attribute
8476   * Extracted from: https://html.spec.whatwg.org/multipage/indices.html#attributes-3
8477   *
8478   * Object.keys( [ ...document.querySelectorAll( '#attributes-1 > tbody > tr' ) ]
8479   *     .filter( ( tr ) => /^("(.+?)";?\s*)+/.test( tr.lastChild.textContent.trim() ) )
8480   *     .reduce( ( result, tr ) => Object.assign( result, {
8481   *         [ tr.firstChild.textContent.trim() ]: true
8482   *     } ), {} ) ).sort();
8483   *
8484   * @type {Array}
8485   */
8486  
8487  var ENUMERATED_ATTRIBUTES = ['autocapitalize', 'autocomplete', 'charset', 'contenteditable', 'crossorigin', 'decoding', 'dir', 'draggable', 'enctype', 'formenctype', 'formmethod', 'http-equiv', 'inputmode', 'kind', 'method', 'preload', 'scope', 'shape', 'spellcheck', 'translate', 'type', 'wrap'];
8488  /**
8489   * Meaningful attributes are those who cannot be safely ignored when omitted in
8490   * one HTML markup string and not another.
8491   *
8492   * @type {Array}
8493   */
8494  
8495  var MEANINGFUL_ATTRIBUTES = [].concat(BOOLEAN_ATTRIBUTES, ENUMERATED_ATTRIBUTES);
8496  /**
8497   * Array of functions which receive a text string on which to apply normalizing
8498   * behavior for consideration in text token equivalence, carefully ordered from
8499   * least-to-most expensive operations.
8500   *
8501   * @type {Array}
8502   */
8503  
8504  var TEXT_NORMALIZATIONS = [external_lodash_["identity"], getTextWithCollapsedWhitespace];
8505  /**
8506   * Regular expression matching a named character reference. In lieu of bundling
8507   * a full set of references, the pattern covers the minimal necessary to test
8508   * positively against the full set.
8509   *
8510   * "The ampersand must be followed by one of the names given in the named
8511   * character references section, using the same case."
8512   *
8513   * Tested aginst "12.5 Named character references":
8514   *
8515   * ```
8516   * const references = [ ...document.querySelectorAll(
8517   *     '#named-character-references-table tr[id^=entity-] td:first-child'
8518   * ) ].map( ( code ) => code.textContent )
8519   * references.every( ( reference ) => /^[\da-z]+$/i.test( reference ) )
8520   * ```
8521   *
8522   * @see https://html.spec.whatwg.org/multipage/syntax.html#character-references
8523   * @see https://html.spec.whatwg.org/multipage/named-characters.html#named-character-references
8524   *
8525   * @type {RegExp}
8526   */
8527  
8528  var REGEXP_NAMED_CHARACTER_REFERENCE = /^[\da-z]+$/i;
8529  /**
8530   * Regular expression matching a decimal character reference.
8531   *
8532   * "The ampersand must be followed by a U+0023 NUMBER SIGN character (#),
8533   * followed by one or more ASCII digits, representing a base-ten integer"
8534   *
8535   * @see https://html.spec.whatwg.org/multipage/syntax.html#character-references
8536   *
8537   * @type {RegExp}
8538   */
8539  
8540  var REGEXP_DECIMAL_CHARACTER_REFERENCE = /^#\d+$/;
8541  /**
8542   * Regular expression matching a hexadecimal character reference.
8543   *
8544   * "The ampersand must be followed by a U+0023 NUMBER SIGN character (#), which
8545   * must be followed by either a U+0078 LATIN SMALL LETTER X character (x) or a
8546   * U+0058 LATIN CAPITAL LETTER X character (X), which must then be followed by
8547   * one or more ASCII hex digits, representing a hexadecimal integer"
8548   *
8549   * @see https://html.spec.whatwg.org/multipage/syntax.html#character-references
8550   *
8551   * @type {RegExp}
8552   */
8553  
8554  var REGEXP_HEXADECIMAL_CHARACTER_REFERENCE = /^#x[\da-f]+$/i;
8555  /**
8556   * Returns true if the given string is a valid character reference segment, or
8557   * false otherwise. The text should be stripped of `&` and `;` demarcations.
8558   *
8559   * @param {string} text Text to test.
8560   *
8561   * @return {boolean} Whether text is valid character reference.
8562   */
8563  
8564  function isValidCharacterReference(text) {
8565    return REGEXP_NAMED_CHARACTER_REFERENCE.test(text) || REGEXP_DECIMAL_CHARACTER_REFERENCE.test(text) || REGEXP_HEXADECIMAL_CHARACTER_REFERENCE.test(text);
8566  }
8567  /**
8568   * Subsitute EntityParser class for `simple-html-tokenizer` which uses the
8569   * implementation of `decodeEntities` from `html-entities`, in order to avoid
8570   * bundling a massive named character reference.
8571   *
8572   * @see https://github.com/tildeio/simple-html-tokenizer/tree/master/src/entity-parser.ts
8573   */
8574  
8575  var validation_DecodeEntityParser =
8576  /*#__PURE__*/
8577  function () {
8578    function DecodeEntityParser() {
8579      Object(classCallCheck["a" /* default */])(this, DecodeEntityParser);
8580    }
8581  
8582    Object(createClass["a" /* default */])(DecodeEntityParser, [{
8583      key: "parse",
8584  
8585      /**
8586       * Returns a substitute string for an entity string sequence between `&`
8587       * and `;`, or undefined if no substitution should occur.
8588       *
8589       * @param {string} entity Entity fragment discovered in HTML.
8590       *
8591       * @return {?string} Entity substitute value.
8592       */
8593      value: function parse(entity) {
8594        if (isValidCharacterReference(entity)) {
8595          return Object(external_this_wp_htmlEntities_["decodeEntities"])('&' + entity + ';');
8596        }
8597      }
8598    }]);
8599  
8600    return DecodeEntityParser;
8601  }();
8602  /**
8603   * Given a specified string, returns an array of strings split by consecutive
8604   * whitespace, ignoring leading or trailing whitespace.
8605   *
8606   * @param {string} text Original text.
8607   *
8608   * @return {string[]} Text pieces split on whitespace.
8609   */
8610  
8611  function getTextPiecesSplitOnWhitespace(text) {
8612    return text.trim().split(REGEXP_WHITESPACE);
8613  }
8614  /**
8615   * Given a specified string, returns a new trimmed string where all consecutive
8616   * whitespace is collapsed to a single space.
8617   *
8618   * @param {string} text Original text.
8619   *
8620   * @return {string} Trimmed text with consecutive whitespace collapsed.
8621   */
8622  
8623  function getTextWithCollapsedWhitespace(text) {
8624    // This is an overly simplified whitespace comparison. The specification is
8625    // more prescriptive of whitespace behavior in inline and block contexts.
8626    //
8627    // See: https://medium.com/@patrickbrosset/when-does-white-space-matter-in-html-b90e8a7cdd33
8628    return getTextPiecesSplitOnWhitespace(text).join(' ');
8629  }
8630  /**
8631   * Returns attribute pairs of the given StartTag token, including only pairs
8632   * where the value is non-empty or the attribute is a boolean attribute, an
8633   * enumerated attribute, or a custom data- attribute.
8634   *
8635   * @see MEANINGFUL_ATTRIBUTES
8636   *
8637   * @param {Object} token StartTag token.
8638   *
8639   * @return {Array[]} Attribute pairs.
8640   */
8641  
8642  function getMeaningfulAttributePairs(token) {
8643    return token.attributes.filter(function (pair) {
8644      var _pair = Object(slicedToArray["a" /* default */])(pair, 2),
8645          key = _pair[0],
8646          value = _pair[1];
8647  
8648      return value || key.indexOf('data-') === 0 || Object(external_lodash_["includes"])(MEANINGFUL_ATTRIBUTES, key);
8649    });
8650  }
8651  /**
8652   * Returns true if two text tokens (with `chars` property) are equivalent, or
8653   * false otherwise.
8654   *
8655   * @param {Object} actual   Actual token.
8656   * @param {Object} expected Expected token.
8657   * @param {Object} logger   Validation logger object.
8658   *
8659   * @return {boolean} Whether two text tokens are equivalent.
8660   */
8661  
8662  function isEquivalentTex