[ Index ] |
PHP Cross Reference of WordPress |
[Summary view] [Print] [Text view]
1 /******/ (function() { // webpackBootstrap 2 /******/ var __webpack_modules__ = ({ 3 4 /***/ 9756: 5 /***/ (function(module) { 6 7 /** 8 * Memize options object. 9 * 10 * @typedef MemizeOptions 11 * 12 * @property {number} [maxSize] Maximum size of the cache. 13 */ 14 15 /** 16 * Internal cache entry. 17 * 18 * @typedef MemizeCacheNode 19 * 20 * @property {?MemizeCacheNode|undefined} [prev] Previous node. 21 * @property {?MemizeCacheNode|undefined} [next] Next node. 22 * @property {Array<*>} args Function arguments for cache 23 * entry. 24 * @property {*} val Function result. 25 */ 26 27 /** 28 * Properties of the enhanced function for controlling cache. 29 * 30 * @typedef MemizeMemoizedFunction 31 * 32 * @property {()=>void} clear Clear the cache. 33 */ 34 35 /** 36 * Accepts a function to be memoized, and returns a new memoized function, with 37 * optional options. 38 * 39 * @template {Function} F 40 * 41 * @param {F} fn Function to memoize. 42 * @param {MemizeOptions} [options] Options object. 43 * 44 * @return {F & MemizeMemoizedFunction} Memoized function. 45 */ 46 function memize( fn, options ) { 47 var size = 0; 48 49 /** @type {?MemizeCacheNode|undefined} */ 50 var head; 51 52 /** @type {?MemizeCacheNode|undefined} */ 53 var tail; 54 55 options = options || {}; 56 57 function memoized( /* ...args */ ) { 58 var node = head, 59 len = arguments.length, 60 args, i; 61 62 searchCache: while ( node ) { 63 // Perform a shallow equality test to confirm that whether the node 64 // under test is a candidate for the arguments passed. Two arrays 65 // are shallowly equal if their length matches and each entry is 66 // strictly equal between the two sets. Avoid abstracting to a 67 // function which could incur an arguments leaking deoptimization. 68 69 // Check whether node arguments match arguments length 70 if ( node.args.length !== arguments.length ) { 71 node = node.next; 72 continue; 73 } 74 75 // Check whether node arguments match arguments values 76 for ( i = 0; i < len; i++ ) { 77 if ( node.args[ i ] !== arguments[ i ] ) { 78 node = node.next; 79 continue searchCache; 80 } 81 } 82 83 // At this point we can assume we've found a match 84 85 // Surface matched node to head if not already 86 if ( node !== head ) { 87 // As tail, shift to previous. Must only shift if not also 88 // head, since if both head and tail, there is no previous. 89 if ( node === tail ) { 90 tail = node.prev; 91 } 92 93 // Adjust siblings to point to each other. If node was tail, 94 // this also handles new tail's empty `next` assignment. 95 /** @type {MemizeCacheNode} */ ( node.prev ).next = node.next; 96 if ( node.next ) { 97 node.next.prev = node.prev; 98 } 99 100 node.next = head; 101 node.prev = null; 102 /** @type {MemizeCacheNode} */ ( head ).prev = node; 103 head = node; 104 } 105 106 // Return immediately 107 return node.val; 108 } 109 110 // No cached value found. Continue to insertion phase: 111 112 // Create a copy of arguments (avoid leaking deoptimization) 113 args = new Array( len ); 114 for ( i = 0; i < len; i++ ) { 115 args[ i ] = arguments[ i ]; 116 } 117 118 node = { 119 args: args, 120 121 // Generate the result from original function 122 val: fn.apply( null, args ), 123 }; 124 125 // Don't need to check whether node is already head, since it would 126 // have been returned above already if it was 127 128 // Shift existing head down list 129 if ( head ) { 130 head.prev = node; 131 node.next = head; 132 } else { 133 // If no head, follows that there's no tail (at initial or reset) 134 tail = node; 135 } 136 137 // Trim tail if we're reached max size and are pending cache insertion 138 if ( size === /** @type {MemizeOptions} */ ( options ).maxSize ) { 139 tail = /** @type {MemizeCacheNode} */ ( tail ).prev; 140 /** @type {MemizeCacheNode} */ ( tail ).next = null; 141 } else { 142 size++; 143 } 144 145 head = node; 146 147 return node.val; 148 } 149 150 memoized.clear = function() { 151 head = null; 152 tail = null; 153 size = 0; 154 }; 155 156 if ( false ) {} 157 158 // Ignore reason: There's not a clear solution to create an intersection of 159 // the function with additional properties, where the goal is to retain the 160 // function signature of the incoming argument and add control properties 161 // on the return value. 162 163 // @ts-ignore 164 return memoized; 165 } 166 167 module.exports = memize; 168 169 170 /***/ }), 171 172 /***/ 7308: 173 /***/ (function(module, exports, __webpack_require__) { 174 175 var __WEBPACK_AMD_DEFINE_RESULT__;;/*! showdown v 1.9.1 - 02-11-2019 */ 176 (function(){ 177 /** 178 * Created by Tivie on 13-07-2015. 179 */ 180 181 function getDefaultOpts (simple) { 182 'use strict'; 183 184 var defaultOptions = { 185 omitExtraWLInCodeBlocks: { 186 defaultValue: false, 187 describe: 'Omit the default extra whiteline added to code blocks', 188 type: 'boolean' 189 }, 190 noHeaderId: { 191 defaultValue: false, 192 describe: 'Turn on/off generated header id', 193 type: 'boolean' 194 }, 195 prefixHeaderId: { 196 defaultValue: false, 197 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', 198 type: 'string' 199 }, 200 rawPrefixHeaderId: { 201 defaultValue: false, 202 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)', 203 type: 'boolean' 204 }, 205 ghCompatibleHeaderId: { 206 defaultValue: false, 207 describe: 'Generate header ids compatible with github style (spaces are replaced with dashes, a bunch of non alphanumeric chars are removed)', 208 type: 'boolean' 209 }, 210 rawHeaderId: { 211 defaultValue: false, 212 describe: 'Remove only spaces, \' and " from generated header ids (including prefixes), replacing them with dashes (-). WARNING: This might result in malformed ids', 213 type: 'boolean' 214 }, 215 headerLevelStart: { 216 defaultValue: false, 217 describe: 'The header blocks level start', 218 type: 'integer' 219 }, 220 parseImgDimensions: { 221 defaultValue: false, 222 describe: 'Turn on/off image dimension parsing', 223 type: 'boolean' 224 }, 225 simplifiedAutoLink: { 226 defaultValue: false, 227 describe: 'Turn on/off GFM autolink style', 228 type: 'boolean' 229 }, 230 excludeTrailingPunctuationFromURLs: { 231 defaultValue: false, 232 describe: 'Excludes trailing punctuation from links generated with autoLinking', 233 type: 'boolean' 234 }, 235 literalMidWordUnderscores: { 236 defaultValue: false, 237 describe: 'Parse midword underscores as literal underscores', 238 type: 'boolean' 239 }, 240 literalMidWordAsterisks: { 241 defaultValue: false, 242 describe: 'Parse midword asterisks as literal asterisks', 243 type: 'boolean' 244 }, 245 strikethrough: { 246 defaultValue: false, 247 describe: 'Turn on/off strikethrough support', 248 type: 'boolean' 249 }, 250 tables: { 251 defaultValue: false, 252 describe: 'Turn on/off tables support', 253 type: 'boolean' 254 }, 255 tablesHeaderId: { 256 defaultValue: false, 257 describe: 'Add an id to table headers', 258 type: 'boolean' 259 }, 260 ghCodeBlocks: { 261 defaultValue: true, 262 describe: 'Turn on/off GFM fenced code blocks support', 263 type: 'boolean' 264 }, 265 tasklists: { 266 defaultValue: false, 267 describe: 'Turn on/off GFM tasklist support', 268 type: 'boolean' 269 }, 270 smoothLivePreview: { 271 defaultValue: false, 272 describe: 'Prevents weird effects in live previews due to incomplete input', 273 type: 'boolean' 274 }, 275 smartIndentationFix: { 276 defaultValue: false, 277 description: 'Tries to smartly fix indentation in es6 strings', 278 type: 'boolean' 279 }, 280 disableForced4SpacesIndentedSublists: { 281 defaultValue: false, 282 description: 'Disables the requirement of indenting nested sublists by 4 spaces', 283 type: 'boolean' 284 }, 285 simpleLineBreaks: { 286 defaultValue: false, 287 description: 'Parses simple line breaks as <br> (GFM Style)', 288 type: 'boolean' 289 }, 290 requireSpaceBeforeHeadingText: { 291 defaultValue: false, 292 description: 'Makes adding a space between `#` and the header text mandatory (GFM Style)', 293 type: 'boolean' 294 }, 295 ghMentions: { 296 defaultValue: false, 297 description: 'Enables github @mentions', 298 type: 'boolean' 299 }, 300 ghMentionsLink: { 301 defaultValue: 'https://github.com/{u}', 302 description: 'Changes the link generated by @mentions. Only applies if ghMentions option is enabled.', 303 type: 'string' 304 }, 305 encodeEmails: { 306 defaultValue: true, 307 description: 'Encode e-mail addresses through the use of Character Entities, transforming ASCII e-mail addresses into its equivalent decimal entities', 308 type: 'boolean' 309 }, 310 openLinksInNewWindow: { 311 defaultValue: false, 312 description: 'Open all links in new windows', 313 type: 'boolean' 314 }, 315 backslashEscapesHTMLTags: { 316 defaultValue: false, 317 description: 'Support for HTML Tag escaping. ex: \<div>foo\</div>', 318 type: 'boolean' 319 }, 320 emoji: { 321 defaultValue: false, 322 description: 'Enable emoji support. Ex: `this is a :smile: emoji`', 323 type: 'boolean' 324 }, 325 underline: { 326 defaultValue: false, 327 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>`', 328 type: 'boolean' 329 }, 330 completeHTMLDocument: { 331 defaultValue: false, 332 description: 'Outputs a complete html document, including `<html>`, `<head>` and `<body>` tags', 333 type: 'boolean' 334 }, 335 metadata: { 336 defaultValue: false, 337 description: 'Enable support for document metadata (defined at the top of the document between `«««` and `»»»` or between `---` and `---`).', 338 type: 'boolean' 339 }, 340 splitAdjacentBlockquotes: { 341 defaultValue: false, 342 description: 'Split adjacent blockquote blocks', 343 type: 'boolean' 344 } 345 }; 346 if (simple === false) { 347 return JSON.parse(JSON.stringify(defaultOptions)); 348 } 349 var ret = {}; 350 for (var opt in defaultOptions) { 351 if (defaultOptions.hasOwnProperty(opt)) { 352 ret[opt] = defaultOptions[opt].defaultValue; 353 } 354 } 355 return ret; 356 } 357 358 function allOptionsOn () { 359 'use strict'; 360 var options = getDefaultOpts(true), 361 ret = {}; 362 for (var opt in options) { 363 if (options.hasOwnProperty(opt)) { 364 ret[opt] = true; 365 } 366 } 367 return ret; 368 } 369 370 /** 371 * Created by Tivie on 06-01-2015. 372 */ 373 374 // Private properties 375 var showdown = {}, 376 parsers = {}, 377 extensions = {}, 378 globalOptions = getDefaultOpts(true), 379 setFlavor = 'vanilla', 380 flavor = { 381 github: { 382 omitExtraWLInCodeBlocks: true, 383 simplifiedAutoLink: true, 384 excludeTrailingPunctuationFromURLs: true, 385 literalMidWordUnderscores: true, 386 strikethrough: true, 387 tables: true, 388 tablesHeaderId: true, 389 ghCodeBlocks: true, 390 tasklists: true, 391 disableForced4SpacesIndentedSublists: true, 392 simpleLineBreaks: true, 393 requireSpaceBeforeHeadingText: true, 394 ghCompatibleHeaderId: true, 395 ghMentions: true, 396 backslashEscapesHTMLTags: true, 397 emoji: true, 398 splitAdjacentBlockquotes: true 399 }, 400 original: { 401 noHeaderId: true, 402 ghCodeBlocks: false 403 }, 404 ghost: { 405 omitExtraWLInCodeBlocks: true, 406 parseImgDimensions: true, 407 simplifiedAutoLink: true, 408 excludeTrailingPunctuationFromURLs: true, 409 literalMidWordUnderscores: true, 410 strikethrough: true, 411 tables: true, 412 tablesHeaderId: true, 413 ghCodeBlocks: true, 414 tasklists: true, 415 smoothLivePreview: true, 416 simpleLineBreaks: true, 417 requireSpaceBeforeHeadingText: true, 418 ghMentions: false, 419 encodeEmails: true 420 }, 421 vanilla: getDefaultOpts(true), 422 allOn: allOptionsOn() 423 }; 424 425 /** 426 * helper namespace 427 * @type {{}} 428 */ 429 showdown.helper = {}; 430 431 /** 432 * TODO LEGACY SUPPORT CODE 433 * @type {{}} 434 */ 435 showdown.extensions = {}; 436 437 /** 438 * Set a global option 439 * @static 440 * @param {string} key 441 * @param {*} value 442 * @returns {showdown} 443 */ 444 showdown.setOption = function (key, value) { 445 'use strict'; 446 globalOptions[key] = value; 447 return this; 448 }; 449 450 /** 451 * Get a global option 452 * @static 453 * @param {string} key 454 * @returns {*} 455 */ 456 showdown.getOption = function (key) { 457 'use strict'; 458 return globalOptions[key]; 459 }; 460 461 /** 462 * Get the global options 463 * @static 464 * @returns {{}} 465 */ 466 showdown.getOptions = function () { 467 'use strict'; 468 return globalOptions; 469 }; 470 471 /** 472 * Reset global options to the default values 473 * @static 474 */ 475 showdown.resetOptions = function () { 476 'use strict'; 477 globalOptions = getDefaultOpts(true); 478 }; 479 480 /** 481 * Set the flavor showdown should use as default 482 * @param {string} name 483 */ 484 showdown.setFlavor = function (name) { 485 'use strict'; 486 if (!flavor.hasOwnProperty(name)) { 487 throw Error(name + ' flavor was not found'); 488 } 489 showdown.resetOptions(); 490 var preset = flavor[name]; 491 setFlavor = name; 492 for (var option in preset) { 493 if (preset.hasOwnProperty(option)) { 494 globalOptions[option] = preset[option]; 495 } 496 } 497 }; 498 499 /** 500 * Get the currently set flavor 501 * @returns {string} 502 */ 503 showdown.getFlavor = function () { 504 'use strict'; 505 return setFlavor; 506 }; 507 508 /** 509 * Get the options of a specified flavor. Returns undefined if the flavor was not found 510 * @param {string} name Name of the flavor 511 * @returns {{}|undefined} 512 */ 513 showdown.getFlavorOptions = function (name) { 514 'use strict'; 515 if (flavor.hasOwnProperty(name)) { 516 return flavor[name]; 517 } 518 }; 519 520 /** 521 * Get the default options 522 * @static 523 * @param {boolean} [simple=true] 524 * @returns {{}} 525 */ 526 showdown.getDefaultOptions = function (simple) { 527 'use strict'; 528 return getDefaultOpts(simple); 529 }; 530 531 /** 532 * Get or set a subParser 533 * 534 * subParser(name) - Get a registered subParser 535 * subParser(name, func) - Register a subParser 536 * @static 537 * @param {string} name 538 * @param {function} [func] 539 * @returns {*} 540 */ 541 showdown.subParser = function (name, func) { 542 'use strict'; 543 if (showdown.helper.isString(name)) { 544 if (typeof func !== 'undefined') { 545 parsers[name] = func; 546 } else { 547 if (parsers.hasOwnProperty(name)) { 548 return parsers[name]; 549 } else { 550 throw Error('SubParser named ' + name + ' not registered!'); 551 } 552 } 553 } 554 }; 555 556 /** 557 * Gets or registers an extension 558 * @static 559 * @param {string} name 560 * @param {object|function=} ext 561 * @returns {*} 562 */ 563 showdown.extension = function (name, ext) { 564 'use strict'; 565 566 if (!showdown.helper.isString(name)) { 567 throw Error('Extension \'name\' must be a string'); 568 } 569 570 name = showdown.helper.stdExtName(name); 571 572 // Getter 573 if (showdown.helper.isUndefined(ext)) { 574 if (!extensions.hasOwnProperty(name)) { 575 throw Error('Extension named ' + name + ' is not registered!'); 576 } 577 return extensions[name]; 578 579 // Setter 580 } else { 581 // Expand extension if it's wrapped in a function 582 if (typeof ext === 'function') { 583 ext = ext(); 584 } 585 586 // Ensure extension is an array 587 if (!showdown.helper.isArray(ext)) { 588 ext = [ext]; 589 } 590 591 var validExtension = validate(ext, name); 592 593 if (validExtension.valid) { 594 extensions[name] = ext; 595 } else { 596 throw Error(validExtension.error); 597 } 598 } 599 }; 600 601 /** 602 * Gets all extensions registered 603 * @returns {{}} 604 */ 605 showdown.getAllExtensions = function () { 606 'use strict'; 607 return extensions; 608 }; 609 610 /** 611 * Remove an extension 612 * @param {string} name 613 */ 614 showdown.removeExtension = function (name) { 615 'use strict'; 616 delete extensions[name]; 617 }; 618 619 /** 620 * Removes all extensions 621 */ 622 showdown.resetExtensions = function () { 623 'use strict'; 624 extensions = {}; 625 }; 626 627 /** 628 * Validate extension 629 * @param {array} extension 630 * @param {string} name 631 * @returns {{valid: boolean, error: string}} 632 */ 633 function validate (extension, name) { 634 'use strict'; 635 636 var errMsg = (name) ? 'Error in ' + name + ' extension->' : 'Error in unnamed extension', 637 ret = { 638 valid: true, 639 error: '' 640 }; 641 642 if (!showdown.helper.isArray(extension)) { 643 extension = [extension]; 644 } 645 646 for (var i = 0; i < extension.length; ++i) { 647 var baseMsg = errMsg + ' sub-extension ' + i + ': ', 648 ext = extension[i]; 649 if (typeof ext !== 'object') { 650 ret.valid = false; 651 ret.error = baseMsg + 'must be an object, but ' + typeof ext + ' given'; 652 return ret; 653 } 654 655 if (!showdown.helper.isString(ext.type)) { 656 ret.valid = false; 657 ret.error = baseMsg + 'property "type" must be a string, but ' + typeof ext.type + ' given'; 658 return ret; 659 } 660 661 var type = ext.type = ext.type.toLowerCase(); 662 663 // normalize extension type 664 if (type === 'language') { 665 type = ext.type = 'lang'; 666 } 667 668 if (type === 'html') { 669 type = ext.type = 'output'; 670 } 671 672 if (type !== 'lang' && type !== 'output' && type !== 'listener') { 673 ret.valid = false; 674 ret.error = baseMsg + 'type ' + type + ' is not recognized. Valid values: "lang/language", "output/html" or "listener"'; 675 return ret; 676 } 677 678 if (type === 'listener') { 679 if (showdown.helper.isUndefined(ext.listeners)) { 680 ret.valid = false; 681 ret.error = baseMsg + '. Extensions of type "listener" must have a property called "listeners"'; 682 return ret; 683 } 684 } else { 685 if (showdown.helper.isUndefined(ext.filter) && showdown.helper.isUndefined(ext.regex)) { 686 ret.valid = false; 687 ret.error = baseMsg + type + ' extensions must define either a "regex" property or a "filter" method'; 688 return ret; 689 } 690 } 691 692 if (ext.listeners) { 693 if (typeof ext.listeners !== 'object') { 694 ret.valid = false; 695 ret.error = baseMsg + '"listeners" property must be an object but ' + typeof ext.listeners + ' given'; 696 return ret; 697 } 698 for (var ln in ext.listeners) { 699 if (ext.listeners.hasOwnProperty(ln)) { 700 if (typeof ext.listeners[ln] !== 'function') { 701 ret.valid = false; 702 ret.error = baseMsg + '"listeners" property must be an hash of [event name]: [callback]. listeners.' + ln + 703 ' must be a function but ' + typeof ext.listeners[ln] + ' given'; 704 return ret; 705 } 706 } 707 } 708 } 709 710 if (ext.filter) { 711 if (typeof ext.filter !== 'function') { 712 ret.valid = false; 713 ret.error = baseMsg + '"filter" must be a function, but ' + typeof ext.filter + ' given'; 714 return ret; 715 } 716 } else if (ext.regex) { 717 if (showdown.helper.isString(ext.regex)) { 718 ext.regex = new RegExp(ext.regex, 'g'); 719 } 720 if (!(ext.regex instanceof RegExp)) { 721 ret.valid = false; 722 ret.error = baseMsg + '"regex" property must either be a string or a RegExp object, but ' + typeof ext.regex + ' given'; 723 return ret; 724 } 725 if (showdown.helper.isUndefined(ext.replace)) { 726 ret.valid = false; 727 ret.error = baseMsg + '"regex" extensions must implement a replace string or function'; 728 return ret; 729 } 730 } 731 } 732 return ret; 733 } 734 735 /** 736 * Validate extension 737 * @param {object} ext 738 * @returns {boolean} 739 */ 740 showdown.validateExtension = function (ext) { 741 'use strict'; 742 743 var validateExtension = validate(ext, null); 744 if (!validateExtension.valid) { 745 console.warn(validateExtension.error); 746 return false; 747 } 748 return true; 749 }; 750 751 /** 752 * showdownjs helper functions 753 */ 754 755 if (!showdown.hasOwnProperty('helper')) { 756 showdown.helper = {}; 757 } 758 759 /** 760 * Check if var is string 761 * @static 762 * @param {string} a 763 * @returns {boolean} 764 */ 765 showdown.helper.isString = function (a) { 766 'use strict'; 767 return (typeof a === 'string' || a instanceof String); 768 }; 769 770 /** 771 * Check if var is a function 772 * @static 773 * @param {*} a 774 * @returns {boolean} 775 */ 776 showdown.helper.isFunction = function (a) { 777 'use strict'; 778 var getType = {}; 779 return a && getType.toString.call(a) === '[object Function]'; 780 }; 781 782 /** 783 * isArray helper function 784 * @static 785 * @param {*} a 786 * @returns {boolean} 787 */ 788 showdown.helper.isArray = function (a) { 789 'use strict'; 790 return Array.isArray(a); 791 }; 792 793 /** 794 * Check if value is undefined 795 * @static 796 * @param {*} value The value to check. 797 * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. 798 */ 799 showdown.helper.isUndefined = function (value) { 800 'use strict'; 801 return typeof value === 'undefined'; 802 }; 803 804 /** 805 * ForEach helper function 806 * Iterates over Arrays and Objects (own properties only) 807 * @static 808 * @param {*} obj 809 * @param {function} callback Accepts 3 params: 1. value, 2. key, 3. the original array/object 810 */ 811 showdown.helper.forEach = function (obj, callback) { 812 'use strict'; 813 // check if obj is defined 814 if (showdown.helper.isUndefined(obj)) { 815 throw new Error('obj param is required'); 816 } 817 818 if (showdown.helper.isUndefined(callback)) { 819 throw new Error('callback param is required'); 820 } 821 822 if (!showdown.helper.isFunction(callback)) { 823 throw new Error('callback param must be a function/closure'); 824 } 825 826 if (typeof obj.forEach === 'function') { 827 obj.forEach(callback); 828 } else if (showdown.helper.isArray(obj)) { 829 for (var i = 0; i < obj.length; i++) { 830 callback(obj[i], i, obj); 831 } 832 } else if (typeof (obj) === 'object') { 833 for (var prop in obj) { 834 if (obj.hasOwnProperty(prop)) { 835 callback(obj[prop], prop, obj); 836 } 837 } 838 } else { 839 throw new Error('obj does not seem to be an array or an iterable object'); 840 } 841 }; 842 843 /** 844 * Standardidize extension name 845 * @static 846 * @param {string} s extension name 847 * @returns {string} 848 */ 849 showdown.helper.stdExtName = function (s) { 850 'use strict'; 851 return s.replace(/[_?*+\/\\.^-]/g, '').replace(/\s/g, '').toLowerCase(); 852 }; 853 854 function escapeCharactersCallback (wholeMatch, m1) { 855 'use strict'; 856 var charCodeToEscape = m1.charCodeAt(0); 857 return '¨E' + charCodeToEscape + 'E'; 858 } 859 860 /** 861 * Callback used to escape characters when passing through String.replace 862 * @static 863 * @param {string} wholeMatch 864 * @param {string} m1 865 * @returns {string} 866 */ 867 showdown.helper.escapeCharactersCallback = escapeCharactersCallback; 868 869 /** 870 * Escape characters in a string 871 * @static 872 * @param {string} text 873 * @param {string} charsToEscape 874 * @param {boolean} afterBackslash 875 * @returns {XML|string|void|*} 876 */ 877 showdown.helper.escapeCharacters = function (text, charsToEscape, afterBackslash) { 878 'use strict'; 879 // First we have to escape the escape characters so that 880 // we can build a character class out of them 881 var regexString = '([' + charsToEscape.replace(/([\[\]\\])/g, '\\$1') + '])'; 882 883 if (afterBackslash) { 884 regexString = '\\\\' + regexString; 885 } 886 887 var regex = new RegExp(regexString, 'g'); 888 text = text.replace(regex, escapeCharactersCallback); 889 890 return text; 891 }; 892 893 /** 894 * Unescape HTML entities 895 * @param txt 896 * @returns {string} 897 */ 898 showdown.helper.unescapeHTMLEntities = function (txt) { 899 'use strict'; 900 901 return txt 902 .replace(/"/g, '"') 903 .replace(/</g, '<') 904 .replace(/>/g, '>') 905 .replace(/&/g, '&'); 906 }; 907 908 var rgxFindMatchPos = function (str, left, right, flags) { 909 'use strict'; 910 var f = flags || '', 911 g = f.indexOf('g') > -1, 912 x = new RegExp(left + '|' + right, 'g' + f.replace(/g/g, '')), 913 l = new RegExp(left, f.replace(/g/g, '')), 914 pos = [], 915 t, s, m, start, end; 916 917 do { 918 t = 0; 919 while ((m = x.exec(str))) { 920 if (l.test(m[0])) { 921 if (!(t++)) { 922 s = x.lastIndex; 923 start = s - m[0].length; 924 } 925 } else if (t) { 926 if (!--t) { 927 end = m.index + m[0].length; 928 var obj = { 929 left: {start: start, end: s}, 930 match: {start: s, end: m.index}, 931 right: {start: m.index, end: end}, 932 wholeMatch: {start: start, end: end} 933 }; 934 pos.push(obj); 935 if (!g) { 936 return pos; 937 } 938 } 939 } 940 } 941 } while (t && (x.lastIndex = s)); 942 943 return pos; 944 }; 945 946 /** 947 * matchRecursiveRegExp 948 * 949 * (c) 2007 Steven Levithan <stevenlevithan.com> 950 * MIT License 951 * 952 * Accepts a string to search, a left and right format delimiter 953 * as regex patterns, and optional regex flags. Returns an array 954 * of matches, allowing nested instances of left/right delimiters. 955 * Use the "g" flag to return all matches, otherwise only the 956 * first is returned. Be careful to ensure that the left and 957 * right format delimiters produce mutually exclusive matches. 958 * Backreferences are not supported within the right delimiter 959 * due to how it is internally combined with the left delimiter. 960 * When matching strings whose format delimiters are unbalanced 961 * to the left or right, the output is intentionally as a 962 * conventional regex library with recursion support would 963 * produce, e.g. "<<x>" and "<x>>" both produce ["x"] when using 964 * "<" and ">" as the delimiters (both strings contain a single, 965 * balanced instance of "<x>"). 966 * 967 * examples: 968 * matchRecursiveRegExp("test", "\\(", "\\)") 969 * returns: [] 970 * matchRecursiveRegExp("<t<<e>><s>>t<>", "<", ">", "g") 971 * returns: ["t<<e>><s>", ""] 972 * matchRecursiveRegExp("<div id=\"x\">test</div>", "<div\\b[^>]*>", "</div>", "gi") 973 * returns: ["test"] 974 */ 975 showdown.helper.matchRecursiveRegExp = function (str, left, right, flags) { 976 'use strict'; 977 978 var matchPos = rgxFindMatchPos (str, left, right, flags), 979 results = []; 980 981 for (var i = 0; i < matchPos.length; ++i) { 982 results.push([ 983 str.slice(matchPos[i].wholeMatch.start, matchPos[i].wholeMatch.end), 984 str.slice(matchPos[i].match.start, matchPos[i].match.end), 985 str.slice(matchPos[i].left.start, matchPos[i].left.end), 986 str.slice(matchPos[i].right.start, matchPos[i].right.end) 987 ]); 988 } 989 return results; 990 }; 991 992 /** 993 * 994 * @param {string} str 995 * @param {string|function} replacement 996 * @param {string} left 997 * @param {string} right 998 * @param {string} flags 999 * @returns {string} 1000 */ 1001 showdown.helper.replaceRecursiveRegExp = function (str, replacement, left, right, flags) { 1002 'use strict'; 1003 1004 if (!showdown.helper.isFunction(replacement)) { 1005 var repStr = replacement; 1006 replacement = function () { 1007 return repStr; 1008 }; 1009 } 1010 1011 var matchPos = rgxFindMatchPos(str, left, right, flags), 1012 finalStr = str, 1013 lng = matchPos.length; 1014 1015 if (lng > 0) { 1016 var bits = []; 1017 if (matchPos[0].wholeMatch.start !== 0) { 1018 bits.push(str.slice(0, matchPos[0].wholeMatch.start)); 1019 } 1020 for (var i = 0; i < lng; ++i) { 1021 bits.push( 1022 replacement( 1023 str.slice(matchPos[i].wholeMatch.start, matchPos[i].wholeMatch.end), 1024 str.slice(matchPos[i].match.start, matchPos[i].match.end), 1025 str.slice(matchPos[i].left.start, matchPos[i].left.end), 1026 str.slice(matchPos[i].right.start, matchPos[i].right.end) 1027 ) 1028 ); 1029 if (i < lng - 1) { 1030 bits.push(str.slice(matchPos[i].wholeMatch.end, matchPos[i + 1].wholeMatch.start)); 1031 } 1032 } 1033 if (matchPos[lng - 1].wholeMatch.end < str.length) { 1034 bits.push(str.slice(matchPos[lng - 1].wholeMatch.end)); 1035 } 1036 finalStr = bits.join(''); 1037 } 1038 return finalStr; 1039 }; 1040 1041 /** 1042 * Returns the index within the passed String object of the first occurrence of the specified regex, 1043 * starting the search at fromIndex. Returns -1 if the value is not found. 1044 * 1045 * @param {string} str string to search 1046 * @param {RegExp} regex Regular expression to search 1047 * @param {int} [fromIndex = 0] Index to start the search 1048 * @returns {Number} 1049 * @throws InvalidArgumentError 1050 */ 1051 showdown.helper.regexIndexOf = function (str, regex, fromIndex) { 1052 'use strict'; 1053 if (!showdown.helper.isString(str)) { 1054 throw 'InvalidArgumentError: first parameter of showdown.helper.regexIndexOf function must be a string'; 1055 } 1056 if (regex instanceof RegExp === false) { 1057 throw 'InvalidArgumentError: second parameter of showdown.helper.regexIndexOf function must be an instance of RegExp'; 1058 } 1059 var indexOf = str.substring(fromIndex || 0).search(regex); 1060 return (indexOf >= 0) ? (indexOf + (fromIndex || 0)) : indexOf; 1061 }; 1062 1063 /** 1064 * Splits the passed string object at the defined index, and returns an array composed of the two substrings 1065 * @param {string} str string to split 1066 * @param {int} index index to split string at 1067 * @returns {[string,string]} 1068 * @throws InvalidArgumentError 1069 */ 1070 showdown.helper.splitAtIndex = function (str, index) { 1071 'use strict'; 1072 if (!showdown.helper.isString(str)) { 1073 throw 'InvalidArgumentError: first parameter of showdown.helper.regexIndexOf function must be a string'; 1074 } 1075 return [str.substring(0, index), str.substring(index)]; 1076 }; 1077 1078 /** 1079 * Obfuscate an e-mail address through the use of Character Entities, 1080 * transforming ASCII characters into their equivalent decimal or hex entities. 1081 * 1082 * Since it has a random component, subsequent calls to this function produce different results 1083 * 1084 * @param {string} mail 1085 * @returns {string} 1086 */ 1087 showdown.helper.encodeEmailAddress = function (mail) { 1088 'use strict'; 1089 var encode = [ 1090 function (ch) { 1091 return '&#' + ch.charCodeAt(0) + ';'; 1092 }, 1093 function (ch) { 1094 return '&#x' + ch.charCodeAt(0).toString(16) + ';'; 1095 }, 1096 function (ch) { 1097 return ch; 1098 } 1099 ]; 1100 1101 mail = mail.replace(/./g, function (ch) { 1102 if (ch === '@') { 1103 // this *must* be encoded. I insist. 1104 ch = encode[Math.floor(Math.random() * 2)](ch); 1105 } else { 1106 var r = Math.random(); 1107 // roughly 10% raw, 45% hex, 45% dec 1108 ch = ( 1109 r > 0.9 ? encode[2](ch) : r > 0.45 ? encode[1](ch) : encode[0](ch) 1110 ); 1111 } 1112 return ch; 1113 }); 1114 1115 return mail; 1116 }; 1117 1118 /** 1119 * 1120 * @param str 1121 * @param targetLength 1122 * @param padString 1123 * @returns {string} 1124 */ 1125 showdown.helper.padEnd = function padEnd (str, targetLength, padString) { 1126 'use strict'; 1127 /*jshint bitwise: false*/ 1128 // eslint-disable-next-line space-infix-ops 1129 targetLength = targetLength>>0; //floor if number or convert non-number to 0; 1130 /*jshint bitwise: true*/ 1131 padString = String(padString || ' '); 1132 if (str.length > targetLength) { 1133 return String(str); 1134 } else { 1135 targetLength = targetLength - str.length; 1136 if (targetLength > padString.length) { 1137 padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed 1138 } 1139 return String(str) + padString.slice(0,targetLength); 1140 } 1141 }; 1142 1143 /** 1144 * POLYFILLS 1145 */ 1146 // use this instead of builtin is undefined for IE8 compatibility 1147 if (typeof console === 'undefined') { 1148 console = { 1149 warn: function (msg) { 1150 'use strict'; 1151 alert(msg); 1152 }, 1153 log: function (msg) { 1154 'use strict'; 1155 alert(msg); 1156 }, 1157 error: function (msg) { 1158 'use strict'; 1159 throw msg; 1160 } 1161 }; 1162 } 1163 1164 /** 1165 * Common regexes. 1166 * We declare some common regexes to improve performance 1167 */ 1168 showdown.helper.regexes = { 1169 asteriskDashAndColon: /([*_:~])/g 1170 }; 1171 1172 /** 1173 * EMOJIS LIST 1174 */ 1175 showdown.helper.emojis = { 1176 '+1':'\ud83d\udc4d', 1177 '-1':'\ud83d\udc4e', 1178 '100':'\ud83d\udcaf', 1179 '1234':'\ud83d\udd22', 1180 '1st_place_medal':'\ud83e\udd47', 1181 '2nd_place_medal':'\ud83e\udd48', 1182 '3rd_place_medal':'\ud83e\udd49', 1183 '8ball':'\ud83c\udfb1', 1184 'a':'\ud83c\udd70\ufe0f', 1185 'ab':'\ud83c\udd8e', 1186 'abc':'\ud83d\udd24', 1187 'abcd':'\ud83d\udd21', 1188 'accept':'\ud83c\ude51', 1189 'aerial_tramway':'\ud83d\udea1', 1190 'airplane':'\u2708\ufe0f', 1191 'alarm_clock':'\u23f0', 1192 'alembic':'\u2697\ufe0f', 1193 'alien':'\ud83d\udc7d', 1194 'ambulance':'\ud83d\ude91', 1195 'amphora':'\ud83c\udffa', 1196 'anchor':'\u2693\ufe0f', 1197 'angel':'\ud83d\udc7c', 1198 'anger':'\ud83d\udca2', 1199 'angry':'\ud83d\ude20', 1200 'anguished':'\ud83d\ude27', 1201 'ant':'\ud83d\udc1c', 1202 'apple':'\ud83c\udf4e', 1203 'aquarius':'\u2652\ufe0f', 1204 'aries':'\u2648\ufe0f', 1205 'arrow_backward':'\u25c0\ufe0f', 1206 'arrow_double_down':'\u23ec', 1207 'arrow_double_up':'\u23eb', 1208 'arrow_down':'\u2b07\ufe0f', 1209 'arrow_down_small':'\ud83d\udd3d', 1210 'arrow_forward':'\u25b6\ufe0f', 1211 'arrow_heading_down':'\u2935\ufe0f', 1212 'arrow_heading_up':'\u2934\ufe0f', 1213 'arrow_left':'\u2b05\ufe0f', 1214 'arrow_lower_left':'\u2199\ufe0f', 1215 'arrow_lower_right':'\u2198\ufe0f', 1216 'arrow_right':'\u27a1\ufe0f', 1217 'arrow_right_hook':'\u21aa\ufe0f', 1218 'arrow_up':'\u2b06\ufe0f', 1219 'arrow_up_down':'\u2195\ufe0f', 1220 'arrow_up_small':'\ud83d\udd3c', 1221 'arrow_upper_left':'\u2196\ufe0f', 1222 'arrow_upper_right':'\u2197\ufe0f', 1223 'arrows_clockwise':'\ud83d\udd03', 1224 'arrows_counterclockwise':'\ud83d\udd04', 1225 'art':'\ud83c\udfa8', 1226 'articulated_lorry':'\ud83d\ude9b', 1227 'artificial_satellite':'\ud83d\udef0', 1228 'astonished':'\ud83d\ude32', 1229 'athletic_shoe':'\ud83d\udc5f', 1230 'atm':'\ud83c\udfe7', 1231 'atom_symbol':'\u269b\ufe0f', 1232 'avocado':'\ud83e\udd51', 1233 'b':'\ud83c\udd71\ufe0f', 1234 'baby':'\ud83d\udc76', 1235 'baby_bottle':'\ud83c\udf7c', 1236 'baby_chick':'\ud83d\udc24', 1237 'baby_symbol':'\ud83d\udebc', 1238 'back':'\ud83d\udd19', 1239 'bacon':'\ud83e\udd53', 1240 'badminton':'\ud83c\udff8', 1241 'baggage_claim':'\ud83d\udec4', 1242 'baguette_bread':'\ud83e\udd56', 1243 'balance_scale':'\u2696\ufe0f', 1244 'balloon':'\ud83c\udf88', 1245 'ballot_box':'\ud83d\uddf3', 1246 'ballot_box_with_check':'\u2611\ufe0f', 1247 'bamboo':'\ud83c\udf8d', 1248 'banana':'\ud83c\udf4c', 1249 'bangbang':'\u203c\ufe0f', 1250 'bank':'\ud83c\udfe6', 1251 'bar_chart':'\ud83d\udcca', 1252 'barber':'\ud83d\udc88', 1253 'baseball':'\u26be\ufe0f', 1254 'basketball':'\ud83c\udfc0', 1255 'basketball_man':'\u26f9\ufe0f', 1256 'basketball_woman':'\u26f9\ufe0f‍\u2640\ufe0f', 1257 'bat':'\ud83e\udd87', 1258 'bath':'\ud83d\udec0', 1259 'bathtub':'\ud83d\udec1', 1260 'battery':'\ud83d\udd0b', 1261 'beach_umbrella':'\ud83c\udfd6', 1262 'bear':'\ud83d\udc3b', 1263 'bed':'\ud83d\udecf', 1264 'bee':'\ud83d\udc1d', 1265 'beer':'\ud83c\udf7a', 1266 'beers':'\ud83c\udf7b', 1267 'beetle':'\ud83d\udc1e', 1268 'beginner':'\ud83d\udd30', 1269 'bell':'\ud83d\udd14', 1270 'bellhop_bell':'\ud83d\udece', 1271 'bento':'\ud83c\udf71', 1272 'biking_man':'\ud83d\udeb4', 1273 'bike':'\ud83d\udeb2', 1274 'biking_woman':'\ud83d\udeb4‍\u2640\ufe0f', 1275 'bikini':'\ud83d\udc59', 1276 'biohazard':'\u2623\ufe0f', 1277 'bird':'\ud83d\udc26', 1278 'birthday':'\ud83c\udf82', 1279 'black_circle':'\u26ab\ufe0f', 1280 'black_flag':'\ud83c\udff4', 1281 'black_heart':'\ud83d\udda4', 1282 'black_joker':'\ud83c\udccf', 1283 'black_large_square':'\u2b1b\ufe0f', 1284 'black_medium_small_square':'\u25fe\ufe0f', 1285 'black_medium_square':'\u25fc\ufe0f', 1286 'black_nib':'\u2712\ufe0f', 1287 'black_small_square':'\u25aa\ufe0f', 1288 'black_square_button':'\ud83d\udd32', 1289 'blonde_man':'\ud83d\udc71', 1290 'blonde_woman':'\ud83d\udc71‍\u2640\ufe0f', 1291 'blossom':'\ud83c\udf3c', 1292 'blowfish':'\ud83d\udc21', 1293 'blue_book':'\ud83d\udcd8', 1294 'blue_car':'\ud83d\ude99', 1295 'blue_heart':'\ud83d\udc99', 1296 'blush':'\ud83d\ude0a', 1297 'boar':'\ud83d\udc17', 1298 'boat':'\u26f5\ufe0f', 1299 'bomb':'\ud83d\udca3', 1300 'book':'\ud83d\udcd6', 1301 'bookmark':'\ud83d\udd16', 1302 'bookmark_tabs':'\ud83d\udcd1', 1303 'books':'\ud83d\udcda', 1304 'boom':'\ud83d\udca5', 1305 'boot':'\ud83d\udc62', 1306 'bouquet':'\ud83d\udc90', 1307 'bowing_man':'\ud83d\ude47', 1308 'bow_and_arrow':'\ud83c\udff9', 1309 'bowing_woman':'\ud83d\ude47‍\u2640\ufe0f', 1310 'bowling':'\ud83c\udfb3', 1311 'boxing_glove':'\ud83e\udd4a', 1312 'boy':'\ud83d\udc66', 1313 'bread':'\ud83c\udf5e', 1314 'bride_with_veil':'\ud83d\udc70', 1315 'bridge_at_night':'\ud83c\udf09', 1316 'briefcase':'\ud83d\udcbc', 1317 'broken_heart':'\ud83d\udc94', 1318 'bug':'\ud83d\udc1b', 1319 'building_construction':'\ud83c\udfd7', 1320 'bulb':'\ud83d\udca1', 1321 'bullettrain_front':'\ud83d\ude85', 1322 'bullettrain_side':'\ud83d\ude84', 1323 'burrito':'\ud83c\udf2f', 1324 'bus':'\ud83d\ude8c', 1325 'business_suit_levitating':'\ud83d\udd74', 1326 'busstop':'\ud83d\ude8f', 1327 'bust_in_silhouette':'\ud83d\udc64', 1328 'busts_in_silhouette':'\ud83d\udc65', 1329 'butterfly':'\ud83e\udd8b', 1330 'cactus':'\ud83c\udf35', 1331 'cake':'\ud83c\udf70', 1332 'calendar':'\ud83d\udcc6', 1333 'call_me_hand':'\ud83e\udd19', 1334 'calling':'\ud83d\udcf2', 1335 'camel':'\ud83d\udc2b', 1336 'camera':'\ud83d\udcf7', 1337 'camera_flash':'\ud83d\udcf8', 1338 'camping':'\ud83c\udfd5', 1339 'cancer':'\u264b\ufe0f', 1340 'candle':'\ud83d\udd6f', 1341 'candy':'\ud83c\udf6c', 1342 'canoe':'\ud83d\udef6', 1343 'capital_abcd':'\ud83d\udd20', 1344 'capricorn':'\u2651\ufe0f', 1345 'car':'\ud83d\ude97', 1346 'card_file_box':'\ud83d\uddc3', 1347 'card_index':'\ud83d\udcc7', 1348 'card_index_dividers':'\ud83d\uddc2', 1349 'carousel_horse':'\ud83c\udfa0', 1350 'carrot':'\ud83e\udd55', 1351 'cat':'\ud83d\udc31', 1352 'cat2':'\ud83d\udc08', 1353 'cd':'\ud83d\udcbf', 1354 'chains':'\u26d3', 1355 'champagne':'\ud83c\udf7e', 1356 'chart':'\ud83d\udcb9', 1357 'chart_with_downwards_trend':'\ud83d\udcc9', 1358 'chart_with_upwards_trend':'\ud83d\udcc8', 1359 'checkered_flag':'\ud83c\udfc1', 1360 'cheese':'\ud83e\uddc0', 1361 'cherries':'\ud83c\udf52', 1362 'cherry_blossom':'\ud83c\udf38', 1363 'chestnut':'\ud83c\udf30', 1364 'chicken':'\ud83d\udc14', 1365 'children_crossing':'\ud83d\udeb8', 1366 'chipmunk':'\ud83d\udc3f', 1367 'chocolate_bar':'\ud83c\udf6b', 1368 'christmas_tree':'\ud83c\udf84', 1369 'church':'\u26ea\ufe0f', 1370 'cinema':'\ud83c\udfa6', 1371 'circus_tent':'\ud83c\udfaa', 1372 'city_sunrise':'\ud83c\udf07', 1373 'city_sunset':'\ud83c\udf06', 1374 'cityscape':'\ud83c\udfd9', 1375 'cl':'\ud83c\udd91', 1376 'clamp':'\ud83d\udddc', 1377 'clap':'\ud83d\udc4f', 1378 'clapper':'\ud83c\udfac', 1379 'classical_building':'\ud83c\udfdb', 1380 'clinking_glasses':'\ud83e\udd42', 1381 'clipboard':'\ud83d\udccb', 1382 'clock1':'\ud83d\udd50', 1383 'clock10':'\ud83d\udd59', 1384 'clock1030':'\ud83d\udd65', 1385 'clock11':'\ud83d\udd5a', 1386 'clock1130':'\ud83d\udd66', 1387 'clock12':'\ud83d\udd5b', 1388 'clock1230':'\ud83d\udd67', 1389 'clock130':'\ud83d\udd5c', 1390 'clock2':'\ud83d\udd51', 1391 'clock230':'\ud83d\udd5d', 1392 'clock3':'\ud83d\udd52', 1393 'clock330':'\ud83d\udd5e', 1394 'clock4':'\ud83d\udd53', 1395 'clock430':'\ud83d\udd5f', 1396 'clock5':'\ud83d\udd54', 1397 'clock530':'\ud83d\udd60', 1398 'clock6':'\ud83d\udd55', 1399 'clock630':'\ud83d\udd61', 1400 'clock7':'\ud83d\udd56', 1401 'clock730':'\ud83d\udd62', 1402 'clock8':'\ud83d\udd57', 1403 'clock830':'\ud83d\udd63', 1404 'clock9':'\ud83d\udd58', 1405 'clock930':'\ud83d\udd64', 1406 'closed_book':'\ud83d\udcd5', 1407 'closed_lock_with_key':'\ud83d\udd10', 1408 'closed_umbrella':'\ud83c\udf02', 1409 'cloud':'\u2601\ufe0f', 1410 'cloud_with_lightning':'\ud83c\udf29', 1411 'cloud_with_lightning_and_rain':'\u26c8', 1412 'cloud_with_rain':'\ud83c\udf27', 1413 'cloud_with_snow':'\ud83c\udf28', 1414 'clown_face':'\ud83e\udd21', 1415 'clubs':'\u2663\ufe0f', 1416 'cocktail':'\ud83c\udf78', 1417 'coffee':'\u2615\ufe0f', 1418 'coffin':'\u26b0\ufe0f', 1419 'cold_sweat':'\ud83d\ude30', 1420 'comet':'\u2604\ufe0f', 1421 'computer':'\ud83d\udcbb', 1422 'computer_mouse':'\ud83d\uddb1', 1423 'confetti_ball':'\ud83c\udf8a', 1424 'confounded':'\ud83d\ude16', 1425 'confused':'\ud83d\ude15', 1426 'congratulations':'\u3297\ufe0f', 1427 'construction':'\ud83d\udea7', 1428 'construction_worker_man':'\ud83d\udc77', 1429 'construction_worker_woman':'\ud83d\udc77‍\u2640\ufe0f', 1430 'control_knobs':'\ud83c\udf9b', 1431 'convenience_store':'\ud83c\udfea', 1432 'cookie':'\ud83c\udf6a', 1433 'cool':'\ud83c\udd92', 1434 'policeman':'\ud83d\udc6e', 1435 'copyright':'\u00a9\ufe0f', 1436 'corn':'\ud83c\udf3d', 1437 'couch_and_lamp':'\ud83d\udecb', 1438 'couple':'\ud83d\udc6b', 1439 'couple_with_heart_woman_man':'\ud83d\udc91', 1440 'couple_with_heart_man_man':'\ud83d\udc68‍\u2764\ufe0f‍\ud83d\udc68', 1441 'couple_with_heart_woman_woman':'\ud83d\udc69‍\u2764\ufe0f‍\ud83d\udc69', 1442 'couplekiss_man_man':'\ud83d\udc68‍\u2764\ufe0f‍\ud83d\udc8b‍\ud83d\udc68', 1443 'couplekiss_man_woman':'\ud83d\udc8f', 1444 'couplekiss_woman_woman':'\ud83d\udc69‍\u2764\ufe0f‍\ud83d\udc8b‍\ud83d\udc69', 1445 'cow':'\ud83d\udc2e', 1446 'cow2':'\ud83d\udc04', 1447 'cowboy_hat_face':'\ud83e\udd20', 1448 'crab':'\ud83e\udd80', 1449 'crayon':'\ud83d\udd8d', 1450 'credit_card':'\ud83d\udcb3', 1451 'crescent_moon':'\ud83c\udf19', 1452 'cricket':'\ud83c\udfcf', 1453 'crocodile':'\ud83d\udc0a', 1454 'croissant':'\ud83e\udd50', 1455 'crossed_fingers':'\ud83e\udd1e', 1456 'crossed_flags':'\ud83c\udf8c', 1457 'crossed_swords':'\u2694\ufe0f', 1458 'crown':'\ud83d\udc51', 1459 'cry':'\ud83d\ude22', 1460 'crying_cat_face':'\ud83d\ude3f', 1461 'crystal_ball':'\ud83d\udd2e', 1462 'cucumber':'\ud83e\udd52', 1463 'cupid':'\ud83d\udc98', 1464 'curly_loop':'\u27b0', 1465 'currency_exchange':'\ud83d\udcb1', 1466 'curry':'\ud83c\udf5b', 1467 'custard':'\ud83c\udf6e', 1468 'customs':'\ud83d\udec3', 1469 'cyclone':'\ud83c\udf00', 1470 'dagger':'\ud83d\udde1', 1471 'dancer':'\ud83d\udc83', 1472 'dancing_women':'\ud83d\udc6f', 1473 'dancing_men':'\ud83d\udc6f‍\u2642\ufe0f', 1474 'dango':'\ud83c\udf61', 1475 'dark_sunglasses':'\ud83d\udd76', 1476 'dart':'\ud83c\udfaf', 1477 'dash':'\ud83d\udca8', 1478 'date':'\ud83d\udcc5', 1479 'deciduous_tree':'\ud83c\udf33', 1480 'deer':'\ud83e\udd8c', 1481 'department_store':'\ud83c\udfec', 1482 'derelict_house':'\ud83c\udfda', 1483 'desert':'\ud83c\udfdc', 1484 'desert_island':'\ud83c\udfdd', 1485 'desktop_computer':'\ud83d\udda5', 1486 'male_detective':'\ud83d\udd75\ufe0f', 1487 'diamond_shape_with_a_dot_inside':'\ud83d\udca0', 1488 'diamonds':'\u2666\ufe0f', 1489 'disappointed':'\ud83d\ude1e', 1490 'disappointed_relieved':'\ud83d\ude25', 1491 'dizzy':'\ud83d\udcab', 1492 'dizzy_face':'\ud83d\ude35', 1493 'do_not_litter':'\ud83d\udeaf', 1494 'dog':'\ud83d\udc36', 1495 'dog2':'\ud83d\udc15', 1496 'dollar':'\ud83d\udcb5', 1497 'dolls':'\ud83c\udf8e', 1498 'dolphin':'\ud83d\udc2c', 1499 'door':'\ud83d\udeaa', 1500 'doughnut':'\ud83c\udf69', 1501 'dove':'\ud83d\udd4a', 1502 'dragon':'\ud83d\udc09', 1503 'dragon_face':'\ud83d\udc32', 1504 'dress':'\ud83d\udc57', 1505 'dromedary_camel':'\ud83d\udc2a', 1506 'drooling_face':'\ud83e\udd24', 1507 'droplet':'\ud83d\udca7', 1508 'drum':'\ud83e\udd41', 1509 'duck':'\ud83e\udd86', 1510 'dvd':'\ud83d\udcc0', 1511 'e-mail':'\ud83d\udce7', 1512 'eagle':'\ud83e\udd85', 1513 'ear':'\ud83d\udc42', 1514 'ear_of_rice':'\ud83c\udf3e', 1515 'earth_africa':'\ud83c\udf0d', 1516 'earth_americas':'\ud83c\udf0e', 1517 'earth_asia':'\ud83c\udf0f', 1518 'egg':'\ud83e\udd5a', 1519 'eggplant':'\ud83c\udf46', 1520 'eight_pointed_black_star':'\u2734\ufe0f', 1521 'eight_spoked_asterisk':'\u2733\ufe0f', 1522 'electric_plug':'\ud83d\udd0c', 1523 'elephant':'\ud83d\udc18', 1524 'email':'\u2709\ufe0f', 1525 'end':'\ud83d\udd1a', 1526 'envelope_with_arrow':'\ud83d\udce9', 1527 'euro':'\ud83d\udcb6', 1528 'european_castle':'\ud83c\udff0', 1529 'european_post_office':'\ud83c\udfe4', 1530 'evergreen_tree':'\ud83c\udf32', 1531 'exclamation':'\u2757\ufe0f', 1532 'expressionless':'\ud83d\ude11', 1533 'eye':'\ud83d\udc41', 1534 'eye_speech_bubble':'\ud83d\udc41‍\ud83d\udde8', 1535 'eyeglasses':'\ud83d\udc53', 1536 'eyes':'\ud83d\udc40', 1537 'face_with_head_bandage':'\ud83e\udd15', 1538 'face_with_thermometer':'\ud83e\udd12', 1539 'fist_oncoming':'\ud83d\udc4a', 1540 'factory':'\ud83c\udfed', 1541 'fallen_leaf':'\ud83c\udf42', 1542 'family_man_woman_boy':'\ud83d\udc6a', 1543 'family_man_boy':'\ud83d\udc68‍\ud83d\udc66', 1544 'family_man_boy_boy':'\ud83d\udc68‍\ud83d\udc66‍\ud83d\udc66', 1545 'family_man_girl':'\ud83d\udc68‍\ud83d\udc67', 1546 'family_man_girl_boy':'\ud83d\udc68‍\ud83d\udc67‍\ud83d\udc66', 1547 'family_man_girl_girl':'\ud83d\udc68‍\ud83d\udc67‍\ud83d\udc67', 1548 'family_man_man_boy':'\ud83d\udc68‍\ud83d\udc68‍\ud83d\udc66', 1549 'family_man_man_boy_boy':'\ud83d\udc68‍\ud83d\udc68‍\ud83d\udc66‍\ud83d\udc66', 1550 'family_man_man_girl':'\ud83d\udc68‍\ud83d\udc68‍\ud83d\udc67', 1551 'family_man_man_girl_boy':'\ud83d\udc68‍\ud83d\udc68‍\ud83d\udc67‍\ud83d\udc66', 1552 'family_man_man_girl_girl':'\ud83d\udc68‍\ud83d\udc68‍\ud83d\udc67‍\ud83d\udc67', 1553 'family_man_woman_boy_boy':'\ud83d\udc68‍\ud83d\udc69‍\ud83d\udc66‍\ud83d\udc66', 1554 'family_man_woman_girl':'\ud83d\udc68‍\ud83d\udc69‍\ud83d\udc67', 1555 'family_man_woman_girl_boy':'\ud83d\udc68‍\ud83d\udc69‍\ud83d\udc67‍\ud83d\udc66', 1556 'family_man_woman_girl_girl':'\ud83d\udc68‍\ud83d\udc69‍\ud83d\udc67‍\ud83d\udc67', 1557 'family_woman_boy':'\ud83d\udc69‍\ud83d\udc66', 1558 'family_woman_boy_boy':'\ud83d\udc69‍\ud83d\udc66‍\ud83d\udc66', 1559 'family_woman_girl':'\ud83d\udc69‍\ud83d\udc67', 1560 'family_woman_girl_boy':'\ud83d\udc69‍\ud83d\udc67‍\ud83d\udc66', 1561 'family_woman_girl_girl':'\ud83d\udc69‍\ud83d\udc67‍\ud83d\udc67', 1562 'family_woman_woman_boy':'\ud83d\udc69‍\ud83d\udc69‍\ud83d\udc66', 1563 'family_woman_woman_boy_boy':'\ud83d\udc69‍\ud83d\udc69‍\ud83d\udc66‍\ud83d\udc66', 1564 'family_woman_woman_girl':'\ud83d\udc69‍\ud83d\udc69‍\ud83d\udc67', 1565 'family_woman_woman_girl_boy':'\ud83d\udc69‍\ud83d\udc69‍\ud83d\udc67‍\ud83d\udc66', 1566 'family_woman_woman_girl_girl':'\ud83d\udc69‍\ud83d\udc69‍\ud83d\udc67‍\ud83d\udc67', 1567 'fast_forward':'\u23e9', 1568 'fax':'\ud83d\udce0', 1569 'fearful':'\ud83d\ude28', 1570 'feet':'\ud83d\udc3e', 1571 'female_detective':'\ud83d\udd75\ufe0f‍\u2640\ufe0f', 1572 'ferris_wheel':'\ud83c\udfa1', 1573 'ferry':'\u26f4', 1574 'field_hockey':'\ud83c\udfd1', 1575 'file_cabinet':'\ud83d\uddc4', 1576 'file_folder':'\ud83d\udcc1', 1577 'film_projector':'\ud83d\udcfd', 1578 'film_strip':'\ud83c\udf9e', 1579 'fire':'\ud83d\udd25', 1580 'fire_engine':'\ud83d\ude92', 1581 'fireworks':'\ud83c\udf86', 1582 'first_quarter_moon':'\ud83c\udf13', 1583 'first_quarter_moon_with_face':'\ud83c\udf1b', 1584 'fish':'\ud83d\udc1f', 1585 'fish_cake':'\ud83c\udf65', 1586 'fishing_pole_and_fish':'\ud83c\udfa3', 1587 'fist_raised':'\u270a', 1588 'fist_left':'\ud83e\udd1b', 1589 'fist_right':'\ud83e\udd1c', 1590 'flags':'\ud83c\udf8f', 1591 'flashlight':'\ud83d\udd26', 1592 'fleur_de_lis':'\u269c\ufe0f', 1593 'flight_arrival':'\ud83d\udeec', 1594 'flight_departure':'\ud83d\udeeb', 1595 'floppy_disk':'\ud83d\udcbe', 1596 'flower_playing_cards':'\ud83c\udfb4', 1597 'flushed':'\ud83d\ude33', 1598 'fog':'\ud83c\udf2b', 1599 'foggy':'\ud83c\udf01', 1600 'football':'\ud83c\udfc8', 1601 'footprints':'\ud83d\udc63', 1602 'fork_and_knife':'\ud83c\udf74', 1603 'fountain':'\u26f2\ufe0f', 1604 'fountain_pen':'\ud83d\udd8b', 1605 'four_leaf_clover':'\ud83c\udf40', 1606 'fox_face':'\ud83e\udd8a', 1607 'framed_picture':'\ud83d\uddbc', 1608 'free':'\ud83c\udd93', 1609 'fried_egg':'\ud83c\udf73', 1610 'fried_shrimp':'\ud83c\udf64', 1611 'fries':'\ud83c\udf5f', 1612 'frog':'\ud83d\udc38', 1613 'frowning':'\ud83d\ude26', 1614 'frowning_face':'\u2639\ufe0f', 1615 'frowning_man':'\ud83d\ude4d‍\u2642\ufe0f', 1616 'frowning_woman':'\ud83d\ude4d', 1617 'middle_finger':'\ud83d\udd95', 1618 'fuelpump':'\u26fd\ufe0f', 1619 'full_moon':'\ud83c\udf15', 1620 'full_moon_with_face':'\ud83c\udf1d', 1621 'funeral_urn':'\u26b1\ufe0f', 1622 'game_die':'\ud83c\udfb2', 1623 'gear':'\u2699\ufe0f', 1624 'gem':'\ud83d\udc8e', 1625 'gemini':'\u264a\ufe0f', 1626 'ghost':'\ud83d\udc7b', 1627 'gift':'\ud83c\udf81', 1628 'gift_heart':'\ud83d\udc9d', 1629 'girl':'\ud83d\udc67', 1630 'globe_with_meridians':'\ud83c\udf10', 1631 'goal_net':'\ud83e\udd45', 1632 'goat':'\ud83d\udc10', 1633 'golf':'\u26f3\ufe0f', 1634 'golfing_man':'\ud83c\udfcc\ufe0f', 1635 'golfing_woman':'\ud83c\udfcc\ufe0f‍\u2640\ufe0f', 1636 'gorilla':'\ud83e\udd8d', 1637 'grapes':'\ud83c\udf47', 1638 'green_apple':'\ud83c\udf4f', 1639 'green_book':'\ud83d\udcd7', 1640 'green_heart':'\ud83d\udc9a', 1641 'green_salad':'\ud83e\udd57', 1642 'grey_exclamation':'\u2755', 1643 'grey_question':'\u2754', 1644 'grimacing':'\ud83d\ude2c', 1645 'grin':'\ud83d\ude01', 1646 'grinning':'\ud83d\ude00', 1647 'guardsman':'\ud83d\udc82', 1648 'guardswoman':'\ud83d\udc82‍\u2640\ufe0f', 1649 'guitar':'\ud83c\udfb8', 1650 'gun':'\ud83d\udd2b', 1651 'haircut_woman':'\ud83d\udc87', 1652 'haircut_man':'\ud83d\udc87‍\u2642\ufe0f', 1653 'hamburger':'\ud83c\udf54', 1654 'hammer':'\ud83d\udd28', 1655 'hammer_and_pick':'\u2692', 1656 'hammer_and_wrench':'\ud83d\udee0', 1657 'hamster':'\ud83d\udc39', 1658 'hand':'\u270b', 1659 'handbag':'\ud83d\udc5c', 1660 'handshake':'\ud83e\udd1d', 1661 'hankey':'\ud83d\udca9', 1662 'hatched_chick':'\ud83d\udc25', 1663 'hatching_chick':'\ud83d\udc23', 1664 'headphones':'\ud83c\udfa7', 1665 'hear_no_evil':'\ud83d\ude49', 1666 'heart':'\u2764\ufe0f', 1667 'heart_decoration':'\ud83d\udc9f', 1668 'heart_eyes':'\ud83d\ude0d', 1669 'heart_eyes_cat':'\ud83d\ude3b', 1670 'heartbeat':'\ud83d\udc93', 1671 'heartpulse':'\ud83d\udc97', 1672 'hearts':'\u2665\ufe0f', 1673 'heavy_check_mark':'\u2714\ufe0f', 1674 'heavy_division_sign':'\u2797', 1675 'heavy_dollar_sign':'\ud83d\udcb2', 1676 'heavy_heart_exclamation':'\u2763\ufe0f', 1677 'heavy_minus_sign':'\u2796', 1678 'heavy_multiplication_x':'\u2716\ufe0f', 1679 'heavy_plus_sign':'\u2795', 1680 'helicopter':'\ud83d\ude81', 1681 'herb':'\ud83c\udf3f', 1682 'hibiscus':'\ud83c\udf3a', 1683 'high_brightness':'\ud83d\udd06', 1684 'high_heel':'\ud83d\udc60', 1685 'hocho':'\ud83d\udd2a', 1686 'hole':'\ud83d\udd73', 1687 'honey_pot':'\ud83c\udf6f', 1688 'horse':'\ud83d\udc34', 1689 'horse_racing':'\ud83c\udfc7', 1690 'hospital':'\ud83c\udfe5', 1691 'hot_pepper':'\ud83c\udf36', 1692 'hotdog':'\ud83c\udf2d', 1693 'hotel':'\ud83c\udfe8', 1694 'hotsprings':'\u2668\ufe0f', 1695 'hourglass':'\u231b\ufe0f', 1696 'hourglass_flowing_sand':'\u23f3', 1697 'house':'\ud83c\udfe0', 1698 'house_with_garden':'\ud83c\udfe1', 1699 'houses':'\ud83c\udfd8', 1700 'hugs':'\ud83e\udd17', 1701 'hushed':'\ud83d\ude2f', 1702 'ice_cream':'\ud83c\udf68', 1703 'ice_hockey':'\ud83c\udfd2', 1704 'ice_skate':'\u26f8', 1705 'icecream':'\ud83c\udf66', 1706 'id':'\ud83c\udd94', 1707 'ideograph_advantage':'\ud83c\ude50', 1708 'imp':'\ud83d\udc7f', 1709 'inbox_tray':'\ud83d\udce5', 1710 'incoming_envelope':'\ud83d\udce8', 1711 'tipping_hand_woman':'\ud83d\udc81', 1712 'information_source':'\u2139\ufe0f', 1713 'innocent':'\ud83d\ude07', 1714 'interrobang':'\u2049\ufe0f', 1715 'iphone':'\ud83d\udcf1', 1716 'izakaya_lantern':'\ud83c\udfee', 1717 'jack_o_lantern':'\ud83c\udf83', 1718 'japan':'\ud83d\uddfe', 1719 'japanese_castle':'\ud83c\udfef', 1720 'japanese_goblin':'\ud83d\udc7a', 1721 'japanese_ogre':'\ud83d\udc79', 1722 'jeans':'\ud83d\udc56', 1723 'joy':'\ud83d\ude02', 1724 'joy_cat':'\ud83d\ude39', 1725 'joystick':'\ud83d\udd79', 1726 'kaaba':'\ud83d\udd4b', 1727 'key':'\ud83d\udd11', 1728 'keyboard':'\u2328\ufe0f', 1729 'keycap_ten':'\ud83d\udd1f', 1730 'kick_scooter':'\ud83d\udef4', 1731 'kimono':'\ud83d\udc58', 1732 'kiss':'\ud83d\udc8b', 1733 'kissing':'\ud83d\ude17', 1734 'kissing_cat':'\ud83d\ude3d', 1735 'kissing_closed_eyes':'\ud83d\ude1a', 1736 'kissing_heart':'\ud83d\ude18', 1737 'kissing_smiling_eyes':'\ud83d\ude19', 1738 'kiwi_fruit':'\ud83e\udd5d', 1739 'koala':'\ud83d\udc28', 1740 'koko':'\ud83c\ude01', 1741 'label':'\ud83c\udff7', 1742 'large_blue_circle':'\ud83d\udd35', 1743 'large_blue_diamond':'\ud83d\udd37', 1744 'large_orange_diamond':'\ud83d\udd36', 1745 'last_quarter_moon':'\ud83c\udf17', 1746 'last_quarter_moon_with_face':'\ud83c\udf1c', 1747 'latin_cross':'\u271d\ufe0f', 1748 'laughing':'\ud83d\ude06', 1749 'leaves':'\ud83c\udf43', 1750 'ledger':'\ud83d\udcd2', 1751 'left_luggage':'\ud83d\udec5', 1752 'left_right_arrow':'\u2194\ufe0f', 1753 'leftwards_arrow_with_hook':'\u21a9\ufe0f', 1754 'lemon':'\ud83c\udf4b', 1755 'leo':'\u264c\ufe0f', 1756 'leopard':'\ud83d\udc06', 1757 'level_slider':'\ud83c\udf9a', 1758 'libra':'\u264e\ufe0f', 1759 'light_rail':'\ud83d\ude88', 1760 'link':'\ud83d\udd17', 1761 'lion':'\ud83e\udd81', 1762 'lips':'\ud83d\udc44', 1763 'lipstick':'\ud83d\udc84', 1764 'lizard':'\ud83e\udd8e', 1765 'lock':'\ud83d\udd12', 1766 'lock_with_ink_pen':'\ud83d\udd0f', 1767 'lollipop':'\ud83c\udf6d', 1768 'loop':'\u27bf', 1769 'loud_sound':'\ud83d\udd0a', 1770 'loudspeaker':'\ud83d\udce2', 1771 'love_hotel':'\ud83c\udfe9', 1772 'love_letter':'\ud83d\udc8c', 1773 'low_brightness':'\ud83d\udd05', 1774 'lying_face':'\ud83e\udd25', 1775 'm':'\u24c2\ufe0f', 1776 'mag':'\ud83d\udd0d', 1777 'mag_right':'\ud83d\udd0e', 1778 'mahjong':'\ud83c\udc04\ufe0f', 1779 'mailbox':'\ud83d\udceb', 1780 'mailbox_closed':'\ud83d\udcea', 1781 'mailbox_with_mail':'\ud83d\udcec', 1782 'mailbox_with_no_mail':'\ud83d\udced', 1783 'man':'\ud83d\udc68', 1784 'man_artist':'\ud83d\udc68‍\ud83c\udfa8', 1785 'man_astronaut':'\ud83d\udc68‍\ud83d\ude80', 1786 'man_cartwheeling':'\ud83e\udd38‍\u2642\ufe0f', 1787 'man_cook':'\ud83d\udc68‍\ud83c\udf73', 1788 'man_dancing':'\ud83d\udd7a', 1789 'man_facepalming':'\ud83e\udd26‍\u2642\ufe0f', 1790 'man_factory_worker':'\ud83d\udc68‍\ud83c\udfed', 1791 'man_farmer':'\ud83d\udc68‍\ud83c\udf3e', 1792 'man_firefighter':'\ud83d\udc68‍\ud83d\ude92', 1793 'man_health_worker':'\ud83d\udc68‍\u2695\ufe0f', 1794 'man_in_tuxedo':'\ud83e\udd35', 1795 'man_judge':'\ud83d\udc68‍\u2696\ufe0f', 1796 'man_juggling':'\ud83e\udd39‍\u2642\ufe0f', 1797 'man_mechanic':'\ud83d\udc68‍\ud83d\udd27', 1798 'man_office_worker':'\ud83d\udc68‍\ud83d\udcbc', 1799 'man_pilot':'\ud83d\udc68‍\u2708\ufe0f', 1800 'man_playing_handball':'\ud83e\udd3e‍\u2642\ufe0f', 1801 'man_playing_water_polo':'\ud83e\udd3d‍\u2642\ufe0f', 1802 'man_scientist':'\ud83d\udc68‍\ud83d\udd2c', 1803 'man_shrugging':'\ud83e\udd37‍\u2642\ufe0f', 1804 'man_singer':'\ud83d\udc68‍\ud83c\udfa4', 1805 'man_student':'\ud83d\udc68‍\ud83c\udf93', 1806 'man_teacher':'\ud83d\udc68‍\ud83c\udfeb', 1807 'man_technologist':'\ud83d\udc68‍\ud83d\udcbb', 1808 'man_with_gua_pi_mao':'\ud83d\udc72', 1809 'man_with_turban':'\ud83d\udc73', 1810 'tangerine':'\ud83c\udf4a', 1811 'mans_shoe':'\ud83d\udc5e', 1812 'mantelpiece_clock':'\ud83d\udd70', 1813 'maple_leaf':'\ud83c\udf41', 1814 'martial_arts_uniform':'\ud83e\udd4b', 1815 'mask':'\ud83d\ude37', 1816 'massage_woman':'\ud83d\udc86', 1817 'massage_man':'\ud83d\udc86‍\u2642\ufe0f', 1818 'meat_on_bone':'\ud83c\udf56', 1819 'medal_military':'\ud83c\udf96', 1820 'medal_sports':'\ud83c\udfc5', 1821 'mega':'\ud83d\udce3', 1822 'melon':'\ud83c\udf48', 1823 'memo':'\ud83d\udcdd', 1824 'men_wrestling':'\ud83e\udd3c‍\u2642\ufe0f', 1825 'menorah':'\ud83d\udd4e', 1826 'mens':'\ud83d\udeb9', 1827 'metal':'\ud83e\udd18', 1828 'metro':'\ud83d\ude87', 1829 'microphone':'\ud83c\udfa4', 1830 'microscope':'\ud83d\udd2c', 1831 'milk_glass':'\ud83e\udd5b', 1832 'milky_way':'\ud83c\udf0c', 1833 'minibus':'\ud83d\ude90', 1834 'minidisc':'\ud83d\udcbd', 1835 'mobile_phone_off':'\ud83d\udcf4', 1836 'money_mouth_face':'\ud83e\udd11', 1837 'money_with_wings':'\ud83d\udcb8', 1838 'moneybag':'\ud83d\udcb0', 1839 'monkey':'\ud83d\udc12', 1840 'monkey_face':'\ud83d\udc35', 1841 'monorail':'\ud83d\ude9d', 1842 'moon':'\ud83c\udf14', 1843 'mortar_board':'\ud83c\udf93', 1844 'mosque':'\ud83d\udd4c', 1845 'motor_boat':'\ud83d\udee5', 1846 'motor_scooter':'\ud83d\udef5', 1847 'motorcycle':'\ud83c\udfcd', 1848 'motorway':'\ud83d\udee3', 1849 'mount_fuji':'\ud83d\uddfb', 1850 'mountain':'\u26f0', 1851 'mountain_biking_man':'\ud83d\udeb5', 1852 'mountain_biking_woman':'\ud83d\udeb5‍\u2640\ufe0f', 1853 'mountain_cableway':'\ud83d\udea0', 1854 'mountain_railway':'\ud83d\ude9e', 1855 'mountain_snow':'\ud83c\udfd4', 1856 'mouse':'\ud83d\udc2d', 1857 'mouse2':'\ud83d\udc01', 1858 'movie_camera':'\ud83c\udfa5', 1859 'moyai':'\ud83d\uddff', 1860 'mrs_claus':'\ud83e\udd36', 1861 'muscle':'\ud83d\udcaa', 1862 'mushroom':'\ud83c\udf44', 1863 'musical_keyboard':'\ud83c\udfb9', 1864 'musical_note':'\ud83c\udfb5', 1865 'musical_score':'\ud83c\udfbc', 1866 'mute':'\ud83d\udd07', 1867 'nail_care':'\ud83d\udc85', 1868 'name_badge':'\ud83d\udcdb', 1869 'national_park':'\ud83c\udfde', 1870 'nauseated_face':'\ud83e\udd22', 1871 'necktie':'\ud83d\udc54', 1872 'negative_squared_cross_mark':'\u274e', 1873 'nerd_face':'\ud83e\udd13', 1874 'neutral_face':'\ud83d\ude10', 1875 'new':'\ud83c\udd95', 1876 'new_moon':'\ud83c\udf11', 1877 'new_moon_with_face':'\ud83c\udf1a', 1878 'newspaper':'\ud83d\udcf0', 1879 'newspaper_roll':'\ud83d\uddde', 1880 'next_track_button':'\u23ed', 1881 'ng':'\ud83c\udd96', 1882 'no_good_man':'\ud83d\ude45‍\u2642\ufe0f', 1883 'no_good_woman':'\ud83d\ude45', 1884 'night_with_stars':'\ud83c\udf03', 1885 'no_bell':'\ud83d\udd15', 1886 'no_bicycles':'\ud83d\udeb3', 1887 'no_entry':'\u26d4\ufe0f', 1888 'no_entry_sign':'\ud83d\udeab', 1889 'no_mobile_phones':'\ud83d\udcf5', 1890 'no_mouth':'\ud83d\ude36', 1891 'no_pedestrians':'\ud83d\udeb7', 1892 'no_smoking':'\ud83d\udead', 1893 'non-potable_water':'\ud83d\udeb1', 1894 'nose':'\ud83d\udc43', 1895 'notebook':'\ud83d\udcd3', 1896 'notebook_with_decorative_cover':'\ud83d\udcd4', 1897 'notes':'\ud83c\udfb6', 1898 'nut_and_bolt':'\ud83d\udd29', 1899 'o':'\u2b55\ufe0f', 1900 'o2':'\ud83c\udd7e\ufe0f', 1901 'ocean':'\ud83c\udf0a', 1902 'octopus':'\ud83d\udc19', 1903 'oden':'\ud83c\udf62', 1904 'office':'\ud83c\udfe2', 1905 'oil_drum':'\ud83d\udee2', 1906 'ok':'\ud83c\udd97', 1907 'ok_hand':'\ud83d\udc4c', 1908 'ok_man':'\ud83d\ude46‍\u2642\ufe0f', 1909 'ok_woman':'\ud83d\ude46', 1910 'old_key':'\ud83d\udddd', 1911 'older_man':'\ud83d\udc74', 1912 'older_woman':'\ud83d\udc75', 1913 'om':'\ud83d\udd49', 1914 'on':'\ud83d\udd1b', 1915 'oncoming_automobile':'\ud83d\ude98', 1916 'oncoming_bus':'\ud83d\ude8d', 1917 'oncoming_police_car':'\ud83d\ude94', 1918 'oncoming_taxi':'\ud83d\ude96', 1919 'open_file_folder':'\ud83d\udcc2', 1920 'open_hands':'\ud83d\udc50', 1921 'open_mouth':'\ud83d\ude2e', 1922 'open_umbrella':'\u2602\ufe0f', 1923 'ophiuchus':'\u26ce', 1924 'orange_book':'\ud83d\udcd9', 1925 'orthodox_cross':'\u2626\ufe0f', 1926 'outbox_tray':'\ud83d\udce4', 1927 'owl':'\ud83e\udd89', 1928 'ox':'\ud83d\udc02', 1929 'package':'\ud83d\udce6', 1930 'page_facing_up':'\ud83d\udcc4', 1931 'page_with_curl':'\ud83d\udcc3', 1932 'pager':'\ud83d\udcdf', 1933 'paintbrush':'\ud83d\udd8c', 1934 'palm_tree':'\ud83c\udf34', 1935 'pancakes':'\ud83e\udd5e', 1936 'panda_face':'\ud83d\udc3c', 1937 'paperclip':'\ud83d\udcce', 1938 'paperclips':'\ud83d\udd87', 1939 'parasol_on_ground':'\u26f1', 1940 'parking':'\ud83c\udd7f\ufe0f', 1941 'part_alternation_mark':'\u303d\ufe0f', 1942 'partly_sunny':'\u26c5\ufe0f', 1943 'passenger_ship':'\ud83d\udef3', 1944 'passport_control':'\ud83d\udec2', 1945 'pause_button':'\u23f8', 1946 'peace_symbol':'\u262e\ufe0f', 1947 'peach':'\ud83c\udf51', 1948 'peanuts':'\ud83e\udd5c', 1949 'pear':'\ud83c\udf50', 1950 'pen':'\ud83d\udd8a', 1951 'pencil2':'\u270f\ufe0f', 1952 'penguin':'\ud83d\udc27', 1953 'pensive':'\ud83d\ude14', 1954 'performing_arts':'\ud83c\udfad', 1955 'persevere':'\ud83d\ude23', 1956 'person_fencing':'\ud83e\udd3a', 1957 'pouting_woman':'\ud83d\ude4e', 1958 'phone':'\u260e\ufe0f', 1959 'pick':'\u26cf', 1960 'pig':'\ud83d\udc37', 1961 'pig2':'\ud83d\udc16', 1962 'pig_nose':'\ud83d\udc3d', 1963 'pill':'\ud83d\udc8a', 1964 'pineapple':'\ud83c\udf4d', 1965 'ping_pong':'\ud83c\udfd3', 1966 'pisces':'\u2653\ufe0f', 1967 'pizza':'\ud83c\udf55', 1968 'place_of_worship':'\ud83d\uded0', 1969 'plate_with_cutlery':'\ud83c\udf7d', 1970 'play_or_pause_button':'\u23ef', 1971 'point_down':'\ud83d\udc47', 1972 'point_left':'\ud83d\udc48', 1973 'point_right':'\ud83d\udc49', 1974 'point_up':'\u261d\ufe0f', 1975 'point_up_2':'\ud83d\udc46', 1976 'police_car':'\ud83d\ude93', 1977 'policewoman':'\ud83d\udc6e‍\u2640\ufe0f', 1978 'poodle':'\ud83d\udc29', 1979 'popcorn':'\ud83c\udf7f', 1980 'post_office':'\ud83c\udfe3', 1981 'postal_horn':'\ud83d\udcef', 1982 'postbox':'\ud83d\udcee', 1983 'potable_water':'\ud83d\udeb0', 1984 'potato':'\ud83e\udd54', 1985 'pouch':'\ud83d\udc5d', 1986 'poultry_leg':'\ud83c\udf57', 1987 'pound':'\ud83d\udcb7', 1988 'rage':'\ud83d\ude21', 1989 'pouting_cat':'\ud83d\ude3e', 1990 'pouting_man':'\ud83d\ude4e‍\u2642\ufe0f', 1991 'pray':'\ud83d\ude4f', 1992 'prayer_beads':'\ud83d\udcff', 1993 'pregnant_woman':'\ud83e\udd30', 1994 'previous_track_button':'\u23ee', 1995 'prince':'\ud83e\udd34', 1996 'princess':'\ud83d\udc78', 1997 'printer':'\ud83d\udda8', 1998 'purple_heart':'\ud83d\udc9c', 1999 'purse':'\ud83d\udc5b', 2000 'pushpin':'\ud83d\udccc', 2001 'put_litter_in_its_place':'\ud83d\udeae', 2002 'question':'\u2753', 2003 'rabbit':'\ud83d\udc30', 2004 'rabbit2':'\ud83d\udc07', 2005 'racehorse':'\ud83d\udc0e', 2006 'racing_car':'\ud83c\udfce', 2007 'radio':'\ud83d\udcfb', 2008 'radio_button':'\ud83d\udd18', 2009 'radioactive':'\u2622\ufe0f', 2010 'railway_car':'\ud83d\ude83', 2011 'railway_track':'\ud83d\udee4', 2012 'rainbow':'\ud83c\udf08', 2013 'rainbow_flag':'\ud83c\udff3\ufe0f‍\ud83c\udf08', 2014 'raised_back_of_hand':'\ud83e\udd1a', 2015 'raised_hand_with_fingers_splayed':'\ud83d\udd90', 2016 'raised_hands':'\ud83d\ude4c', 2017 'raising_hand_woman':'\ud83d\ude4b', 2018 'raising_hand_man':'\ud83d\ude4b‍\u2642\ufe0f', 2019 'ram':'\ud83d\udc0f', 2020 'ramen':'\ud83c\udf5c', 2021 'rat':'\ud83d\udc00', 2022 'record_button':'\u23fa', 2023 'recycle':'\u267b\ufe0f', 2024 'red_circle':'\ud83d\udd34', 2025 'registered':'\u00ae\ufe0f', 2026 'relaxed':'\u263a\ufe0f', 2027 'relieved':'\ud83d\ude0c', 2028 'reminder_ribbon':'\ud83c\udf97', 2029 'repeat':'\ud83d\udd01', 2030 'repeat_one':'\ud83d\udd02', 2031 'rescue_worker_helmet':'\u26d1', 2032 'restroom':'\ud83d\udebb', 2033 'revolving_hearts':'\ud83d\udc9e', 2034 'rewind':'\u23ea', 2035 'rhinoceros':'\ud83e\udd8f', 2036 'ribbon':'\ud83c\udf80', 2037 'rice':'\ud83c\udf5a', 2038 'rice_ball':'\ud83c\udf59', 2039 'rice_cracker':'\ud83c\udf58', 2040 'rice_scene':'\ud83c\udf91', 2041 'right_anger_bubble':'\ud83d\uddef', 2042 'ring':'\ud83d\udc8d', 2043 'robot':'\ud83e\udd16', 2044 'rocket':'\ud83d\ude80', 2045 'rofl':'\ud83e\udd23', 2046 'roll_eyes':'\ud83d\ude44', 2047 'roller_coaster':'\ud83c\udfa2', 2048 'rooster':'\ud83d\udc13', 2049 'rose':'\ud83c\udf39', 2050 'rosette':'\ud83c\udff5', 2051 'rotating_light':'\ud83d\udea8', 2052 'round_pushpin':'\ud83d\udccd', 2053 'rowing_man':'\ud83d\udea3', 2054 'rowing_woman':'\ud83d\udea3‍\u2640\ufe0f', 2055 'rugby_football':'\ud83c\udfc9', 2056 'running_man':'\ud83c\udfc3', 2057 'running_shirt_with_sash':'\ud83c\udfbd', 2058 'running_woman':'\ud83c\udfc3‍\u2640\ufe0f', 2059 'sa':'\ud83c\ude02\ufe0f', 2060 'sagittarius':'\u2650\ufe0f', 2061 'sake':'\ud83c\udf76', 2062 'sandal':'\ud83d\udc61', 2063 'santa':'\ud83c\udf85', 2064 'satellite':'\ud83d\udce1', 2065 'saxophone':'\ud83c\udfb7', 2066 'school':'\ud83c\udfeb', 2067 'school_satchel':'\ud83c\udf92', 2068 'scissors':'\u2702\ufe0f', 2069 'scorpion':'\ud83e\udd82', 2070 'scorpius':'\u264f\ufe0f', 2071 'scream':'\ud83d\ude31', 2072 'scream_cat':'\ud83d\ude40', 2073 'scroll':'\ud83d\udcdc', 2074 'seat':'\ud83d\udcba', 2075 'secret':'\u3299\ufe0f', 2076 'see_no_evil':'\ud83d\ude48', 2077 'seedling':'\ud83c\udf31', 2078 'selfie':'\ud83e\udd33', 2079 'shallow_pan_of_food':'\ud83e\udd58', 2080 'shamrock':'\u2618\ufe0f', 2081 'shark':'\ud83e\udd88', 2082 'shaved_ice':'\ud83c\udf67', 2083 'sheep':'\ud83d\udc11', 2084 'shell':'\ud83d\udc1a', 2085 'shield':'\ud83d\udee1', 2086 'shinto_shrine':'\u26e9', 2087 'ship':'\ud83d\udea2', 2088 'shirt':'\ud83d\udc55', 2089 'shopping':'\ud83d\udecd', 2090 'shopping_cart':'\ud83d\uded2', 2091 'shower':'\ud83d\udebf', 2092 'shrimp':'\ud83e\udd90', 2093 'signal_strength':'\ud83d\udcf6', 2094 'six_pointed_star':'\ud83d\udd2f', 2095 'ski':'\ud83c\udfbf', 2096 'skier':'\u26f7', 2097 'skull':'\ud83d\udc80', 2098 'skull_and_crossbones':'\u2620\ufe0f', 2099 'sleeping':'\ud83d\ude34', 2100 'sleeping_bed':'\ud83d\udecc', 2101 'sleepy':'\ud83d\ude2a', 2102 'slightly_frowning_face':'\ud83d\ude41', 2103 'slightly_smiling_face':'\ud83d\ude42', 2104 'slot_machine':'\ud83c\udfb0', 2105 'small_airplane':'\ud83d\udee9', 2106 'small_blue_diamond':'\ud83d\udd39', 2107 'small_orange_diamond':'\ud83d\udd38', 2108 'small_red_triangle':'\ud83d\udd3a', 2109 'small_red_triangle_down':'\ud83d\udd3b', 2110 'smile':'\ud83d\ude04', 2111 'smile_cat':'\ud83d\ude38', 2112 'smiley':'\ud83d\ude03', 2113 'smiley_cat':'\ud83d\ude3a', 2114 'smiling_imp':'\ud83d\ude08', 2115 'smirk':'\ud83d\ude0f', 2116 'smirk_cat':'\ud83d\ude3c', 2117 'smoking':'\ud83d\udeac', 2118 'snail':'\ud83d\udc0c', 2119 'snake':'\ud83d\udc0d', 2120 'sneezing_face':'\ud83e\udd27', 2121 'snowboarder':'\ud83c\udfc2', 2122 'snowflake':'\u2744\ufe0f', 2123 'snowman':'\u26c4\ufe0f', 2124 'snowman_with_snow':'\u2603\ufe0f', 2125 'sob':'\ud83d\ude2d', 2126 'soccer':'\u26bd\ufe0f', 2127 'soon':'\ud83d\udd1c', 2128 'sos':'\ud83c\udd98', 2129 'sound':'\ud83d\udd09', 2130 'space_invader':'\ud83d\udc7e', 2131 'spades':'\u2660\ufe0f', 2132 'spaghetti':'\ud83c\udf5d', 2133 'sparkle':'\u2747\ufe0f', 2134 'sparkler':'\ud83c\udf87', 2135 'sparkles':'\u2728', 2136 'sparkling_heart':'\ud83d\udc96', 2137 'speak_no_evil':'\ud83d\ude4a', 2138 'speaker':'\ud83d\udd08', 2139 'speaking_head':'\ud83d\udde3', 2140 'speech_balloon':'\ud83d\udcac', 2141 'speedboat':'\ud83d\udea4', 2142 'spider':'\ud83d\udd77', 2143 'spider_web':'\ud83d\udd78', 2144 'spiral_calendar':'\ud83d\uddd3', 2145 'spiral_notepad':'\ud83d\uddd2', 2146 'spoon':'\ud83e\udd44', 2147 'squid':'\ud83e\udd91', 2148 'stadium':'\ud83c\udfdf', 2149 'star':'\u2b50\ufe0f', 2150 'star2':'\ud83c\udf1f', 2151 'star_and_crescent':'\u262a\ufe0f', 2152 'star_of_david':'\u2721\ufe0f', 2153 'stars':'\ud83c\udf20', 2154 'station':'\ud83d\ude89', 2155 'statue_of_liberty':'\ud83d\uddfd', 2156 'steam_locomotive':'\ud83d\ude82', 2157 'stew':'\ud83c\udf72', 2158 'stop_button':'\u23f9', 2159 'stop_sign':'\ud83d\uded1', 2160 'stopwatch':'\u23f1', 2161 'straight_ruler':'\ud83d\udccf', 2162 'strawberry':'\ud83c\udf53', 2163 'stuck_out_tongue':'\ud83d\ude1b', 2164 'stuck_out_tongue_closed_eyes':'\ud83d\ude1d', 2165 'stuck_out_tongue_winking_eye':'\ud83d\ude1c', 2166 'studio_microphone':'\ud83c\udf99', 2167 'stuffed_flatbread':'\ud83e\udd59', 2168 'sun_behind_large_cloud':'\ud83c\udf25', 2169 'sun_behind_rain_cloud':'\ud83c\udf26', 2170 'sun_behind_small_cloud':'\ud83c\udf24', 2171 'sun_with_face':'\ud83c\udf1e', 2172 'sunflower':'\ud83c\udf3b', 2173 'sunglasses':'\ud83d\ude0e', 2174 'sunny':'\u2600\ufe0f', 2175 'sunrise':'\ud83c\udf05', 2176 'sunrise_over_mountains':'\ud83c\udf04', 2177 'surfing_man':'\ud83c\udfc4', 2178 'surfing_woman':'\ud83c\udfc4‍\u2640\ufe0f', 2179 'sushi':'\ud83c\udf63', 2180 'suspension_railway':'\ud83d\ude9f', 2181 'sweat':'\ud83d\ude13', 2182 'sweat_drops':'\ud83d\udca6', 2183 'sweat_smile':'\ud83d\ude05', 2184 'sweet_potato':'\ud83c\udf60', 2185 'swimming_man':'\ud83c\udfca', 2186 'swimming_woman':'\ud83c\udfca‍\u2640\ufe0f', 2187 'symbols':'\ud83d\udd23', 2188 'synagogue':'\ud83d\udd4d', 2189 'syringe':'\ud83d\udc89', 2190 'taco':'\ud83c\udf2e', 2191 'tada':'\ud83c\udf89', 2192 'tanabata_tree':'\ud83c\udf8b', 2193 'taurus':'\u2649\ufe0f', 2194 'taxi':'\ud83d\ude95', 2195 'tea':'\ud83c\udf75', 2196 'telephone_receiver':'\ud83d\udcde', 2197 'telescope':'\ud83d\udd2d', 2198 'tennis':'\ud83c\udfbe', 2199 'tent':'\u26fa\ufe0f', 2200 'thermometer':'\ud83c\udf21', 2201 'thinking':'\ud83e\udd14', 2202 'thought_balloon':'\ud83d\udcad', 2203 'ticket':'\ud83c\udfab', 2204 'tickets':'\ud83c\udf9f', 2205 'tiger':'\ud83d\udc2f', 2206 'tiger2':'\ud83d\udc05', 2207 'timer_clock':'\u23f2', 2208 'tipping_hand_man':'\ud83d\udc81‍\u2642\ufe0f', 2209 'tired_face':'\ud83d\ude2b', 2210 'tm':'\u2122\ufe0f', 2211 'toilet':'\ud83d\udebd', 2212 'tokyo_tower':'\ud83d\uddfc', 2213 'tomato':'\ud83c\udf45', 2214 'tongue':'\ud83d\udc45', 2215 'top':'\ud83d\udd1d', 2216 'tophat':'\ud83c\udfa9', 2217 'tornado':'\ud83c\udf2a', 2218 'trackball':'\ud83d\uddb2', 2219 'tractor':'\ud83d\ude9c', 2220 'traffic_light':'\ud83d\udea5', 2221 'train':'\ud83d\ude8b', 2222 'train2':'\ud83d\ude86', 2223 'tram':'\ud83d\ude8a', 2224 'triangular_flag_on_post':'\ud83d\udea9', 2225 'triangular_ruler':'\ud83d\udcd0', 2226 'trident':'\ud83d\udd31', 2227 'triumph':'\ud83d\ude24', 2228 'trolleybus':'\ud83d\ude8e', 2229 'trophy':'\ud83c\udfc6', 2230 'tropical_drink':'\ud83c\udf79', 2231 'tropical_fish':'\ud83d\udc20', 2232 'truck':'\ud83d\ude9a', 2233 'trumpet':'\ud83c\udfba', 2234 'tulip':'\ud83c\udf37', 2235 'tumbler_glass':'\ud83e\udd43', 2236 'turkey':'\ud83e\udd83', 2237 'turtle':'\ud83d\udc22', 2238 'tv':'\ud83d\udcfa', 2239 'twisted_rightwards_arrows':'\ud83d\udd00', 2240 'two_hearts':'\ud83d\udc95', 2241 'two_men_holding_hands':'\ud83d\udc6c', 2242 'two_women_holding_hands':'\ud83d\udc6d', 2243 'u5272':'\ud83c\ude39', 2244 'u5408':'\ud83c\ude34', 2245 'u55b6':'\ud83c\ude3a', 2246 'u6307':'\ud83c\ude2f\ufe0f', 2247 'u6708':'\ud83c\ude37\ufe0f', 2248 'u6709':'\ud83c\ude36', 2249 'u6e80':'\ud83c\ude35', 2250 'u7121':'\ud83c\ude1a\ufe0f', 2251 'u7533':'\ud83c\ude38', 2252 'u7981':'\ud83c\ude32', 2253 'u7a7a':'\ud83c\ude33', 2254 'umbrella':'\u2614\ufe0f', 2255 'unamused':'\ud83d\ude12', 2256 'underage':'\ud83d\udd1e', 2257 'unicorn':'\ud83e\udd84', 2258 'unlock':'\ud83d\udd13', 2259 'up':'\ud83c\udd99', 2260 'upside_down_face':'\ud83d\ude43', 2261 'v':'\u270c\ufe0f', 2262 'vertical_traffic_light':'\ud83d\udea6', 2263 'vhs':'\ud83d\udcfc', 2264 'vibration_mode':'\ud83d\udcf3', 2265 'video_camera':'\ud83d\udcf9', 2266 'video_game':'\ud83c\udfae', 2267 'violin':'\ud83c\udfbb', 2268 'virgo':'\u264d\ufe0f', 2269 'volcano':'\ud83c\udf0b', 2270 'volleyball':'\ud83c\udfd0', 2271 'vs':'\ud83c\udd9a', 2272 'vulcan_salute':'\ud83d\udd96', 2273 'walking_man':'\ud83d\udeb6', 2274 'walking_woman':'\ud83d\udeb6‍\u2640\ufe0f', 2275 'waning_crescent_moon':'\ud83c\udf18', 2276 'waning_gibbous_moon':'\ud83c\udf16', 2277 'warning':'\u26a0\ufe0f', 2278 'wastebasket':'\ud83d\uddd1', 2279 'watch':'\u231a\ufe0f', 2280 'water_buffalo':'\ud83d\udc03', 2281 'watermelon':'\ud83c\udf49', 2282 'wave':'\ud83d\udc4b', 2283 'wavy_dash':'\u3030\ufe0f', 2284 'waxing_crescent_moon':'\ud83c\udf12', 2285 'wc':'\ud83d\udebe', 2286 'weary':'\ud83d\ude29', 2287 'wedding':'\ud83d\udc92', 2288 'weight_lifting_man':'\ud83c\udfcb\ufe0f', 2289 'weight_lifting_woman':'\ud83c\udfcb\ufe0f‍\u2640\ufe0f', 2290 'whale':'\ud83d\udc33', 2291 'whale2':'\ud83d\udc0b', 2292 'wheel_of_dharma':'\u2638\ufe0f', 2293 'wheelchair':'\u267f\ufe0f', 2294 'white_check_mark':'\u2705', 2295 'white_circle':'\u26aa\ufe0f', 2296 'white_flag':'\ud83c\udff3\ufe0f', 2297 'white_flower':'\ud83d\udcae', 2298 'white_large_square':'\u2b1c\ufe0f', 2299 'white_medium_small_square':'\u25fd\ufe0f', 2300 'white_medium_square':'\u25fb\ufe0f', 2301 'white_small_square':'\u25ab\ufe0f', 2302 'white_square_button':'\ud83d\udd33', 2303 'wilted_flower':'\ud83e\udd40', 2304 'wind_chime':'\ud83c\udf90', 2305 'wind_face':'\ud83c\udf2c', 2306 'wine_glass':'\ud83c\udf77', 2307 'wink':'\ud83d\ude09', 2308 'wolf':'\ud83d\udc3a', 2309 'woman':'\ud83d\udc69', 2310 'woman_artist':'\ud83d\udc69‍\ud83c\udfa8', 2311 'woman_astronaut':'\ud83d\udc69‍\ud83d\ude80', 2312 'woman_cartwheeling':'\ud83e\udd38‍\u2640\ufe0f', 2313 'woman_cook':'\ud83d\udc69‍\ud83c\udf73', 2314 'woman_facepalming':'\ud83e\udd26‍\u2640\ufe0f', 2315 'woman_factory_worker':'\ud83d\udc69‍\ud83c\udfed', 2316 'woman_farmer':'\ud83d\udc69‍\ud83c\udf3e', 2317 'woman_firefighter':'\ud83d\udc69‍\ud83d\ude92', 2318 'woman_health_worker':'\ud83d\udc69‍\u2695\ufe0f', 2319 'woman_judge':'\ud83d\udc69‍\u2696\ufe0f', 2320 'woman_juggling':'\ud83e\udd39‍\u2640\ufe0f', 2321 'woman_mechanic':'\ud83d\udc69‍\ud83d\udd27', 2322 'woman_office_worker':'\ud83d\udc69‍\ud83d\udcbc', 2323 'woman_pilot':'\ud83d\udc69‍\u2708\ufe0f', 2324 'woman_playing_handball':'\ud83e\udd3e‍\u2640\ufe0f', 2325 'woman_playing_water_polo':'\ud83e\udd3d‍\u2640\ufe0f', 2326 'woman_scientist':'\ud83d\udc69‍\ud83d\udd2c', 2327 'woman_shrugging':'\ud83e\udd37‍\u2640\ufe0f', 2328 'woman_singer':'\ud83d\udc69‍\ud83c\udfa4', 2329 'woman_student':'\ud83d\udc69‍\ud83c\udf93', 2330 'woman_teacher':'\ud83d\udc69‍\ud83c\udfeb', 2331 'woman_technologist':'\ud83d\udc69‍\ud83d\udcbb', 2332 'woman_with_turban':'\ud83d\udc73‍\u2640\ufe0f', 2333 'womans_clothes':'\ud83d\udc5a', 2334 'womans_hat':'\ud83d\udc52', 2335 'women_wrestling':'\ud83e\udd3c‍\u2640\ufe0f', 2336 'womens':'\ud83d\udeba', 2337 'world_map':'\ud83d\uddfa', 2338 'worried':'\ud83d\ude1f', 2339 'wrench':'\ud83d\udd27', 2340 'writing_hand':'\u270d\ufe0f', 2341 'x':'\u274c', 2342 'yellow_heart':'\ud83d\udc9b', 2343 'yen':'\ud83d\udcb4', 2344 'yin_yang':'\u262f\ufe0f', 2345 'yum':'\ud83d\ude0b', 2346 'zap':'\u26a1\ufe0f', 2347 'zipper_mouth_face':'\ud83e\udd10', 2348 'zzz':'\ud83d\udca4', 2349 2350 /* special emojis :P */ 2351 'octocat': '<img alt=":octocat:" height="20" width="20" align="absmiddle" src="https://assets-cdn.github.com/images/icons/emoji/octocat.png">', 2352 '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>' 2353 }; 2354 2355 /** 2356 * Created by Estevao on 31-05-2015. 2357 */ 2358 2359 /** 2360 * Showdown Converter class 2361 * @class 2362 * @param {object} [converterOptions] 2363 * @returns {Converter} 2364 */ 2365 showdown.Converter = function (converterOptions) { 2366 'use strict'; 2367 2368 var 2369 /** 2370 * Options used by this converter 2371 * @private 2372 * @type {{}} 2373 */ 2374 options = {}, 2375 2376 /** 2377 * Language extensions used by this converter 2378 * @private 2379 * @type {Array} 2380 */ 2381 langExtensions = [], 2382 2383 /** 2384 * Output modifiers extensions used by this converter 2385 * @private 2386 * @type {Array} 2387 */ 2388 outputModifiers = [], 2389 2390 /** 2391 * Event listeners 2392 * @private 2393 * @type {{}} 2394 */ 2395 listeners = {}, 2396 2397 /** 2398 * The flavor set in this converter 2399 */ 2400 setConvFlavor = setFlavor, 2401 2402 /** 2403 * Metadata of the document 2404 * @type {{parsed: {}, raw: string, format: string}} 2405 */ 2406 metadata = { 2407 parsed: {}, 2408 raw: '', 2409 format: '' 2410 }; 2411 2412 _constructor(); 2413 2414 /** 2415 * Converter constructor 2416 * @private 2417 */ 2418 function _constructor () { 2419 converterOptions = converterOptions || {}; 2420 2421 for (var gOpt in globalOptions) { 2422 if (globalOptions.hasOwnProperty(gOpt)) { 2423 options[gOpt] = globalOptions[gOpt]; 2424 } 2425 } 2426 2427 // Merge options 2428 if (typeof converterOptions === 'object') { 2429 for (var opt in converterOptions) { 2430 if (converterOptions.hasOwnProperty(opt)) { 2431 options[opt] = converterOptions[opt]; 2432 } 2433 } 2434 } else { 2435 throw Error('Converter expects the passed parameter to be an object, but ' + typeof converterOptions + 2436 ' was passed instead.'); 2437 } 2438 2439 if (options.extensions) { 2440 showdown.helper.forEach(options.extensions, _parseExtension); 2441 } 2442 } 2443 2444 /** 2445 * Parse extension 2446 * @param {*} ext 2447 * @param {string} [name=''] 2448 * @private 2449 */ 2450 function _parseExtension (ext, name) { 2451 2452 name = name || null; 2453 // If it's a string, the extension was previously loaded 2454 if (showdown.helper.isString(ext)) { 2455 ext = showdown.helper.stdExtName(ext); 2456 name = ext; 2457 2458 // LEGACY_SUPPORT CODE 2459 if (showdown.extensions[ext]) { 2460 console.warn('DEPRECATION WARNING: ' + ext + ' is an old extension that uses a deprecated loading method.' + 2461 'Please inform the developer that the extension should be updated!'); 2462 legacyExtensionLoading(showdown.extensions[ext], ext); 2463 return; 2464 // END LEGACY SUPPORT CODE 2465 2466 } else if (!showdown.helper.isUndefined(extensions[ext])) { 2467 ext = extensions[ext]; 2468 2469 } else { 2470 throw Error('Extension "' + ext + '" could not be loaded. It was either not found or is not a valid extension.'); 2471 } 2472 } 2473 2474 if (typeof ext === 'function') { 2475 ext = ext(); 2476 } 2477 2478 if (!showdown.helper.isArray(ext)) { 2479 ext = [ext]; 2480 } 2481 2482 var validExt = validate(ext, name); 2483 if (!validExt.valid) { 2484 throw Error(validExt.error); 2485 } 2486 2487 for (var i = 0; i < ext.length; ++i) { 2488 switch (ext[i].type) { 2489 2490 case 'lang': 2491 langExtensions.push(ext[i]); 2492 break; 2493 2494 case 'output': 2495 outputModifiers.push(ext[i]); 2496 break; 2497 } 2498 if (ext[i].hasOwnProperty('listeners')) { 2499 for (var ln in ext[i].listeners) { 2500 if (ext[i].listeners.hasOwnProperty(ln)) { 2501 listen(ln, ext[i].listeners[ln]); 2502 } 2503 } 2504 } 2505 } 2506 2507 } 2508 2509 /** 2510 * LEGACY_SUPPORT 2511 * @param {*} ext 2512 * @param {string} name 2513 */ 2514 function legacyExtensionLoading (ext, name) { 2515 if (typeof ext === 'function') { 2516 ext = ext(new showdown.Converter()); 2517 } 2518 if (!showdown.helper.isArray(ext)) { 2519 ext = [ext]; 2520 } 2521 var valid = validate(ext, name); 2522 2523 if (!valid.valid) { 2524 throw Error(valid.error); 2525 } 2526 2527 for (var i = 0; i < ext.length; ++i) { 2528 switch (ext[i].type) { 2529 case 'lang': 2530 langExtensions.push(ext[i]); 2531 break; 2532 case 'output': 2533 outputModifiers.push(ext[i]); 2534 break; 2535 default:// should never reach here 2536 throw Error('Extension loader error: Type unrecognized!!!'); 2537 } 2538 } 2539 } 2540 2541 /** 2542 * Listen to an event 2543 * @param {string} name 2544 * @param {function} callback 2545 */ 2546 function listen (name, callback) { 2547 if (!showdown.helper.isString(name)) { 2548 throw Error('Invalid argument in converter.listen() method: name must be a string, but ' + typeof name + ' given'); 2549 } 2550 2551 if (typeof callback !== 'function') { 2552 throw Error('Invalid argument in converter.listen() method: callback must be a function, but ' + typeof callback + ' given'); 2553 } 2554 2555 if (!listeners.hasOwnProperty(name)) { 2556 listeners[name] = []; 2557 } 2558 listeners[name].push(callback); 2559 } 2560 2561 function rTrimInputText (text) { 2562 var rsp = text.match(/^\s*/)[0].length, 2563 rgx = new RegExp('^\\s{0,' + rsp + '}', 'gm'); 2564 return text.replace(rgx, ''); 2565 } 2566 2567 /** 2568 * Dispatch an event 2569 * @private 2570 * @param {string} evtName Event name 2571 * @param {string} text Text 2572 * @param {{}} options Converter Options 2573 * @param {{}} globals 2574 * @returns {string} 2575 */ 2576 this._dispatch = function dispatch (evtName, text, options, globals) { 2577 if (listeners.hasOwnProperty(evtName)) { 2578 for (var ei = 0; ei < listeners[evtName].length; ++ei) { 2579 var nText = listeners[evtName][ei](evtName, text, this, options, globals); 2580 if (nText && typeof nText !== 'undefined') { 2581 text = nText; 2582 } 2583 } 2584 } 2585 return text; 2586 }; 2587 2588 /** 2589 * Listen to an event 2590 * @param {string} name 2591 * @param {function} callback 2592 * @returns {showdown.Converter} 2593 */ 2594 this.listen = function (name, callback) { 2595 listen(name, callback); 2596 return this; 2597 }; 2598 2599 /** 2600 * Converts a markdown string into HTML 2601 * @param {string} text 2602 * @returns {*} 2603 */ 2604 this.makeHtml = function (text) { 2605 //check if text is not falsy 2606 if (!text) { 2607 return text; 2608 } 2609 2610 var globals = { 2611 gHtmlBlocks: [], 2612 gHtmlMdBlocks: [], 2613 gHtmlSpans: [], 2614 gUrls: {}, 2615 gTitles: {}, 2616 gDimensions: {}, 2617 gListLevel: 0, 2618 hashLinkCounts: {}, 2619 langExtensions: langExtensions, 2620 outputModifiers: outputModifiers, 2621 converter: this, 2622 ghCodeBlocks: [], 2623 metadata: { 2624 parsed: {}, 2625 raw: '', 2626 format: '' 2627 } 2628 }; 2629 2630 // This lets us use ¨ trema as an escape char to avoid md5 hashes 2631 // The choice of character is arbitrary; anything that isn't 2632 // magic in Markdown will work. 2633 text = text.replace(/¨/g, '¨T'); 2634 2635 // Replace $ with ¨D 2636 // RegExp interprets $ as a special character 2637 // when it's in a replacement string 2638 text = text.replace(/\$/g, '¨D'); 2639 2640 // Standardize line endings 2641 text = text.replace(/\r\n/g, '\n'); // DOS to Unix 2642 text = text.replace(/\r/g, '\n'); // Mac to Unix 2643 2644 // Stardardize line spaces 2645 text = text.replace(/\u00A0/g, ' '); 2646 2647 if (options.smartIndentationFix) { 2648 text = rTrimInputText(text); 2649 } 2650 2651 // Make sure text begins and ends with a couple of newlines: 2652 text = '\n\n' + text + '\n\n'; 2653 2654 // detab 2655 text = showdown.subParser('detab')(text, options, globals); 2656 2657 /** 2658 * Strip any lines consisting only of spaces and tabs. 2659 * This makes subsequent regexs easier to write, because we can 2660 * match consecutive blank lines with /\n+/ instead of something 2661 * contorted like /[ \t]*\n+/ 2662 */ 2663 text = text.replace(/^[ \t]+$/mg, ''); 2664 2665 //run languageExtensions 2666 showdown.helper.forEach(langExtensions, function (ext) { 2667 text = showdown.subParser('runExtension')(ext, text, options, globals); 2668 }); 2669 2670 // run the sub parsers 2671 text = showdown.subParser('metadata')(text, options, globals); 2672 text = showdown.subParser('hashPreCodeTags')(text, options, globals); 2673 text = showdown.subParser('githubCodeBlocks')(text, options, globals); 2674 text = showdown.subParser('hashHTMLBlocks')(text, options, globals); 2675 text = showdown.subParser('hashCodeTags')(text, options, globals); 2676 text = showdown.subParser('stripLinkDefinitions')(text, options, globals); 2677 text = showdown.subParser('blockGamut')(text, options, globals); 2678 text = showdown.subParser('unhashHTMLSpans')(text, options, globals); 2679 text = showdown.subParser('unescapeSpecialChars')(text, options, globals); 2680 2681 // attacklab: Restore dollar signs 2682 text = text.replace(/¨D/g, '$$'); 2683 2684 // attacklab: Restore tremas 2685 text = text.replace(/¨T/g, '¨'); 2686 2687 // render a complete html document instead of a partial if the option is enabled 2688 text = showdown.subParser('completeHTMLDocument')(text, options, globals); 2689 2690 // Run output modifiers 2691 showdown.helper.forEach(outputModifiers, function (ext) { 2692 text = showdown.subParser('runExtension')(ext, text, options, globals); 2693 }); 2694 2695 // update metadata 2696 metadata = globals.metadata; 2697 return text; 2698 }; 2699 2700 /** 2701 * Converts an HTML string into a markdown string 2702 * @param src 2703 * @param [HTMLParser] A WHATWG DOM and HTML parser, such as JSDOM. If none is supplied, window.document will be used. 2704 * @returns {string} 2705 */ 2706 this.makeMarkdown = this.makeMd = function (src, HTMLParser) { 2707 2708 // replace \r\n with \n 2709 src = src.replace(/\r\n/g, '\n'); 2710 src = src.replace(/\r/g, '\n'); // old macs 2711 2712 // due to an edge case, we need to find this: > < 2713 // to prevent removing of non silent white spaces 2714 // ex: <em>this is</em> <strong>sparta</strong> 2715 src = src.replace(/>[ \t]+</, '>¨NBSP;<'); 2716 2717 if (!HTMLParser) { 2718 if (window && window.document) { 2719 HTMLParser = window.document; 2720 } else { 2721 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'); 2722 } 2723 } 2724 2725 var doc = HTMLParser.createElement('div'); 2726 doc.innerHTML = src; 2727 2728 var globals = { 2729 preList: substitutePreCodeTags(doc) 2730 }; 2731 2732 // remove all newlines and collapse spaces 2733 clean(doc); 2734 2735 // some stuff, like accidental reference links must now be escaped 2736 // TODO 2737 // doc.innerHTML = doc.innerHTML.replace(/\[[\S\t ]]/); 2738 2739 var nodes = doc.childNodes, 2740 mdDoc = ''; 2741 2742 for (var i = 0; i < nodes.length; i++) { 2743 mdDoc += showdown.subParser('makeMarkdown.node')(nodes[i], globals); 2744 } 2745 2746 function clean (node) { 2747 for (var n = 0; n < node.childNodes.length; ++n) { 2748 var child = node.childNodes[n]; 2749 if (child.nodeType === 3) { 2750 if (!/\S/.test(child.nodeValue)) { 2751 node.removeChild(child); 2752 --n; 2753 } else { 2754 child.nodeValue = child.nodeValue.split('\n').join(' '); 2755 child.nodeValue = child.nodeValue.replace(/(\s)+/g, '$1'); 2756 } 2757 } else if (child.nodeType === 1) { 2758 clean(child); 2759 } 2760 } 2761 } 2762 2763 // find all pre tags and replace contents with placeholder 2764 // we need this so that we can remove all indentation from html 2765 // to ease up parsing 2766 function substitutePreCodeTags (doc) { 2767 2768 var pres = doc.querySelectorAll('pre'), 2769 presPH = []; 2770 2771 for (var i = 0; i < pres.length; ++i) { 2772 2773 if (pres[i].childElementCount === 1 && pres[i].firstChild.tagName.toLowerCase() === 'code') { 2774 var content = pres[i].firstChild.innerHTML.trim(), 2775 language = pres[i].firstChild.getAttribute('data-language') || ''; 2776 2777 // if data-language attribute is not defined, then we look for class language-* 2778 if (language === '') { 2779 var classes = pres[i].firstChild.className.split(' '); 2780 for (var c = 0; c < classes.length; ++c) { 2781 var matches = classes[c].match(/^language-(.+)$/); 2782 if (matches !== null) { 2783 language = matches[1]; 2784 break; 2785 } 2786 } 2787 } 2788 2789 // unescape html entities in content 2790 content = showdown.helper.unescapeHTMLEntities(content); 2791 2792 presPH.push(content); 2793 pres[i].outerHTML = '<precode language="' + language + '" precodenum="' + i.toString() + '"></precode>'; 2794 } else { 2795 presPH.push(pres[i].innerHTML); 2796 pres[i].innerHTML = ''; 2797 pres[i].setAttribute('prenum', i.toString()); 2798 } 2799 } 2800 return presPH; 2801 } 2802 2803 return mdDoc; 2804 }; 2805 2806 /** 2807 * Set an option of this Converter instance 2808 * @param {string} key 2809 * @param {*} value 2810 */ 2811 this.setOption = function (key, value) { 2812 options[key] = value; 2813 }; 2814 2815 /** 2816 * Get the option of this Converter instance 2817 * @param {string} key 2818 * @returns {*} 2819 */ 2820 this.getOption = function (key) { 2821 return options[key]; 2822 }; 2823 2824 /** 2825 * Get the options of this Converter instance 2826 * @returns {{}} 2827 */ 2828 this.getOptions = function () { 2829 return options; 2830 }; 2831 2832 /** 2833 * Add extension to THIS converter 2834 * @param {{}} extension 2835 * @param {string} [name=null] 2836 */ 2837 this.addExtension = function (extension, name) { 2838 name = name || null; 2839 _parseExtension(extension, name); 2840 }; 2841 2842 /** 2843 * Use a global registered extension with THIS converter 2844 * @param {string} extensionName Name of the previously registered extension 2845 */ 2846 this.useExtension = function (extensionName) { 2847 _parseExtension(extensionName); 2848 }; 2849 2850 /** 2851 * Set the flavor THIS converter should use 2852 * @param {string} name 2853 */ 2854 this.setFlavor = function (name) { 2855 if (!flavor.hasOwnProperty(name)) { 2856 throw Error(name + ' flavor was not found'); 2857 } 2858 var preset = flavor[name]; 2859 setConvFlavor = name; 2860 for (var option in preset) { 2861 if (preset.hasOwnProperty(option)) { 2862 options[option] = preset[option]; 2863 } 2864 } 2865 }; 2866 2867 /** 2868 * Get the currently set flavor of this converter 2869 * @returns {string} 2870 */ 2871 this.getFlavor = function () { 2872 return setConvFlavor; 2873 }; 2874 2875 /** 2876 * Remove an extension from THIS converter. 2877 * Note: This is a costly operation. It's better to initialize a new converter 2878 * and specify the extensions you wish to use 2879 * @param {Array} extension 2880 */ 2881 this.removeExtension = function (extension) { 2882 if (!showdown.helper.isArray(extension)) { 2883 extension = [extension]; 2884 } 2885 for (var a = 0; a < extension.length; ++a) { 2886 var ext = extension[a]; 2887 for (var i = 0; i < langExtensions.length; ++i) { 2888 if (langExtensions[i] === ext) { 2889 langExtensions[i].splice(i, 1); 2890 } 2891 } 2892 for (var ii = 0; ii < outputModifiers.length; ++i) { 2893 if (outputModifiers[ii] === ext) { 2894 outputModifiers[ii].splice(i, 1); 2895 } 2896 } 2897 } 2898 }; 2899 2900 /** 2901 * Get all extension of THIS converter 2902 * @returns {{language: Array, output: Array}} 2903 */ 2904 this.getAllExtensions = function () { 2905 return { 2906 language: langExtensions, 2907 output: outputModifiers 2908 }; 2909 }; 2910 2911 /** 2912 * Get the metadata of the previously parsed document 2913 * @param raw 2914 * @returns {string|{}} 2915 */ 2916 this.getMetadata = function (raw) { 2917 if (raw) { 2918 return metadata.raw; 2919 } else { 2920 return metadata.parsed; 2921 } 2922 }; 2923 2924 /** 2925 * Get the metadata format of the previously parsed document 2926 * @returns {string} 2927 */ 2928 this.getMetadataFormat = function () { 2929 return metadata.format; 2930 }; 2931 2932 /** 2933 * Private: set a single key, value metadata pair 2934 * @param {string} key 2935 * @param {string} value 2936 */ 2937 this._setMetadataPair = function (key, value) { 2938 metadata.parsed[key] = value; 2939 }; 2940 2941 /** 2942 * Private: set metadata format 2943 * @param {string} format 2944 */ 2945 this._setMetadataFormat = function (format) { 2946 metadata.format = format; 2947 }; 2948 2949 /** 2950 * Private: set metadata raw text 2951 * @param {string} raw 2952 */ 2953 this._setMetadataRaw = function (raw) { 2954 metadata.raw = raw; 2955 }; 2956 }; 2957 2958 /** 2959 * Turn Markdown link shortcuts into XHTML <a> tags. 2960 */ 2961 showdown.subParser('anchors', function (text, options, globals) { 2962 'use strict'; 2963 2964 text = globals.converter._dispatch('anchors.before', text, options, globals); 2965 2966 var writeAnchorTag = function (wholeMatch, linkText, linkId, url, m5, m6, title) { 2967 if (showdown.helper.isUndefined(title)) { 2968 title = ''; 2969 } 2970 linkId = linkId.toLowerCase(); 2971 2972 // Special case for explicit empty url 2973 if (wholeMatch.search(/\(<?\s*>? ?(['"].*['"])?\)$/m) > -1) { 2974 url = ''; 2975 } else if (!url) { 2976 if (!linkId) { 2977 // lower-case and turn embedded newlines into spaces 2978 linkId = linkText.toLowerCase().replace(/ ?\n/g, ' '); 2979 } 2980 url = '#' + linkId; 2981 2982 if (!showdown.helper.isUndefined(globals.gUrls[linkId])) { 2983 url = globals.gUrls[linkId]; 2984 if (!showdown.helper.isUndefined(globals.gTitles[linkId])) { 2985 title = globals.gTitles[linkId]; 2986 } 2987 } else { 2988 return wholeMatch; 2989 } 2990 } 2991 2992 //url = showdown.helper.escapeCharacters(url, '*_', false); // replaced line to improve performance 2993 url = url.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback); 2994 2995 var result = '<a href="' + url + '"'; 2996 2997 if (title !== '' && title !== null) { 2998 title = title.replace(/"/g, '"'); 2999 //title = showdown.helper.escapeCharacters(title, '*_', false); // replaced line to improve performance 3000 title = title.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback); 3001 result += ' title="' + title + '"'; 3002 } 3003 3004 // optionLinksInNewWindow only applies 3005 // to external links. Hash links (#) open in same page 3006 if (options.openLinksInNewWindow && !/^#/.test(url)) { 3007 // escaped _ 3008 result += ' rel="noopener noreferrer" target="¨E95Eblank"'; 3009 } 3010 3011 result += '>' + linkText + '</a>'; 3012 3013 return result; 3014 }; 3015 3016 // First, handle reference-style links: [link text] [id] 3017 text = text.replace(/\[((?:\[[^\]]*]|[^\[\]])*)] ?(?:\n *)?\[(.*?)]()()()()/g, writeAnchorTag); 3018 3019 // Next, inline-style links: [link text](url "optional title") 3020 // cases with crazy urls like ./image/cat1).png 3021 text = text.replace(/\[((?:\[[^\]]*]|[^\[\]])*)]()[ \t]*\([ \t]?<([^>]*)>(?:[ \t]*((["'])([^"]*?)\5))?[ \t]?\)/g, 3022 writeAnchorTag); 3023 3024 // normal cases 3025 text = text.replace(/\[((?:\[[^\]]*]|[^\[\]])*)]()[ \t]*\([ \t]?<?([\S]+?(?:\([\S]*?\)[\S]*?)?)>?(?:[ \t]*((["'])([^"]*?)\5))?[ \t]?\)/g, 3026 writeAnchorTag); 3027 3028 // handle reference-style shortcuts: [link text] 3029 // These must come last in case you've also got [link test][1] 3030 // or [link test](/foo) 3031 text = text.replace(/\[([^\[\]]+)]()()()()()/g, writeAnchorTag); 3032 3033 // Lastly handle GithubMentions if option is enabled 3034 if (options.ghMentions) { 3035 text = text.replace(/(^|\s)(\\)?(@([a-z\d]+(?:[a-z\d.-]+?[a-z\d]+)*))/gmi, function (wm, st, escape, mentions, username) { 3036 if (escape === '\\') { 3037 return st + mentions; 3038 } 3039 3040 //check if options.ghMentionsLink is a string 3041 if (!showdown.helper.isString(options.ghMentionsLink)) { 3042 throw new Error('ghMentionsLink option must be a string'); 3043 } 3044 var lnk = options.ghMentionsLink.replace(/\{u}/g, username), 3045 target = ''; 3046 if (options.openLinksInNewWindow) { 3047 target = ' rel="noopener noreferrer" target="¨E95Eblank"'; 3048 } 3049 return st + '<a href="' + lnk + '"' + target + '>' + mentions + '</a>'; 3050 }); 3051 } 3052 3053 text = globals.converter._dispatch('anchors.after', text, options, globals); 3054 return text; 3055 }); 3056 3057 // url allowed chars [a-z\d_.~:/?#[]@!$&'()*+,;=-] 3058 3059 var simpleURLRegex = /([*~_]+|\b)(((https?|ftp|dict):\/\/|www\.)[^'">\s]+?\.[^'">\s]+?)()(\1)?(?=\s|$)(?!["<>])/gi, 3060 simpleURLRegex2 = /([*~_]+|\b)(((https?|ftp|dict):\/\/|www\.)[^'">\s]+\.[^'">\s]+?)([.!?,()\[\]])?(\1)?(?=\s|$)(?!["<>])/gi, 3061 delimUrlRegex = /()<(((https?|ftp|dict):\/\/|www\.)[^'">\s]+)()>()/gi, 3062 simpleMailRegex = /(^|\s)(?:mailto:)?([A-Za-z0-9!#$%&'*+-/=?^_`{|}~.]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)(?=$|\s)/gmi, 3063 delimMailRegex = /<()(?:mailto:)?([-.\w]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi, 3064 3065 replaceLink = function (options) { 3066 'use strict'; 3067 return function (wm, leadingMagicChars, link, m2, m3, trailingPunctuation, trailingMagicChars) { 3068 link = link.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback); 3069 var lnkTxt = link, 3070 append = '', 3071 target = '', 3072 lmc = leadingMagicChars || '', 3073 tmc = trailingMagicChars || ''; 3074 if (/^www\./i.test(link)) { 3075 link = link.replace(/^www\./i, 'http://www.'); 3076 } 3077 if (options.excludeTrailingPunctuationFromURLs && trailingPunctuation) { 3078 append = trailingPunctuation; 3079 } 3080 if (options.openLinksInNewWindow) { 3081 target = ' rel="noopener noreferrer" target="¨E95Eblank"'; 3082 } 3083 return lmc + '<a href="' + link + '"' + target + '>' + lnkTxt + '</a>' + append + tmc; 3084 }; 3085 }, 3086 3087 replaceMail = function (options, globals) { 3088 'use strict'; 3089 return function (wholeMatch, b, mail) { 3090 var href = 'mailto:'; 3091 b = b || ''; 3092 mail = showdown.subParser('unescapeSpecialChars')(mail, options, globals); 3093 if (options.encodeEmails) { 3094 href = showdown.helper.encodeEmailAddress(href + mail); 3095 mail = showdown.helper.encodeEmailAddress(mail); 3096 } else { 3097 href = href + mail; 3098 } 3099 return b + '<a href="' + href + '">' + mail + '</a>'; 3100 }; 3101 }; 3102 3103 showdown.subParser('autoLinks', function (text, options, globals) { 3104 'use strict'; 3105 3106 text = globals.converter._dispatch('autoLinks.before', text, options, globals); 3107 3108 text = text.replace(delimUrlRegex, replaceLink(options)); 3109 text = text.replace(delimMailRegex, replaceMail(options, globals)); 3110 3111 text = globals.converter._dispatch('autoLinks.after', text, options, globals); 3112 3113 return text; 3114 }); 3115 3116 showdown.subParser('simplifiedAutoLinks', function (text, options, globals) { 3117 'use strict'; 3118 3119 if (!options.simplifiedAutoLink) { 3120 return text; 3121 } 3122 3123 text = globals.converter._dispatch('simplifiedAutoLinks.before', text, options, globals); 3124 3125 if (options.excludeTrailingPunctuationFromURLs) { 3126 text = text.replace(simpleURLRegex2, replaceLink(options)); 3127 } else { 3128 text = text.replace(simpleURLRegex, replaceLink(options)); 3129 } 3130 text = text.replace(simpleMailRegex, replaceMail(options, globals)); 3131 3132 text = globals.converter._dispatch('simplifiedAutoLinks.after', text, options, globals); 3133 3134 return text; 3135 }); 3136 3137 /** 3138 * These are all the transformations that form block-level 3139 * tags like paragraphs, headers, and list items. 3140 */ 3141 showdown.subParser('blockGamut', function (text, options, globals) { 3142 'use strict'; 3143 3144 text = globals.converter._dispatch('blockGamut.before', text, options, globals); 3145 3146 // we parse blockquotes first so that we can have headings and hrs 3147 // inside blockquotes 3148 text = showdown.subParser('blockQuotes')(text, options, globals); 3149 text = showdown.subParser('headers')(text, options, globals); 3150 3151 // Do Horizontal Rules: 3152 text = showdown.subParser('horizontalRule')(text, options, globals); 3153 3154 text = showdown.subParser('lists')(text, options, globals); 3155 text = showdown.subParser('codeBlocks')(text, options, globals); 3156 text = showdown.subParser('tables')(text, options, globals); 3157 3158 // We already ran _HashHTMLBlocks() before, in Markdown(), but that 3159 // was to escape raw HTML in the original Markdown source. This time, 3160 // we're escaping the markup we've just created, so that we don't wrap 3161 // <p> tags around block-level tags. 3162 text = showdown.subParser('hashHTMLBlocks')(text, options, globals); 3163 text = showdown.subParser('paragraphs')(text, options, globals); 3164 3165 text = globals.converter._dispatch('blockGamut.after', text, options, globals); 3166 3167 return text; 3168 }); 3169 3170 showdown.subParser('blockQuotes', function (text, options, globals) { 3171 'use strict'; 3172 3173 text = globals.converter._dispatch('blockQuotes.before', text, options, globals); 3174 3175 // add a couple extra lines after the text and endtext mark 3176 text = text + '\n\n'; 3177 3178 var rgx = /(^ {0,3}>[ \t]?.+\n(.+\n)*\n*)+/gm; 3179 3180 if (options.splitAdjacentBlockquotes) { 3181 rgx = /^ {0,3}>[\s\S]*?(?:\n\n)/gm; 3182 } 3183 3184 text = text.replace(rgx, function (bq) { 3185 // attacklab: hack around Konqueror 3.5.4 bug: 3186 // "----------bug".replace(/^-/g,"") == "bug" 3187 bq = bq.replace(/^[ \t]*>[ \t]?/gm, ''); // trim one level of quoting 3188 3189 // attacklab: clean up hack 3190 bq = bq.replace(/¨0/g, ''); 3191 3192 bq = bq.replace(/^[ \t]+$/gm, ''); // trim whitespace-only lines 3193 bq = showdown.subParser('githubCodeBlocks')(bq, options, globals); 3194 bq = showdown.subParser('blockGamut')(bq, options, globals); // recurse 3195 3196 bq = bq.replace(/(^|\n)/g, '$1 '); 3197 // These leading spaces screw with <pre> content, so we need to fix that: 3198 bq = bq.replace(/(\s*<pre>[^\r]+?<\/pre>)/gm, function (wholeMatch, m1) { 3199 var pre = m1; 3200 // attacklab: hack around Konqueror 3.5.4 bug: 3201 pre = pre.replace(/^ /mg, '¨0'); 3202 pre = pre.replace(/¨0/g, ''); 3203 return pre; 3204 }); 3205 3206 return showdown.subParser('hashBlock')('<blockquote>\n' + bq + '\n</blockquote>', options, globals); 3207 }); 3208 3209 text = globals.converter._dispatch('blockQuotes.after', text, options, globals); 3210 return text; 3211 }); 3212 3213 /** 3214 * Process Markdown `<pre><code>` blocks. 3215 */ 3216 showdown.subParser('codeBlocks', function (text, options, globals) { 3217 'use strict'; 3218 3219 text = globals.converter._dispatch('codeBlocks.before', text, options, globals); 3220 3221 // sentinel workarounds for lack of \A and \Z, safari\khtml bug 3222 text += '¨0'; 3223 3224 var pattern = /(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=¨0))/g; 3225 text = text.replace(pattern, function (wholeMatch, m1, m2) { 3226 var codeblock = m1, 3227 nextChar = m2, 3228 end = '\n'; 3229 3230 codeblock = showdown.subParser('outdent')(codeblock, options, globals); 3231 codeblock = showdown.subParser('encodeCode')(codeblock, options, globals); 3232 codeblock = showdown.subParser('detab')(codeblock, options, globals); 3233 codeblock = codeblock.replace(/^\n+/g, ''); // trim leading newlines 3234 codeblock = codeblock.replace(/\n+$/g, ''); // trim trailing newlines 3235 3236 if (options.omitExtraWLInCodeBlocks) { 3237 end = ''; 3238 } 3239 3240 codeblock = '<pre><code>' + codeblock + end + '</code></pre>'; 3241 3242 return showdown.subParser('hashBlock')(codeblock, options, globals) + nextChar; 3243 }); 3244 3245 // strip sentinel 3246 text = text.replace(/¨0/, ''); 3247 3248 text = globals.converter._dispatch('codeBlocks.after', text, options, globals); 3249 return text; 3250 }); 3251 3252 /** 3253 * 3254 * * Backtick quotes are used for <code></code> spans. 3255 * 3256 * * You can use multiple backticks as the delimiters if you want to 3257 * include literal backticks in the code span. So, this input: 3258 * 3259 * Just type ``foo `bar` baz`` at the prompt. 3260 * 3261 * Will translate to: 3262 * 3263 * <p>Just type <code>foo `bar` baz</code> at the prompt.</p> 3264 * 3265 * There's no arbitrary limit to the number of backticks you 3266 * can use as delimters. If you need three consecutive backticks 3267 * in your code, use four for delimiters, etc. 3268 * 3269 * * You can use spaces to get literal backticks at the edges: 3270 * 3271 * ... type `` `bar` `` ... 3272 * 3273 * Turns to: 3274 * 3275 * ... type <code>`bar`</code> ... 3276 */ 3277 showdown.subParser('codeSpans', function (text, options, globals) { 3278 'use strict'; 3279 3280 text = globals.converter._dispatch('codeSpans.before', text, options, globals); 3281 3282 if (typeof text === 'undefined') { 3283 text = ''; 3284 } 3285 text = text.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm, 3286 function (wholeMatch, m1, m2, m3) { 3287 var c = m3; 3288 c = c.replace(/^([ \t]*)/g, ''); // leading whitespace 3289 c = c.replace(/[ \t]*$/g, ''); // trailing whitespace 3290 c = showdown.subParser('encodeCode')(c, options, globals); 3291 c = m1 + '<code>' + c + '</code>'; 3292 c = showdown.subParser('hashHTMLSpans')(c, options, globals); 3293 return c; 3294 } 3295 ); 3296 3297 text = globals.converter._dispatch('codeSpans.after', text, options, globals); 3298 return text; 3299 }); 3300 3301 /** 3302 * Create a full HTML document from the processed markdown 3303 */ 3304 showdown.subParser('completeHTMLDocument', function (text, options, globals) { 3305 'use strict'; 3306 3307 if (!options.completeHTMLDocument) { 3308 return text; 3309 } 3310 3311 text = globals.converter._dispatch('completeHTMLDocument.before', text, options, globals); 3312 3313 var doctype = 'html', 3314 doctypeParsed = '<!DOCTYPE HTML>\n', 3315 title = '', 3316 charset = '<meta charset="utf-8">\n', 3317 lang = '', 3318 metadata = ''; 3319 3320 if (typeof globals.metadata.parsed.doctype !== 'undefined') { 3321 doctypeParsed = '<!DOCTYPE ' + globals.metadata.parsed.doctype + '>\n'; 3322 doctype = globals.metadata.parsed.doctype.toString().toLowerCase(); 3323 if (doctype === 'html' || doctype === 'html5') { 3324 charset = '<meta charset="utf-8">'; 3325 } 3326 } 3327 3328 for (var meta in globals.metadata.parsed) { 3329 if (globals.metadata.parsed.hasOwnProperty(meta)) { 3330 switch (meta.toLowerCase()) { 3331 case 'doctype': 3332 break; 3333 3334 case 'title': 3335 title = '<title>' + globals.metadata.parsed.title + '</title>\n'; 3336 break; 3337 3338 case 'charset': 3339 if (doctype === 'html' || doctype === 'html5') { 3340 charset = '<meta charset="' + globals.metadata.parsed.charset + '">\n'; 3341 } else { 3342 charset = '<meta name="charset" content="' + globals.metadata.parsed.charset + '">\n'; 3343 } 3344 break; 3345 3346 case 'language': 3347 case 'lang': 3348 lang = ' lang="' + globals.metadata.parsed[meta] + '"'; 3349 metadata += '<meta name="' + meta + '" content="' + globals.metadata.parsed[meta] + '">\n'; 3350 break; 3351 3352 default: 3353 metadata += '<meta name="' + meta + '" content="' + globals.metadata.parsed[meta] + '">\n'; 3354 } 3355 } 3356 } 3357 3358 text = doctypeParsed + '<html' + lang + '>\n<head>\n' + title + charset + metadata + '</head>\n<body>\n' + text.trim() + '\n</body>\n</html>'; 3359 3360 text = globals.converter._dispatch('completeHTMLDocument.after', text, options, globals); 3361 return text; 3362 }); 3363 3364 /** 3365 * Convert all tabs to spaces 3366 */ 3367 showdown.subParser('detab', function (text, options, globals) { 3368 'use strict'; 3369 text = globals.converter._dispatch('detab.before', text, options, globals); 3370 3371 // expand first n-1 tabs 3372 text = text.replace(/\t(?=\t)/g, ' '); // g_tab_width 3373 3374 // replace the nth with two sentinels 3375 text = text.replace(/\t/g, '¨A¨B'); 3376 3377 // use the sentinel to anchor our regex so it doesn't explode 3378 text = text.replace(/¨B(.+?)¨A/g, function (wholeMatch, m1) { 3379 var leadingText = m1, 3380 numSpaces = 4 - leadingText.length % 4; // g_tab_width 3381 3382 // there *must* be a better way to do this: 3383 for (var i = 0; i < numSpaces; i++) { 3384 leadingText += ' '; 3385 } 3386 3387 return leadingText; 3388 }); 3389 3390 // clean up sentinels 3391 text = text.replace(/¨A/g, ' '); // g_tab_width 3392 text = text.replace(/¨B/g, ''); 3393 3394 text = globals.converter._dispatch('detab.after', text, options, globals); 3395 return text; 3396 }); 3397 3398 showdown.subParser('ellipsis', function (text, options, globals) { 3399 'use strict'; 3400 3401 text = globals.converter._dispatch('ellipsis.before', text, options, globals); 3402 3403 text = text.replace(/\.\.\./g, '…'); 3404 3405 text = globals.converter._dispatch('ellipsis.after', text, options, globals); 3406 3407 return text; 3408 }); 3409 3410 /** 3411 * Turn emoji codes into emojis 3412 * 3413 * List of supported emojis: https://github.com/showdownjs/showdown/wiki/Emojis 3414 */ 3415 showdown.subParser('emoji', function (text, options, globals) { 3416 'use strict'; 3417 3418 if (!options.emoji) { 3419 return text; 3420 } 3421 3422 text = globals.converter._dispatch('emoji.before', text, options, globals); 3423 3424 var emojiRgx = /:([\S]+?):/g; 3425 3426 text = text.replace(emojiRgx, function (wm, emojiCode) { 3427 if (showdown.helper.emojis.hasOwnProperty(emojiCode)) { 3428 return showdown.helper.emojis[emojiCode]; 3429 } 3430 return wm; 3431 }); 3432 3433 text = globals.converter._dispatch('emoji.after', text, options, globals); 3434 3435 return text; 3436 }); 3437 3438 /** 3439 * Smart processing for ampersands and angle brackets that need to be encoded. 3440 */ 3441 showdown.subParser('encodeAmpsAndAngles', function (text, options, globals) { 3442 'use strict'; 3443 text = globals.converter._dispatch('encodeAmpsAndAngles.before', text, options, globals); 3444 3445 // Ampersand-encoding based entirely on Nat Irons's Amputator MT plugin: 3446 // http://bumppo.net/projects/amputator/ 3447 text = text.replace(/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/g, '&'); 3448 3449 // Encode naked <'s 3450 text = text.replace(/<(?![a-z\/?$!])/gi, '<'); 3451 3452 // Encode < 3453 text = text.replace(/</g, '<'); 3454 3455 // Encode > 3456 text = text.replace(/>/g, '>'); 3457 3458 text = globals.converter._dispatch('encodeAmpsAndAngles.after', text, options, globals); 3459 return text; 3460 }); 3461 3462 /** 3463 * Returns the string, with after processing the following backslash escape sequences. 3464 * 3465 * attacklab: The polite way to do this is with the new escapeCharacters() function: 3466 * 3467 * text = escapeCharacters(text,"\\",true); 3468 * text = escapeCharacters(text,"`*_{}[]()>#+-.!",true); 3469 * 3470 * ...but we're sidestepping its use of the (slow) RegExp constructor 3471 * as an optimization for Firefox. This function gets called a LOT. 3472 */ 3473 showdown.subParser('encodeBackslashEscapes', function (text, options, globals) { 3474 'use strict'; 3475 text = globals.converter._dispatch('encodeBackslashEscapes.before', text, options, globals); 3476 3477 text = text.replace(/\\(\\)/g, showdown.helper.escapeCharactersCallback); 3478 text = text.replace(/\\([`*_{}\[\]()>#+.!~=|-])/g, showdown.helper.escapeCharactersCallback); 3479 3480 text = globals.converter._dispatch('encodeBackslashEscapes.after', text, options, globals); 3481 return text; 3482 }); 3483 3484 /** 3485 * Encode/escape certain characters inside Markdown code runs. 3486 * The point is that in code, these characters are literals, 3487 * and lose their special Markdown meanings. 3488 */ 3489 showdown.subParser('encodeCode', function (text, options, globals) { 3490 'use strict'; 3491 3492 text = globals.converter._dispatch('encodeCode.before', text, options, globals); 3493 3494 // Encode all ampersands; HTML entities are not 3495 // entities within a Markdown code span. 3496 text = text 3497 .replace(/&/g, '&') 3498 // Do the angle bracket song and dance: 3499 .replace(/</g, '<') 3500 .replace(/>/g, '>') 3501 // Now, escape characters that are magic in Markdown: 3502 .replace(/([*_{}\[\]\\=~-])/g, showdown.helper.escapeCharactersCallback); 3503 3504 text = globals.converter._dispatch('encodeCode.after', text, options, globals); 3505 return text; 3506 }); 3507 3508 /** 3509 * Within tags -- meaning between < and > -- encode [\ ` * _ ~ =] so they 3510 * don't conflict with their use in Markdown for code, italics and strong. 3511 */ 3512 showdown.subParser('escapeSpecialCharsWithinTagAttributes', function (text, options, globals) { 3513 'use strict'; 3514 text = globals.converter._dispatch('escapeSpecialCharsWithinTagAttributes.before', text, options, globals); 3515 3516 // Build a regex to find HTML tags. 3517 var tags = /<\/?[a-z\d_:-]+(?:[\s]+[\s\S]+?)?>/gi, 3518 comments = /<!(--(?:(?:[^>-]|-[^>])(?:[^-]|-[^-])*)--)>/gi; 3519 3520 text = text.replace(tags, function (wholeMatch) { 3521 return wholeMatch 3522 .replace(/(.)<\/?code>(?=.)/g, '$1`') 3523 .replace(/([\\`*_~=|])/g, showdown.helper.escapeCharactersCallback); 3524 }); 3525 3526 text = text.replace(comments, function (wholeMatch) { 3527 return wholeMatch 3528 .replace(/([\\`*_~=|])/g, showdown.helper.escapeCharactersCallback); 3529 }); 3530 3531 text = globals.converter._dispatch('escapeSpecialCharsWithinTagAttributes.after', text, options, globals); 3532 return text; 3533 }); 3534 3535 /** 3536 * Handle github codeblocks prior to running HashHTML so that 3537 * HTML contained within the codeblock gets escaped properly 3538 * Example: 3539 * ```ruby 3540 * def hello_world(x) 3541 * puts "Hello, #{x}" 3542 * end 3543 * ``` 3544 */ 3545 showdown.subParser('githubCodeBlocks', function (text, options, globals) { 3546 'use strict'; 3547 3548 // early exit if option is not enabled 3549 if (!options.ghCodeBlocks) { 3550 return text; 3551 } 3552 3553 text = globals.converter._dispatch('githubCodeBlocks.before', text, options, globals); 3554 3555 text += '¨0'; 3556 3557 text = text.replace(/(?:^|\n)(?: {0,3})(```+|~~~+)(?: *)([^\s`~]*)\n([\s\S]*?)\n(?: {0,3})\1/g, function (wholeMatch, delim, language, codeblock) { 3558 var end = (options.omitExtraWLInCodeBlocks) ? '' : '\n'; 3559 3560 // First parse the github code block 3561 codeblock = showdown.subParser('encodeCode')(codeblock, options, globals); 3562 codeblock = showdown.subParser('detab')(codeblock, options, globals); 3563 codeblock = codeblock.replace(/^\n+/g, ''); // trim leading newlines 3564 codeblock = codeblock.replace(/\n+$/g, ''); // trim trailing whitespace 3565 3566 codeblock = '<pre><code' + (language ? ' class="' + language + ' language-' + language + '"' : '') + '>' + codeblock + end + '</code></pre>'; 3567 3568 codeblock = showdown.subParser('hashBlock')(codeblock, options, globals); 3569 3570 // Since GHCodeblocks can be false positives, we need to 3571 // store the primitive text and the parsed text in a global var, 3572 // and then return a token 3573 return '\n\n¨G' + (globals.ghCodeBlocks.push({text: wholeMatch, codeblock: codeblock}) - 1) + 'G\n\n'; 3574 }); 3575 3576 // attacklab: strip sentinel 3577 text = text.replace(/¨0/, ''); 3578 3579 return globals.converter._dispatch('githubCodeBlocks.after', text, options, globals); 3580 }); 3581 3582 showdown.subParser('hashBlock', function (text, options, globals) { 3583 'use strict'; 3584 text = globals.converter._dispatch('hashBlock.before', text, options, globals); 3585 text = text.replace(/(^\n+|\n+$)/g, ''); 3586 text = '\n\n¨K' + (globals.gHtmlBlocks.push(text) - 1) + 'K\n\n'; 3587 text = globals.converter._dispatch('hashBlock.after', text, options, globals); 3588 return text; 3589 }); 3590 3591 /** 3592 * Hash and escape <code> elements that should not be parsed as markdown 3593 */ 3594 showdown.subParser('hashCodeTags', function (text, options, globals) { 3595 'use strict'; 3596 text = globals.converter._dispatch('hashCodeTags.before', text, options, globals); 3597 3598 var repFunc = function (wholeMatch, match, left, right) { 3599 var codeblock = left + showdown.subParser('encodeCode')(match, options, globals) + right; 3600 return '¨C' + (globals.gHtmlSpans.push(codeblock) - 1) + 'C'; 3601 }; 3602 3603 // Hash naked <code> 3604 text = showdown.helper.replaceRecursiveRegExp(text, repFunc, '<code\\b[^>]*>', '</code>', 'gim'); 3605 3606 text = globals.converter._dispatch('hashCodeTags.after', text, options, globals); 3607 return text; 3608 }); 3609 3610 showdown.subParser('hashElement', function (text, options, globals) { 3611 'use strict'; 3612 3613 return function (wholeMatch, m1) { 3614 var blockText = m1; 3615 3616 // Undo double lines 3617 blockText = blockText.replace(/\n\n/g, '\n'); 3618 blockText = blockText.replace(/^\n/, ''); 3619 3620 // strip trailing blank lines 3621 blockText = blockText.replace(/\n+$/g, ''); 3622 3623 // Replace the element text with a marker ("¨KxK" where x is its key) 3624 blockText = '\n\n¨K' + (globals.gHtmlBlocks.push(blockText) - 1) + 'K\n\n'; 3625 3626 return blockText; 3627 }; 3628 }); 3629 3630 showdown.subParser('hashHTMLBlocks', function (text, options, globals) { 3631 'use strict'; 3632 text = globals.converter._dispatch('hashHTMLBlocks.before', text, options, globals); 3633 3634 var blockTags = [ 3635 'pre', 3636 'div', 3637 'h1', 3638 'h2', 3639 'h3', 3640 'h4', 3641 'h5', 3642 'h6', 3643 'blockquote', 3644 'table', 3645 'dl', 3646 'ol', 3647 'ul', 3648 'script', 3649 'noscript', 3650 'form', 3651 'fieldset', 3652 'iframe', 3653 'math', 3654 'style', 3655 'section', 3656 'header', 3657 'footer', 3658 'nav', 3659 'article', 3660 'aside', 3661 'address', 3662 'audio', 3663 'canvas', 3664 'figure', 3665 'hgroup', 3666 'output', 3667 'video', 3668 'p' 3669 ], 3670 repFunc = function (wholeMatch, match, left, right) { 3671 var txt = wholeMatch; 3672 // check if this html element is marked as markdown 3673 // if so, it's contents should be parsed as markdown 3674 if (left.search(/\bmarkdown\b/) !== -1) { 3675 txt = left + globals.converter.makeHtml(match) + right; 3676 } 3677 return '\n\n¨K' + (globals.gHtmlBlocks.push(txt) - 1) + 'K\n\n'; 3678 }; 3679 3680 if (options.backslashEscapesHTMLTags) { 3681 // encode backslash escaped HTML tags 3682 text = text.replace(/\\<(\/?[^>]+?)>/g, function (wm, inside) { 3683 return '<' + inside + '>'; 3684 }); 3685 } 3686 3687 // hash HTML Blocks 3688 for (var i = 0; i < blockTags.length; ++i) { 3689 3690 var opTagPos, 3691 rgx1 = new RegExp('^ {0,3}(<' + blockTags[i] + '\\b[^>]*>)', 'im'), 3692 patLeft = '<' + blockTags[i] + '\\b[^>]*>', 3693 patRight = '</' + blockTags[i] + '>'; 3694 // 1. Look for the first position of the first opening HTML tag in the text 3695 while ((opTagPos = showdown.helper.regexIndexOf(text, rgx1)) !== -1) { 3696 3697 // if the HTML tag is \ escaped, we need to escape it and break 3698 3699 3700 //2. Split the text in that position 3701 var subTexts = showdown.helper.splitAtIndex(text, opTagPos), 3702 //3. Match recursively 3703 newSubText1 = showdown.helper.replaceRecursiveRegExp(subTexts[1], repFunc, patLeft, patRight, 'im'); 3704 3705 // prevent an infinite loop 3706 if (newSubText1 === subTexts[1]) { 3707 break; 3708 } 3709 text = subTexts[0].concat(newSubText1); 3710 } 3711 } 3712 // HR SPECIAL CASE 3713 text = text.replace(/(\n {0,3}(<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g, 3714 showdown.subParser('hashElement')(text, options, globals)); 3715 3716 // Special case for standalone HTML comments 3717 text = showdown.helper.replaceRecursiveRegExp(text, function (txt) { 3718 return '\n\n¨K' + (globals.gHtmlBlocks.push(txt) - 1) + 'K\n\n'; 3719 }, '^ {0,3}<!--', '-->', 'gm'); 3720 3721 // PHP and ASP-style processor instructions (<?...?> and <%...%>) 3722 text = text.replace(/(?:\n\n)( {0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g, 3723 showdown.subParser('hashElement')(text, options, globals)); 3724 3725 text = globals.converter._dispatch('hashHTMLBlocks.after', text, options, globals); 3726 return text; 3727 }); 3728 3729 /** 3730 * Hash span elements that should not be parsed as markdown 3731 */ 3732 showdown.subParser('hashHTMLSpans', function (text, options, globals) { 3733 'use strict'; 3734 text = globals.converter._dispatch('hashHTMLSpans.before', text, options, globals); 3735 3736 function hashHTMLSpan (html) { 3737 return '¨C' + (globals.gHtmlSpans.push(html) - 1) + 'C'; 3738 } 3739 3740 // Hash Self Closing tags 3741 text = text.replace(/<[^>]+?\/>/gi, function (wm) { 3742 return hashHTMLSpan(wm); 3743 }); 3744 3745 // Hash tags without properties 3746 text = text.replace(/<([^>]+?)>[\s\S]*?<\/\1>/g, function (wm) { 3747 return hashHTMLSpan(wm); 3748 }); 3749 3750 // Hash tags with properties 3751 text = text.replace(/<([^>]+?)\s[^>]+?>[\s\S]*?<\/\1>/g, function (wm) { 3752 return hashHTMLSpan(wm); 3753 }); 3754 3755 // Hash self closing tags without /> 3756 text = text.replace(/<[^>]+?>/gi, function (wm) { 3757 return hashHTMLSpan(wm); 3758 }); 3759 3760 /*showdown.helper.matchRecursiveRegExp(text, '<code\\b[^>]*>', '</code>', 'gi');*/ 3761 3762 text = globals.converter._dispatch('hashHTMLSpans.after', text, options, globals); 3763 return text; 3764 }); 3765 3766 /** 3767 * Unhash HTML spans 3768 */ 3769 showdown.subParser('unhashHTMLSpans', function (text, options, globals) { 3770 'use strict'; 3771 text = globals.converter._dispatch('unhashHTMLSpans.before', text, options, globals); 3772 3773 for (var i = 0; i < globals.gHtmlSpans.length; ++i) { 3774 var repText = globals.gHtmlSpans[i], 3775 // limiter to prevent infinite loop (assume 10 as limit for recurse) 3776 limit = 0; 3777 3778 while (/¨C(\d+)C/.test(repText)) { 3779 var num = RegExp.$1; 3780 repText = repText.replace('¨C' + num + 'C', globals.gHtmlSpans[num]); 3781 if (limit === 10) { 3782 console.error('maximum nesting of 10 spans reached!!!'); 3783 break; 3784 } 3785 ++limit; 3786 } 3787 text = text.replace('¨C' + i + 'C', repText); 3788 } 3789 3790 text = globals.converter._dispatch('unhashHTMLSpans.after', text, options, globals); 3791 return text; 3792 }); 3793 3794 /** 3795 * Hash and escape <pre><code> elements that should not be parsed as markdown 3796 */ 3797 showdown.subParser('hashPreCodeTags', function (text, options, globals) { 3798 'use strict'; 3799 text = globals.converter._dispatch('hashPreCodeTags.before', text, options, globals); 3800 3801 var repFunc = function (wholeMatch, match, left, right) { 3802 // encode html entities 3803 var codeblock = left + showdown.subParser('encodeCode')(match, options, globals) + right; 3804 return '\n\n¨G' + (globals.ghCodeBlocks.push({text: wholeMatch, codeblock: codeblock}) - 1) + 'G\n\n'; 3805 }; 3806 3807 // Hash <pre><code> 3808 text = showdown.helper.replaceRecursiveRegExp(text, repFunc, '^ {0,3}<pre\\b[^>]*>\\s*<code\\b[^>]*>', '^ {0,3}</code>\\s*</pre>', 'gim'); 3809 3810 text = globals.converter._dispatch('hashPreCodeTags.after', text, options, globals); 3811 return text; 3812 }); 3813 3814 showdown.subParser('headers', function (text, options, globals) { 3815 'use strict'; 3816 3817 text = globals.converter._dispatch('headers.before', text, options, globals); 3818 3819 var headerLevelStart = (isNaN(parseInt(options.headerLevelStart))) ? 1 : parseInt(options.headerLevelStart), 3820 3821 // Set text-style headers: 3822 // Header 1 3823 // ======== 3824 // 3825 // Header 2 3826 // -------- 3827 // 3828 setextRegexH1 = (options.smoothLivePreview) ? /^(.+)[ \t]*\n={2,}[ \t]*\n+/gm : /^(.+)[ \t]*\n=+[ \t]*\n+/gm, 3829 setextRegexH2 = (options.smoothLivePreview) ? /^(.+)[ \t]*\n-{2,}[ \t]*\n+/gm : /^(.+)[ \t]*\n-+[ \t]*\n+/gm; 3830 3831 text = text.replace(setextRegexH1, function (wholeMatch, m1) { 3832 3833 var spanGamut = showdown.subParser('spanGamut')(m1, options, globals), 3834 hID = (options.noHeaderId) ? '' : ' id="' + headerId(m1) + '"', 3835 hLevel = headerLevelStart, 3836 hashBlock = '<h' + hLevel + hID + '>' + spanGamut + '</h' + hLevel + '>'; 3837 return showdown.subParser('hashBlock')(hashBlock, options, globals); 3838 }); 3839 3840 text = text.replace(setextRegexH2, function (matchFound, m1) { 3841 var spanGamut = showdown.subParser('spanGamut')(m1, options, globals), 3842 hID = (options.noHeaderId) ? '' : ' id="' + headerId(m1) + '"', 3843 hLevel = headerLevelStart + 1, 3844 hashBlock = '<h' + hLevel + hID + '>' + spanGamut + '</h' + hLevel + '>'; 3845 return showdown.subParser('hashBlock')(hashBlock, options, globals); 3846 }); 3847 3848 // atx-style headers: 3849 // # Header 1 3850 // ## Header 2 3851 // ## Header 2 with closing hashes ## 3852 // ... 3853 // ###### Header 6 3854 // 3855 var atxStyle = (options.requireSpaceBeforeHeadingText) ? /^(#{1,6})[ \t]+(.+?)[ \t]*#*\n+/gm : /^(#{1,6})[ \t]*(.+?)[ \t]*#*\n+/gm; 3856 3857 text = text.replace(atxStyle, function (wholeMatch, m1, m2) { 3858 var hText = m2; 3859 if (options.customizedHeaderId) { 3860 hText = m2.replace(/\s?\{([^{]+?)}\s*$/, ''); 3861 } 3862 3863 var span = showdown.subParser('spanGamut')(hText, options, globals), 3864 hID = (options.noHeaderId) ? '' : ' id="' + headerId(m2) + '"', 3865 hLevel = headerLevelStart - 1 + m1.length, 3866 header = '<h' + hLevel + hID + '>' + span + '</h' + hLevel + '>'; 3867 3868 return showdown.subParser('hashBlock')(header, options, globals); 3869 }); 3870 3871 function headerId (m) { 3872 var title, 3873 prefix; 3874 3875 // It is separate from other options to allow combining prefix and customized 3876 if (options.customizedHeaderId) { 3877 var match = m.match(/\{([^{]+?)}\s*$/); 3878 if (match && match[1]) { 3879 m = match[1]; 3880 } 3881 } 3882 3883 title = m; 3884 3885 // Prefix id to prevent causing inadvertent pre-existing style matches. 3886 if (showdown.helper.isString(options.prefixHeaderId)) { 3887 prefix = options.prefixHeaderId; 3888 } else if (options.prefixHeaderId === true) { 3889 prefix = 'section-'; 3890 } else { 3891 prefix = ''; 3892 } 3893 3894 if (!options.rawPrefixHeaderId) { 3895 title = prefix + title; 3896 } 3897 3898 if (options.ghCompatibleHeaderId) { 3899 title = title 3900 .replace(/ /g, '-') 3901 // replace previously escaped chars (&, ¨ and $) 3902 .replace(/&/g, '') 3903 .replace(/¨T/g, '') 3904 .replace(/¨D/g, '') 3905 // replace rest of the chars (&~$ are repeated as they might have been escaped) 3906 // borrowed from github's redcarpet (some they should produce similar results) 3907 .replace(/[&+$,\/:;=?@"#{}|^¨~\[\]`\\*)(%.!'<>]/g, '') 3908 .toLowerCase(); 3909 } else if (options.rawHeaderId) { 3910 title = title 3911 .replace(/ /g, '-') 3912 // replace previously escaped chars (&, ¨ and $) 3913 .replace(/&/g, '&') 3914 .replace(/¨T/g, '¨') 3915 .replace(/¨D/g, '$') 3916 // replace " and ' 3917 .replace(/["']/g, '-') 3918 .toLowerCase(); 3919 } else { 3920 title = title 3921 .replace(/[^\w]/g, '') 3922 .toLowerCase(); 3923 } 3924 3925 if (options.rawPrefixHeaderId) { 3926 title = prefix + title; 3927 } 3928 3929 if (globals.hashLinkCounts[title]) { 3930 title = title + '-' + (globals.hashLinkCounts[title]++); 3931 } else { 3932 globals.hashLinkCounts[title] = 1; 3933 } 3934 return title; 3935 } 3936 3937 text = globals.converter._dispatch('headers.after', text, options, globals); 3938 return text; 3939 }); 3940 3941 /** 3942 * Turn Markdown link shortcuts into XHTML <a> tags. 3943 */ 3944 showdown.subParser('horizontalRule', function (text, options, globals) { 3945 'use strict'; 3946 text = globals.converter._dispatch('horizontalRule.before', text, options, globals); 3947 3948 var key = showdown.subParser('hashBlock')('<hr />', options, globals); 3949 text = text.replace(/^ {0,2}( ?-){3,}[ \t]*$/gm, key); 3950 text = text.replace(/^ {0,2}( ?\*){3,}[ \t]*$/gm, key); 3951 text = text.replace(/^ {0,2}( ?_){3,}[ \t]*$/gm, key); 3952 3953 text = globals.converter._dispatch('horizontalRule.after', text, options, globals); 3954 return text; 3955 }); 3956 3957 /** 3958 * Turn Markdown image shortcuts into <img> tags. 3959 */ 3960 showdown.subParser('images', function (text, options, globals) { 3961 'use strict'; 3962 3963 text = globals.converter._dispatch('images.before', text, options, globals); 3964 3965 var inlineRegExp = /!\[([^\]]*?)][ \t]*()\([ \t]?<?([\S]+?(?:\([\S]*?\)[\S]*?)?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(["'])([^"]*?)\6)?[ \t]?\)/g, 3966 crazyRegExp = /!\[([^\]]*?)][ \t]*()\([ \t]?<([^>]*)>(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(?:(["'])([^"]*?)\6))?[ \t]?\)/g, 3967 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, 3968 referenceRegExp = /!\[([^\]]*?)] ?(?:\n *)?\[([\s\S]*?)]()()()()()/g, 3969 refShortcutRegExp = /!\[([^\[\]]+)]()()()()()/g; 3970 3971 function writeImageTagBase64 (wholeMatch, altText, linkId, url, width, height, m5, title) { 3972 url = url.replace(/\s/g, ''); 3973 return writeImageTag (wholeMatch, altText, linkId, url, width, height, m5, title); 3974 } 3975 3976 function writeImageTag (wholeMatch, altText, linkId, url, width, height, m5, title) { 3977 3978 var gUrls = globals.gUrls, 3979 gTitles = globals.gTitles, 3980 gDims = globals.gDimensions; 3981 3982 linkId = linkId.toLowerCase(); 3983 3984 if (!title) { 3985 title = ''; 3986 } 3987 // Special case for explicit empty url 3988 if (wholeMatch.search(/\(<?\s*>? ?(['"].*['"])?\)$/m) > -1) { 3989 url = ''; 3990 3991 } else if (url === '' || url === null) { 3992 if (linkId === '' || linkId === null) { 3993 // lower-case and turn embedded newlines into spaces 3994 linkId = altText.toLowerCase().replace(/ ?\n/g, ' '); 3995 } 3996 url = '#' + linkId; 3997 3998 if (!showdown.helper.isUndefined(gUrls[linkId])) { 3999 url = gUrls[linkId]; 4000 if (!showdown.helper.isUndefined(gTitles[linkId])) { 4001 title = gTitles[linkId]; 4002 } 4003 if (!showdown.helper.isUndefined(gDims[linkId])) { 4004 width = gDims[linkId].width; 4005 height = gDims[linkId].height; 4006 } 4007 } else { 4008 return wholeMatch; 4009 } 4010 } 4011 4012 altText = altText 4013 .replace(/"/g, '"') 4014 //altText = showdown.helper.escapeCharacters(altText, '*_', false); 4015 .replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback); 4016 //url = showdown.helper.escapeCharacters(url, '*_', false); 4017 url = url.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback); 4018 var result = '<img src="' + url + '" alt="' + altText + '"'; 4019 4020 if (title && showdown.helper.isString(title)) { 4021 title = title 4022 .replace(/"/g, '"') 4023 //title = showdown.helper.escapeCharacters(title, '*_', false); 4024 .replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback); 4025 result += ' title="' + title + '"'; 4026 } 4027 4028 if (width && height) { 4029 width = (width === '*') ? 'auto' : width; 4030 height = (height === '*') ? 'auto' : height; 4031 4032 result += ' width="' + width + '"'; 4033 result += ' height="' + height + '"'; 4034 } 4035 4036 result += ' />'; 4037 4038 return result; 4039 } 4040 4041 // First, handle reference-style labeled images: ![alt text][id] 4042 text = text.replace(referenceRegExp, writeImageTag); 4043 4044 // Next, handle inline images: ![alt text](url =<width>x<height> "optional title") 4045 4046 // base64 encoded images 4047 text = text.replace(base64RegExp, writeImageTagBase64); 4048 4049 // cases with crazy urls like ./image/cat1).png 4050 text = text.replace(crazyRegExp, writeImageTag); 4051 4052 // normal cases 4053 text = text.replace(inlineRegExp, writeImageTag); 4054 4055 // handle reference-style shortcuts: ![img text] 4056 text = text.replace(refShortcutRegExp, writeImageTag); 4057 4058 text = globals.converter._dispatch('images.after', text, options, globals); 4059 return text; 4060 }); 4061 4062 showdown.subParser('italicsAndBold', function (text, options, globals) { 4063 'use strict'; 4064 4065 text = globals.converter._dispatch('italicsAndBold.before', text, options, globals); 4066 4067 // it's faster to have 3 separate regexes for each case than have just one 4068 // because of backtracing, in some cases, it could lead to an exponential effect 4069 // called "catastrophic backtrace". Ominous! 4070 4071 function parseInside (txt, left, right) { 4072 /* 4073 if (options.simplifiedAutoLink) { 4074 txt = showdown.subParser('simplifiedAutoLinks')(txt, options, globals); 4075 } 4076 */ 4077 return left + txt + right; 4078 } 4079 4080 // Parse underscores 4081 if (options.literalMidWordUnderscores) { 4082 text = text.replace(/\b___(\S[\s\S]*?)___\b/g, function (wm, txt) { 4083 return parseInside (txt, '<strong><em>', '</em></strong>'); 4084 }); 4085 text = text.replace(/\b__(\S[\s\S]*?)__\b/g, function (wm, txt) { 4086 return parseInside (txt, '<strong>', '</strong>'); 4087 }); 4088 text = text.replace(/\b_(\S[\s\S]*?)_\b/g, function (wm, txt) { 4089 return parseInside (txt, '<em>', '</em>'); 4090 }); 4091 } else { 4092 text = text.replace(/___(\S[\s\S]*?)___/g, function (wm, m) { 4093 return (/\S$/.test(m)) ? parseInside (m, '<strong><em>', '</em></strong>') : wm; 4094 }); 4095 text = text.replace(/__(\S[\s\S]*?)__/g, function (wm, m) { 4096 return (/\S$/.test(m)) ? parseInside (m, '<strong>', '</strong>') : wm; 4097 }); 4098 text = text.replace(/_([^\s_][\s\S]*?)_/g, function (wm, m) { 4099 // !/^_[^_]/.test(m) - test if it doesn't start with __ (since it seems redundant, we removed it) 4100 return (/\S$/.test(m)) ? parseInside (m, '<em>', '</em>') : wm; 4101 }); 4102 } 4103 4104 // Now parse asterisks 4105 if (options.literalMidWordAsterisks) { 4106 text = text.replace(/([^*]|^)\B\*\*\*(\S[\s\S]*?)\*\*\*\B(?!\*)/g, function (wm, lead, txt) { 4107 return parseInside (txt, lead + '<strong><em>', '</em></strong>'); 4108 }); 4109 text = text.replace(/([^*]|^)\B\*\*(\S[\s\S]*?)\*\*\B(?!\*)/g, function (wm, lead, txt) { 4110 return parseInside (txt, lead + '<strong>', '</strong>'); 4111 }); 4112 text = text.replace(/([^*]|^)\B\*(\S[\s\S]*?)\*\B(?!\*)/g, function (wm, lead, txt) { 4113 return parseInside (txt, lead + '<em>', '</em>'); 4114 }); 4115 } else { 4116 text = text.replace(/\*\*\*(\S[\s\S]*?)\*\*\*/g, function (wm, m) { 4117 return (/\S$/.test(m)) ? parseInside (m, '<strong><em>', '</em></strong>') : wm; 4118 }); 4119 text = text.replace(/\*\*(\S[\s\S]*?)\*\*/g, function (wm, m) { 4120 return (/\S$/.test(m)) ? parseInside (m, '<strong>', '</strong>') : wm; 4121 }); 4122 text = text.replace(/\*([^\s*][\s\S]*?)\*/g, function (wm, m) { 4123 // !/^\*[^*]/.test(m) - test if it doesn't start with ** (since it seems redundant, we removed it) 4124 return (/\S$/.test(m)) ? parseInside (m, '<em>', '</em>') : wm; 4125 }); 4126 } 4127 4128 4129 text = globals.converter._dispatch('italicsAndBold.after', text, options, globals); 4130 return text; 4131 }); 4132 4133 /** 4134 * Form HTML ordered (numbered) and unordered (bulleted) lists. 4135 */ 4136 showdown.subParser('lists', function (text, options, globals) { 4137 'use strict'; 4138 4139 /** 4140 * Process the contents of a single ordered or unordered list, splitting it 4141 * into individual list items. 4142 * @param {string} listStr 4143 * @param {boolean} trimTrailing 4144 * @returns {string} 4145 */ 4146 function processListItems (listStr, trimTrailing) { 4147 // The $g_list_level global keeps track of when we're inside a list. 4148 // Each time we enter a list, we increment it; when we leave a list, 4149 // we decrement. If it's zero, we're not in a list anymore. 4150 // 4151 // We do this because when we're not inside a list, we want to treat 4152 // something like this: 4153 // 4154 // I recommend upgrading to version 4155 // 8. Oops, now this line is treated 4156 // as a sub-list. 4157 // 4158 // As a single paragraph, despite the fact that the second line starts 4159 // with a digit-period-space sequence. 4160 // 4161 // Whereas when we're inside a list (or sub-list), that line will be 4162 // treated as the start of a sub-list. What a kludge, huh? This is 4163 // an aspect of Markdown's syntax that's hard to parse perfectly 4164 // without resorting to mind-reading. Perhaps the solution is to 4165 // change the syntax rules such that sub-lists must start with a 4166 // starting cardinal number; e.g. "1." or "a.". 4167 globals.gListLevel++; 4168 4169 // trim trailing blank lines: 4170 listStr = listStr.replace(/\n{2,}$/, '\n'); 4171 4172 // attacklab: add sentinel to emulate \z 4173 listStr += '¨0'; 4174 4175 var rgx = /(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0| {0,3}([*+-]|\d+[.])[ \t]+))/gm, 4176 isParagraphed = (/\n[ \t]*\n(?!¨0)/.test(listStr)); 4177 4178 // Since version 1.5, nesting sublists requires 4 spaces (or 1 tab) indentation, 4179 // which is a syntax breaking change 4180 // activating this option reverts to old behavior 4181 if (options.disableForced4SpacesIndentedSublists) { 4182 rgx = /(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0|\2([*+-]|\d+[.])[ \t]+))/gm; 4183 } 4184 4185 listStr = listStr.replace(rgx, function (wholeMatch, m1, m2, m3, m4, taskbtn, checked) { 4186 checked = (checked && checked.trim() !== ''); 4187 4188 var item = showdown.subParser('outdent')(m4, options, globals), 4189 bulletStyle = ''; 4190 4191 // Support for github tasklists 4192 if (taskbtn && options.tasklists) { 4193 bulletStyle = ' class="task-list-item" style="list-style-type: none;"'; 4194 item = item.replace(/^[ \t]*\[(x|X| )?]/m, function () { 4195 var otp = '<input type="checkbox" disabled style="margin: 0px 0.35em 0.25em -1.6em; vertical-align: middle;"'; 4196 if (checked) { 4197 otp += ' checked'; 4198 } 4199 otp += '>'; 4200 return otp; 4201 }); 4202 } 4203 4204 // ISSUE #312 4205 // This input: - - - a 4206 // causes trouble to the parser, since it interprets it as: 4207 // <ul><li><li><li>a</li></li></li></ul> 4208 // instead of: 4209 // <ul><li>- - a</li></ul> 4210 // So, to prevent it, we will put a marker (¨A)in the beginning of the line 4211 // Kind of hackish/monkey patching, but seems more effective than overcomplicating the list parser 4212 item = item.replace(/^([-*+]|\d\.)[ \t]+[\S\n ]*/g, function (wm2) { 4213 return '¨A' + wm2; 4214 }); 4215 4216 // m1 - Leading line or 4217 // Has a double return (multi paragraph) or 4218 // Has sublist 4219 if (m1 || (item.search(/\n{2,}/) > -1)) { 4220 item = showdown.subParser('githubCodeBlocks')(item, options, globals); 4221 item = showdown.subParser('blockGamut')(item, options, globals); 4222 } else { 4223 // Recursion for sub-lists: 4224 item = showdown.subParser('lists')(item, options, globals); 4225 item = item.replace(/\n$/, ''); // chomp(item) 4226 item = showdown.subParser('hashHTMLBlocks')(item, options, globals); 4227 4228 // Colapse double linebreaks 4229 item = item.replace(/\n\n+/g, '\n\n'); 4230 if (isParagraphed) { 4231 item = showdown.subParser('paragraphs')(item, options, globals); 4232 } else { 4233 item = showdown.subParser('spanGamut')(item, options, globals); 4234 } 4235 } 4236 4237 // now we need to remove the marker (¨A) 4238 item = item.replace('¨A', ''); 4239 // we can finally wrap the line in list item tags 4240 item = '<li' + bulletStyle + '>' + item + '</li>\n'; 4241 4242 return item; 4243 }); 4244 4245 // attacklab: strip sentinel 4246 listStr = listStr.replace(/¨0/g, ''); 4247 4248 globals.gListLevel--; 4249 4250 if (trimTrailing) { 4251 listStr = listStr.replace(/\s+$/, ''); 4252 } 4253 4254 return listStr; 4255 } 4256 4257 function styleStartNumber (list, listType) { 4258 // check if ol and starts by a number different than 1 4259 if (listType === 'ol') { 4260 var res = list.match(/^ *(\d+)\./); 4261 if (res && res[1] !== '1') { 4262 return ' start="' + res[1] + '"'; 4263 } 4264 } 4265 return ''; 4266 } 4267 4268 /** 4269 * Check and parse consecutive lists (better fix for issue #142) 4270 * @param {string} list 4271 * @param {string} listType 4272 * @param {boolean} trimTrailing 4273 * @returns {string} 4274 */ 4275 function parseConsecutiveLists (list, listType, trimTrailing) { 4276 // check if we caught 2 or more consecutive lists by mistake 4277 // we use the counterRgx, meaning if listType is UL we look for OL and vice versa 4278 var olRgx = (options.disableForced4SpacesIndentedSublists) ? /^ ?\d+\.[ \t]/gm : /^ {0,3}\d+\.[ \t]/gm, 4279 ulRgx = (options.disableForced4SpacesIndentedSublists) ? /^ ?[*+-][ \t]/gm : /^ {0,3}[*+-][ \t]/gm, 4280 counterRxg = (listType === 'ul') ? olRgx : ulRgx, 4281 result = ''; 4282 4283 if (list.search(counterRxg) !== -1) { 4284 (function parseCL (txt) { 4285 var pos = txt.search(counterRxg), 4286 style = styleStartNumber(list, listType); 4287 if (pos !== -1) { 4288 // slice 4289 result += '\n\n<' + listType + style + '>\n' + processListItems(txt.slice(0, pos), !!trimTrailing) + '</' + listType + '>\n'; 4290 4291 // invert counterType and listType 4292 listType = (listType === 'ul') ? 'ol' : 'ul'; 4293 counterRxg = (listType === 'ul') ? olRgx : ulRgx; 4294 4295 //recurse 4296 parseCL(txt.slice(pos)); 4297 } else { 4298 result += '\n\n<' + listType + style + '>\n' + processListItems(txt, !!trimTrailing) + '</' + listType + '>\n'; 4299 } 4300 })(list); 4301 } else { 4302 var style = styleStartNumber(list, listType); 4303 result = '\n\n<' + listType + style + '>\n' + processListItems(list, !!trimTrailing) + '</' + listType + '>\n'; 4304 } 4305 4306 return result; 4307 } 4308 4309 /** Start of list parsing **/ 4310 text = globals.converter._dispatch('lists.before', text, options, globals); 4311 // add sentinel to hack around khtml/safari bug: 4312 // http://bugs.webkit.org/show_bug.cgi?id=11231 4313 text += '¨0'; 4314 4315 if (globals.gListLevel) { 4316 text = text.replace(/^(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(¨0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm, 4317 function (wholeMatch, list, m2) { 4318 var listType = (m2.search(/[*+-]/g) > -1) ? 'ul' : 'ol'; 4319 return parseConsecutiveLists(list, listType, true); 4320 } 4321 ); 4322 } else { 4323 text = text.replace(/(\n\n|^\n?)(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(¨0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm, 4324 function (wholeMatch, m1, list, m3) { 4325 var listType = (m3.search(/[*+-]/g) > -1) ? 'ul' : 'ol'; 4326 return parseConsecutiveLists(list, listType, false); 4327 } 4328 ); 4329 } 4330 4331 // strip sentinel 4332 text = text.replace(/¨0/, ''); 4333 text = globals.converter._dispatch('lists.after', text, options, globals); 4334 return text; 4335 }); 4336 4337 /** 4338 * Parse metadata at the top of the document 4339 */ 4340 showdown.subParser('metadata', function (text, options, globals) { 4341 'use strict'; 4342 4343 if (!options.metadata) { 4344 return text; 4345 } 4346 4347 text = globals.converter._dispatch('metadata.before', text, options, globals); 4348 4349 function parseMetadataContents (content) { 4350 // raw is raw so it's not changed in any way 4351 globals.metadata.raw = content; 4352 4353 // escape chars forbidden in html attributes 4354 // double quotes 4355 content = content 4356 // ampersand first 4357 .replace(/&/g, '&') 4358 // double quotes 4359 .replace(/"/g, '"'); 4360 4361 content = content.replace(/\n {4}/g, ' '); 4362 content.replace(/^([\S ]+): +([\s\S]+?)$/gm, function (wm, key, value) { 4363 globals.metadata.parsed[key] = value; 4364 return ''; 4365 }); 4366 } 4367 4368 text = text.replace(/^\s*«««+(\S*?)\n([\s\S]+?)\n»»»+\n/, function (wholematch, format, content) { 4369 parseMetadataContents(content); 4370 return '¨M'; 4371 }); 4372 4373 text = text.replace(/^\s*---+(\S*?)\n([\s\S]+?)\n---+\n/, function (wholematch, format, content) { 4374 if (format) { 4375 globals.metadata.format = format; 4376 } 4377 parseMetadataContents(content); 4378 return '¨M'; 4379 }); 4380 4381 text = text.replace(/¨M/g, ''); 4382 4383 text = globals.converter._dispatch('metadata.after', text, options, globals); 4384 return text; 4385 }); 4386 4387 /** 4388 * Remove one level of line-leading tabs or spaces 4389 */ 4390 showdown.subParser('outdent', function (text, options, globals) { 4391 'use strict'; 4392 text = globals.converter._dispatch('outdent.before', text, options, globals); 4393 4394 // attacklab: hack around Konqueror 3.5.4 bug: 4395 // "----------bug".replace(/^-/g,"") == "bug" 4396 text = text.replace(/^(\t|[ ]{1,4})/gm, '¨0'); // attacklab: g_tab_width 4397 4398 // attacklab: clean up hack 4399 text = text.replace(/¨0/g, ''); 4400 4401 text = globals.converter._dispatch('outdent.after', text, options, globals); 4402 return text; 4403 }); 4404 4405 /** 4406 * 4407 */ 4408 showdown.subParser('paragraphs', function (text, options, globals) { 4409 'use strict'; 4410 4411 text = globals.converter._dispatch('paragraphs.before', text, options, globals); 4412 // Strip leading and trailing lines: 4413 text = text.replace(/^\n+/g, ''); 4414 text = text.replace(/\n+$/g, ''); 4415 4416 var grafs = text.split(/\n{2,}/g), 4417 grafsOut = [], 4418 end = grafs.length; // Wrap <p> tags 4419 4420 for (var i = 0; i < end; i++) { 4421 var str = grafs[i]; 4422 // if this is an HTML marker, copy it 4423 if (str.search(/¨(K|G)(\d+)\1/g) >= 0) { 4424 grafsOut.push(str); 4425 4426 // test for presence of characters to prevent empty lines being parsed 4427 // as paragraphs (resulting in undesired extra empty paragraphs) 4428 } else if (str.search(/\S/) >= 0) { 4429 str = showdown.subParser('spanGamut')(str, options, globals); 4430 str = str.replace(/^([ \t]*)/g, '<p>'); 4431 str += '</p>'; 4432 grafsOut.push(str); 4433 } 4434 } 4435 4436 /** Unhashify HTML blocks */ 4437 end = grafsOut.length; 4438 for (i = 0; i < end; i++) { 4439 var blockText = '', 4440 grafsOutIt = grafsOut[i], 4441 codeFlag = false; 4442 // if this is a marker for an html block... 4443 // use RegExp.test instead of string.search because of QML bug 4444 while (/¨(K|G)(\d+)\1/.test(grafsOutIt)) { 4445 var delim = RegExp.$1, 4446 num = RegExp.$2; 4447 4448 if (delim === 'K') { 4449 blockText = globals.gHtmlBlocks[num]; 4450 } else { 4451 // we need to check if ghBlock is a false positive 4452 if (codeFlag) { 4453 // use encoded version of all text 4454 blockText = showdown.subParser('encodeCode')(globals.ghCodeBlocks[num].text, options, globals); 4455 } else { 4456 blockText = globals.ghCodeBlocks[num].codeblock; 4457 } 4458 } 4459 blockText = blockText.replace(/\$/g, '$$$$'); // Escape any dollar signs 4460 4461 grafsOutIt = grafsOutIt.replace(/(\n\n)?¨(K|G)\d+\2(\n\n)?/, blockText); 4462 // Check if grafsOutIt is a pre->code 4463 if (/^<pre\b[^>]*>\s*<code\b[^>]*>/.test(grafsOutIt)) { 4464 codeFlag = true; 4465 } 4466 } 4467 grafsOut[i] = grafsOutIt; 4468 } 4469 text = grafsOut.join('\n'); 4470 // Strip leading and trailing lines: 4471 text = text.replace(/^\n+/g, ''); 4472 text = text.replace(/\n+$/g, ''); 4473 return globals.converter._dispatch('paragraphs.after', text, options, globals); 4474 }); 4475 4476 /** 4477 * Run extension 4478 */ 4479 showdown.subParser('runExtension', function (ext, text, options, globals) { 4480 'use strict'; 4481 4482 if (ext.filter) { 4483 text = ext.filter(text, globals.converter, options); 4484 4485 } else if (ext.regex) { 4486 // TODO remove this when old extension loading mechanism is deprecated 4487 var re = ext.regex; 4488 if (!(re instanceof RegExp)) { 4489 re = new RegExp(re, 'g'); 4490 } 4491 text = text.replace(re, ext.replace); 4492 } 4493 4494 return text; 4495 }); 4496 4497 /** 4498 * These are all the transformations that occur *within* block-level 4499 * tags like paragraphs, headers, and list items. 4500 */ 4501 showdown.subParser('spanGamut', function (text, options, globals) { 4502 'use strict'; 4503 4504 text = globals.converter._dispatch('spanGamut.before', text, options, globals); 4505 text = showdown.subParser('codeSpans')(text, options, globals); 4506 text = showdown.subParser('escapeSpecialCharsWithinTagAttributes')(text, options, globals); 4507 text = showdown.subParser('encodeBackslashEscapes')(text, options, globals); 4508 4509 // Process anchor and image tags. Images must come first, 4510 // because ![foo][f] looks like an anchor. 4511 text = showdown.subParser('images')(text, options, globals); 4512 text = showdown.subParser('anchors')(text, options, globals); 4513 4514 // Make links out of things like `<http://example.com/>` 4515 // Must come after anchors, because you can use < and > 4516 // delimiters in inline links like [this](<url>). 4517 text = showdown.subParser('autoLinks')(text, options, globals); 4518 text = showdown.subParser('simplifiedAutoLinks')(text, options, globals); 4519 text = showdown.subParser('emoji')(text, options, globals); 4520 text = showdown.subParser('underline')(text, options, globals); 4521 text = showdown.subParser('italicsAndBold')(text, options, globals); 4522 text = showdown.subParser('strikethrough')(text, options, globals); 4523 text = showdown.subParser('ellipsis')(text, options, globals); 4524 4525 // we need to hash HTML tags inside spans 4526 text = showdown.subParser('hashHTMLSpans')(text, options, globals); 4527 4528 // now we encode amps and angles 4529 text = showdown.subParser('encodeAmpsAndAngles')(text, options, globals); 4530 4531 // Do hard breaks 4532 if (options.simpleLineBreaks) { 4533 // GFM style hard breaks 4534 // only add line breaks if the text does not contain a block (special case for lists) 4535 if (!/\n\n¨K/.test(text)) { 4536 text = text.replace(/\n+/g, '<br />\n'); 4537 } 4538 } else { 4539 // Vanilla hard breaks 4540 text = text.replace(/ +\n/g, '<br />\n'); 4541 } 4542 4543 text = globals.converter._dispatch('spanGamut.after', text, options, globals); 4544 return text; 4545 }); 4546 4547 showdown.subParser('strikethrough', function (text, options, globals) { 4548 'use strict'; 4549 4550 function parseInside (txt) { 4551 if (options.simplifiedAutoLink) { 4552 txt = showdown.subParser('simplifiedAutoLinks')(txt, options, globals); 4553 } 4554 return '<del>' + txt + '</del>'; 4555 } 4556 4557 if (options.strikethrough) { 4558 text = globals.converter._dispatch('strikethrough.before', text, options, globals); 4559 text = text.replace(/(?:~){2}([\s\S]+?)(?:~){2}/g, function (wm, txt) { return parseInside(txt); }); 4560 text = globals.converter._dispatch('strikethrough.after', text, options, globals); 4561 } 4562 4563 return text; 4564 }); 4565 4566 /** 4567 * Strips link definitions from text, stores the URLs and titles in 4568 * hash references. 4569 * Link defs are in the form: ^[id]: url "optional title" 4570 */ 4571 showdown.subParser('stripLinkDefinitions', function (text, options, globals) { 4572 'use strict'; 4573 4574 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, 4575 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; 4576 4577 // attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug 4578 text += '¨0'; 4579 4580 var replaceFunc = function (wholeMatch, linkId, url, width, height, blankLines, title) { 4581 linkId = linkId.toLowerCase(); 4582 if (url.match(/^data:.+?\/.+?;base64,/)) { 4583 // remove newlines 4584 globals.gUrls[linkId] = url.replace(/\s/g, ''); 4585 } else { 4586 globals.gUrls[linkId] = showdown.subParser('encodeAmpsAndAngles')(url, options, globals); // Link IDs are case-insensitive 4587 } 4588 4589 if (blankLines) { 4590 // Oops, found blank lines, so it's not a title. 4591 // Put back the parenthetical statement we stole. 4592 return blankLines + title; 4593 4594 } else { 4595 if (title) { 4596 globals.gTitles[linkId] = title.replace(/"|'/g, '"'); 4597 } 4598 if (options.parseImgDimensions && width && height) { 4599 globals.gDimensions[linkId] = { 4600 width: width, 4601 height: height 4602 }; 4603 } 4604 } 4605 // Completely remove the definition from the text 4606 return ''; 4607 }; 4608 4609 // first we try to find base64 link references 4610 text = text.replace(base64Regex, replaceFunc); 4611 4612 text = text.replace(regex, replaceFunc); 4613 4614 // attacklab: strip sentinel 4615 text = text.replace(/¨0/, ''); 4616 4617 return text; 4618 }); 4619 4620 showdown.subParser('tables', function (text, options, globals) { 4621 'use strict'; 4622 4623 if (!options.tables) { 4624 return text; 4625 } 4626 4627 var tableRgx = /^ {0,3}\|?.+\|.+\n {0,3}\|?[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*:?[ \t]*(?:[-=]){2,}[\s\S]+?(?:\n\n|¨0)/gm, 4628 //singeColTblRgx = /^ {0,3}\|.+\|\n {0,3}\|[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*\n(?: {0,3}\|.+\|\n)+(?:\n\n|¨0)/gm; 4629 singeColTblRgx = /^ {0,3}\|.+\|[ \t]*\n {0,3}\|[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*\n( {0,3}\|.+\|[ \t]*\n)*(?:\n|¨0)/gm; 4630 4631 function parseStyles (sLine) { 4632 if (/^:[ \t]*--*$/.test(sLine)) { 4633 return ' style="text-align:left;"'; 4634 } else if (/^--*[ \t]*:[ \t]*$/.test(sLine)) { 4635 return ' style="text-align:right;"'; 4636 } else if (/^:[ \t]*--*[ \t]*:$/.test(sLine)) { 4637 return ' style="text-align:center;"'; 4638 } else { 4639 return ''; 4640 } 4641 } 4642 4643 function parseHeaders (header, style) { 4644 var id = ''; 4645 header = header.trim(); 4646 // support both tablesHeaderId and tableHeaderId due to error in documentation so we don't break backwards compatibility 4647 if (options.tablesHeaderId || options.tableHeaderId) { 4648 id = ' id="' + header.replace(/ /g, '_').toLowerCase() + '"'; 4649 } 4650 header = showdown.subParser('spanGamut')(header, options, globals); 4651 4652 return '<th' + id + style + '>' + header + '</th>\n'; 4653 } 4654 4655 function parseCells (cell, style) { 4656 var subText = showdown.subParser('spanGamut')(cell, options, globals); 4657 return '<td' + style + '>' + subText + '</td>\n'; 4658 } 4659 4660 function buildTable (headers, cells) { 4661 var tb = '<table>\n<thead>\n<tr>\n', 4662 tblLgn = headers.length; 4663 4664 for (var i = 0; i < tblLgn; ++i) { 4665 tb += headers[i]; 4666 } 4667 tb += '</tr>\n</thead>\n<tbody>\n'; 4668 4669 for (i = 0; i < cells.length; ++i) { 4670 tb += '<tr>\n'; 4671 for (var ii = 0; ii < tblLgn; ++ii) { 4672 tb += cells[i][ii]; 4673 } 4674 tb += '</tr>\n'; 4675 } 4676 tb += '</tbody>\n</table>\n'; 4677 return tb; 4678 } 4679 4680 function parseTable (rawTable) { 4681 var i, tableLines = rawTable.split('\n'); 4682 4683 for (i = 0; i < tableLines.length; ++i) { 4684 // strip wrong first and last column if wrapped tables are used 4685 if (/^ {0,3}\|/.test(tableLines[i])) { 4686 tableLines[i] = tableLines[i].replace(/^ {0,3}\|/, ''); 4687 } 4688 if (/\|[ \t]*$/.test(tableLines[i])) { 4689 tableLines[i] = tableLines[i].replace(/\|[ \t]*$/, ''); 4690 } 4691 // parse code spans first, but we only support one line code spans 4692 tableLines[i] = showdown.subParser('codeSpans')(tableLines[i], options, globals); 4693 } 4694 4695 var rawHeaders = tableLines[0].split('|').map(function (s) { return s.trim();}), 4696 rawStyles = tableLines[1].split('|').map(function (s) { return s.trim();}), 4697 rawCells = [], 4698 headers = [], 4699 styles = [], 4700 cells = []; 4701 4702 tableLines.shift(); 4703 tableLines.shift(); 4704 4705 for (i = 0; i < tableLines.length; ++i) { 4706 if (tableLines[i].trim() === '') { 4707 continue; 4708 } 4709 rawCells.push( 4710 tableLines[i] 4711 .split('|') 4712 .map(function (s) { 4713 return s.trim(); 4714 }) 4715 ); 4716 } 4717 4718 if (rawHeaders.length < rawStyles.length) { 4719 return rawTable; 4720 } 4721 4722 for (i = 0; i < rawStyles.length; ++i) { 4723 styles.push(parseStyles(rawStyles[i])); 4724 } 4725 4726 for (i = 0; i < rawHeaders.length; ++i) { 4727 if (showdown.helper.isUndefined(styles[i])) { 4728 styles[i] = ''; 4729 } 4730 headers.push(parseHeaders(rawHeaders[i], styles[i])); 4731 } 4732 4733 for (i = 0; i < rawCells.length; ++i) { 4734 var row = []; 4735 for (var ii = 0; ii < headers.length; ++ii) { 4736 if (showdown.helper.isUndefined(rawCells[i][ii])) { 4737 4738 } 4739 row.push(parseCells(rawCells[i][ii], styles[ii])); 4740 } 4741 cells.push(row); 4742 } 4743 4744 return buildTable(headers, cells); 4745 } 4746 4747 text = globals.converter._dispatch('tables.before', text, options, globals); 4748 4749 // find escaped pipe characters 4750 text = text.replace(/\\(\|)/g, showdown.helper.escapeCharactersCallback); 4751 4752 // parse multi column tables 4753 text = text.replace(tableRgx, parseTable); 4754 4755 // parse one column tables 4756 text = text.replace(singeColTblRgx, parseTable); 4757 4758 text = globals.converter._dispatch('tables.after', text, options, globals); 4759 4760 return text; 4761 }); 4762 4763 showdown.subParser('underline', function (text, options, globals) { 4764 'use strict'; 4765 4766 if (!options.underline) { 4767 return text; 4768 } 4769 4770 text = globals.converter._dispatch('underline.before', text, options, globals); 4771 4772 if (options.literalMidWordUnderscores) { 4773 text = text.replace(/\b___(\S[\s\S]*?)___\b/g, function (wm, txt) { 4774 return '<u>' + txt + '</u>'; 4775 }); 4776 text = text.replace(/\b__(\S[\s\S]*?)__\b/g, function (wm, txt) { 4777 return '<u>' + txt + '</u>'; 4778 }); 4779 } else { 4780 text = text.replace(/___(\S[\s\S]*?)___/g, function (wm, m) { 4781 return (/\S$/.test(m)) ? '<u>' + m + '</u>' : wm; 4782 }); 4783 text = text.replace(/__(\S[\s\S]*?)__/g, function (wm, m) { 4784 return (/\S$/.test(m)) ? '<u>' + m + '</u>' : wm; 4785 }); 4786 } 4787 4788 // escape remaining underscores to prevent them being parsed by italic and bold 4789 text = text.replace(/(_)/g, showdown.helper.escapeCharactersCallback); 4790 4791 text = globals.converter._dispatch('underline.after', text, options, globals); 4792 4793 return text; 4794 }); 4795 4796 /** 4797 * Swap back in all the special characters we've hidden. 4798 */ 4799 showdown.subParser('unescapeSpecialChars', function (text, options, globals) { 4800 'use strict'; 4801 text = globals.converter._dispatch('unescapeSpecialChars.before', text, options, globals); 4802 4803 text = text.replace(/¨E(\d+)E/g, function (wholeMatch, m1) { 4804 var charCodeToReplace = parseInt(m1); 4805 return String.fromCharCode(charCodeToReplace); 4806 }); 4807 4808 text = globals.converter._dispatch('unescapeSpecialChars.after', text, options, globals); 4809 return text; 4810 }); 4811 4812 showdown.subParser('makeMarkdown.blockquote', function (node, globals) { 4813 'use strict'; 4814 4815 var txt = ''; 4816 if (node.hasChildNodes()) { 4817 var children = node.childNodes, 4818 childrenLength = children.length; 4819 4820 for (var i = 0; i < childrenLength; ++i) { 4821 var innerTxt = showdown.subParser('makeMarkdown.node')(children[i], globals); 4822 4823 if (innerTxt === '') { 4824 continue; 4825 } 4826 txt += innerTxt; 4827 } 4828 } 4829 // cleanup 4830 txt = txt.trim(); 4831 txt = '> ' + txt.split('\n').join('\n> '); 4832 return txt; 4833 }); 4834 4835 showdown.subParser('makeMarkdown.codeBlock', function (node, globals) { 4836 'use strict'; 4837 4838 var lang = node.getAttribute('language'), 4839 num = node.getAttribute('precodenum'); 4840 return '```' + lang + '\n' + globals.preList[num] + '\n```'; 4841 }); 4842 4843 showdown.subParser('makeMarkdown.codeSpan', function (node) { 4844 'use strict'; 4845 4846 return '`' + node.innerHTML + '`'; 4847 }); 4848 4849 showdown.subParser('makeMarkdown.emphasis', function (node, globals) { 4850 'use strict'; 4851 4852 var txt = ''; 4853 if (node.hasChildNodes()) { 4854 txt += '*'; 4855 var children = node.childNodes, 4856 childrenLength = children.length; 4857 for (var i = 0; i < childrenLength; ++i) { 4858 txt += showdown.subParser('makeMarkdown.node')(children[i], globals); 4859 } 4860 txt += '*'; 4861 } 4862 return txt; 4863 }); 4864 4865 showdown.subParser('makeMarkdown.header', function (node, globals, headerLevel) { 4866 'use strict'; 4867 4868 var headerMark = new Array(headerLevel + 1).join('#'), 4869 txt = ''; 4870 4871 if (node.hasChildNodes()) { 4872 txt = headerMark + ' '; 4873 var children = node.childNodes, 4874 childrenLength = children.length; 4875 4876 for (var i = 0; i < childrenLength; ++i) { 4877 txt += showdown.subParser('makeMarkdown.node')(children[i], globals); 4878 } 4879 } 4880 return txt; 4881 }); 4882 4883 showdown.subParser('makeMarkdown.hr', function () { 4884 'use strict'; 4885 4886 return '---'; 4887 }); 4888 4889 showdown.subParser('makeMarkdown.image', function (node) { 4890 'use strict'; 4891 4892 var txt = ''; 4893 if (node.hasAttribute('src')) { 4894 txt += '![' + node.getAttribute('alt') + ']('; 4895 txt += '<' + node.getAttribute('src') + '>'; 4896 if (node.hasAttribute('width') && node.hasAttribute('height')) { 4897 txt += ' =' + node.getAttribute('width') + 'x' + node.getAttribute('height'); 4898 } 4899 4900 if (node.hasAttribute('title')) { 4901 txt += ' "' + node.getAttribute('title') + '"'; 4902 } 4903 txt += ')'; 4904 } 4905 return txt; 4906 }); 4907 4908 showdown.subParser('makeMarkdown.links', function (node, globals) { 4909 'use strict'; 4910 4911 var txt = ''; 4912 if (node.hasChildNodes() && node.hasAttribute('href')) { 4913 var children = node.childNodes, 4914 childrenLength = children.length; 4915 txt = '['; 4916 for (var i = 0; i < childrenLength; ++i) { 4917 txt += showdown.subParser('makeMarkdown.node')(children[i], globals); 4918 } 4919 txt += ']('; 4920 txt += '<' + node.getAttribute('href') + '>'; 4921 if (node.hasAttribute('title')) { 4922 txt += ' "' + node.getAttribute('title') + '"'; 4923 } 4924 txt += ')'; 4925 } 4926 return txt; 4927 }); 4928 4929 showdown.subParser('makeMarkdown.list', function (node, globals, type) { 4930 'use strict'; 4931 4932 var txt = ''; 4933 if (!node.hasChildNodes()) { 4934 return ''; 4935 } 4936 var listItems = node.childNodes, 4937 listItemsLenght = listItems.length, 4938 listNum = node.getAttribute('start') || 1; 4939 4940 for (var i = 0; i < listItemsLenght; ++i) { 4941 if (typeof listItems[i].tagName === 'undefined' || listItems[i].tagName.toLowerCase() !== 'li') { 4942 continue; 4943 } 4944 4945 // define the bullet to use in list 4946 var bullet = ''; 4947 if (type === 'ol') { 4948 bullet = listNum.toString() + '. '; 4949 } else { 4950 bullet = '- '; 4951 } 4952 4953 // parse list item 4954 txt += bullet + showdown.subParser('makeMarkdown.listItem')(listItems[i], globals); 4955 ++listNum; 4956 } 4957 4958 // add comment at the end to prevent consecutive lists to be parsed as one 4959 txt += '\n<!-- -->\n'; 4960 return txt.trim(); 4961 }); 4962 4963 showdown.subParser('makeMarkdown.listItem', function (node, globals) { 4964 'use strict'; 4965 4966 var listItemTxt = ''; 4967 4968 var children = node.childNodes, 4969 childrenLenght = children.length; 4970 4971 for (var i = 0; i < childrenLenght; ++i) { 4972 listItemTxt += showdown.subParser('makeMarkdown.node')(children[i], globals); 4973 } 4974 // if it's only one liner, we need to add a newline at the end 4975 if (!/\n$/.test(listItemTxt)) { 4976 listItemTxt += '\n'; 4977 } else { 4978 // it's multiparagraph, so we need to indent 4979 listItemTxt = listItemTxt 4980 .split('\n') 4981 .join('\n ') 4982 .replace(/^ {4}$/gm, '') 4983 .replace(/\n\n+/g, '\n\n'); 4984 } 4985 4986 return listItemTxt; 4987 }); 4988 4989 4990 4991 showdown.subParser('makeMarkdown.node', function (node, globals, spansOnly) { 4992 'use strict'; 4993 4994 spansOnly = spansOnly || false; 4995 4996 var txt = ''; 4997 4998 // edge case of text without wrapper paragraph 4999 if (node.nodeType === 3) { 5000 return showdown.subParser('makeMarkdown.txt')(node, globals); 5001 } 5002 5003 // HTML comment 5004 if (node.nodeType === 8) { 5005 return '<!--' + node.data + '-->\n\n'; 5006 } 5007 5008 // process only node elements 5009 if (node.nodeType !== 1) { 5010 return ''; 5011 } 5012 5013 var tagName = node.tagName.toLowerCase(); 5014 5015 switch (tagName) { 5016 5017 // 5018 // BLOCKS 5019 // 5020 case 'h1': 5021 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 1) + '\n\n'; } 5022 break; 5023 case 'h2': 5024 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 2) + '\n\n'; } 5025 break; 5026 case 'h3': 5027 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 3) + '\n\n'; } 5028 break; 5029 case 'h4': 5030 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 4) + '\n\n'; } 5031 break; 5032 case 'h5': 5033 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 5) + '\n\n'; } 5034 break; 5035 case 'h6': 5036 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 6) + '\n\n'; } 5037 break; 5038 5039 case 'p': 5040 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.paragraph')(node, globals) + '\n\n'; } 5041 break; 5042 5043 case 'blockquote': 5044 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.blockquote')(node, globals) + '\n\n'; } 5045 break; 5046 5047 case 'hr': 5048 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.hr')(node, globals) + '\n\n'; } 5049 break; 5050 5051 case 'ol': 5052 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.list')(node, globals, 'ol') + '\n\n'; } 5053 break; 5054 5055 case 'ul': 5056 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.list')(node, globals, 'ul') + '\n\n'; } 5057 break; 5058 5059 case 'precode': 5060 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.codeBlock')(node, globals) + '\n\n'; } 5061 break; 5062 5063 case 'pre': 5064 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.pre')(node, globals) + '\n\n'; } 5065 break; 5066 5067 case 'table': 5068 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.table')(node, globals) + '\n\n'; } 5069 break; 5070 5071 // 5072 // SPANS 5073 // 5074 case 'code': 5075 txt = showdown.subParser('makeMarkdown.codeSpan')(node, globals); 5076 break; 5077 5078 case 'em': 5079 case 'i': 5080 txt = showdown.subParser('makeMarkdown.emphasis')(node, globals); 5081 break; 5082 5083 case 'strong': 5084 case 'b': 5085 txt = showdown.subParser('makeMarkdown.strong')(node, globals); 5086 break; 5087 5088 case 'del': 5089 txt = showdown.subParser('makeMarkdown.strikethrough')(node, globals); 5090 break; 5091 5092 case 'a': 5093 txt = showdown.subParser('makeMarkdown.links')(node, globals); 5094 break; 5095 5096 case 'img': 5097 txt = showdown.subParser('makeMarkdown.image')(node, globals); 5098 break; 5099 5100 default: 5101 txt = node.outerHTML + '\n\n'; 5102 } 5103 5104 // common normalization 5105 // TODO eventually 5106 5107 return txt; 5108 }); 5109 5110 showdown.subParser('makeMarkdown.paragraph', function (node, globals) { 5111 'use strict'; 5112 5113 var txt = ''; 5114 if (node.hasChildNodes()) { 5115 var children = node.childNodes, 5116 childrenLength = children.length; 5117 for (var i = 0; i < childrenLength; ++i) { 5118 txt += showdown.subParser('makeMarkdown.node')(children[i], globals); 5119 } 5120 } 5121 5122 // some text normalization 5123 txt = txt.trim(); 5124 5125 return txt; 5126 }); 5127 5128 showdown.subParser('makeMarkdown.pre', function (node, globals) { 5129 'use strict'; 5130 5131 var num = node.getAttribute('prenum'); 5132 return '<pre>' + globals.preList[num] + '</pre>'; 5133 }); 5134 5135 showdown.subParser('makeMarkdown.strikethrough', function (node, globals) { 5136 'use strict'; 5137 5138 var txt = ''; 5139 if (node.hasChildNodes()) { 5140 txt += '~~'; 5141 var children = node.childNodes, 5142 childrenLength = children.length; 5143 for (var i = 0; i < childrenLength; ++i) { 5144 txt += showdown.subParser('makeMarkdown.node')(children[i], globals); 5145 } 5146 txt += '~~'; 5147 } 5148 return txt; 5149 }); 5150 5151 showdown.subParser('makeMarkdown.strong', function (node, globals) { 5152 'use strict'; 5153 5154 var txt = ''; 5155 if (node.hasChildNodes()) { 5156 txt += '**'; 5157 var children = node.childNodes, 5158 childrenLength = children.length; 5159 for (var i = 0; i < childrenLength; ++i) { 5160 txt += showdown.subParser('makeMarkdown.node')(children[i], globals); 5161 } 5162 txt += '**'; 5163 } 5164 return txt; 5165 }); 5166 5167 showdown.subParser('makeMarkdown.table', function (node, globals) { 5168 'use strict'; 5169 5170 var txt = '', 5171 tableArray = [[], []], 5172 headings = node.querySelectorAll('thead>tr>th'), 5173 rows = node.querySelectorAll('tbody>tr'), 5174 i, ii; 5175 for (i = 0; i < headings.length; ++i) { 5176 var headContent = showdown.subParser('makeMarkdown.tableCell')(headings[i], globals), 5177 allign = '---'; 5178 5179 if (headings[i].hasAttribute('style')) { 5180 var style = headings[i].getAttribute('style').toLowerCase().replace(/\s/g, ''); 5181 switch (style) { 5182 case 'text-align:left;': 5183 allign = ':---'; 5184 break; 5185 case 'text-align:right;': 5186 allign = '---:'; 5187 break; 5188 case 'text-align:center;': 5189 allign = ':---:'; 5190 break; 5191 } 5192 } 5193 tableArray[0][i] = headContent.trim(); 5194 tableArray[1][i] = allign; 5195 } 5196 5197 for (i = 0; i < rows.length; ++i) { 5198 var r = tableArray.push([]) - 1, 5199 cols = rows[i].getElementsByTagName('td'); 5200 5201 for (ii = 0; ii < headings.length; ++ii) { 5202 var cellContent = ' '; 5203 if (typeof cols[ii] !== 'undefined') { 5204 cellContent = showdown.subParser('makeMarkdown.tableCell')(cols[ii], globals); 5205 } 5206 tableArray[r].push(cellContent); 5207 } 5208 } 5209 5210 var cellSpacesCount = 3; 5211 for (i = 0; i < tableArray.length; ++i) { 5212 for (ii = 0; ii < tableArray[i].length; ++ii) { 5213 var strLen = tableArray[i][ii].length; 5214 if (strLen > cellSpacesCount) { 5215 cellSpacesCount = strLen; 5216 } 5217 } 5218 } 5219 5220 for (i = 0; i < tableArray.length; ++i) { 5221 for (ii = 0; ii < tableArray[i].length; ++ii) { 5222 if (i === 1) { 5223 if (tableArray[i][ii].slice(-1) === ':') { 5224 tableArray[i][ii] = showdown.helper.padEnd(tableArray[i][ii].slice(-1), cellSpacesCount - 1, '-') + ':'; 5225 } else { 5226 tableArray[i][ii] = showdown.helper.padEnd(tableArray[i][ii], cellSpacesCount, '-'); 5227 } 5228 } else { 5229 tableArray[i][ii] = showdown.helper.padEnd(tableArray[i][ii], cellSpacesCount); 5230 } 5231 } 5232 txt += '| ' + tableArray[i].join(' | ') + ' |\n'; 5233 } 5234 5235 return txt.trim(); 5236 }); 5237 5238 showdown.subParser('makeMarkdown.tableCell', function (node, globals) { 5239 'use strict'; 5240 5241 var txt = ''; 5242 if (!node.hasChildNodes()) { 5243 return ''; 5244 } 5245 var children = node.childNodes, 5246 childrenLength = children.length; 5247 5248 for (var i = 0; i < childrenLength; ++i) { 5249 txt += showdown.subParser('makeMarkdown.node')(children[i], globals, true); 5250 } 5251 return txt.trim(); 5252 }); 5253 5254 showdown.subParser('makeMarkdown.txt', function (node) { 5255 'use strict'; 5256 5257 var txt = node.nodeValue; 5258 5259 // multiple spaces are collapsed 5260 txt = txt.replace(/ +/g, ' '); 5261 5262 // replace the custom ¨NBSP; with a space 5263 txt = txt.replace(/¨NBSP;/g, ' '); 5264 5265 // ", <, > and & should replace escaped html entities 5266 txt = showdown.helper.unescapeHTMLEntities(txt); 5267 5268 // escape markdown magic characters 5269 // emphasis, strong and strikethrough - can appear everywhere 5270 // we also escape pipe (|) because of tables 5271 // and escape ` because of code blocks and spans 5272 txt = txt.replace(/([*_~|`])/g, '\\$1'); 5273 5274 // escape > because of blockquotes 5275 txt = txt.replace(/^(\s*)>/g, '\\$1>'); 5276 5277 // hash character, only troublesome at the beginning of a line because of headers 5278 txt = txt.replace(/^#/gm, '\\#'); 5279 5280 // horizontal rules 5281 txt = txt.replace(/^(\s*)([-=]{3,})(\s*)$/, '$1\\$2$3'); 5282 5283 // dot, because of ordered lists, only troublesome at the beginning of a line when preceded by an integer 5284 txt = txt.replace(/^( {0,3}\d+)\./gm, '$1\\.'); 5285 5286 // +, * and -, at the beginning of a line becomes a list, so we need to escape them also (asterisk was already escaped) 5287 txt = txt.replace(/^( {0,3})([+-])/gm, '$1\\$2'); 5288 5289 // images and links, ] followed by ( is problematic, so we escape it 5290 txt = txt.replace(/]([\s]*)\(/g, '\\]$1\\('); 5291 5292 // reference URIs must also be escaped 5293 txt = txt.replace(/^ {0,3}\[([\S \t]*?)]:/gm, '\\[$1]:'); 5294 5295 return txt; 5296 }); 5297 5298 var root = this; 5299 5300 // AMD Loader 5301 if (true) { 5302 !(__WEBPACK_AMD_DEFINE_RESULT__ = (function () { 5303 'use strict'; 5304 return showdown; 5305 }).call(exports, __webpack_require__, exports, module), 5306 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 5307 5308 // CommonJS/nodeJS Loader 5309 } else {} 5310 }).call(this); 5311 5312 5313 5314 5315 /***/ }) 5316 5317 /******/ }); 5318 /************************************************************************/ 5319 /******/ // The module cache 5320 /******/ var __webpack_module_cache__ = {}; 5321 /******/ 5322 /******/ // The require function 5323 /******/ function __webpack_require__(moduleId) { 5324 /******/ // Check if module is in cache 5325 /******/ var cachedModule = __webpack_module_cache__[moduleId]; 5326 /******/ if (cachedModule !== undefined) { 5327 /******/ return cachedModule.exports; 5328 /******/ } 5329 /******/ // Create a new module (and put it into the cache) 5330 /******/ var module = __webpack_module_cache__[moduleId] = { 5331 /******/ // no module.id needed 5332 /******/ // no module.loaded needed 5333 /******/ exports: {} 5334 /******/ }; 5335 /******/ 5336 /******/ // Execute the module function 5337 /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__); 5338 /******/ 5339 /******/ // Return the exports of the module 5340 /******/ return module.exports; 5341 /******/ } 5342 /******/ 5343 /************************************************************************/ 5344 /******/ /* webpack/runtime/compat get default export */ 5345 /******/ !function() { 5346 /******/ // getDefaultExport function for compatibility with non-harmony modules 5347 /******/ __webpack_require__.n = function(module) { 5348 /******/ var getter = module && module.__esModule ? 5349 /******/ function() { return module['default']; } : 5350 /******/ function() { return module; }; 5351 /******/ __webpack_require__.d(getter, { a: getter }); 5352 /******/ return getter; 5353 /******/ }; 5354 /******/ }(); 5355 /******/ 5356 /******/ /* webpack/runtime/define property getters */ 5357 /******/ !function() { 5358 /******/ // define getter functions for harmony exports 5359 /******/ __webpack_require__.d = function(exports, definition) { 5360 /******/ for(var key in definition) { 5361 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { 5362 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); 5363 /******/ } 5364 /******/ } 5365 /******/ }; 5366 /******/ }(); 5367 /******/ 5368 /******/ /* webpack/runtime/hasOwnProperty shorthand */ 5369 /******/ !function() { 5370 /******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); } 5371 /******/ }(); 5372 /******/ 5373 /******/ /* webpack/runtime/make namespace object */ 5374 /******/ !function() { 5375 /******/ // define __esModule on exports 5376 /******/ __webpack_require__.r = function(exports) { 5377 /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 5378 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 5379 /******/ } 5380 /******/ Object.defineProperty(exports, '__esModule', { value: true }); 5381 /******/ }; 5382 /******/ }(); 5383 /******/ 5384 /************************************************************************/ 5385 var __webpack_exports__ = {}; 5386 // This entry need to be wrapped in an IIFE because it need to be in strict mode. 5387 !function() { 5388 "use strict"; 5389 // ESM COMPAT FLAG 5390 __webpack_require__.r(__webpack_exports__); 5391 5392 // EXPORTS 5393 __webpack_require__.d(__webpack_exports__, { 5394 "__EXPERIMENTAL_ELEMENTS": function() { return /* reexport */ __EXPERIMENTAL_ELEMENTS; }, 5395 "__EXPERIMENTAL_PATHS_WITH_MERGE": function() { return /* reexport */ __EXPERIMENTAL_PATHS_WITH_MERGE; }, 5396 "__EXPERIMENTAL_STYLE_PROPERTY": function() { return /* reexport */ __EXPERIMENTAL_STYLE_PROPERTY; }, 5397 "__experimentalCloneSanitizedBlock": function() { return /* reexport */ __experimentalCloneSanitizedBlock; }, 5398 "__experimentalGetAccessibleBlockLabel": function() { return /* reexport */ getAccessibleBlockLabel; }, 5399 "__experimentalGetBlockAttributesNamesByRole": function() { return /* reexport */ __experimentalGetBlockAttributesNamesByRole; }, 5400 "__experimentalGetBlockLabel": function() { return /* reexport */ getBlockLabel; }, 5401 "__experimentalSanitizeBlockAttributes": function() { return /* reexport */ __experimentalSanitizeBlockAttributes; }, 5402 "__unstableGetBlockProps": function() { return /* reexport */ getBlockProps; }, 5403 "__unstableGetInnerBlocksProps": function() { return /* reexport */ getInnerBlocksProps; }, 5404 "__unstableSerializeAndClean": function() { return /* reexport */ __unstableSerializeAndClean; }, 5405 "children": function() { return /* reexport */ children; }, 5406 "cloneBlock": function() { return /* reexport */ cloneBlock; }, 5407 "createBlock": function() { return /* reexport */ createBlock; }, 5408 "createBlocksFromInnerBlocksTemplate": function() { return /* reexport */ createBlocksFromInnerBlocksTemplate; }, 5409 "doBlocksMatchTemplate": function() { return /* reexport */ doBlocksMatchTemplate; }, 5410 "findTransform": function() { return /* reexport */ findTransform; }, 5411 "getBlockAttributes": function() { return /* reexport */ getBlockAttributes; }, 5412 "getBlockContent": function() { return /* reexport */ getBlockInnerHTML; }, 5413 "getBlockDefaultClassName": function() { return /* reexport */ getBlockDefaultClassName; }, 5414 "getBlockFromExample": function() { return /* reexport */ getBlockFromExample; }, 5415 "getBlockMenuDefaultClassName": function() { return /* reexport */ getBlockMenuDefaultClassName; }, 5416 "getBlockSupport": function() { return /* reexport */ registration_getBlockSupport; }, 5417 "getBlockTransforms": function() { return /* reexport */ getBlockTransforms; }, 5418 "getBlockType": function() { return /* reexport */ registration_getBlockType; }, 5419 "getBlockTypes": function() { return /* reexport */ registration_getBlockTypes; }, 5420 "getBlockVariations": function() { return /* reexport */ registration_getBlockVariations; }, 5421 "getCategories": function() { return /* reexport */ categories_getCategories; }, 5422 "getChildBlockNames": function() { return /* reexport */ registration_getChildBlockNames; }, 5423 "getDefaultBlockName": function() { return /* reexport */ registration_getDefaultBlockName; }, 5424 "getFreeformContentHandlerName": function() { return /* reexport */ getFreeformContentHandlerName; }, 5425 "getGroupingBlockName": function() { return /* reexport */ registration_getGroupingBlockName; }, 5426 "getPhrasingContentSchema": function() { return /* reexport */ deprecatedGetPhrasingContentSchema; }, 5427 "getPossibleBlockTransformations": function() { return /* reexport */ getPossibleBlockTransformations; }, 5428 "getSaveContent": function() { return /* reexport */ getSaveContent; }, 5429 "getSaveElement": function() { return /* reexport */ getSaveElement; }, 5430 "getUnregisteredTypeHandlerName": function() { return /* reexport */ getUnregisteredTypeHandlerName; }, 5431 "hasBlockSupport": function() { return /* reexport */ registration_hasBlockSupport; }, 5432 "hasChildBlocks": function() { return /* reexport */ registration_hasChildBlocks; }, 5433 "hasChildBlocksWithInserterSupport": function() { return /* reexport */ registration_hasChildBlocksWithInserterSupport; }, 5434 "isReusableBlock": function() { return /* reexport */ isReusableBlock; }, 5435 "isTemplatePart": function() { return /* reexport */ isTemplatePart; }, 5436 "isUnmodifiedDefaultBlock": function() { return /* reexport */ isUnmodifiedDefaultBlock; }, 5437 "isValidBlockContent": function() { return /* reexport */ isValidBlockContent; }, 5438 "isValidIcon": function() { return /* reexport */ isValidIcon; }, 5439 "node": function() { return /* reexport */ node; }, 5440 "normalizeIconObject": function() { return /* reexport */ normalizeIconObject; }, 5441 "parse": function() { return /* reexport */ parser_parse; }, 5442 "parseWithAttributeSchema": function() { return /* reexport */ parseWithAttributeSchema; }, 5443 "pasteHandler": function() { return /* reexport */ pasteHandler; }, 5444 "rawHandler": function() { return /* reexport */ rawHandler; }, 5445 "registerBlockCollection": function() { return /* reexport */ registerBlockCollection; }, 5446 "registerBlockStyle": function() { return /* reexport */ registerBlockStyle; }, 5447 "registerBlockType": function() { return /* reexport */ registerBlockType; }, 5448 "registerBlockVariation": function() { return /* reexport */ registerBlockVariation; }, 5449 "serialize": function() { return /* reexport */ serializer_serialize; }, 5450 "serializeRawBlock": function() { return /* reexport */ serializeRawBlock; }, 5451 "setCategories": function() { return /* reexport */ categories_setCategories; }, 5452 "setDefaultBlockName": function() { return /* reexport */ setDefaultBlockName; }, 5453 "setFreeformContentHandlerName": function() { return /* reexport */ setFreeformContentHandlerName; }, 5454 "setGroupingBlockName": function() { return /* reexport */ setGroupingBlockName; }, 5455 "setUnregisteredTypeHandlerName": function() { return /* reexport */ setUnregisteredTypeHandlerName; }, 5456 "store": function() { return /* reexport */ store; }, 5457 "switchToBlockType": function() { return /* reexport */ switchToBlockType; }, 5458 "synchronizeBlocksWithTemplate": function() { return /* reexport */ synchronizeBlocksWithTemplate; }, 5459 "unregisterBlockStyle": function() { return /* reexport */ unregisterBlockStyle; }, 5460 "unregisterBlockType": function() { return /* reexport */ unregisterBlockType; }, 5461 "unregisterBlockVariation": function() { return /* reexport */ unregisterBlockVariation; }, 5462 "unstable__bootstrapServerSideBlockDefinitions": function() { return /* reexport */ unstable__bootstrapServerSideBlockDefinitions; }, 5463 "updateCategory": function() { return /* reexport */ categories_updateCategory; }, 5464 "validateBlock": function() { return /* reexport */ validateBlock; }, 5465 "withBlockContentContext": function() { return /* reexport */ withBlockContentContext; } 5466 }); 5467 5468 // NAMESPACE OBJECT: ./node_modules/@wordpress/blocks/build-module/store/selectors.js 5469 var selectors_namespaceObject = {}; 5470 __webpack_require__.r(selectors_namespaceObject); 5471 __webpack_require__.d(selectors_namespaceObject, { 5472 "__experimentalGetUnprocessedBlockTypes": function() { return __experimentalGetUnprocessedBlockTypes; }, 5473 "getActiveBlockVariation": function() { return getActiveBlockVariation; }, 5474 "getBlockStyles": function() { return getBlockStyles; }, 5475 "getBlockSupport": function() { return getBlockSupport; }, 5476 "getBlockType": function() { return getBlockType; }, 5477 "getBlockTypes": function() { return getBlockTypes; }, 5478 "getBlockVariations": function() { return getBlockVariations; }, 5479 "getCategories": function() { return getCategories; }, 5480 "getChildBlockNames": function() { return getChildBlockNames; }, 5481 "getCollections": function() { return getCollections; }, 5482 "getDefaultBlockName": function() { return getDefaultBlockName; }, 5483 "getDefaultBlockVariation": function() { return getDefaultBlockVariation; }, 5484 "getFreeformFallbackBlockName": function() { return getFreeformFallbackBlockName; }, 5485 "getGroupingBlockName": function() { return getGroupingBlockName; }, 5486 "getUnregisteredFallbackBlockName": function() { return getUnregisteredFallbackBlockName; }, 5487 "hasBlockSupport": function() { return hasBlockSupport; }, 5488 "hasChildBlocks": function() { return hasChildBlocks; }, 5489 "hasChildBlocksWithInserterSupport": function() { return hasChildBlocksWithInserterSupport; }, 5490 "isMatchingSearchTerm": function() { return isMatchingSearchTerm; } 5491 }); 5492 5493 // NAMESPACE OBJECT: ./node_modules/@wordpress/blocks/build-module/store/actions.js 5494 var actions_namespaceObject = {}; 5495 __webpack_require__.r(actions_namespaceObject); 5496 __webpack_require__.d(actions_namespaceObject, { 5497 "__experimentalReapplyBlockTypeFilters": function() { return __experimentalReapplyBlockTypeFilters; }, 5498 "__experimentalRegisterBlockType": function() { return __experimentalRegisterBlockType; }, 5499 "addBlockCollection": function() { return addBlockCollection; }, 5500 "addBlockStyles": function() { return addBlockStyles; }, 5501 "addBlockTypes": function() { return addBlockTypes; }, 5502 "addBlockVariations": function() { return addBlockVariations; }, 5503 "removeBlockCollection": function() { return removeBlockCollection; }, 5504 "removeBlockStyles": function() { return removeBlockStyles; }, 5505 "removeBlockTypes": function() { return removeBlockTypes; }, 5506 "removeBlockVariations": function() { return removeBlockVariations; }, 5507 "setCategories": function() { return setCategories; }, 5508 "setDefaultBlockName": function() { return actions_setDefaultBlockName; }, 5509 "setFreeformFallbackBlockName": function() { return setFreeformFallbackBlockName; }, 5510 "setGroupingBlockName": function() { return actions_setGroupingBlockName; }, 5511 "setUnregisteredFallbackBlockName": function() { return setUnregisteredFallbackBlockName; }, 5512 "updateCategory": function() { return updateCategory; } 5513 }); 5514 5515 ;// CONCATENATED MODULE: external ["wp","data"] 5516 var external_wp_data_namespaceObject = window["wp"]["data"]; 5517 ;// CONCATENATED MODULE: external "lodash" 5518 var external_lodash_namespaceObject = window["lodash"]; 5519 ;// CONCATENATED MODULE: external ["wp","i18n"] 5520 var external_wp_i18n_namespaceObject = window["wp"]["i18n"]; 5521 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/store/reducer.js 5522 /** 5523 * External dependencies 5524 */ 5525 5526 /** 5527 * WordPress dependencies 5528 */ 5529 5530 5531 5532 /** 5533 * @typedef {Object} WPBlockCategory 5534 * 5535 * @property {string} slug Unique category slug. 5536 * @property {string} title Category label, for display in user interface. 5537 */ 5538 5539 /** 5540 * Default set of categories. 5541 * 5542 * @type {WPBlockCategory[]} 5543 */ 5544 5545 const DEFAULT_CATEGORIES = [{ 5546 slug: 'text', 5547 title: (0,external_wp_i18n_namespaceObject.__)('Text') 5548 }, { 5549 slug: 'media', 5550 title: (0,external_wp_i18n_namespaceObject.__)('Media') 5551 }, { 5552 slug: 'design', 5553 title: (0,external_wp_i18n_namespaceObject.__)('Design') 5554 }, { 5555 slug: 'widgets', 5556 title: (0,external_wp_i18n_namespaceObject.__)('Widgets') 5557 }, { 5558 slug: 'theme', 5559 title: (0,external_wp_i18n_namespaceObject.__)('Theme') 5560 }, { 5561 slug: 'embed', 5562 title: (0,external_wp_i18n_namespaceObject.__)('Embeds') 5563 }, { 5564 slug: 'reusable', 5565 title: (0,external_wp_i18n_namespaceObject.__)('Reusable blocks') 5566 }]; 5567 /** 5568 * Reducer managing the unprocessed block types in a form passed when registering the by block. 5569 * It's for internal use only. It allows recomputing the processed block types on-demand after block type filters 5570 * get added or removed. 5571 * 5572 * @param {Object} state Current state. 5573 * @param {Object} action Dispatched action. 5574 * 5575 * @return {Object} Updated state. 5576 */ 5577 5578 function unprocessedBlockTypes() { 5579 let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 5580 let action = arguments.length > 1 ? arguments[1] : undefined; 5581 5582 switch (action.type) { 5583 case 'ADD_UNPROCESSED_BLOCK_TYPE': 5584 return { ...state, 5585 [action.blockType.name]: action.blockType 5586 }; 5587 5588 case 'REMOVE_BLOCK_TYPES': 5589 return (0,external_lodash_namespaceObject.omit)(state, action.names); 5590 } 5591 5592 return state; 5593 } 5594 /** 5595 * Reducer managing the processed block types with all filters applied. 5596 * The state is derived from the `unprocessedBlockTypes` reducer. 5597 * 5598 * @param {Object} state Current state. 5599 * @param {Object} action Dispatched action. 5600 * 5601 * @return {Object} Updated state. 5602 */ 5603 5604 function blockTypes() { 5605 let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 5606 let action = arguments.length > 1 ? arguments[1] : undefined; 5607 5608 switch (action.type) { 5609 case 'ADD_BLOCK_TYPES': 5610 return { ...state, 5611 ...(0,external_lodash_namespaceObject.keyBy)(action.blockTypes, 'name') 5612 }; 5613 5614 case 'REMOVE_BLOCK_TYPES': 5615 return (0,external_lodash_namespaceObject.omit)(state, action.names); 5616 } 5617 5618 return state; 5619 } 5620 /** 5621 * Reducer managing the block style variations. 5622 * 5623 * @param {Object} state Current state. 5624 * @param {Object} action Dispatched action. 5625 * 5626 * @return {Object} Updated state. 5627 */ 5628 5629 function blockStyles() { 5630 let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 5631 let action = arguments.length > 1 ? arguments[1] : undefined; 5632 5633 switch (action.type) { 5634 case 'ADD_BLOCK_TYPES': 5635 return { ...state, 5636 ...(0,external_lodash_namespaceObject.mapValues)((0,external_lodash_namespaceObject.keyBy)(action.blockTypes, 'name'), blockType => { 5637 return (0,external_lodash_namespaceObject.uniqBy)([...(0,external_lodash_namespaceObject.get)(blockType, ['styles'], []).map(style => ({ ...style, 5638 source: 'block' 5639 })), ...(0,external_lodash_namespaceObject.get)(state, [blockType.name], []).filter(_ref => { 5640 let { 5641 source 5642 } = _ref; 5643 return 'block' !== source; 5644 })], style => style.name); 5645 }) 5646 }; 5647 5648 case 'ADD_BLOCK_STYLES': 5649 return { ...state, 5650 [action.blockName]: (0,external_lodash_namespaceObject.uniqBy)([...(0,external_lodash_namespaceObject.get)(state, [action.blockName], []), ...action.styles], style => style.name) 5651 }; 5652 5653 case 'REMOVE_BLOCK_STYLES': 5654 return { ...state, 5655 [action.blockName]: (0,external_lodash_namespaceObject.filter)((0,external_lodash_namespaceObject.get)(state, [action.blockName], []), style => action.styleNames.indexOf(style.name) === -1) 5656 }; 5657 } 5658 5659 return state; 5660 } 5661 /** 5662 * Reducer managing the block variations. 5663 * 5664 * @param {Object} state Current state. 5665 * @param {Object} action Dispatched action. 5666 * 5667 * @return {Object} Updated state. 5668 */ 5669 5670 function blockVariations() { 5671 let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 5672 let action = arguments.length > 1 ? arguments[1] : undefined; 5673 5674 switch (action.type) { 5675 case 'ADD_BLOCK_TYPES': 5676 return { ...state, 5677 ...(0,external_lodash_namespaceObject.mapValues)((0,external_lodash_namespaceObject.keyBy)(action.blockTypes, 'name'), blockType => { 5678 return (0,external_lodash_namespaceObject.uniqBy)([...(0,external_lodash_namespaceObject.get)(blockType, ['variations'], []).map(variation => ({ ...variation, 5679 source: 'block' 5680 })), ...(0,external_lodash_namespaceObject.get)(state, [blockType.name], []).filter(_ref2 => { 5681 let { 5682 source 5683 } = _ref2; 5684 return 'block' !== source; 5685 })], variation => variation.name); 5686 }) 5687 }; 5688 5689 case 'ADD_BLOCK_VARIATIONS': 5690 return { ...state, 5691 [action.blockName]: (0,external_lodash_namespaceObject.uniqBy)([...(0,external_lodash_namespaceObject.get)(state, [action.blockName], []), ...action.variations], variation => variation.name) 5692 }; 5693 5694 case 'REMOVE_BLOCK_VARIATIONS': 5695 return { ...state, 5696 [action.blockName]: (0,external_lodash_namespaceObject.filter)((0,external_lodash_namespaceObject.get)(state, [action.blockName], []), variation => action.variationNames.indexOf(variation.name) === -1) 5697 }; 5698 } 5699 5700 return state; 5701 } 5702 /** 5703 * Higher-order Reducer creating a reducer keeping track of given block name. 5704 * 5705 * @param {string} setActionType Action type. 5706 * 5707 * @return {Function} Reducer. 5708 */ 5709 5710 function createBlockNameSetterReducer(setActionType) { 5711 return function () { 5712 let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; 5713 let action = arguments.length > 1 ? arguments[1] : undefined; 5714 5715 switch (action.type) { 5716 case 'REMOVE_BLOCK_TYPES': 5717 if (action.names.indexOf(state) !== -1) { 5718 return null; 5719 } 5720 5721 return state; 5722 5723 case setActionType: 5724 return action.name || null; 5725 } 5726 5727 return state; 5728 }; 5729 } 5730 const defaultBlockName = createBlockNameSetterReducer('SET_DEFAULT_BLOCK_NAME'); 5731 const freeformFallbackBlockName = createBlockNameSetterReducer('SET_FREEFORM_FALLBACK_BLOCK_NAME'); 5732 const unregisteredFallbackBlockName = createBlockNameSetterReducer('SET_UNREGISTERED_FALLBACK_BLOCK_NAME'); 5733 const groupingBlockName = createBlockNameSetterReducer('SET_GROUPING_BLOCK_NAME'); 5734 /** 5735 * Reducer managing the categories 5736 * 5737 * @param {WPBlockCategory[]} state Current state. 5738 * @param {Object} action Dispatched action. 5739 * 5740 * @return {WPBlockCategory[]} Updated state. 5741 */ 5742 5743 function categories() { 5744 let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : DEFAULT_CATEGORIES; 5745 let action = arguments.length > 1 ? arguments[1] : undefined; 5746 5747 switch (action.type) { 5748 case 'SET_CATEGORIES': 5749 return action.categories || []; 5750 5751 case 'UPDATE_CATEGORY': 5752 { 5753 if (!action.category || (0,external_lodash_namespaceObject.isEmpty)(action.category)) { 5754 return state; 5755 } 5756 5757 const categoryToChange = (0,external_lodash_namespaceObject.find)(state, ['slug', action.slug]); 5758 5759 if (categoryToChange) { 5760 return (0,external_lodash_namespaceObject.map)(state, category => { 5761 if (category.slug === action.slug) { 5762 return { ...category, 5763 ...action.category 5764 }; 5765 } 5766 5767 return category; 5768 }); 5769 } 5770 } 5771 } 5772 5773 return state; 5774 } 5775 function collections() { 5776 let state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 5777 let action = arguments.length > 1 ? arguments[1] : undefined; 5778 5779 switch (action.type) { 5780 case 'ADD_BLOCK_COLLECTION': 5781 return { ...state, 5782 [action.namespace]: { 5783 title: action.title, 5784 icon: action.icon 5785 } 5786 }; 5787 5788 case 'REMOVE_BLOCK_COLLECTION': 5789 return (0,external_lodash_namespaceObject.omit)(state, action.namespace); 5790 } 5791 5792 return state; 5793 } 5794 /* harmony default export */ var reducer = ((0,external_wp_data_namespaceObject.combineReducers)({ 5795 unprocessedBlockTypes, 5796 blockTypes, 5797 blockStyles, 5798 blockVariations, 5799 defaultBlockName, 5800 freeformFallbackBlockName, 5801 unregisteredFallbackBlockName, 5802 groupingBlockName, 5803 categories, 5804 collections 5805 })); 5806 5807 ;// CONCATENATED MODULE: ./node_modules/rememo/es/rememo.js 5808 5809 5810 var LEAF_KEY, hasWeakMap; 5811 5812 /** 5813 * Arbitrary value used as key for referencing cache object in WeakMap tree. 5814 * 5815 * @type {Object} 5816 */ 5817 LEAF_KEY = {}; 5818 5819 /** 5820 * Whether environment supports WeakMap. 5821 * 5822 * @type {boolean} 5823 */ 5824 hasWeakMap = typeof WeakMap !== 'undefined'; 5825 5826 /** 5827 * Returns the first argument as the sole entry in an array. 5828 * 5829 * @param {*} value Value to return. 5830 * 5831 * @return {Array} Value returned as entry in array. 5832 */ 5833 function arrayOf( value ) { 5834 return [ value ]; 5835 } 5836 5837 /** 5838 * Returns true if the value passed is object-like, or false otherwise. A value 5839 * is object-like if it can support property assignment, e.g. object or array. 5840 * 5841 * @param {*} value Value to test. 5842 * 5843 * @return {boolean} Whether value is object-like. 5844 */ 5845 function isObjectLike( value ) { 5846 return !! value && 'object' === typeof value; 5847 } 5848 5849 /** 5850 * Creates and returns a new cache object. 5851 * 5852 * @return {Object} Cache object. 5853 */ 5854 function createCache() { 5855 var cache = { 5856 clear: function() { 5857 cache.head = null; 5858 }, 5859 }; 5860 5861 return cache; 5862 } 5863 5864 /** 5865 * Returns true if entries within the two arrays are strictly equal by 5866 * reference from a starting index. 5867 * 5868 * @param {Array} a First array. 5869 * @param {Array} b Second array. 5870 * @param {number} fromIndex Index from which to start comparison. 5871 * 5872 * @return {boolean} Whether arrays are shallowly equal. 5873 */ 5874 function isShallowEqual( a, b, fromIndex ) { 5875 var i; 5876 5877 if ( a.length !== b.length ) { 5878 return false; 5879 } 5880 5881 for ( i = fromIndex; i < a.length; i++ ) { 5882 if ( a[ i ] !== b[ i ] ) { 5883 return false; 5884 } 5885 } 5886 5887 return true; 5888 } 5889 5890 /** 5891 * Returns a memoized selector function. The getDependants function argument is 5892 * called before the memoized selector and is expected to return an immutable 5893 * reference or array of references on which the selector depends for computing 5894 * its own return value. The memoize cache is preserved only as long as those 5895 * dependant references remain the same. If getDependants returns a different 5896 * reference(s), the cache is cleared and the selector value regenerated. 5897 * 5898 * @param {Function} selector Selector function. 5899 * @param {Function} getDependants Dependant getter returning an immutable 5900 * reference or array of reference used in 5901 * cache bust consideration. 5902 * 5903 * @return {Function} Memoized selector. 5904 */ 5905 /* harmony default export */ function rememo(selector, getDependants ) { 5906 var rootCache, getCache; 5907 5908 // Use object source as dependant if getter not provided 5909 if ( ! getDependants ) { 5910 getDependants = arrayOf; 5911 } 5912 5913 /** 5914 * Returns the root cache. If WeakMap is supported, this is assigned to the 5915 * root WeakMap cache set, otherwise it is a shared instance of the default 5916 * cache object. 5917 * 5918 * @return {(WeakMap|Object)} Root cache object. 5919 */ 5920 function getRootCache() { 5921 return rootCache; 5922 } 5923 5924 /** 5925 * Returns the cache for a given dependants array. When possible, a WeakMap 5926 * will be used to create a unique cache for each set of dependants. This 5927 * is feasible due to the nature of WeakMap in allowing garbage collection 5928 * to occur on entries where the key object is no longer referenced. Since 5929 * WeakMap requires the key to be an object, this is only possible when the 5930 * dependant is object-like. The root cache is created as a hierarchy where 5931 * each top-level key is the first entry in a dependants set, the value a 5932 * WeakMap where each key is the next dependant, and so on. This continues 5933 * so long as the dependants are object-like. If no dependants are object- 5934 * like, then the cache is shared across all invocations. 5935 * 5936 * @see isObjectLike 5937 * 5938 * @param {Array} dependants Selector dependants. 5939 * 5940 * @return {Object} Cache object. 5941 */ 5942 function getWeakMapCache( dependants ) { 5943 var caches = rootCache, 5944 isUniqueByDependants = true, 5945 i, dependant, map, cache; 5946 5947 for ( i = 0; i < dependants.length; i++ ) { 5948 dependant = dependants[ i ]; 5949 5950 // Can only compose WeakMap from object-like key. 5951 if ( ! isObjectLike( dependant ) ) { 5952 isUniqueByDependants = false; 5953 break; 5954 } 5955 5956 // Does current segment of cache already have a WeakMap? 5957 if ( caches.has( dependant ) ) { 5958 // Traverse into nested WeakMap. 5959 caches = caches.get( dependant ); 5960 } else { 5961 // Create, set, and traverse into a new one. 5962 map = new WeakMap(); 5963 caches.set( dependant, map ); 5964 caches = map; 5965 } 5966 } 5967 5968 // We use an arbitrary (but consistent) object as key for the last item 5969 // in the WeakMap to serve as our running cache. 5970 if ( ! caches.has( LEAF_KEY ) ) { 5971 cache = createCache(); 5972 cache.isUniqueByDependants = isUniqueByDependants; 5973 caches.set( LEAF_KEY, cache ); 5974 } 5975 5976 return caches.get( LEAF_KEY ); 5977 } 5978 5979 // Assign cache handler by availability of WeakMap 5980 getCache = hasWeakMap ? getWeakMapCache : getRootCache; 5981 5982 /** 5983 * Resets root memoization cache. 5984 */ 5985 function clear() { 5986 rootCache = hasWeakMap ? new WeakMap() : createCache(); 5987 } 5988 5989 // eslint-disable-next-line jsdoc/check-param-names 5990 /** 5991 * The augmented selector call, considering first whether dependants have 5992 * changed before passing it to underlying memoize function. 5993 * 5994 * @param {Object} source Source object for derivation. 5995 * @param {...*} extraArgs Additional arguments to pass to selector. 5996 * 5997 * @return {*} Selector result. 5998 */ 5999 function callSelector( /* source, ...extraArgs */ ) { 6000 var len = arguments.length, 6001 cache, node, i, args, dependants; 6002 6003 // Create copy of arguments (avoid leaking deoptimization). 6004 args = new Array( len ); 6005 for ( i = 0; i < len; i++ ) { 6006 args[ i ] = arguments[ i ]; 6007 } 6008 6009 dependants = getDependants.apply( null, args ); 6010 cache = getCache( dependants ); 6011 6012 // If not guaranteed uniqueness by dependants (primitive type or lack 6013 // of WeakMap support), shallow compare against last dependants and, if 6014 // references have changed, destroy cache to recalculate result. 6015 if ( ! cache.isUniqueByDependants ) { 6016 if ( cache.lastDependants && ! isShallowEqual( dependants, cache.lastDependants, 0 ) ) { 6017 cache.clear(); 6018 } 6019 6020 cache.lastDependants = dependants; 6021 } 6022 6023 node = cache.head; 6024 while ( node ) { 6025 // Check whether node arguments match arguments 6026 if ( ! isShallowEqual( node.args, args, 1 ) ) { 6027 node = node.next; 6028 continue; 6029 } 6030 6031 // At this point we can assume we've found a match 6032 6033 // Surface matched node to head if not already 6034 if ( node !== cache.head ) { 6035 // Adjust siblings to point to each other. 6036 node.prev.next = node.next; 6037 if ( node.next ) { 6038 node.next.prev = node.prev; 6039 } 6040 6041 node.next = cache.head; 6042 node.prev = null; 6043 cache.head.prev = node; 6044 cache.head = node; 6045 } 6046 6047 // Return immediately 6048 return node.val; 6049 } 6050 6051 // No cached value found. Continue to insertion phase: 6052 6053 node = { 6054 // Generate the result from original function 6055 val: selector.apply( null, args ), 6056 }; 6057 6058 // Avoid including the source object in the cache. 6059 args[ 0 ] = null; 6060 node.args = args; 6061 6062 // Don't need to check whether node is already head, since it would 6063 // have been returned above already if it was 6064 6065 // Shift existing head down list 6066 if ( cache.head ) { 6067 cache.head.prev = node; 6068 node.next = cache.head; 6069 } 6070 6071 cache.head = node; 6072 6073 return node.val; 6074 } 6075 6076 callSelector.getDependants = getDependants; 6077 callSelector.clear = clear; 6078 clear(); 6079 6080 return callSelector; 6081 } 6082 6083 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/store/selectors.js 6084 /** 6085 * External dependencies 6086 */ 6087 6088 6089 /** @typedef {import('../api/registration').WPBlockVariation} WPBlockVariation */ 6090 6091 /** @typedef {import('../api/registration').WPBlockVariationScope} WPBlockVariationScope */ 6092 6093 /** @typedef {import('./reducer').WPBlockCategory} WPBlockCategory */ 6094 6095 /** 6096 * Given a block name or block type object, returns the corresponding 6097 * normalized block type object. 6098 * 6099 * @param {Object} state Blocks state. 6100 * @param {(string|Object)} nameOrType Block name or type object 6101 * 6102 * @return {Object} Block type object. 6103 */ 6104 6105 const getNormalizedBlockType = (state, nameOrType) => 'string' === typeof nameOrType ? getBlockType(state, nameOrType) : nameOrType; 6106 /** 6107 * Returns all the unprocessed block types as passed during the registration. 6108 * 6109 * @param {Object} state Data state. 6110 * 6111 * @return {Array} Unprocessed block types. 6112 */ 6113 6114 6115 function __experimentalGetUnprocessedBlockTypes(state) { 6116 return state.unprocessedBlockTypes; 6117 } 6118 /** 6119 * Returns all the available block types. 6120 * 6121 * @param {Object} state Data state. 6122 * 6123 * @return {Array} Block Types. 6124 */ 6125 6126 const getBlockTypes = rememo(state => Object.values(state.blockTypes), state => [state.blockTypes]); 6127 /** 6128 * Returns a block type by name. 6129 * 6130 * @param {Object} state Data state. 6131 * @param {string} name Block type name. 6132 * 6133 * @return {Object?} Block Type. 6134 */ 6135 6136 function getBlockType(state, name) { 6137 return state.blockTypes[name]; 6138 } 6139 /** 6140 * Returns block styles by block name. 6141 * 6142 * @param {Object} state Data state. 6143 * @param {string} name Block type name. 6144 * 6145 * @return {Array?} Block Styles. 6146 */ 6147 6148 function getBlockStyles(state, name) { 6149 return state.blockStyles[name]; 6150 } 6151 /** 6152 * Returns block variations by block name. 6153 * 6154 * @param {Object} state Data state. 6155 * @param {string} blockName Block type name. 6156 * @param {WPBlockVariationScope} [scope] Block variation scope name. 6157 * 6158 * @return {(WPBlockVariation[]|void)} Block variations. 6159 */ 6160 6161 const getBlockVariations = rememo((state, blockName, scope) => { 6162 const variations = state.blockVariations[blockName]; 6163 6164 if (!variations || !scope) { 6165 return variations; 6166 } 6167 6168 return variations.filter(variation => { 6169 // For backward compatibility reasons, variation's scope defaults to 6170 // `block` and `inserter` when not set. 6171 return (variation.scope || ['block', 'inserter']).includes(scope); 6172 }); 6173 }, (state, blockName) => [state.blockVariations[blockName]]); 6174 /** 6175 * Returns the active block variation for a given block based on its attributes. 6176 * Variations are determined by their `isActive` property. 6177 * Which is either an array of block attribute keys or a function. 6178 * 6179 * In case of an array of block attribute keys, the `attributes` are compared 6180 * to the variation's attributes using strict equality check. 6181 * 6182 * In case of function type, the function should accept a block's attributes 6183 * and the variation's attributes and determines if a variation is active. 6184 * A function that accepts a block's attributes and the variation's attributes and determines if a variation is active. 6185 * 6186 * @param {Object} state Data state. 6187 * @param {string} blockName Name of block (example: “core/columns”). 6188 * @param {Object} attributes Block attributes used to determine active variation. 6189 * @param {WPBlockVariationScope} [scope] Block variation scope name. 6190 * 6191 * @return {(WPBlockVariation|undefined)} Active block variation. 6192 */ 6193 6194 function getActiveBlockVariation(state, blockName, attributes, scope) { 6195 const variations = getBlockVariations(state, blockName, scope); 6196 const match = variations === null || variations === void 0 ? void 0 : variations.find(variation => { 6197 var _variation$isActive; 6198 6199 if (Array.isArray(variation.isActive)) { 6200 const blockType = getBlockType(state, blockName); 6201 const attributeKeys = Object.keys((blockType === null || blockType === void 0 ? void 0 : blockType.attributes) || {}); 6202 const definedAttributes = variation.isActive.filter(attribute => attributeKeys.includes(attribute)); 6203 6204 if (definedAttributes.length === 0) { 6205 return false; 6206 } 6207 6208 return definedAttributes.every(attribute => attributes[attribute] === variation.attributes[attribute]); 6209 } 6210 6211 return (_variation$isActive = variation.isActive) === null || _variation$isActive === void 0 ? void 0 : _variation$isActive.call(variation, attributes, variation.attributes); 6212 }); 6213 return match; 6214 } 6215 /** 6216 * Returns the default block variation for the given block type. 6217 * When there are multiple variations annotated as the default one, 6218 * the last added item is picked. This simplifies registering overrides. 6219 * When there is no default variation set, it returns the first item. 6220 * 6221 * @param {Object} state Data state. 6222 * @param {string} blockName Block type name. 6223 * @param {WPBlockVariationScope} [scope] Block variation scope name. 6224 * 6225 * @return {?WPBlockVariation} The default block variation. 6226 */ 6227 6228 function getDefaultBlockVariation(state, blockName, scope) { 6229 const variations = getBlockVariations(state, blockName, scope); 6230 return (0,external_lodash_namespaceObject.findLast)(variations, 'isDefault') || (0,external_lodash_namespaceObject.first)(variations); 6231 } 6232 /** 6233 * Returns all the available categories. 6234 * 6235 * @param {Object} state Data state. 6236 * 6237 * @return {WPBlockCategory[]} Categories list. 6238 */ 6239 6240 function getCategories(state) { 6241 return state.categories; 6242 } 6243 /** 6244 * Returns all the available collections. 6245 * 6246 * @param {Object} state Data state. 6247 * 6248 * @return {Object} Collections list. 6249 */ 6250 6251 function getCollections(state) { 6252 return state.collections; 6253 } 6254 /** 6255 * Returns the name of the default block name. 6256 * 6257 * @param {Object} state Data state. 6258 * 6259 * @return {string?} Default block name. 6260 */ 6261 6262 function getDefaultBlockName(state) { 6263 return state.defaultBlockName; 6264 } 6265 /** 6266 * Returns the name of the block for handling non-block content. 6267 * 6268 * @param {Object} state Data state. 6269 * 6270 * @return {string?} Name of the block for handling non-block content. 6271 */ 6272 6273 function getFreeformFallbackBlockName(state) { 6274 return state.freeformFallbackBlockName; 6275 } 6276 /** 6277 * Returns the name of the block for handling unregistered blocks. 6278 * 6279 * @param {Object} state Data state. 6280 * 6281 * @return {string?} Name of the block for handling unregistered blocks. 6282 */ 6283 6284 function getUnregisteredFallbackBlockName(state) { 6285 return state.unregisteredFallbackBlockName; 6286 } 6287 /** 6288 * Returns the name of the block for handling unregistered blocks. 6289 * 6290 * @param {Object} state Data state. 6291 * 6292 * @return {string?} Name of the block for handling unregistered blocks. 6293 */ 6294 6295 function getGroupingBlockName(state) { 6296 return state.groupingBlockName; 6297 } 6298 /** 6299 * Returns an array with the child blocks of a given block. 6300 * 6301 * @param {Object} state Data state. 6302 * @param {string} blockName Block type name. 6303 * 6304 * @return {Array} Array of child block names. 6305 */ 6306 6307 const getChildBlockNames = rememo((state, blockName) => { 6308 return (0,external_lodash_namespaceObject.map)((0,external_lodash_namespaceObject.filter)(state.blockTypes, blockType => { 6309 return (0,external_lodash_namespaceObject.includes)(blockType.parent, blockName); 6310 }), _ref => { 6311 let { 6312 name 6313 } = _ref; 6314 return name; 6315 }); 6316 }, state => [state.blockTypes]); 6317 /** 6318 * Returns the block support value for a feature, if defined. 6319 * 6320 * @param {Object} state Data state. 6321 * @param {(string|Object)} nameOrType Block name or type object 6322 * @param {Array|string} feature Feature to retrieve 6323 * @param {*} defaultSupports Default value to return if not 6324 * explicitly defined 6325 * 6326 * @return {?*} Block support value 6327 */ 6328 6329 const getBlockSupport = (state, nameOrType, feature, defaultSupports) => { 6330 const blockType = getNormalizedBlockType(state, nameOrType); 6331 6332 if (!(blockType !== null && blockType !== void 0 && blockType.supports)) { 6333 return defaultSupports; 6334 } 6335 6336 return (0,external_lodash_namespaceObject.get)(blockType.supports, feature, defaultSupports); 6337 }; 6338 /** 6339 * Returns true if the block defines support for a feature, or false otherwise. 6340 * 6341 * @param {Object} state Data state. 6342 * @param {(string|Object)} nameOrType Block name or type object. 6343 * @param {string} feature Feature to test. 6344 * @param {boolean} defaultSupports Whether feature is supported by 6345 * default if not explicitly defined. 6346 * 6347 * @return {boolean} Whether block supports feature. 6348 */ 6349 6350 function hasBlockSupport(state, nameOrType, feature, defaultSupports) { 6351 return !!getBlockSupport(state, nameOrType, feature, defaultSupports); 6352 } 6353 /** 6354 * Returns true if the block type by the given name or object value matches a 6355 * search term, or false otherwise. 6356 * 6357 * @param {Object} state Blocks state. 6358 * @param {(string|Object)} nameOrType Block name or type object. 6359 * @param {string} searchTerm Search term by which to filter. 6360 * 6361 * @return {Object[]} Whether block type matches search term. 6362 */ 6363 6364 function isMatchingSearchTerm(state, nameOrType, searchTerm) { 6365 const blockType = getNormalizedBlockType(state, nameOrType); 6366 const getNormalizedSearchTerm = (0,external_lodash_namespaceObject.flow)([// Disregard diacritics. 6367 // Input: "média" 6368 external_lodash_namespaceObject.deburr, // Lowercase. 6369 // Input: "MEDIA" 6370 term => term.toLowerCase(), // Strip leading and trailing whitespace. 6371 // Input: " media " 6372 term => term.trim()]); 6373 const normalizedSearchTerm = getNormalizedSearchTerm(searchTerm); 6374 const isSearchMatch = (0,external_lodash_namespaceObject.flow)([getNormalizedSearchTerm, normalizedCandidate => (0,external_lodash_namespaceObject.includes)(normalizedCandidate, normalizedSearchTerm)]); 6375 return isSearchMatch(blockType.title) || (0,external_lodash_namespaceObject.some)(blockType.keywords, isSearchMatch) || isSearchMatch(blockType.category) || isSearchMatch(blockType.description); 6376 } 6377 /** 6378 * Returns a boolean indicating if a block has child blocks or not. 6379 * 6380 * @param {Object} state Data state. 6381 * @param {string} blockName Block type name. 6382 * 6383 * @return {boolean} True if a block contains child blocks and false otherwise. 6384 */ 6385 6386 const hasChildBlocks = (state, blockName) => { 6387 return getChildBlockNames(state, blockName).length > 0; 6388 }; 6389 /** 6390 * Returns a boolean indicating if a block has at least one child block with inserter support. 6391 * 6392 * @param {Object} state Data state. 6393 * @param {string} blockName Block type name. 6394 * 6395 * @return {boolean} True if a block contains at least one child blocks with inserter support 6396 * and false otherwise. 6397 */ 6398 6399 const hasChildBlocksWithInserterSupport = (state, blockName) => { 6400 return (0,external_lodash_namespaceObject.some)(getChildBlockNames(state, blockName), childBlockName => { 6401 return hasBlockSupport(state, childBlockName, 'inserter', true); 6402 }); 6403 }; 6404 6405 ;// CONCATENATED MODULE: external ["wp","hooks"] 6406 var external_wp_hooks_namespaceObject = window["wp"]["hooks"]; 6407 ;// CONCATENATED MODULE: ./node_modules/colord/index.mjs 6408 var r={grad:.9,turn:360,rad:360/(2*Math.PI)},t=function(r){return"string"==typeof r?r.length>0:"number"==typeof r},n=function(r,t,n){return void 0===t&&(t=0),void 0===n&&(n=Math.pow(10,t)),Math.round(n*r)/n+0},e=function(r,t,n){return void 0===t&&(t=0),void 0===n&&(n=1),r>n?n:r>t?r:t},u=function(r){return(r=isFinite(r)?r%360:0)>0?r:r+360},a=function(r){return{r:e(r.r,0,255),g:e(r.g,0,255),b:e(r.b,0,255),a:e(r.a)}},o=function(r){return{r:n(r.r),g:n(r.g),b:n(r.b),a:n(r.a,3)}},i=/^#([0-9a-f]{3,8})$/i,s=function(r){var t=r.toString(16);return t.length<2?"0"+t:t},h=function(r){var t=r.r,n=r.g,e=r.b,u=r.a,a=Math.max(t,n,e),o=a-Math.min(t,n,e),i=o?a===t?(n-e)/o:a===n?2+(e-t)/o:4+(t-n)/o:0;return{h:60*(i<0?i+6:i),s:a?o/a*100:0,v:a/255*100,a:u}},b=function(r){var t=r.h,n=r.s,e=r.v,u=r.a;t=t/360*6,n/=100,e/=100;var a=Math.floor(t),o=e*(1-n),i=e*(1-(t-a)*n),s=e*(1-(1-t+a)*n),h=a%6;return{r:255*[e,i,o,o,s,e][h],g:255*[s,e,e,i,o,o][h],b:255*[o,o,s,e,e,i][h],a:u}},g=function(r){return{h:u(r.h),s:e(r.s,0,100),l:e(r.l,0,100),a:e(r.a)}},d=function(r){return{h:n(r.h),s:n(r.s),l:n(r.l),a:n(r.a,3)}},f=function(r){return b((n=(t=r).s,{h:t.h,s:(n*=((e=t.l)<50?e:100-e)/100)>0?2*n/(e+n)*100:0,v:e+n,a:t.a}));var t,n,e},c=function(r){return{h:(t=h(r)).h,s:(u=(200-(n=t.s))*(e=t.v)/100)>0&&u<200?n*e/100/(u<=100?u:200-u)*100:0,l:u/2,a:t.a};var t,n,e,u},l=/^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s*,\s*([+-]?\d*\.?\d+)%\s*,\s*([+-]?\d*\.?\d+)%\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,p=/^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s+([+-]?\d*\.?\d+)%\s+([+-]?\d*\.?\d+)%\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,v=/^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,m=/^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,y={string:[[function(r){var t=i.exec(r);return t?(r=t[1]).length<=4?{r:parseInt(r[0]+r[0],16),g:parseInt(r[1]+r[1],16),b:parseInt(r[2]+r[2],16),a:4===r.length?n(parseInt(r[3]+r[3],16)/255,2):1}:6===r.length||8===r.length?{r:parseInt(r.substr(0,2),16),g:parseInt(r.substr(2,2),16),b:parseInt(r.substr(4,2),16),a:8===r.length?n(parseInt(r.substr(6,2),16)/255,2):1}:null:null},"hex"],[function(r){var t=v.exec(r)||m.exec(r);return t?t[2]!==t[4]||t[4]!==t[6]?null:a({r:Number(t[1])/(t[2]?100/255:1),g:Number(t[3])/(t[4]?100/255:1),b:Number(t[5])/(t[6]?100/255:1),a:void 0===t[7]?1:Number(t[7])/(t[8]?100:1)}):null},"rgb"],[function(t){var n=l.exec(t)||p.exec(t);if(!n)return null;var e,u,a=g({h:(e=n[1],u=n[2],void 0===u&&(u="deg"),Number(e)*(r[u]||1)),s:Number(n[3]),l:Number(n[4]),a:void 0===n[5]?1:Number(n[5])/(n[6]?100:1)});return f(a)},"hsl"]],object:[[function(r){var n=r.r,e=r.g,u=r.b,o=r.a,i=void 0===o?1:o;return t(n)&&t(e)&&t(u)?a({r:Number(n),g:Number(e),b:Number(u),a:Number(i)}):null},"rgb"],[function(r){var n=r.h,e=r.s,u=r.l,a=r.a,o=void 0===a?1:a;if(!t(n)||!t(e)||!t(u))return null;var i=g({h:Number(n),s:Number(e),l:Number(u),a:Number(o)});return f(i)},"hsl"],[function(r){var n=r.h,a=r.s,o=r.v,i=r.a,s=void 0===i?1:i;if(!t(n)||!t(a)||!t(o))return null;var h=function(r){return{h:u(r.h),s:e(r.s,0,100),v:e(r.v,0,100),a:e(r.a)}}({h:Number(n),s:Number(a),v:Number(o),a:Number(s)});return b(h)},"hsv"]]},N=function(r,t){for(var n=0;n<t.length;n++){var e=t[n][0](r);if(e)return[e,t[n][1]]}return[null,void 0]},x=function(r){return"string"==typeof r?N(r.trim(),y.string):"object"==typeof r&&null!==r?N(r,y.object):[null,void 0]},I=function(r){return x(r)[1]},M=function(r,t){var n=c(r);return{h:n.h,s:e(n.s+100*t,0,100),l:n.l,a:n.a}},H=function(r){return(299*r.r+587*r.g+114*r.b)/1e3/255},$=function(r,t){var n=c(r);return{h:n.h,s:n.s,l:e(n.l+100*t,0,100),a:n.a}},j=function(){function r(r){this.parsed=x(r)[0],this.rgba=this.parsed||{r:0,g:0,b:0,a:1}}return r.prototype.isValid=function(){return null!==this.parsed},r.prototype.brightness=function(){return n(H(this.rgba),2)},r.prototype.isDark=function(){return H(this.rgba)<.5},r.prototype.isLight=function(){return H(this.rgba)>=.5},r.prototype.toHex=function(){return r=o(this.rgba),t=r.r,e=r.g,u=r.b,i=(a=r.a)<1?s(n(255*a)):"","#"+s(t)+s(e)+s(u)+i;var r,t,e,u,a,i},r.prototype.toRgb=function(){return o(this.rgba)},r.prototype.toRgbString=function(){return r=o(this.rgba),t=r.r,n=r.g,e=r.b,(u=r.a)<1?"rgba("+t+", "+n+", "+e+", "+u+")":"rgb("+t+", "+n+", "+e+")";var r,t,n,e,u},r.prototype.toHsl=function(){return d(c(this.rgba))},r.prototype.toHslString=function(){return r=d(c(this.rgba)),t=r.h,n=r.s,e=r.l,(u=r.a)<1?"hsla("+t+", "+n+"%, "+e+"%, "+u+")":"hsl("+t+", "+n+"%, "+e+"%)";var r,t,n,e,u},r.prototype.toHsv=function(){return r=h(this.rgba),{h:n(r.h),s:n(r.s),v:n(r.v),a:n(r.a,3)};var r},r.prototype.invert=function(){return w({r:255-(r=this.rgba).r,g:255-r.g,b:255-r.b,a:r.a});var r},r.prototype.saturate=function(r){return void 0===r&&(r=.1),w(M(this.rgba,r))},r.prototype.desaturate=function(r){return void 0===r&&(r=.1),w(M(this.rgba,-r))},r.prototype.grayscale=function(){return w(M(this.rgba,-1))},r.prototype.lighten=function(r){return void 0===r&&(r=.1),w($(this.rgba,r))},r.prototype.darken=function(r){return void 0===r&&(r=.1),w($(this.rgba,-r))},r.prototype.rotate=function(r){return void 0===r&&(r=15),this.hue(this.hue()+r)},r.prototype.alpha=function(r){return"number"==typeof r?w({r:(t=this.rgba).r,g:t.g,b:t.b,a:r}):n(this.rgba.a,3);var t},r.prototype.hue=function(r){var t=c(this.rgba);return"number"==typeof r?w({h:r,s:t.s,l:t.l,a:t.a}):n(t.h)},r.prototype.isEqual=function(r){return this.toHex()===w(r).toHex()},r}(),w=function(r){return r instanceof j?r:new j(r)},S=[],k=function(r){r.forEach(function(r){S.indexOf(r)<0&&(r(j,y),S.push(r))})},E=function(){return new j({r:255*Math.random(),g:255*Math.random(),b:255*Math.random()})}; 6409 6410 ;// CONCATENATED MODULE: ./node_modules/colord/plugins/names.mjs 6411 /* harmony default export */ function names(e,f){var a={white:"#ffffff",bisque:"#ffe4c4",blue:"#0000ff",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",antiquewhite:"#faebd7",aqua:"#00ffff",azure:"#f0ffff",whitesmoke:"#f5f5f5",papayawhip:"#ffefd5",plum:"#dda0dd",blanchedalmond:"#ffebcd",black:"#000000",gold:"#ffd700",goldenrod:"#daa520",gainsboro:"#dcdcdc",cornsilk:"#fff8dc",cornflowerblue:"#6495ed",burlywood:"#deb887",aquamarine:"#7fffd4",beige:"#f5f5dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkkhaki:"#bdb76b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",peachpuff:"#ffdab9",darkmagenta:"#8b008b",darkred:"#8b0000",darkorchid:"#9932cc",darkorange:"#ff8c00",darkslateblue:"#483d8b",gray:"#808080",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",deeppink:"#ff1493",deepskyblue:"#00bfff",wheat:"#f5deb3",firebrick:"#b22222",floralwhite:"#fffaf0",ghostwhite:"#f8f8ff",darkviolet:"#9400d3",magenta:"#ff00ff",green:"#008000",dodgerblue:"#1e90ff",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",blueviolet:"#8a2be2",forestgreen:"#228b22",lawngreen:"#7cfc00",indianred:"#cd5c5c",indigo:"#4b0082",fuchsia:"#ff00ff",brown:"#a52a2a",maroon:"#800000",mediumblue:"#0000cd",lightcoral:"#f08080",darkturquoise:"#00ced1",lightcyan:"#e0ffff",ivory:"#fffff0",lightyellow:"#ffffe0",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",linen:"#faf0e6",mediumaquamarine:"#66cdaa",lemonchiffon:"#fffacd",lime:"#00ff00",khaki:"#f0e68c",mediumseagreen:"#3cb371",limegreen:"#32cd32",mediumspringgreen:"#00fa9a",lightskyblue:"#87cefa",lightblue:"#add8e6",midnightblue:"#191970",lightpink:"#ffb6c1",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",mintcream:"#f5fffa",lightslategray:"#778899",lightslategrey:"#778899",navajowhite:"#ffdead",navy:"#000080",mediumvioletred:"#c71585",powderblue:"#b0e0e6",palegoldenrod:"#eee8aa",oldlace:"#fdf5e6",paleturquoise:"#afeeee",mediumturquoise:"#48d1cc",mediumorchid:"#ba55d3",rebeccapurple:"#663399",lightsteelblue:"#b0c4de",mediumslateblue:"#7b68ee",thistle:"#d8bfd8",tan:"#d2b48c",orchid:"#da70d6",mediumpurple:"#9370db",purple:"#800080",pink:"#ffc0cb",skyblue:"#87ceeb",springgreen:"#00ff7f",palegreen:"#98fb98",red:"#ff0000",yellow:"#ffff00",slateblue:"#6a5acd",lavenderblush:"#fff0f5",peru:"#cd853f",palevioletred:"#db7093",violet:"#ee82ee",teal:"#008080",slategray:"#708090",slategrey:"#708090",aliceblue:"#f0f8ff",darkseagreen:"#8fbc8f",darkolivegreen:"#556b2f",greenyellow:"#adff2f",seagreen:"#2e8b57",seashell:"#fff5ee",tomato:"#ff6347",silver:"#c0c0c0",sienna:"#a0522d",lavender:"#e6e6fa",lightgreen:"#90ee90",orange:"#ffa500",orangered:"#ff4500",steelblue:"#4682b4",royalblue:"#4169e1",turquoise:"#40e0d0",yellowgreen:"#9acd32",salmon:"#fa8072",saddlebrown:"#8b4513",sandybrown:"#f4a460",rosybrown:"#bc8f8f",darksalmon:"#e9967a",lightgoldenrodyellow:"#fafad2",snow:"#fffafa",lightgrey:"#d3d3d3",lightgray:"#d3d3d3",dimgray:"#696969",dimgrey:"#696969",olivedrab:"#6b8e23",olive:"#808000"},r={};for(var d in a)r[a[d]]=d;var l={};e.prototype.toName=function(f){if(!(this.rgba.a||this.rgba.r||this.rgba.g||this.rgba.b))return"transparent";var d,i,n=r[this.toHex()];if(n)return n;if(null==f?void 0:f.closest){var o=this.toRgb(),t=1/0,b="black";if(!l.length)for(var c in a)l[c]=new e(a[c]).toRgb();for(var g in a){var u=(d=o,i=l[g],Math.pow(d.r-i.r,2)+Math.pow(d.g-i.g,2)+Math.pow(d.b-i.b,2));u<t&&(t=u,b=g)}return b}};f.string.push([function(f){var r=f.toLowerCase(),d="transparent"===r?"#0000":a[r];return d?new e(d).toRgb():null},"name"])} 6412 6413 ;// CONCATENATED MODULE: ./node_modules/colord/plugins/a11y.mjs 6414 var a11y_o=function(o){var t=o/255;return t<.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)},a11y_t=function(t){return.2126*a11y_o(t.r)+.7152*a11y_o(t.g)+.0722*a11y_o(t.b)};/* harmony default export */ function a11y(o){o.prototype.luminance=function(){return o=a11y_t(this.rgba),void 0===(r=2)&&(r=0),void 0===n&&(n=Math.pow(10,r)),Math.round(n*o)/n+0;var o,r,n},o.prototype.contrast=function(r){void 0===r&&(r="#FFF");var n,a,i,e,v,u,d,c=r instanceof o?r:new o(r);return e=this.rgba,v=c.toRgb(),u=a11y_t(e),d=a11y_t(v),n=u>d?(u+.05)/(d+.05):(d+.05)/(u+.05),void 0===(a=2)&&(a=0),void 0===i&&(i=Math.pow(10,a)),Math.floor(i*n)/i+0},o.prototype.isReadable=function(o,t){return void 0===o&&(o="#FFF"),void 0===t&&(t={}),this.contrast(o)>=(e=void 0===(i=(r=t).size)?"normal":i,"AAA"===(a=void 0===(n=r.level)?"AA":n)&&"normal"===e?7:"AA"===a&&"large"===e?3:4.5);var r,n,a,i,e}} 6415 6416 ;// CONCATENATED MODULE: external ["wp","element"] 6417 var external_wp_element_namespaceObject = window["wp"]["element"]; 6418 ;// CONCATENATED MODULE: external ["wp","dom"] 6419 var external_wp_dom_namespaceObject = window["wp"]["dom"]; 6420 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/constants.js 6421 const BLOCK_ICON_DEFAULT = 'block-default'; 6422 /** 6423 * Array of valid keys in a block type settings deprecation object. 6424 * 6425 * @type {string[]} 6426 */ 6427 6428 const DEPRECATED_ENTRY_KEYS = ['attributes', 'supports', 'save', 'migrate', 'isEligible', 'apiVersion']; 6429 const __EXPERIMENTAL_STYLE_PROPERTY = { 6430 // Kept for back-compatibility purposes. 6431 '--wp--style--color--link': { 6432 value: ['color', 'link'], 6433 support: ['color', 'link'] 6434 }, 6435 background: { 6436 value: ['color', 'gradient'], 6437 support: ['color', 'gradients'] 6438 }, 6439 backgroundColor: { 6440 value: ['color', 'background'], 6441 support: ['color', 'background'], 6442 requiresOptOut: true 6443 }, 6444 borderColor: { 6445 value: ['border', 'color'], 6446 support: ['__experimentalBorder', 'color'] 6447 }, 6448 borderRadius: { 6449 value: ['border', 'radius'], 6450 support: ['__experimentalBorder', 'radius'], 6451 properties: { 6452 borderTopLeftRadius: 'topLeft', 6453 borderTopRightRadius: 'topRight', 6454 borderBottomLeftRadius: 'bottomLeft', 6455 borderBottomRightRadius: 'bottomRight' 6456 } 6457 }, 6458 borderStyle: { 6459 value: ['border', 'style'], 6460 support: ['__experimentalBorder', 'style'] 6461 }, 6462 borderWidth: { 6463 value: ['border', 'width'], 6464 support: ['__experimentalBorder', 'width'] 6465 }, 6466 color: { 6467 value: ['color', 'text'], 6468 support: ['color', 'text'], 6469 requiresOptOut: true 6470 }, 6471 filter: { 6472 value: ['filter', 'duotone'], 6473 support: ['color', '__experimentalDuotone'] 6474 }, 6475 linkColor: { 6476 value: ['elements', 'link', 'color', 'text'], 6477 support: ['color', 'link'] 6478 }, 6479 fontFamily: { 6480 value: ['typography', 'fontFamily'], 6481 support: ['typography', '__experimentalFontFamily'] 6482 }, 6483 fontSize: { 6484 value: ['typography', 'fontSize'], 6485 support: ['typography', 'fontSize'] 6486 }, 6487 fontStyle: { 6488 value: ['typography', 'fontStyle'], 6489 support: ['typography', '__experimentalFontStyle'] 6490 }, 6491 fontWeight: { 6492 value: ['typography', 'fontWeight'], 6493 support: ['typography', '__experimentalFontWeight'] 6494 }, 6495 lineHeight: { 6496 value: ['typography', 'lineHeight'], 6497 support: ['typography', 'lineHeight'] 6498 }, 6499 margin: { 6500 value: ['spacing', 'margin'], 6501 support: ['spacing', 'margin'], 6502 properties: { 6503 marginTop: 'top', 6504 marginRight: 'right', 6505 marginBottom: 'bottom', 6506 marginLeft: 'left' 6507 }, 6508 useEngine: true 6509 }, 6510 padding: { 6511 value: ['spacing', 'padding'], 6512 support: ['spacing', 'padding'], 6513 properties: { 6514 paddingTop: 'top', 6515 paddingRight: 'right', 6516 paddingBottom: 'bottom', 6517 paddingLeft: 'left' 6518 }, 6519 useEngine: true 6520 }, 6521 textDecoration: { 6522 value: ['typography', 'textDecoration'], 6523 support: ['typography', '__experimentalTextDecoration'] 6524 }, 6525 textTransform: { 6526 value: ['typography', 'textTransform'], 6527 support: ['typography', '__experimentalTextTransform'] 6528 }, 6529 letterSpacing: { 6530 value: ['typography', 'letterSpacing'], 6531 support: ['typography', '__experimentalLetterSpacing'] 6532 }, 6533 '--wp--style--block-gap': { 6534 value: ['spacing', 'blockGap'], 6535 support: ['spacing', 'blockGap'] 6536 } 6537 }; 6538 const __EXPERIMENTAL_ELEMENTS = { 6539 link: 'a', 6540 h1: 'h1', 6541 h2: 'h2', 6542 h3: 'h3', 6543 h4: 'h4', 6544 h5: 'h5', 6545 h6: 'h6' 6546 }; 6547 const __EXPERIMENTAL_PATHS_WITH_MERGE = { 6548 'color.duotone': true, 6549 'color.gradients': true, 6550 'color.palette': true, 6551 'typography.fontFamilies': true, 6552 'typography.fontSizes': true 6553 }; 6554 6555 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/registration.js 6556 /* eslint no-console: [ 'error', { allow: [ 'error', 'warn' ] } ] */ 6557 6558 /** 6559 * External dependencies 6560 */ 6561 6562 /** 6563 * WordPress dependencies 6564 */ 6565 6566 6567 6568 /** 6569 * Internal dependencies 6570 */ 6571 6572 const i18nBlockSchema = { 6573 title: "block title", 6574 description: "block description", 6575 keywords: ["block keyword"], 6576 styles: [{ 6577 label: "block style label" 6578 }], 6579 variations: [{ 6580 title: "block variation title", 6581 description: "block variation description", 6582 keywords: ["block variation keyword"] 6583 }] 6584 }; 6585 6586 6587 /** 6588 * An icon type definition. One of a Dashicon slug, an element, 6589 * or a component. 6590 * 6591 * @typedef {(string|WPElement|WPComponent)} WPIcon 6592 * 6593 * @see https://developer.wordpress.org/resource/dashicons/ 6594 */ 6595 6596 /** 6597 * Render behavior of a block type icon; one of a Dashicon slug, an element, 6598 * or a component. 6599 * 6600 * @typedef {WPIcon} WPBlockTypeIconRender 6601 */ 6602 6603 /** 6604 * An object describing a normalized block type icon. 6605 * 6606 * @typedef {Object} WPBlockTypeIconDescriptor 6607 * 6608 * @property {WPBlockTypeIconRender} src Render behavior of the icon, 6609 * one of a Dashicon slug, an 6610 * element, or a component. 6611 * @property {string} background Optimal background hex string 6612 * color when displaying icon. 6613 * @property {string} foreground Optimal foreground hex string 6614 * color when displaying icon. 6615 * @property {string} shadowColor Optimal shadow hex string 6616 * color when displaying icon. 6617 */ 6618 6619 /** 6620 * Value to use to render the icon for a block type in an editor interface, 6621 * either a Dashicon slug, an element, a component, or an object describing 6622 * the icon. 6623 * 6624 * @typedef {(WPBlockTypeIconDescriptor|WPBlockTypeIconRender)} WPBlockTypeIcon 6625 */ 6626 6627 /** 6628 * Named block variation scopes. 6629 * 6630 * @typedef {'block'|'inserter'|'transform'} WPBlockVariationScope 6631 */ 6632 6633 /** 6634 * An object describing a variation defined for the block type. 6635 * 6636 * @typedef {Object} WPBlockVariation 6637 * 6638 * @property {string} name The unique and machine-readable name. 6639 * @property {string} title A human-readable variation title. 6640 * @property {string} [description] A detailed variation description. 6641 * @property {string} [category] Block type category classification, 6642 * used in search interfaces to arrange 6643 * block types by category. 6644 * @property {WPIcon} [icon] An icon helping to visualize the variation. 6645 * @property {boolean} [isDefault] Indicates whether the current variation is 6646 * the default one. Defaults to `false`. 6647 * @property {Object} [attributes] Values which override block attributes. 6648 * @property {Array[]} [innerBlocks] Initial configuration of nested blocks. 6649 * @property {Object} [example] Example provides structured data for 6650 * the block preview. You can set to 6651 * `undefined` to disable the preview shown 6652 * for the block type. 6653 * @property {WPBlockVariationScope[]} [scope] The list of scopes where the variation 6654 * is applicable. When not provided, it 6655 * assumes all available scopes. 6656 * @property {string[]} [keywords] An array of terms (which can be translated) 6657 * that help users discover the variation 6658 * while searching. 6659 * @property {Function|string[]} [isActive] This can be a function or an array of block attributes. 6660 * Function that accepts a block's attributes and the 6661 * variation's attributes and determines if a variation is active. 6662 * This function doesn't try to find a match dynamically based 6663 * on all block's attributes, as in many cases some attributes are irrelevant. 6664 * An example would be for `embed` block where we only care 6665 * about `providerNameSlug` attribute's value. 6666 * We can also use a `string[]` to tell which attributes 6667 * should be compared as a shorthand. Each attributes will 6668 * be matched and the variation will be active if all of them are matching. 6669 */ 6670 6671 /** 6672 * Defined behavior of a block type. 6673 * 6674 * @typedef {Object} WPBlockType 6675 * 6676 * @property {string} name Block type's namespaced name. 6677 * @property {string} title Human-readable block type label. 6678 * @property {string} [description] A detailed block type description. 6679 * @property {string} [category] Block type category classification, 6680 * used in search interfaces to arrange 6681 * block types by category. 6682 * @property {WPBlockTypeIcon} [icon] Block type icon. 6683 * @property {string[]} [keywords] Additional keywords to produce block 6684 * type as result in search interfaces. 6685 * @property {Object} [attributes] Block type attributes. 6686 * @property {WPComponent} [save] Optional component describing 6687 * serialized markup structure of a 6688 * block type. 6689 * @property {WPComponent} edit Component rendering an element to 6690 * manipulate the attributes of a block 6691 * in the context of an editor. 6692 * @property {WPBlockVariation[]} [variations] The list of block variations. 6693 * @property {Object} [example] Example provides structured data for 6694 * the block preview. When not defined 6695 * then no preview is shown. 6696 */ 6697 6698 const serverSideBlockDefinitions = {}; 6699 /** 6700 * Sets the server side block definition of blocks. 6701 * 6702 * @param {Object} definitions Server-side block definitions 6703 */ 6704 // eslint-disable-next-line camelcase 6705 6706 function unstable__bootstrapServerSideBlockDefinitions(definitions) { 6707 for (const blockName of Object.keys(definitions)) { 6708 // Don't overwrite if already set. It covers the case when metadata 6709 // was initialized from the server. 6710 if (serverSideBlockDefinitions[blockName]) { 6711 // We still need to polyfill `apiVersion` for WordPress version 6712 // lower than 5.7. If it isn't present in the definition shared 6713 // from the server, we try to fallback to the definition passed. 6714 // @see https://github.com/WordPress/gutenberg/pull/29279 6715 if (serverSideBlockDefinitions[blockName].apiVersion === undefined && definitions[blockName].apiVersion) { 6716 serverSideBlockDefinitions[blockName].apiVersion = definitions[blockName].apiVersion; 6717 } // The `ancestor` prop is not included in the definitions shared 6718 // from the server yet, so it needs to be polyfilled as well. 6719 // @see https://github.com/WordPress/gutenberg/pull/39894 6720 6721 6722 if (serverSideBlockDefinitions[blockName].ancestor === undefined && definitions[blockName].ancestor) { 6723 serverSideBlockDefinitions[blockName].ancestor = definitions[blockName].ancestor; 6724 } 6725 6726 continue; 6727 } 6728 6729 serverSideBlockDefinitions[blockName] = (0,external_lodash_namespaceObject.mapKeys)((0,external_lodash_namespaceObject.pickBy)(definitions[blockName], value => !(0,external_lodash_namespaceObject.isNil)(value)), (value, key) => (0,external_lodash_namespaceObject.camelCase)(key)); 6730 } 6731 } 6732 /** 6733 * Gets block settings from metadata loaded from `block.json` file. 6734 * 6735 * @param {Object} metadata Block metadata loaded from `block.json`. 6736 * @param {string} metadata.textdomain Textdomain to use with translations. 6737 * 6738 * @return {Object} Block settings. 6739 */ 6740 6741 function getBlockSettingsFromMetadata(_ref) { 6742 let { 6743 textdomain, 6744 ...metadata 6745 } = _ref; 6746 const allowedFields = ['apiVersion', 'title', 'category', 'parent', 'ancestor', 'icon', 'description', 'keywords', 'attributes', 'providesContext', 'usesContext', 'supports', 'styles', 'example', 'variations']; 6747 const settings = (0,external_lodash_namespaceObject.pick)(metadata, allowedFields); 6748 6749 if (textdomain) { 6750 Object.keys(i18nBlockSchema).forEach(key => { 6751 if (!settings[key]) { 6752 return; 6753 } 6754 6755 settings[key] = translateBlockSettingUsingI18nSchema(i18nBlockSchema[key], settings[key], textdomain); 6756 }); 6757 } 6758 6759 return settings; 6760 } 6761 /** 6762 * Registers a new block provided a unique name and an object defining its 6763 * behavior. Once registered, the block is made available as an option to any 6764 * editor interface where blocks are implemented. 6765 * 6766 * @param {string|Object} blockNameOrMetadata Block type name or its metadata. 6767 * @param {Object} settings Block settings. 6768 * 6769 * @return {?WPBlockType} The block, if it has been successfully registered; 6770 * otherwise `undefined`. 6771 */ 6772 6773 6774 function registerBlockType(blockNameOrMetadata, settings) { 6775 const name = (0,external_lodash_namespaceObject.isObject)(blockNameOrMetadata) ? blockNameOrMetadata.name : blockNameOrMetadata; 6776 6777 if (typeof name !== 'string') { 6778 console.error('Block names must be strings.'); 6779 return; 6780 } 6781 6782 if (!/^[a-z][a-z0-9-]*\/[a-z][a-z0-9-]*$/.test(name)) { 6783 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'); 6784 return; 6785 } 6786 6787 if ((0,external_wp_data_namespaceObject.select)(store).getBlockType(name)) { 6788 console.error('Block "' + name + '" is already registered.'); 6789 return; 6790 } 6791 6792 if ((0,external_lodash_namespaceObject.isObject)(blockNameOrMetadata)) { 6793 unstable__bootstrapServerSideBlockDefinitions({ 6794 [name]: getBlockSettingsFromMetadata(blockNameOrMetadata) 6795 }); 6796 } 6797 6798 const blockType = { 6799 name, 6800 icon: BLOCK_ICON_DEFAULT, 6801 keywords: [], 6802 attributes: {}, 6803 providesContext: {}, 6804 usesContext: [], 6805 supports: {}, 6806 styles: [], 6807 variations: [], 6808 save: () => null, 6809 ...(serverSideBlockDefinitions === null || serverSideBlockDefinitions === void 0 ? void 0 : serverSideBlockDefinitions[name]), 6810 ...settings 6811 }; 6812 6813 (0,external_wp_data_namespaceObject.dispatch)(store).__experimentalRegisterBlockType(blockType); 6814 6815 return (0,external_wp_data_namespaceObject.select)(store).getBlockType(name); 6816 } 6817 /** 6818 * Translates block settings provided with metadata using the i18n schema. 6819 * 6820 * @param {string|string[]|Object[]} i18nSchema I18n schema for the block setting. 6821 * @param {string|string[]|Object[]} settingValue Value for the block setting. 6822 * @param {string} textdomain Textdomain to use with translations. 6823 * 6824 * @return {string|string[]|Object[]} Translated setting. 6825 */ 6826 6827 function translateBlockSettingUsingI18nSchema(i18nSchema, settingValue, textdomain) { 6828 if ((0,external_lodash_namespaceObject.isString)(i18nSchema) && (0,external_lodash_namespaceObject.isString)(settingValue)) { 6829 // eslint-disable-next-line @wordpress/i18n-no-variables, @wordpress/i18n-text-domain 6830 return (0,external_wp_i18n_namespaceObject._x)(settingValue, i18nSchema, textdomain); 6831 } 6832 6833 if ((0,external_lodash_namespaceObject.isArray)(i18nSchema) && !(0,external_lodash_namespaceObject.isEmpty)(i18nSchema) && (0,external_lodash_namespaceObject.isArray)(settingValue)) { 6834 return settingValue.map(value => translateBlockSettingUsingI18nSchema(i18nSchema[0], value, textdomain)); 6835 } 6836 6837 if ((0,external_lodash_namespaceObject.isObject)(i18nSchema) && !(0,external_lodash_namespaceObject.isEmpty)(i18nSchema) && (0,external_lodash_namespaceObject.isObject)(settingValue)) { 6838 return Object.keys(settingValue).reduce((accumulator, key) => { 6839 if (!i18nSchema[key]) { 6840 accumulator[key] = settingValue[key]; 6841 return accumulator; 6842 } 6843 6844 accumulator[key] = translateBlockSettingUsingI18nSchema(i18nSchema[key], settingValue[key], textdomain); 6845 return accumulator; 6846 }, {}); 6847 } 6848 6849 return settingValue; 6850 } 6851 /** 6852 * Registers a new block collection to group blocks in the same namespace in the inserter. 6853 * 6854 * @param {string} namespace The namespace to group blocks by in the inserter; corresponds to the block namespace. 6855 * @param {Object} settings The block collection settings. 6856 * @param {string} settings.title The title to display in the block inserter. 6857 * @param {Object} [settings.icon] The icon to display in the block inserter. 6858 */ 6859 6860 6861 function registerBlockCollection(namespace, _ref2) { 6862 let { 6863 title, 6864 icon 6865 } = _ref2; 6866 (0,external_wp_data_namespaceObject.dispatch)(store).addBlockCollection(namespace, title, icon); 6867 } 6868 /** 6869 * Unregisters a block collection 6870 * 6871 * @param {string} namespace The namespace to group blocks by in the inserter; corresponds to the block namespace 6872 * 6873 */ 6874 6875 function unregisterBlockCollection(namespace) { 6876 dispatch(blocksStore).removeBlockCollection(namespace); 6877 } 6878 /** 6879 * Unregisters a block. 6880 * 6881 * @param {string} name Block name. 6882 * 6883 * @return {?WPBlockType} The previous block value, if it has been successfully 6884 * unregistered; otherwise `undefined`. 6885 */ 6886 6887 function unregisterBlockType(name) { 6888 const oldBlock = (0,external_wp_data_namespaceObject.select)(store).getBlockType(name); 6889 6890 if (!oldBlock) { 6891 console.error('Block "' + name + '" is not registered.'); 6892 return; 6893 } 6894 6895 (0,external_wp_data_namespaceObject.dispatch)(store).removeBlockTypes(name); 6896 return oldBlock; 6897 } 6898 /** 6899 * Assigns name of block for handling non-block content. 6900 * 6901 * @param {string} blockName Block name. 6902 */ 6903 6904 function setFreeformContentHandlerName(blockName) { 6905 (0,external_wp_data_namespaceObject.dispatch)(store).setFreeformFallbackBlockName(blockName); 6906 } 6907 /** 6908 * Retrieves name of block handling non-block content, or undefined if no 6909 * handler has been defined. 6910 * 6911 * @return {?string} Block name. 6912 */ 6913 6914 function getFreeformContentHandlerName() { 6915 return (0,external_wp_data_namespaceObject.select)(store).getFreeformFallbackBlockName(); 6916 } 6917 /** 6918 * Retrieves name of block used for handling grouping interactions. 6919 * 6920 * @return {?string} Block name. 6921 */ 6922 6923 function registration_getGroupingBlockName() { 6924 return (0,external_wp_data_namespaceObject.select)(store).getGroupingBlockName(); 6925 } 6926 /** 6927 * Assigns name of block handling unregistered block types. 6928 * 6929 * @param {string} blockName Block name. 6930 */ 6931 6932 function setUnregisteredTypeHandlerName(blockName) { 6933 (0,external_wp_data_namespaceObject.dispatch)(store).setUnregisteredFallbackBlockName(blockName); 6934 } 6935 /** 6936 * Retrieves name of block handling unregistered block types, or undefined if no 6937 * handler has been defined. 6938 * 6939 * @return {?string} Block name. 6940 */ 6941 6942 function getUnregisteredTypeHandlerName() { 6943 return (0,external_wp_data_namespaceObject.select)(store).getUnregisteredFallbackBlockName(); 6944 } 6945 /** 6946 * Assigns the default block name. 6947 * 6948 * @param {string} name Block name. 6949 */ 6950 6951 function setDefaultBlockName(name) { 6952 (0,external_wp_data_namespaceObject.dispatch)(store).setDefaultBlockName(name); 6953 } 6954 /** 6955 * Assigns name of block for handling block grouping interactions. 6956 * 6957 * @param {string} name Block name. 6958 */ 6959 6960 function setGroupingBlockName(name) { 6961 (0,external_wp_data_namespaceObject.dispatch)(store).setGroupingBlockName(name); 6962 } 6963 /** 6964 * Retrieves the default block name. 6965 * 6966 * @return {?string} Block name. 6967 */ 6968 6969 function registration_getDefaultBlockName() { 6970 return (0,external_wp_data_namespaceObject.select)(store).getDefaultBlockName(); 6971 } 6972 /** 6973 * Returns a registered block type. 6974 * 6975 * @param {string} name Block name. 6976 * 6977 * @return {?Object} Block type. 6978 */ 6979 6980 function registration_getBlockType(name) { 6981 var _select; 6982 6983 return (_select = (0,external_wp_data_namespaceObject.select)(store)) === null || _select === void 0 ? void 0 : _select.getBlockType(name); 6984 } 6985 /** 6986 * Returns all registered blocks. 6987 * 6988 * @return {Array} Block settings. 6989 */ 6990 6991 function registration_getBlockTypes() { 6992 return (0,external_wp_data_namespaceObject.select)(store).getBlockTypes(); 6993 } 6994 /** 6995 * Returns the block support value for a feature, if defined. 6996 * 6997 * @param {(string|Object)} nameOrType Block name or type object 6998 * @param {string} feature Feature to retrieve 6999 * @param {*} defaultSupports Default value to return if not 7000 * explicitly defined 7001 * 7002 * @return {?*} Block support value 7003 */ 7004 7005 function registration_getBlockSupport(nameOrType, feature, defaultSupports) { 7006 return (0,external_wp_data_namespaceObject.select)(store).getBlockSupport(nameOrType, feature, defaultSupports); 7007 } 7008 /** 7009 * Returns true if the block defines support for a feature, or false otherwise. 7010 * 7011 * @param {(string|Object)} nameOrType Block name or type object. 7012 * @param {string} feature Feature to test. 7013 * @param {boolean} defaultSupports Whether feature is supported by 7014 * default if not explicitly defined. 7015 * 7016 * @return {boolean} Whether block supports feature. 7017 */ 7018 7019 function registration_hasBlockSupport(nameOrType, feature, defaultSupports) { 7020 return (0,external_wp_data_namespaceObject.select)(store).hasBlockSupport(nameOrType, feature, defaultSupports); 7021 } 7022 /** 7023 * Determines whether or not the given block is a reusable block. This is a 7024 * special block type that is used to point to a global block stored via the 7025 * API. 7026 * 7027 * @param {Object} blockOrType Block or Block Type to test. 7028 * 7029 * @return {boolean} Whether the given block is a reusable block. 7030 */ 7031 7032 function isReusableBlock(blockOrType) { 7033 return (blockOrType === null || blockOrType === void 0 ? void 0 : blockOrType.name) === 'core/block'; 7034 } 7035 /** 7036 * Determines whether or not the given block is a template part. This is a 7037 * special block type that allows composing a page template out of reusable 7038 * design elements. 7039 * 7040 * @param {Object} blockOrType Block or Block Type to test. 7041 * 7042 * @return {boolean} Whether the given block is a template part. 7043 */ 7044 7045 function isTemplatePart(blockOrType) { 7046 return blockOrType.name === 'core/template-part'; 7047 } 7048 /** 7049 * Returns an array with the child blocks of a given block. 7050 * 7051 * @param {string} blockName Name of block (example: “latest-posts”). 7052 * 7053 * @return {Array} Array of child block names. 7054 */ 7055 7056 const registration_getChildBlockNames = blockName => { 7057 return (0,external_wp_data_namespaceObject.select)(store).getChildBlockNames(blockName); 7058 }; 7059 /** 7060 * Returns a boolean indicating if a block has child blocks or not. 7061 * 7062 * @param {string} blockName Name of block (example: “latest-posts”). 7063 * 7064 * @return {boolean} True if a block contains child blocks and false otherwise. 7065 */ 7066 7067 const registration_hasChildBlocks = blockName => { 7068 return (0,external_wp_data_namespaceObject.select)(store).hasChildBlocks(blockName); 7069 }; 7070 /** 7071 * Returns a boolean indicating if a block has at least one child block with inserter support. 7072 * 7073 * @param {string} blockName Block type name. 7074 * 7075 * @return {boolean} True if a block contains at least one child blocks with inserter support 7076 * and false otherwise. 7077 */ 7078 7079 const registration_hasChildBlocksWithInserterSupport = blockName => { 7080 return (0,external_wp_data_namespaceObject.select)(store).hasChildBlocksWithInserterSupport(blockName); 7081 }; 7082 /** 7083 * Registers a new block style variation for the given block. 7084 * 7085 * @param {string} blockName Name of block (example: “core/latest-posts”). 7086 * @param {Object} styleVariation Object containing `name` which is the class name applied to the block and `label` which identifies the variation to the user. 7087 */ 7088 7089 const registerBlockStyle = (blockName, styleVariation) => { 7090 (0,external_wp_data_namespaceObject.dispatch)(store).addBlockStyles(blockName, styleVariation); 7091 }; 7092 /** 7093 * Unregisters a block style variation for the given block. 7094 * 7095 * @param {string} blockName Name of block (example: “core/latest-posts”). 7096 * @param {string} styleVariationName Name of class applied to the block. 7097 */ 7098 7099 const unregisterBlockStyle = (blockName, styleVariationName) => { 7100 (0,external_wp_data_namespaceObject.dispatch)(store).removeBlockStyles(blockName, styleVariationName); 7101 }; 7102 /** 7103 * Returns an array with the variations of a given block type. 7104 * 7105 * @param {string} blockName Name of block (example: “core/columns”). 7106 * @param {WPBlockVariationScope} [scope] Block variation scope name. 7107 * 7108 * @return {(WPBlockVariation[]|void)} Block variations. 7109 */ 7110 7111 const registration_getBlockVariations = (blockName, scope) => { 7112 return (0,external_wp_data_namespaceObject.select)(store).getBlockVariations(blockName, scope); 7113 }; 7114 /** 7115 * Registers a new block variation for the given block type. 7116 * 7117 * @param {string} blockName Name of the block (example: “core/columns”). 7118 * @param {WPBlockVariation} variation Object describing a block variation. 7119 */ 7120 7121 const registerBlockVariation = (blockName, variation) => { 7122 (0,external_wp_data_namespaceObject.dispatch)(store).addBlockVariations(blockName, variation); 7123 }; 7124 /** 7125 * Unregisters a block variation defined for the given block type. 7126 * 7127 * @param {string} blockName Name of the block (example: “core/columns”). 7128 * @param {string} variationName Name of the variation defined for the block. 7129 */ 7130 7131 const unregisterBlockVariation = (blockName, variationName) => { 7132 (0,external_wp_data_namespaceObject.dispatch)(store).removeBlockVariations(blockName, variationName); 7133 }; 7134 7135 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/rng.js 7136 // Unique ID creation requires a high quality random # generator. In the browser we therefore 7137 // require the crypto API and do not support built-in fallback to lower quality random number 7138 // generators (like Math.random()). 7139 var getRandomValues; 7140 var rnds8 = new Uint8Array(16); 7141 function rng() { 7142 // lazy load so that environments that need to polyfill have a chance to do so 7143 if (!getRandomValues) { 7144 // getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. Also, 7145 // find the complete implementation of crypto (msCrypto) on IE11. 7146 getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || typeof msCrypto !== 'undefined' && typeof msCrypto.getRandomValues === 'function' && msCrypto.getRandomValues.bind(msCrypto); 7147 7148 if (!getRandomValues) { 7149 throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported'); 7150 } 7151 } 7152 7153 return getRandomValues(rnds8); 7154 } 7155 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/regex.js 7156 /* harmony default export */ var regex = (/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i); 7157 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/validate.js 7158 7159 7160 function validate(uuid) { 7161 return typeof uuid === 'string' && regex.test(uuid); 7162 } 7163 7164 /* harmony default export */ var esm_browser_validate = (validate); 7165 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/stringify.js 7166 7167 /** 7168 * Convert array of 16 byte values to UUID string format of the form: 7169 * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX 7170 */ 7171 7172 var byteToHex = []; 7173 7174 for (var stringify_i = 0; stringify_i < 256; ++stringify_i) { 7175 byteToHex.push((stringify_i + 0x100).toString(16).substr(1)); 7176 } 7177 7178 function stringify(arr) { 7179 var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; 7180 // Note: Be careful editing this code! It's been tuned for performance 7181 // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434 7182 var uuid = (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); // Consistency check for valid UUID. If this throws, it's likely due to one 7183 // of the following: 7184 // - One or more input array values don't map to a hex octet (leading to 7185 // "undefined" in the uuid) 7186 // - Invalid input values for the RFC `version` or `variant` fields 7187 7188 if (!esm_browser_validate(uuid)) { 7189 throw TypeError('Stringified UUID is invalid'); 7190 } 7191 7192 return uuid; 7193 } 7194 7195 /* harmony default export */ var esm_browser_stringify = (stringify); 7196 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/v4.js 7197 7198 7199 7200 function v4(options, buf, offset) { 7201 options = options || {}; 7202 var rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` 7203 7204 rnds[6] = rnds[6] & 0x0f | 0x40; 7205 rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided 7206 7207 if (buf) { 7208 offset = offset || 0; 7209 7210 for (var i = 0; i < 16; ++i) { 7211 buf[offset + i] = rnds[i]; 7212 } 7213 7214 return buf; 7215 } 7216 7217 return esm_browser_stringify(rnds); 7218 } 7219 7220 /* harmony default export */ var esm_browser_v4 = (v4); 7221 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/factory.js 7222 /** 7223 * External dependencies 7224 */ 7225 7226 7227 /** 7228 * WordPress dependencies 7229 */ 7230 7231 7232 /** 7233 * Internal dependencies 7234 */ 7235 7236 7237 7238 /** 7239 * Returns a block object given its type and attributes. 7240 * 7241 * @param {string} name Block name. 7242 * @param {Object} attributes Block attributes. 7243 * @param {?Array} innerBlocks Nested blocks. 7244 * 7245 * @return {Object} Block object. 7246 */ 7247 7248 function createBlock(name) { 7249 let attributes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 7250 let innerBlocks = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : []; 7251 7252 const sanitizedAttributes = __experimentalSanitizeBlockAttributes(name, attributes); 7253 7254 const clientId = esm_browser_v4(); // Blocks are stored with a unique ID, the assigned type name, the block 7255 // attributes, and their inner blocks. 7256 7257 return { 7258 clientId, 7259 name, 7260 isValid: true, 7261 attributes: sanitizedAttributes, 7262 innerBlocks 7263 }; 7264 } 7265 /** 7266 * Given an array of InnerBlocks templates or Block Objects, 7267 * returns an array of created Blocks from them. 7268 * It handles the case of having InnerBlocks as Blocks by 7269 * converting them to the proper format to continue recursively. 7270 * 7271 * @param {Array} innerBlocksOrTemplate Nested blocks or InnerBlocks templates. 7272 * 7273 * @return {Object[]} Array of Block objects. 7274 */ 7275 7276 function createBlocksFromInnerBlocksTemplate() { 7277 let innerBlocksOrTemplate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 7278 return innerBlocksOrTemplate.map(innerBlock => { 7279 const innerBlockTemplate = Array.isArray(innerBlock) ? innerBlock : [innerBlock.name, innerBlock.attributes, innerBlock.innerBlocks]; 7280 const [name, attributes, innerBlocks = []] = innerBlockTemplate; 7281 return createBlock(name, attributes, createBlocksFromInnerBlocksTemplate(innerBlocks)); 7282 }); 7283 } 7284 /** 7285 * Given a block object, returns a copy of the block object while sanitizing its attributes, 7286 * optionally merging new attributes and/or replacing its inner blocks. 7287 * 7288 * @param {Object} block Block instance. 7289 * @param {Object} mergeAttributes Block attributes. 7290 * @param {?Array} newInnerBlocks Nested blocks. 7291 * 7292 * @return {Object} A cloned block. 7293 */ 7294 7295 function __experimentalCloneSanitizedBlock(block) { 7296 let mergeAttributes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 7297 let newInnerBlocks = arguments.length > 2 ? arguments[2] : undefined; 7298 const clientId = esm_browser_v4(); 7299 7300 const sanitizedAttributes = __experimentalSanitizeBlockAttributes(block.name, { ...block.attributes, 7301 ...mergeAttributes 7302 }); 7303 7304 return { ...block, 7305 clientId, 7306 attributes: sanitizedAttributes, 7307 innerBlocks: newInnerBlocks || block.innerBlocks.map(innerBlock => __experimentalCloneSanitizedBlock(innerBlock)) 7308 }; 7309 } 7310 /** 7311 * Given a block object, returns a copy of the block object, 7312 * optionally merging new attributes and/or replacing its inner blocks. 7313 * 7314 * @param {Object} block Block instance. 7315 * @param {Object} mergeAttributes Block attributes. 7316 * @param {?Array} newInnerBlocks Nested blocks. 7317 * 7318 * @return {Object} A cloned block. 7319 */ 7320 7321 function cloneBlock(block) { 7322 let mergeAttributes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 7323 let newInnerBlocks = arguments.length > 2 ? arguments[2] : undefined; 7324 const clientId = esm_browser_v4(); 7325 return { ...block, 7326 clientId, 7327 attributes: { ...block.attributes, 7328 ...mergeAttributes 7329 }, 7330 innerBlocks: newInnerBlocks || block.innerBlocks.map(innerBlock => cloneBlock(innerBlock)) 7331 }; 7332 } 7333 /** 7334 * Returns a boolean indicating whether a transform is possible based on 7335 * various bits of context. 7336 * 7337 * @param {Object} transform The transform object to validate. 7338 * @param {string} direction Is this a 'from' or 'to' transform. 7339 * @param {Array} blocks The blocks to transform from. 7340 * 7341 * @return {boolean} Is the transform possible? 7342 */ 7343 7344 const isPossibleTransformForSource = (transform, direction, blocks) => { 7345 if ((0,external_lodash_namespaceObject.isEmpty)(blocks)) { 7346 return false; 7347 } // If multiple blocks are selected, only multi block transforms 7348 // or wildcard transforms are allowed. 7349 7350 7351 const isMultiBlock = blocks.length > 1; 7352 const firstBlockName = (0,external_lodash_namespaceObject.first)(blocks).name; 7353 const isValidForMultiBlocks = isWildcardBlockTransform(transform) || !isMultiBlock || transform.isMultiBlock; 7354 7355 if (!isValidForMultiBlocks) { 7356 return false; 7357 } // Check non-wildcard transforms to ensure that transform is valid 7358 // for a block selection of multiple blocks of different types. 7359 7360 7361 if (!isWildcardBlockTransform(transform) && !(0,external_lodash_namespaceObject.every)(blocks, { 7362 name: firstBlockName 7363 })) { 7364 return false; 7365 } // Only consider 'block' type transforms as valid. 7366 7367 7368 const isBlockType = transform.type === 'block'; 7369 7370 if (!isBlockType) { 7371 return false; 7372 } // Check if the transform's block name matches the source block (or is a wildcard) 7373 // only if this is a transform 'from'. 7374 7375 7376 const sourceBlock = (0,external_lodash_namespaceObject.first)(blocks); 7377 const hasMatchingName = direction !== 'from' || transform.blocks.indexOf(sourceBlock.name) !== -1 || isWildcardBlockTransform(transform); 7378 7379 if (!hasMatchingName) { 7380 return false; 7381 } // Don't allow single Grouping blocks to be transformed into 7382 // a Grouping block. 7383 7384 7385 if (!isMultiBlock && isContainerGroupBlock(sourceBlock.name) && isContainerGroupBlock(transform.blockName)) { 7386 return false; 7387 } // If the transform has a `isMatch` function specified, check that it returns true. 7388 7389 7390 if ((0,external_lodash_namespaceObject.isFunction)(transform.isMatch)) { 7391 const attributes = transform.isMultiBlock ? blocks.map(block => block.attributes) : sourceBlock.attributes; 7392 const block = transform.isMultiBlock ? blocks : sourceBlock; 7393 7394 if (!transform.isMatch(attributes, block)) { 7395 return false; 7396 } 7397 } 7398 7399 if (transform.usingMobileTransformations && isWildcardBlockTransform(transform) && !isContainerGroupBlock(sourceBlock.name)) { 7400 return false; 7401 } 7402 7403 return true; 7404 }; 7405 /** 7406 * Returns block types that the 'blocks' can be transformed into, based on 7407 * 'from' transforms on other blocks. 7408 * 7409 * @param {Array} blocks The blocks to transform from. 7410 * 7411 * @return {Array} Block types that the blocks can be transformed into. 7412 */ 7413 7414 7415 const getBlockTypesForPossibleFromTransforms = blocks => { 7416 if ((0,external_lodash_namespaceObject.isEmpty)(blocks)) { 7417 return []; 7418 } 7419 7420 const allBlockTypes = registration_getBlockTypes(); // filter all blocks to find those with a 'from' transform. 7421 7422 const blockTypesWithPossibleFromTransforms = (0,external_lodash_namespaceObject.filter)(allBlockTypes, blockType => { 7423 const fromTransforms = getBlockTransforms('from', blockType.name); 7424 return !!findTransform(fromTransforms, transform => { 7425 return isPossibleTransformForSource(transform, 'from', blocks); 7426 }); 7427 }); 7428 return blockTypesWithPossibleFromTransforms; 7429 }; 7430 /** 7431 * Returns block types that the 'blocks' can be transformed into, based on 7432 * the source block's own 'to' transforms. 7433 * 7434 * @param {Array} blocks The blocks to transform from. 7435 * 7436 * @return {Array} Block types that the source can be transformed into. 7437 */ 7438 7439 7440 const getBlockTypesForPossibleToTransforms = blocks => { 7441 if ((0,external_lodash_namespaceObject.isEmpty)(blocks)) { 7442 return []; 7443 } 7444 7445 const sourceBlock = (0,external_lodash_namespaceObject.first)(blocks); 7446 const blockType = registration_getBlockType(sourceBlock.name); 7447 const transformsTo = blockType ? getBlockTransforms('to', blockType.name) : []; // filter all 'to' transforms to find those that are possible. 7448 7449 const possibleTransforms = (0,external_lodash_namespaceObject.filter)(transformsTo, transform => { 7450 return transform && isPossibleTransformForSource(transform, 'to', blocks); 7451 }); // Build a list of block names using the possible 'to' transforms. 7452 7453 const blockNames = (0,external_lodash_namespaceObject.flatMap)(possibleTransforms, transformation => transformation.blocks); // Map block names to block types. 7454 7455 return blockNames.map(name => name === '*' ? name : registration_getBlockType(name)); 7456 }; 7457 /** 7458 * Determines whether transform is a "block" type 7459 * and if so whether it is a "wildcard" transform 7460 * ie: targets "any" block type 7461 * 7462 * @param {Object} t the Block transform object 7463 * 7464 * @return {boolean} whether transform is a wildcard transform 7465 */ 7466 7467 7468 const isWildcardBlockTransform = t => t && t.type === 'block' && Array.isArray(t.blocks) && t.blocks.includes('*'); 7469 /** 7470 * Determines whether the given Block is the core Block which 7471 * acts as a container Block for other Blocks as part of the 7472 * Grouping mechanics 7473 * 7474 * @param {string} name the name of the Block to test against 7475 * 7476 * @return {boolean} whether or not the Block is the container Block type 7477 */ 7478 7479 const isContainerGroupBlock = name => name === registration_getGroupingBlockName(); 7480 /** 7481 * Returns an array of block types that the set of blocks received as argument 7482 * can be transformed into. 7483 * 7484 * @param {Array} blocks Blocks array. 7485 * 7486 * @return {Array} Block types that the blocks argument can be transformed to. 7487 */ 7488 7489 function getPossibleBlockTransformations(blocks) { 7490 if ((0,external_lodash_namespaceObject.isEmpty)(blocks)) { 7491 return []; 7492 } 7493 7494 const blockTypesForFromTransforms = getBlockTypesForPossibleFromTransforms(blocks); 7495 const blockTypesForToTransforms = getBlockTypesForPossibleToTransforms(blocks); 7496 return (0,external_lodash_namespaceObject.uniq)([...blockTypesForFromTransforms, ...blockTypesForToTransforms]); 7497 } 7498 /** 7499 * Given an array of transforms, returns the highest-priority transform where 7500 * the predicate function returns a truthy value. A higher-priority transform 7501 * is one with a lower priority value (i.e. first in priority order). Returns 7502 * null if the transforms set is empty or the predicate function returns a 7503 * falsey value for all entries. 7504 * 7505 * @param {Object[]} transforms Transforms to search. 7506 * @param {Function} predicate Function returning true on matching transform. 7507 * 7508 * @return {?Object} Highest-priority transform candidate. 7509 */ 7510 7511 function findTransform(transforms, predicate) { 7512 // The hooks library already has built-in mechanisms for managing priority 7513 // queue, so leverage via locally-defined instance. 7514 const hooks = (0,external_wp_hooks_namespaceObject.createHooks)(); 7515 7516 for (let i = 0; i < transforms.length; i++) { 7517 const candidate = transforms[i]; 7518 7519 if (predicate(candidate)) { 7520 hooks.addFilter('transform', 'transform/' + i.toString(), result => result ? result : candidate, candidate.priority); 7521 } 7522 } // Filter name is arbitrarily chosen but consistent with above aggregation. 7523 7524 7525 return hooks.applyFilters('transform', null); 7526 } 7527 /** 7528 * Returns normal block transforms for a given transform direction, optionally 7529 * for a specific block by name, or an empty array if there are no transforms. 7530 * If no block name is provided, returns transforms for all blocks. A normal 7531 * transform object includes `blockName` as a property. 7532 * 7533 * @param {string} direction Transform direction ("to", "from"). 7534 * @param {string|Object} blockTypeOrName Block type or name. 7535 * 7536 * @return {Array} Block transforms for direction. 7537 */ 7538 7539 function getBlockTransforms(direction, blockTypeOrName) { 7540 // When retrieving transforms for all block types, recurse into self. 7541 if (blockTypeOrName === undefined) { 7542 return (0,external_lodash_namespaceObject.flatMap)(registration_getBlockTypes(), _ref => { 7543 let { 7544 name 7545 } = _ref; 7546 return getBlockTransforms(direction, name); 7547 }); 7548 } // Validate that block type exists and has array of direction. 7549 7550 7551 const blockType = normalizeBlockType(blockTypeOrName); 7552 const { 7553 name: blockName, 7554 transforms 7555 } = blockType || {}; 7556 7557 if (!transforms || !Array.isArray(transforms[direction])) { 7558 return []; 7559 } 7560 7561 const usingMobileTransformations = transforms.supportedMobileTransforms && Array.isArray(transforms.supportedMobileTransforms); 7562 const filteredTransforms = usingMobileTransformations ? (0,external_lodash_namespaceObject.filter)(transforms[direction], t => { 7563 if (t.type === 'raw') { 7564 return true; 7565 } 7566 7567 if (!t.blocks || !t.blocks.length) { 7568 return false; 7569 } 7570 7571 if (isWildcardBlockTransform(t)) { 7572 return true; 7573 } 7574 7575 return (0,external_lodash_namespaceObject.every)(t.blocks, transformBlockName => transforms.supportedMobileTransforms.includes(transformBlockName)); 7576 }) : transforms[direction]; // Map transforms to normal form. 7577 7578 return filteredTransforms.map(transform => ({ ...transform, 7579 blockName, 7580 usingMobileTransformations 7581 })); 7582 } 7583 /** 7584 * Switch one or more blocks into one or more blocks of the new block type. 7585 * 7586 * @param {Array|Object} blocks Blocks array or block object. 7587 * @param {string} name Block name. 7588 * 7589 * @return {?Array} Array of blocks or null. 7590 */ 7591 7592 function switchToBlockType(blocks, name) { 7593 const blocksArray = (0,external_lodash_namespaceObject.castArray)(blocks); 7594 const isMultiBlock = blocksArray.length > 1; 7595 const firstBlock = blocksArray[0]; 7596 const sourceName = firstBlock.name; // Find the right transformation by giving priority to the "to" 7597 // transformation. 7598 7599 const transformationsFrom = getBlockTransforms('from', name); 7600 const transformationsTo = getBlockTransforms('to', sourceName); 7601 const transformation = findTransform(transformationsTo, t => t.type === 'block' && (isWildcardBlockTransform(t) || t.blocks.indexOf(name) !== -1) && (!isMultiBlock || t.isMultiBlock)) || findTransform(transformationsFrom, t => t.type === 'block' && (isWildcardBlockTransform(t) || t.blocks.indexOf(sourceName) !== -1) && (!isMultiBlock || t.isMultiBlock)); // Stop if there is no valid transformation. 7602 7603 if (!transformation) { 7604 return null; 7605 } 7606 7607 let transformationResults; 7608 7609 if (transformation.isMultiBlock) { 7610 if ((0,external_lodash_namespaceObject.has)(transformation, '__experimentalConvert')) { 7611 transformationResults = transformation.__experimentalConvert(blocksArray); 7612 } else { 7613 transformationResults = transformation.transform(blocksArray.map(currentBlock => currentBlock.attributes), blocksArray.map(currentBlock => currentBlock.innerBlocks)); 7614 } 7615 } else if ((0,external_lodash_namespaceObject.has)(transformation, '__experimentalConvert')) { 7616 transformationResults = transformation.__experimentalConvert(firstBlock); 7617 } else { 7618 transformationResults = transformation.transform(firstBlock.attributes, firstBlock.innerBlocks); 7619 } // Ensure that the transformation function returned an object or an array 7620 // of objects. 7621 7622 7623 if (!(0,external_lodash_namespaceObject.isObjectLike)(transformationResults)) { 7624 return null; 7625 } // If the transformation function returned a single object, we want to work 7626 // with an array instead. 7627 7628 7629 transformationResults = (0,external_lodash_namespaceObject.castArray)(transformationResults); // Ensure that every block object returned by the transformation has a 7630 // valid block type. 7631 7632 if (transformationResults.some(result => !registration_getBlockType(result.name))) { 7633 return null; 7634 } 7635 7636 const hasSwitchedBlock = name === '*' || (0,external_lodash_namespaceObject.some)(transformationResults, result => result.name === name); // Ensure that at least one block object returned by the transformation has 7637 // the expected "destination" block type. 7638 7639 if (!hasSwitchedBlock) { 7640 return null; 7641 } 7642 7643 const ret = transformationResults.map((result, index, results) => { 7644 /** 7645 * Filters an individual transform result from block transformation. 7646 * All of the original blocks are passed, since transformations are 7647 * many-to-many, not one-to-one. 7648 * 7649 * @param {Object} transformedBlock The transformed block. 7650 * @param {Object[]} blocks Original blocks transformed. 7651 * @param {Object[]} index Index of the transformed block on the array of results. 7652 * @param {Object[]} results An array all the blocks that resulted from the transformation. 7653 */ 7654 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.switchToBlockType.transformedBlock', result, blocks, index, results); 7655 }); 7656 return ret; 7657 } 7658 /** 7659 * Create a block object from the example API. 7660 * 7661 * @param {string} name 7662 * @param {Object} example 7663 * 7664 * @return {Object} block. 7665 */ 7666 7667 const getBlockFromExample = (name, example) => { 7668 return createBlock(name, example.attributes, (0,external_lodash_namespaceObject.map)(example.innerBlocks, innerBlock => getBlockFromExample(innerBlock.name, innerBlock))); 7669 }; 7670 7671 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/utils.js 7672 /** 7673 * External dependencies 7674 */ 7675 7676 7677 7678 7679 /** 7680 * WordPress dependencies 7681 */ 7682 7683 7684 7685 7686 /** 7687 * Internal dependencies 7688 */ 7689 7690 7691 7692 7693 k([names, a11y]); 7694 /** 7695 * Array of icon colors containing a color to be used if the icon color 7696 * was not explicitly set but the icon background color was. 7697 * 7698 * @type {Object} 7699 */ 7700 7701 const ICON_COLORS = ['#191e23', '#f8f9f9']; 7702 /** 7703 * Determines whether the block is a default block 7704 * and its attributes are equal to the default attributes 7705 * which means the block is unmodified. 7706 * 7707 * @param {WPBlock} block Block Object 7708 * 7709 * @return {boolean} Whether the block is an unmodified default block 7710 */ 7711 7712 function isUnmodifiedDefaultBlock(block) { 7713 const defaultBlockName = registration_getDefaultBlockName(); 7714 7715 if (block.name !== defaultBlockName) { 7716 return false; 7717 } // Cache a created default block if no cache exists or the default block 7718 // name changed. 7719 7720 7721 if (!isUnmodifiedDefaultBlock.block || isUnmodifiedDefaultBlock.block.name !== defaultBlockName) { 7722 isUnmodifiedDefaultBlock.block = createBlock(defaultBlockName); 7723 } 7724 7725 const newDefaultBlock = isUnmodifiedDefaultBlock.block; 7726 const blockType = registration_getBlockType(defaultBlockName); 7727 return (0,external_lodash_namespaceObject.every)(blockType === null || blockType === void 0 ? void 0 : blockType.attributes, (value, key) => newDefaultBlock.attributes[key] === block.attributes[key]); 7728 } 7729 /** 7730 * Function that checks if the parameter is a valid icon. 7731 * 7732 * @param {*} icon Parameter to be checked. 7733 * 7734 * @return {boolean} True if the parameter is a valid icon and false otherwise. 7735 */ 7736 7737 function isValidIcon(icon) { 7738 return !!icon && ((0,external_lodash_namespaceObject.isString)(icon) || (0,external_wp_element_namespaceObject.isValidElement)(icon) || (0,external_lodash_namespaceObject.isFunction)(icon) || icon instanceof external_wp_element_namespaceObject.Component); 7739 } 7740 /** 7741 * Function that receives an icon as set by the blocks during the registration 7742 * and returns a new icon object that is normalized so we can rely on just on possible icon structure 7743 * in the codebase. 7744 * 7745 * @param {WPBlockTypeIconRender} icon Render behavior of a block type icon; 7746 * one of a Dashicon slug, an element, or a 7747 * component. 7748 * 7749 * @return {WPBlockTypeIconDescriptor} Object describing the icon. 7750 */ 7751 7752 function normalizeIconObject(icon) { 7753 icon = icon || BLOCK_ICON_DEFAULT; 7754 7755 if (isValidIcon(icon)) { 7756 return { 7757 src: icon 7758 }; 7759 } 7760 7761 if ((0,external_lodash_namespaceObject.has)(icon, ['background'])) { 7762 const colordBgColor = w(icon.background); 7763 return { ...icon, 7764 foreground: icon.foreground ? icon.foreground : (0,external_lodash_namespaceObject.maxBy)(ICON_COLORS, iconColor => colordBgColor.contrast(iconColor)), 7765 shadowColor: colordBgColor.alpha(0.3).toRgbString() 7766 }; 7767 } 7768 7769 return icon; 7770 } 7771 /** 7772 * Normalizes block type passed as param. When string is passed then 7773 * it converts it to the matching block type object. 7774 * It passes the original object otherwise. 7775 * 7776 * @param {string|Object} blockTypeOrName Block type or name. 7777 * 7778 * @return {?Object} Block type. 7779 */ 7780 7781 function normalizeBlockType(blockTypeOrName) { 7782 if ((0,external_lodash_namespaceObject.isString)(blockTypeOrName)) { 7783 return registration_getBlockType(blockTypeOrName); 7784 } 7785 7786 return blockTypeOrName; 7787 } 7788 /** 7789 * Get the label for the block, usually this is either the block title, 7790 * or the value of the block's `label` function when that's specified. 7791 * 7792 * @param {Object} blockType The block type. 7793 * @param {Object} attributes The values of the block's attributes. 7794 * @param {Object} context The intended use for the label. 7795 * 7796 * @return {string} The block label. 7797 */ 7798 7799 function getBlockLabel(blockType, attributes) { 7800 let context = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'visual'; 7801 const { 7802 __experimentalLabel: getLabel, 7803 title 7804 } = blockType; 7805 const label = getLabel && getLabel(attributes, { 7806 context 7807 }); 7808 7809 if (!label) { 7810 return title; 7811 } // Strip any HTML (i.e. RichText formatting) before returning. 7812 7813 7814 return (0,external_wp_dom_namespaceObject.__unstableStripHTML)(label); 7815 } 7816 /** 7817 * Get a label for the block for use by screenreaders, this is more descriptive 7818 * than the visual label and includes the block title and the value of the 7819 * `getLabel` function if it's specified. 7820 * 7821 * @param {Object} blockType The block type. 7822 * @param {Object} attributes The values of the block's attributes. 7823 * @param {?number} position The position of the block in the block list. 7824 * @param {string} [direction='vertical'] The direction of the block layout. 7825 * 7826 * @return {string} The block label. 7827 */ 7828 7829 function getAccessibleBlockLabel(blockType, attributes, position) { 7830 let direction = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'vertical'; 7831 // `title` is already localized, `label` is a user-supplied value. 7832 const title = blockType === null || blockType === void 0 ? void 0 : blockType.title; 7833 const label = blockType ? getBlockLabel(blockType, attributes, 'accessibility') : ''; 7834 const hasPosition = position !== undefined; // getBlockLabel returns the block title as a fallback when there's no label, 7835 // if it did return the title, this function needs to avoid adding the 7836 // title twice within the accessible label. Use this `hasLabel` boolean to 7837 // handle that. 7838 7839 const hasLabel = label && label !== title; 7840 7841 if (hasPosition && direction === 'vertical') { 7842 if (hasLabel) { 7843 return (0,external_wp_i18n_namespaceObject.sprintf)( 7844 /* translators: accessibility text. 1: The block title. 2: The block row number. 3: The block label.. */ 7845 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. Row %2$d. %3$s'), title, position, label); 7846 } 7847 7848 return (0,external_wp_i18n_namespaceObject.sprintf)( 7849 /* translators: accessibility text. 1: The block title. 2: The block row number. */ 7850 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. Row %2$d'), title, position); 7851 } else if (hasPosition && direction === 'horizontal') { 7852 if (hasLabel) { 7853 return (0,external_wp_i18n_namespaceObject.sprintf)( 7854 /* translators: accessibility text. 1: The block title. 2: The block column number. 3: The block label.. */ 7855 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. Column %2$d. %3$s'), title, position, label); 7856 } 7857 7858 return (0,external_wp_i18n_namespaceObject.sprintf)( 7859 /* translators: accessibility text. 1: The block title. 2: The block column number. */ 7860 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. Column %2$d'), title, position); 7861 } 7862 7863 if (hasLabel) { 7864 return (0,external_wp_i18n_namespaceObject.sprintf)( 7865 /* translators: accessibility text. %1: The block title. %2: The block label. */ 7866 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. %2$s'), title, label); 7867 } 7868 7869 return (0,external_wp_i18n_namespaceObject.sprintf)( 7870 /* translators: accessibility text. %s: The block title. */ 7871 (0,external_wp_i18n_namespaceObject.__)('%s Block'), title); 7872 } 7873 /** 7874 * Ensure attributes contains only values defined by block type, and merge 7875 * default values for missing attributes. 7876 * 7877 * @param {string} name The block's name. 7878 * @param {Object} attributes The block's attributes. 7879 * @return {Object} The sanitized attributes. 7880 */ 7881 7882 function __experimentalSanitizeBlockAttributes(name, attributes) { 7883 // Get the type definition associated with a registered block. 7884 const blockType = registration_getBlockType(name); 7885 7886 if (undefined === blockType) { 7887 throw new Error(`Block type '$name}' is not registered.`); 7888 } 7889 7890 return (0,external_lodash_namespaceObject.reduce)(blockType.attributes, (accumulator, schema, key) => { 7891 const value = attributes[key]; 7892 7893 if (undefined !== value) { 7894 accumulator[key] = value; 7895 } else if (schema.hasOwnProperty('default')) { 7896 accumulator[key] = schema.default; 7897 } 7898 7899 if (['node', 'children'].indexOf(schema.source) !== -1) { 7900 // Ensure value passed is always an array, which we're expecting in 7901 // the RichText component to handle the deprecated value. 7902 if (typeof accumulator[key] === 'string') { 7903 accumulator[key] = [accumulator[key]]; 7904 } else if (!Array.isArray(accumulator[key])) { 7905 accumulator[key] = []; 7906 } 7907 } 7908 7909 return accumulator; 7910 }, {}); 7911 } 7912 /** 7913 * Filter block attributes by `role` and return their names. 7914 * 7915 * @param {string} name Block attribute's name. 7916 * @param {string} role The role of a block attribute. 7917 * 7918 * @return {string[]} The attribute names that have the provided role. 7919 */ 7920 7921 function __experimentalGetBlockAttributesNamesByRole(name, role) { 7922 var _getBlockType; 7923 7924 const attributes = (_getBlockType = registration_getBlockType(name)) === null || _getBlockType === void 0 ? void 0 : _getBlockType.attributes; 7925 if (!attributes) return []; 7926 const attributesNames = Object.keys(attributes); 7927 if (!role) return attributesNames; 7928 return attributesNames.filter(attributeName => { 7929 var _attributes$attribute; 7930 7931 return ((_attributes$attribute = attributes[attributeName]) === null || _attributes$attribute === void 0 ? void 0 : _attributes$attribute.__experimentalRole) === role; 7932 }); 7933 } 7934 7935 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/store/actions.js 7936 /** 7937 * External dependencies 7938 */ 7939 7940 /** 7941 * WordPress dependencies 7942 */ 7943 7944 7945 /** 7946 * Internal dependencies 7947 */ 7948 7949 7950 7951 /** @typedef {import('../api/registration').WPBlockVariation} WPBlockVariation */ 7952 7953 const { 7954 error, 7955 warn 7956 } = window.console; 7957 /** 7958 * Mapping of legacy category slugs to their latest normal values, used to 7959 * accommodate updates of the default set of block categories. 7960 * 7961 * @type {Record<string,string>} 7962 */ 7963 7964 const LEGACY_CATEGORY_MAPPING = { 7965 common: 'text', 7966 formatting: 'text', 7967 layout: 'design' 7968 }; 7969 /** 7970 * Takes the unprocessed block type data and applies all the existing filters for the registered block type. 7971 * Next, it validates all the settings and performs additional processing to the block type definition. 7972 * 7973 * @param {WPBlockType} blockType Unprocessed block type settings. 7974 * @param {Object} thunkArgs Argument object for the thunk middleware. 7975 * @param {Function} thunkArgs.select Function to select from the store. 7976 * 7977 * @return {?WPBlockType} The block, if it has been successfully registered; otherwise `undefined`. 7978 */ 7979 7980 const processBlockType = (blockType, _ref) => { 7981 let { 7982 select 7983 } = _ref; 7984 const { 7985 name 7986 } = blockType; 7987 const settings = (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.registerBlockType', { ...blockType 7988 }, name); 7989 7990 if (settings.deprecated) { 7991 settings.deprecated = settings.deprecated.map(deprecation => (0,external_lodash_namespaceObject.pick)( // Only keep valid deprecation keys. 7992 (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.registerBlockType', // Merge deprecation keys with pre-filter settings 7993 // so that filters that depend on specific keys being 7994 // present don't fail. 7995 { // Omit deprecation keys here so that deprecations 7996 // can opt out of specific keys like "supports". 7997 ...(0,external_lodash_namespaceObject.omit)(blockType, DEPRECATED_ENTRY_KEYS), 7998 ...deprecation 7999 }, name), DEPRECATED_ENTRY_KEYS)); 8000 } 8001 8002 if (!(0,external_lodash_namespaceObject.isPlainObject)(settings)) { 8003 error('Block settings must be a valid object.'); 8004 return; 8005 } 8006 8007 if (!(0,external_lodash_namespaceObject.isFunction)(settings.save)) { 8008 error('The "save" property must be a valid function.'); 8009 return; 8010 } 8011 8012 if ('edit' in settings && !(0,external_lodash_namespaceObject.isFunction)(settings.edit)) { 8013 error('The "edit" property must be a valid function.'); 8014 return; 8015 } // Canonicalize legacy categories to equivalent fallback. 8016 8017 8018 if (LEGACY_CATEGORY_MAPPING.hasOwnProperty(settings.category)) { 8019 settings.category = LEGACY_CATEGORY_MAPPING[settings.category]; 8020 } 8021 8022 if ('category' in settings && !(0,external_lodash_namespaceObject.some)(select.getCategories(), { 8023 slug: settings.category 8024 })) { 8025 warn('The block "' + name + '" is registered with an invalid category "' + settings.category + '".'); 8026 delete settings.category; 8027 } 8028 8029 if (!('title' in settings) || settings.title === '') { 8030 error('The block "' + name + '" must have a title.'); 8031 return; 8032 } 8033 8034 if (typeof settings.title !== 'string') { 8035 error('Block titles must be strings.'); 8036 return; 8037 } 8038 8039 settings.icon = normalizeIconObject(settings.icon); 8040 8041 if (!isValidIcon(settings.icon.src)) { 8042 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'); 8043 return; 8044 } 8045 8046 return settings; 8047 }; 8048 /** 8049 * Returns an action object used in signalling that block types have been added. 8050 * 8051 * @param {Array|Object} blockTypes Block types received. 8052 * 8053 * @return {Object} Action object. 8054 */ 8055 8056 8057 function addBlockTypes(blockTypes) { 8058 return { 8059 type: 'ADD_BLOCK_TYPES', 8060 blockTypes: (0,external_lodash_namespaceObject.castArray)(blockTypes) 8061 }; 8062 } 8063 /** 8064 * Signals that the passed block type's settings should be stored in the state. 8065 * 8066 * @param {WPBlockType} blockType Unprocessed block type settings. 8067 */ 8068 8069 const __experimentalRegisterBlockType = blockType => _ref2 => { 8070 let { 8071 dispatch, 8072 select 8073 } = _ref2; 8074 dispatch({ 8075 type: 'ADD_UNPROCESSED_BLOCK_TYPE', 8076 blockType 8077 }); 8078 const processedBlockType = processBlockType(blockType, { 8079 select 8080 }); 8081 8082 if (!processedBlockType) { 8083 return; 8084 } 8085 8086 dispatch.addBlockTypes(processedBlockType); 8087 }; 8088 /** 8089 * Signals that all block types should be computed again. 8090 * It uses stored unprocessed block types and all the most recent list of registered filters. 8091 * 8092 * It addresses the issue where third party block filters get registered after third party blocks. A sample sequence: 8093 * 1. Filter A. 8094 * 2. Block B. 8095 * 3. Block C. 8096 * 4. Filter D. 8097 * 5. Filter E. 8098 * 6. Block F. 8099 * 7. Filter G. 8100 * In this scenario some filters would not get applied for all blocks because they are registered too late. 8101 */ 8102 8103 const __experimentalReapplyBlockTypeFilters = () => _ref3 => { 8104 let { 8105 dispatch, 8106 select 8107 } = _ref3; 8108 8109 const unprocessedBlockTypes = select.__experimentalGetUnprocessedBlockTypes(); 8110 8111 const processedBlockTypes = Object.keys(unprocessedBlockTypes).reduce((accumulator, blockName) => { 8112 const result = processBlockType(unprocessedBlockTypes[blockName], { 8113 select 8114 }); 8115 8116 if (result) { 8117 accumulator.push(result); 8118 } 8119 8120 return accumulator; 8121 }, []); 8122 8123 if (!processedBlockTypes.length) { 8124 return; 8125 } 8126 8127 dispatch.addBlockTypes(processedBlockTypes); 8128 }; 8129 /** 8130 * Returns an action object used to remove a registered block type. 8131 * 8132 * @param {string|Array} names Block name. 8133 * 8134 * @return {Object} Action object. 8135 */ 8136 8137 function removeBlockTypes(names) { 8138 return { 8139 type: 'REMOVE_BLOCK_TYPES', 8140 names: (0,external_lodash_namespaceObject.castArray)(names) 8141 }; 8142 } 8143 /** 8144 * Returns an action object used in signalling that new block styles have been added. 8145 * 8146 * @param {string} blockName Block name. 8147 * @param {Array|Object} styles Block styles. 8148 * 8149 * @return {Object} Action object. 8150 */ 8151 8152 function addBlockStyles(blockName, styles) { 8153 return { 8154 type: 'ADD_BLOCK_STYLES', 8155 styles: (0,external_lodash_namespaceObject.castArray)(styles), 8156 blockName 8157 }; 8158 } 8159 /** 8160 * Returns an action object used in signalling that block styles have been removed. 8161 * 8162 * @param {string} blockName Block name. 8163 * @param {Array|string} styleNames Block style names. 8164 * 8165 * @return {Object} Action object. 8166 */ 8167 8168 function removeBlockStyles(blockName, styleNames) { 8169 return { 8170 type: 'REMOVE_BLOCK_STYLES', 8171 styleNames: (0,external_lodash_namespaceObject.castArray)(styleNames), 8172 blockName 8173 }; 8174 } 8175 /** 8176 * Returns an action object used in signalling that new block variations have been added. 8177 * 8178 * @param {string} blockName Block name. 8179 * @param {WPBlockVariation|WPBlockVariation[]} variations Block variations. 8180 * 8181 * @return {Object} Action object. 8182 */ 8183 8184 function addBlockVariations(blockName, variations) { 8185 return { 8186 type: 'ADD_BLOCK_VARIATIONS', 8187 variations: (0,external_lodash_namespaceObject.castArray)(variations), 8188 blockName 8189 }; 8190 } 8191 /** 8192 * Returns an action object used in signalling that block variations have been removed. 8193 * 8194 * @param {string} blockName Block name. 8195 * @param {string|string[]} variationNames Block variation names. 8196 * 8197 * @return {Object} Action object. 8198 */ 8199 8200 function removeBlockVariations(blockName, variationNames) { 8201 return { 8202 type: 'REMOVE_BLOCK_VARIATIONS', 8203 variationNames: (0,external_lodash_namespaceObject.castArray)(variationNames), 8204 blockName 8205 }; 8206 } 8207 /** 8208 * Returns an action object used to set the default block name. 8209 * 8210 * @param {string} name Block name. 8211 * 8212 * @return {Object} Action object. 8213 */ 8214 8215 function actions_setDefaultBlockName(name) { 8216 return { 8217 type: 'SET_DEFAULT_BLOCK_NAME', 8218 name 8219 }; 8220 } 8221 /** 8222 * Returns an action object used to set the name of the block used as a fallback 8223 * for non-block content. 8224 * 8225 * @param {string} name Block name. 8226 * 8227 * @return {Object} Action object. 8228 */ 8229 8230 function setFreeformFallbackBlockName(name) { 8231 return { 8232 type: 'SET_FREEFORM_FALLBACK_BLOCK_NAME', 8233 name 8234 }; 8235 } 8236 /** 8237 * Returns an action object used to set the name of the block used as a fallback 8238 * for unregistered blocks. 8239 * 8240 * @param {string} name Block name. 8241 * 8242 * @return {Object} Action object. 8243 */ 8244 8245 function setUnregisteredFallbackBlockName(name) { 8246 return { 8247 type: 'SET_UNREGISTERED_FALLBACK_BLOCK_NAME', 8248 name 8249 }; 8250 } 8251 /** 8252 * Returns an action object used to set the name of the block used 8253 * when grouping other blocks 8254 * eg: in "Group/Ungroup" interactions 8255 * 8256 * @param {string} name Block name. 8257 * 8258 * @return {Object} Action object. 8259 */ 8260 8261 function actions_setGroupingBlockName(name) { 8262 return { 8263 type: 'SET_GROUPING_BLOCK_NAME', 8264 name 8265 }; 8266 } 8267 /** 8268 * Returns an action object used to set block categories. 8269 * 8270 * @param {Object[]} categories Block categories. 8271 * 8272 * @return {Object} Action object. 8273 */ 8274 8275 function setCategories(categories) { 8276 return { 8277 type: 'SET_CATEGORIES', 8278 categories 8279 }; 8280 } 8281 /** 8282 * Returns an action object used to update a category. 8283 * 8284 * @param {string} slug Block category slug. 8285 * @param {Object} category Object containing the category properties that should be updated. 8286 * 8287 * @return {Object} Action object. 8288 */ 8289 8290 function updateCategory(slug, category) { 8291 return { 8292 type: 'UPDATE_CATEGORY', 8293 slug, 8294 category 8295 }; 8296 } 8297 /** 8298 * Returns an action object used to add block collections 8299 * 8300 * @param {string} namespace The namespace of the blocks to put in the collection 8301 * @param {string} title The title to display in the block inserter 8302 * @param {Object} icon (optional) The icon to display in the block inserter 8303 * 8304 * @return {Object} Action object. 8305 */ 8306 8307 function addBlockCollection(namespace, title, icon) { 8308 return { 8309 type: 'ADD_BLOCK_COLLECTION', 8310 namespace, 8311 title, 8312 icon 8313 }; 8314 } 8315 /** 8316 * Returns an action object used to remove block collections 8317 * 8318 * @param {string} namespace The namespace of the blocks to put in the collection 8319 * 8320 * @return {Object} Action object. 8321 */ 8322 8323 function removeBlockCollection(namespace) { 8324 return { 8325 type: 'REMOVE_BLOCK_COLLECTION', 8326 namespace 8327 }; 8328 } 8329 8330 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/store/constants.js 8331 const STORE_NAME = 'core/blocks'; 8332 8333 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/store/index.js 8334 /** 8335 * WordPress dependencies 8336 */ 8337 8338 /** 8339 * Internal dependencies 8340 */ 8341 8342 8343 8344 8345 8346 /** 8347 * Store definition for the blocks namespace. 8348 * 8349 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#createReduxStore 8350 * 8351 * @type {Object} 8352 */ 8353 8354 const store = (0,external_wp_data_namespaceObject.createReduxStore)(STORE_NAME, { 8355 reducer: reducer, 8356 selectors: selectors_namespaceObject, 8357 actions: actions_namespaceObject 8358 }); 8359 (0,external_wp_data_namespaceObject.register)(store); 8360 8361 ;// CONCATENATED MODULE: external ["wp","blockSerializationDefaultParser"] 8362 var external_wp_blockSerializationDefaultParser_namespaceObject = window["wp"]["blockSerializationDefaultParser"]; 8363 ;// CONCATENATED MODULE: external ["wp","autop"] 8364 var external_wp_autop_namespaceObject = window["wp"]["autop"]; 8365 ;// CONCATENATED MODULE: external ["wp","isShallowEqual"] 8366 var external_wp_isShallowEqual_namespaceObject = window["wp"]["isShallowEqual"]; 8367 var external_wp_isShallowEqual_default = /*#__PURE__*/__webpack_require__.n(external_wp_isShallowEqual_namespaceObject); 8368 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/parser/serialize-raw-block.js 8369 /** 8370 * Internal dependencies 8371 */ 8372 8373 /** 8374 * @typedef {Object} Options Serialization options. 8375 * @property {boolean} [isCommentDelimited=true] Whether to output HTML comments around blocks. 8376 */ 8377 8378 /** @typedef {import("./").WPRawBlock} WPRawBlock */ 8379 8380 /** 8381 * Serializes a block node into the native HTML-comment-powered block format. 8382 * CAVEAT: This function is intended for re-serializing blocks as parsed by 8383 * valid parsers and skips any validation steps. This is NOT a generic 8384 * serialization function for in-memory blocks. For most purposes, see the 8385 * following functions available in the `@wordpress/blocks` package: 8386 * 8387 * @see serializeBlock 8388 * @see serialize 8389 * 8390 * For more on the format of block nodes as returned by valid parsers: 8391 * 8392 * @see `@wordpress/block-serialization-default-parser` package 8393 * @see `@wordpress/block-serialization-spec-parser` package 8394 * 8395 * @param {WPRawBlock} rawBlock A block node as returned by a valid parser. 8396 * @param {Options} [options={}] Serialization options. 8397 * 8398 * @return {string} An HTML string representing a block. 8399 */ 8400 8401 function serializeRawBlock(rawBlock) { 8402 let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 8403 const { 8404 isCommentDelimited = true 8405 } = options; 8406 const { 8407 blockName, 8408 attrs = {}, 8409 innerBlocks = [], 8410 innerContent = [] 8411 } = rawBlock; 8412 let childIndex = 0; 8413 const content = innerContent.map(item => // `null` denotes a nested block, otherwise we have an HTML fragment. 8414 item !== null ? item : serializeRawBlock(innerBlocks[childIndex++], options)).join('\n').replace(/\n+/g, '\n').trim(); 8415 return isCommentDelimited ? getCommentDelimitedContent(blockName, attrs, content) : content; 8416 } 8417 8418 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/serializer.js 8419 8420 8421 /** 8422 * External dependencies 8423 */ 8424 8425 /** 8426 * WordPress dependencies 8427 */ 8428 8429 8430 8431 8432 8433 /** 8434 * Internal dependencies 8435 */ 8436 8437 8438 8439 8440 /** @typedef {import('./parser').WPBlock} WPBlock */ 8441 8442 /** 8443 * @typedef {Object} WPBlockSerializationOptions Serialization Options. 8444 * 8445 * @property {boolean} isInnerBlocks Whether we are serializing inner blocks. 8446 */ 8447 8448 /** 8449 * Returns the block's default classname from its name. 8450 * 8451 * @param {string} blockName The block name. 8452 * 8453 * @return {string} The block's default class. 8454 */ 8455 8456 function getBlockDefaultClassName(blockName) { 8457 // Generated HTML classes for blocks follow the `wp-block-{name}` nomenclature. 8458 // Blocks provided by WordPress drop the prefixes 'core/' or 'core-' (historically used in 'core-embed/'). 8459 const className = 'wp-block-' + blockName.replace(/\//, '-').replace(/^core-/, ''); 8460 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getBlockDefaultClassName', className, blockName); 8461 } 8462 /** 8463 * Returns the block's default menu item classname from its name. 8464 * 8465 * @param {string} blockName The block name. 8466 * 8467 * @return {string} The block's default menu item class. 8468 */ 8469 8470 function getBlockMenuDefaultClassName(blockName) { 8471 // Generated HTML classes for blocks follow the `editor-block-list-item-{name}` nomenclature. 8472 // Blocks provided by WordPress drop the prefixes 'core/' or 'core-' (historically used in 'core-embed/'). 8473 const className = 'editor-block-list-item-' + blockName.replace(/\//, '-').replace(/^core-/, ''); 8474 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getBlockMenuDefaultClassName', className, blockName); 8475 } 8476 const blockPropsProvider = {}; 8477 const innerBlocksPropsProvider = {}; 8478 /** 8479 * Call within a save function to get the props for the block wrapper. 8480 * 8481 * @param {Object} props Optional. Props to pass to the element. 8482 */ 8483 8484 function getBlockProps() { 8485 let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 8486 const { 8487 blockType, 8488 attributes 8489 } = blockPropsProvider; 8490 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getSaveContent.extraProps', { ...props 8491 }, blockType, attributes); 8492 } 8493 /** 8494 * Call within a save function to get the props for the inner blocks wrapper. 8495 * 8496 * @param {Object} props Optional. Props to pass to the element. 8497 */ 8498 8499 function getInnerBlocksProps() { 8500 let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 8501 const { 8502 innerBlocks 8503 } = innerBlocksPropsProvider; // Value is an array of blocks, so defer to block serializer. 8504 8505 const html = serializer_serialize(innerBlocks, { 8506 isInnerBlocks: true 8507 }); // Use special-cased raw HTML tag to avoid default escaping. 8508 8509 const children = (0,external_wp_element_namespaceObject.createElement)(external_wp_element_namespaceObject.RawHTML, null, html); 8510 return { ...props, 8511 children 8512 }; 8513 } 8514 /** 8515 * Given a block type containing a save render implementation and attributes, returns the 8516 * enhanced element to be saved or string when raw HTML expected. 8517 * 8518 * @param {string|Object} blockTypeOrName Block type or name. 8519 * @param {Object} attributes Block attributes. 8520 * @param {?Array} innerBlocks Nested blocks. 8521 * 8522 * @return {Object|string} Save element or raw HTML string. 8523 */ 8524 8525 function getSaveElement(blockTypeOrName, attributes) { 8526 let innerBlocks = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : []; 8527 const blockType = normalizeBlockType(blockTypeOrName); 8528 let { 8529 save 8530 } = blockType; // Component classes are unsupported for save since serialization must 8531 // occur synchronously. For improved interoperability with higher-order 8532 // components which often return component class, emulate basic support. 8533 8534 if (save.prototype instanceof external_wp_element_namespaceObject.Component) { 8535 const instance = new save({ 8536 attributes 8537 }); 8538 save = instance.render.bind(instance); 8539 } 8540 8541 blockPropsProvider.blockType = blockType; 8542 blockPropsProvider.attributes = attributes; 8543 innerBlocksPropsProvider.innerBlocks = innerBlocks; 8544 let element = save({ 8545 attributes, 8546 innerBlocks 8547 }); 8548 8549 if ((0,external_lodash_namespaceObject.isObject)(element) && (0,external_wp_hooks_namespaceObject.hasFilter)('blocks.getSaveContent.extraProps') && !(blockType.apiVersion > 1)) { 8550 /** 8551 * Filters the props applied to the block save result element. 8552 * 8553 * @param {Object} props Props applied to save element. 8554 * @param {WPBlock} blockType Block type definition. 8555 * @param {Object} attributes Block attributes. 8556 */ 8557 const props = (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getSaveContent.extraProps', { ...element.props 8558 }, blockType, attributes); 8559 8560 if (!external_wp_isShallowEqual_default()(props, element.props)) { 8561 element = (0,external_wp_element_namespaceObject.cloneElement)(element, props); 8562 } 8563 } 8564 /** 8565 * Filters the save result of a block during serialization. 8566 * 8567 * @param {WPElement} element Block save result. 8568 * @param {WPBlock} blockType Block type definition. 8569 * @param {Object} attributes Block attributes. 8570 */ 8571 8572 8573 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getSaveElement', element, blockType, attributes); 8574 } 8575 /** 8576 * Given a block type containing a save render implementation and attributes, returns the 8577 * static markup to be saved. 8578 * 8579 * @param {string|Object} blockTypeOrName Block type or name. 8580 * @param {Object} attributes Block attributes. 8581 * @param {?Array} innerBlocks Nested blocks. 8582 * 8583 * @return {string} Save content. 8584 */ 8585 8586 function getSaveContent(blockTypeOrName, attributes, innerBlocks) { 8587 const blockType = normalizeBlockType(blockTypeOrName); 8588 return (0,external_wp_element_namespaceObject.renderToString)(getSaveElement(blockType, attributes, innerBlocks)); 8589 } 8590 /** 8591 * Returns attributes which are to be saved and serialized into the block 8592 * comment delimiter. 8593 * 8594 * When a block exists in memory it contains as its attributes both those 8595 * parsed the block comment delimiter _and_ those which matched from the 8596 * contents of the block. 8597 * 8598 * This function returns only those attributes which are needed to persist and 8599 * which cannot be matched from the block content. 8600 * 8601 * @param {Object<string,*>} blockType Block type. 8602 * @param {Object<string,*>} attributes Attributes from in-memory block data. 8603 * 8604 * @return {Object<string,*>} Subset of attributes for comment serialization. 8605 */ 8606 8607 function getCommentAttributes(blockType, attributes) { 8608 return (0,external_lodash_namespaceObject.reduce)(blockType.attributes, (accumulator, attributeSchema, key) => { 8609 const value = attributes[key]; // Ignore undefined values. 8610 8611 if (undefined === value) { 8612 return accumulator; 8613 } // Ignore all attributes but the ones with an "undefined" source 8614 // "undefined" source refers to attributes saved in the block comment. 8615 8616 8617 if (attributeSchema.source !== undefined) { 8618 return accumulator; 8619 } // Ignore default value. 8620 8621 8622 if ('default' in attributeSchema && attributeSchema.default === value) { 8623 return accumulator; 8624 } // Otherwise, include in comment set. 8625 8626 8627 accumulator[key] = value; 8628 return accumulator; 8629 }, {}); 8630 } 8631 /** 8632 * Given an attributes object, returns a string in the serialized attributes 8633 * format prepared for post content. 8634 * 8635 * @param {Object} attributes Attributes object. 8636 * 8637 * @return {string} Serialized attributes. 8638 */ 8639 8640 function serializeAttributes(attributes) { 8641 return JSON.stringify(attributes) // Don't break HTML comments. 8642 .replace(/--/g, '\\u002d\\u002d') // Don't break non-standard-compliant tools. 8643 .replace(/</g, '\\u003c').replace(/>/g, '\\u003e').replace(/&/g, '\\u0026') // Bypass server stripslashes behavior which would unescape stringify's 8644 // escaping of quotation mark. 8645 // 8646 // See: https://developer.wordpress.org/reference/functions/wp_kses_stripslashes/ 8647 .replace(/\\"/g, '\\u0022'); 8648 } 8649 /** 8650 * Given a block object, returns the Block's Inner HTML markup. 8651 * 8652 * @param {Object} block Block instance. 8653 * 8654 * @return {string} HTML. 8655 */ 8656 8657 function getBlockInnerHTML(block) { 8658 // If block was parsed as invalid or encounters an error while generating 8659 // save content, use original content instead to avoid content loss. If a 8660 // block contains nested content, exempt it from this condition because we 8661 // otherwise have no access to its original content and content loss would 8662 // still occur. 8663 let saveContent = block.originalContent; 8664 8665 if (block.isValid || block.innerBlocks.length) { 8666 try { 8667 saveContent = getSaveContent(block.name, block.attributes, block.innerBlocks); 8668 } catch (error) {} 8669 } 8670 8671 return saveContent; 8672 } 8673 /** 8674 * Returns the content of a block, including comment delimiters. 8675 * 8676 * @param {string} rawBlockName Block name. 8677 * @param {Object} attributes Block attributes. 8678 * @param {string} content Block save content. 8679 * 8680 * @return {string} Comment-delimited block content. 8681 */ 8682 8683 function getCommentDelimitedContent(rawBlockName, attributes, content) { 8684 const serializedAttributes = !(0,external_lodash_namespaceObject.isEmpty)(attributes) ? serializeAttributes(attributes) + ' ' : ''; // Strip core blocks of their namespace prefix. 8685 8686 const blockName = (0,external_lodash_namespaceObject.startsWith)(rawBlockName, 'core/') ? rawBlockName.slice(5) : rawBlockName; // @todo make the `wp:` prefix potentially configurable. 8687 8688 if (!content) { 8689 return `<!-- wp:$blockName} $serializedAttributes}/-->`; 8690 } 8691 8692 return `<!-- wp:$blockName} $serializedAttributes}-->\n` + content + `\n<!-- /wp:$blockName} -->`; 8693 } 8694 /** 8695 * Returns the content of a block, including comment delimiters, determining 8696 * serialized attributes and content form from the current state of the block. 8697 * 8698 * @param {WPBlock} block Block instance. 8699 * @param {WPBlockSerializationOptions} options Serialization options. 8700 * 8701 * @return {string} Serialized block. 8702 */ 8703 8704 function serializeBlock(block) { 8705 let { 8706 isInnerBlocks = false 8707 } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 8708 8709 if (!block.isValid && block.__unstableBlockSource) { 8710 return serializeRawBlock(block.__unstableBlockSource); 8711 } 8712 8713 const blockName = block.name; 8714 const saveContent = getBlockInnerHTML(block); 8715 8716 if (blockName === getUnregisteredTypeHandlerName() || !isInnerBlocks && blockName === getFreeformContentHandlerName()) { 8717 return saveContent; 8718 } 8719 8720 const blockType = registration_getBlockType(blockName); 8721 const saveAttributes = getCommentAttributes(blockType, block.attributes); 8722 return getCommentDelimitedContent(blockName, saveAttributes, saveContent); 8723 } 8724 function __unstableSerializeAndClean(blocks) { 8725 // A single unmodified default block is assumed to 8726 // be equivalent to an empty post. 8727 if (blocks.length === 1 && isUnmodifiedDefaultBlock(blocks[0])) { 8728 blocks = []; 8729 } 8730 8731 let content = serializer_serialize(blocks); // For compatibility, treat a post consisting of a 8732 // single freeform block as legacy content and apply 8733 // pre-block-editor removep'd content formatting. 8734 8735 if (blocks.length === 1 && blocks[0].name === getFreeformContentHandlerName()) { 8736 content = (0,external_wp_autop_namespaceObject.removep)(content); 8737 } 8738 8739 return content; 8740 } 8741 /** 8742 * Takes a block or set of blocks and returns the serialized post content. 8743 * 8744 * @param {Array} blocks Block(s) to serialize. 8745 * @param {WPBlockSerializationOptions} options Serialization options. 8746 * 8747 * @return {string} The post content. 8748 */ 8749 8750 function serializer_serialize(blocks, options) { 8751 return (0,external_lodash_namespaceObject.castArray)(blocks).map(block => serializeBlock(block, options)).join('\n\n'); 8752 } 8753 8754 ;// CONCATENATED MODULE: ./node_modules/simple-html-tokenizer/dist/es6/index.js 8755 /** 8756 * generated from https://raw.githubusercontent.com/w3c/html/26b5126f96f736f796b9e29718138919dd513744/entities.json 8757 * do not edit 8758 */ 8759 var namedCharRefs = { 8760 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" 8761 }; 8762 8763 var HEXCHARCODE = /^#[xX]([A-Fa-f0-9]+)$/; 8764 var CHARCODE = /^#([0-9]+)$/; 8765 var NAMED = /^([A-Za-z0-9]+)$/; 8766 var EntityParser = /** @class */ (function () { 8767 function EntityParser(named) { 8768 this.named = named; 8769 } 8770 EntityParser.prototype.parse = function (entity) { 8771 if (!entity) { 8772 return; 8773 } 8774 var matches = entity.match(HEXCHARCODE); 8775 if (matches) { 8776 return String.fromCharCode(parseInt(matches[1], 16)); 8777 } 8778 matches = entity.match(CHARCODE); 8779 if (matches) { 8780 return String.fromCharCode(parseInt(matches[1], 10)); 8781 } 8782 matches = entity.match(NAMED); 8783 if (matches) { 8784 return this.named[matches[1]]; 8785 } 8786 }; 8787 return EntityParser; 8788 }()); 8789 8790 var WSP = /[\t\n\f ]/; 8791 var ALPHA = /[A-Za-z]/; 8792 var CRLF = /\r\n?/g; 8793 function isSpace(char) { 8794 return WSP.test(char); 8795 } 8796 function isAlpha(char) { 8797 return ALPHA.test(char); 8798 } 8799 function preprocessInput(input) { 8800 return input.replace(CRLF, '\n'); 8801 } 8802 8803 var EventedTokenizer = /** @class */ (function () { 8804 function EventedTokenizer(delegate, entityParser, mode) { 8805 if (mode === void 0) { mode = 'precompile'; } 8806 this.delegate = delegate; 8807 this.entityParser = entityParser; 8808 this.mode = mode; 8809 this.state = "beforeData" /* beforeData */; 8810 this.line = -1; 8811 this.column = -1; 8812 this.input = ''; 8813 this.index = -1; 8814 this.tagNameBuffer = ''; 8815 this.states = { 8816 beforeData: function () { 8817 var char = this.peek(); 8818 if (char === '<' && !this.isIgnoredEndTag()) { 8819 this.transitionTo("tagOpen" /* tagOpen */); 8820 this.markTagStart(); 8821 this.consume(); 8822 } 8823 else { 8824 if (this.mode === 'precompile' && char === '\n') { 8825 var tag = this.tagNameBuffer.toLowerCase(); 8826 if (tag === 'pre' || tag === 'textarea') { 8827 this.consume(); 8828 } 8829 } 8830 this.transitionTo("data" /* data */); 8831 this.delegate.beginData(); 8832 } 8833 }, 8834 data: function () { 8835 var char = this.peek(); 8836 var tag = this.tagNameBuffer; 8837 if (char === '<' && !this.isIgnoredEndTag()) { 8838 this.delegate.finishData(); 8839 this.transitionTo("tagOpen" /* tagOpen */); 8840 this.markTagStart(); 8841 this.consume(); 8842 } 8843 else if (char === '&' && tag !== 'script' && tag !== 'style') { 8844 this.consume(); 8845 this.delegate.appendToData(this.consumeCharRef() || '&'); 8846 } 8847 else { 8848 this.consume(); 8849 this.delegate.appendToData(char); 8850 } 8851 }, 8852 tagOpen: function () { 8853 var char = this.consume(); 8854 if (char === '!') { 8855 this.transitionTo("markupDeclarationOpen" /* markupDeclarationOpen */); 8856 } 8857 else if (char === '/') { 8858 this.transitionTo("endTagOpen" /* endTagOpen */); 8859 } 8860 else if (char === '@' || char === ':' || isAlpha(char)) { 8861 this.transitionTo("tagName" /* tagName */); 8862 this.tagNameBuffer = ''; 8863 this.delegate.beginStartTag(); 8864 this.appendToTagName(char); 8865 } 8866 }, 8867 markupDeclarationOpen: function () { 8868 var char = this.consume(); 8869 if (char === '-' && this.peek() === '-') { 8870 this.consume(); 8871 this.transitionTo("commentStart" /* commentStart */); 8872 this.delegate.beginComment(); 8873 } 8874 else { 8875 var maybeDoctype = char.toUpperCase() + this.input.substring(this.index, this.index + 6).toUpperCase(); 8876 if (maybeDoctype === 'DOCTYPE') { 8877 this.consume(); 8878 this.consume(); 8879 this.consume(); 8880 this.consume(); 8881 this.consume(); 8882 this.consume(); 8883 this.transitionTo("doctype" /* doctype */); 8884 if (this.delegate.beginDoctype) 8885 this.delegate.beginDoctype(); 8886 } 8887 } 8888 }, 8889 doctype: function () { 8890 var char = this.consume(); 8891 if (isSpace(char)) { 8892 this.transitionTo("beforeDoctypeName" /* beforeDoctypeName */); 8893 } 8894 }, 8895 beforeDoctypeName: function () { 8896 var char = this.consume(); 8897 if (isSpace(char)) { 8898 return; 8899 } 8900 else { 8901 this.transitionTo("doctypeName" /* doctypeName */); 8902 if (this.delegate.appendToDoctypeName) 8903 this.delegate.appendToDoctypeName(char.toLowerCase()); 8904 } 8905 }, 8906 doctypeName: function () { 8907 var char = this.consume(); 8908 if (isSpace(char)) { 8909 this.transitionTo("afterDoctypeName" /* afterDoctypeName */); 8910 } 8911 else if (char === '>') { 8912 if (this.delegate.endDoctype) 8913 this.delegate.endDoctype(); 8914 this.transitionTo("beforeData" /* beforeData */); 8915 } 8916 else { 8917 if (this.delegate.appendToDoctypeName) 8918 this.delegate.appendToDoctypeName(char.toLowerCase()); 8919 } 8920 }, 8921 afterDoctypeName: function () { 8922 var char = this.consume(); 8923 if (isSpace(char)) { 8924 return; 8925 } 8926 else if (char === '>') { 8927 if (this.delegate.endDoctype) 8928 this.delegate.endDoctype(); 8929 this.transitionTo("beforeData" /* beforeData */); 8930 } 8931 else { 8932 var nextSixChars = char.toUpperCase() + this.input.substring(this.index, this.index + 5).toUpperCase(); 8933 var isPublic = nextSixChars.toUpperCase() === 'PUBLIC'; 8934 var isSystem = nextSixChars.toUpperCase() === 'SYSTEM'; 8935 if (isPublic || isSystem) { 8936 this.consume(); 8937 this.consume(); 8938 this.consume(); 8939 this.consume(); 8940 this.consume(); 8941 this.consume(); 8942 } 8943 if (isPublic) { 8944 this.transitionTo("afterDoctypePublicKeyword" /* afterDoctypePublicKeyword */); 8945 } 8946 else if (isSystem) { 8947 this.transitionTo("afterDoctypeSystemKeyword" /* afterDoctypeSystemKeyword */); 8948 } 8949 } 8950 }, 8951 afterDoctypePublicKeyword: function () { 8952 var char = this.peek(); 8953 if (isSpace(char)) { 8954 this.transitionTo("beforeDoctypePublicIdentifier" /* beforeDoctypePublicIdentifier */); 8955 this.consume(); 8956 } 8957 else if (char === '"') { 8958 this.transitionTo("doctypePublicIdentifierDoubleQuoted" /* doctypePublicIdentifierDoubleQuoted */); 8959 this.consume(); 8960 } 8961 else if (char === "'") { 8962 this.transitionTo("doctypePublicIdentifierSingleQuoted" /* doctypePublicIdentifierSingleQuoted */); 8963 this.consume(); 8964 } 8965 else if (char === '>') { 8966 this.consume(); 8967 if (this.delegate.endDoctype) 8968 this.delegate.endDoctype(); 8969 this.transitionTo("beforeData" /* beforeData */); 8970 } 8971 }, 8972 doctypePublicIdentifierDoubleQuoted: function () { 8973 var char = this.consume(); 8974 if (char === '"') { 8975 this.transitionTo("afterDoctypePublicIdentifier" /* afterDoctypePublicIdentifier */); 8976 } 8977 else if (char === '>') { 8978 if (this.delegate.endDoctype) 8979 this.delegate.endDoctype(); 8980 this.transitionTo("beforeData" /* beforeData */); 8981 } 8982 else { 8983 if (this.delegate.appendToDoctypePublicIdentifier) 8984 this.delegate.appendToDoctypePublicIdentifier(char); 8985 } 8986 }, 8987 doctypePublicIdentifierSingleQuoted: function () { 8988 var char = this.consume(); 8989 if (char === "'") { 8990 this.transitionTo("afterDoctypePublicIdentifier" /* afterDoctypePublicIdentifier */); 8991 } 8992 else if (char === '>') { 8993 if (this.delegate.endDoctype) 8994 this.delegate.endDoctype(); 8995 this.transitionTo("beforeData" /* beforeData */); 8996 } 8997 else { 8998 if (this.delegate.appendToDoctypePublicIdentifier) 8999 this.delegate.appendToDoctypePublicIdentifier(char); 9000 } 9001 }, 9002 afterDoctypePublicIdentifier: function () { 9003 var char = this.consume(); 9004 if (isSpace(char)) { 9005 this.transitionTo("betweenDoctypePublicAndSystemIdentifiers" /* betweenDoctypePublicAndSystemIdentifiers */); 9006 } 9007 else if (char === '>') { 9008 if (this.delegate.endDoctype) 9009 this.delegate.endDoctype(); 9010 this.transitionTo("beforeData" /* beforeData */); 9011 } 9012 else if (char === '"') { 9013 this.transitionTo("doctypeSystemIdentifierDoubleQuoted" /* doctypeSystemIdentifierDoubleQuoted */); 9014 } 9015 else if (char === "'") { 9016 this.transitionTo("doctypeSystemIdentifierSingleQuoted" /* doctypeSystemIdentifierSingleQuoted */); 9017 } 9018 }, 9019 betweenDoctypePublicAndSystemIdentifiers: function () { 9020 var char = this.consume(); 9021 if (isSpace(char)) { 9022 return; 9023 } 9024 else if (char === '>') { 9025 if (this.delegate.endDoctype) 9026 this.delegate.endDoctype(); 9027 this.transitionTo("beforeData" /* beforeData */); 9028 } 9029 else if (char === '"') { 9030 this.transitionTo("doctypeSystemIdentifierDoubleQuoted" /* doctypeSystemIdentifierDoubleQuoted */); 9031 } 9032 else if (char === "'") { 9033 this.transitionTo("doctypeSystemIdentifierSingleQuoted" /* doctypeSystemIdentifierSingleQuoted */); 9034 } 9035 }, 9036 doctypeSystemIdentifierDoubleQuoted: function () { 9037 var char = this.consume(); 9038 if (char === '"') { 9039 this.transitionTo("afterDoctypeSystemIdentifier" /* afterDoctypeSystemIdentifier */); 9040 } 9041 else if (char === '>') { 9042 if (this.delegate.endDoctype) 9043 this.delegate.endDoctype(); 9044 this.transitionTo("beforeData" /* beforeData */); 9045 } 9046 else { 9047 if (this.delegate.appendToDoctypeSystemIdentifier) 9048 this.delegate.appendToDoctypeSystemIdentifier(char); 9049 } 9050 }, 9051 doctypeSystemIdentifierSingleQuoted: function () { 9052 var char = this.consume(); 9053 if (char === "'") { 9054 this.transitionTo("afterDoctypeSystemIdentifier" /* afterDoctypeSystemIdentifier */); 9055 } 9056 else if (char === '>') { 9057 if (this.delegate.endDoctype) 9058 this.delegate.endDoctype(); 9059 this.transitionTo("beforeData" /* beforeData */); 9060 } 9061 else { 9062 if (this.delegate.appendToDoctypeSystemIdentifier) 9063 this.delegate.appendToDoctypeSystemIdentifier(char); 9064 } 9065 }, 9066 afterDoctypeSystemIdentifier: function () { 9067 var char = this.consume(); 9068 if (isSpace(char)) { 9069 return; 9070 } 9071 else if (char === '>') { 9072 if (this.delegate.endDoctype) 9073 this.delegate.endDoctype(); 9074 this.transitionTo("beforeData" /* beforeData */); 9075 } 9076 }, 9077 commentStart: function () { 9078 var char = this.consume(); 9079 if (char === '-') { 9080 this.transitionTo("commentStartDash" /* commentStartDash */); 9081 } 9082 else if (char === '>') { 9083 this.delegate.finishComment(); 9084 this.transitionTo("beforeData" /* beforeData */); 9085 } 9086 else { 9087 this.delegate.appendToCommentData(char); 9088 this.transitionTo("comment" /* comment */); 9089 } 9090 }, 9091 commentStartDash: function () { 9092 var char = this.consume(); 9093 if (char === '-') { 9094 this.transitionTo("commentEnd" /* commentEnd */); 9095 } 9096 else if (char === '>') { 9097 this.delegate.finishComment(); 9098 this.transitionTo("beforeData" /* beforeData */); 9099 } 9100 else { 9101 this.delegate.appendToCommentData('-'); 9102 this.transitionTo("comment" /* comment */); 9103 } 9104 }, 9105 comment: function () { 9106 var char = this.consume(); 9107 if (char === '-') { 9108 this.transitionTo("commentEndDash" /* commentEndDash */); 9109 } 9110 else { 9111 this.delegate.appendToCommentData(char); 9112 } 9113 }, 9114 commentEndDash: function () { 9115 var char = this.consume(); 9116 if (char === '-') { 9117 this.transitionTo("commentEnd" /* commentEnd */); 9118 } 9119 else { 9120 this.delegate.appendToCommentData('-' + char); 9121 this.transitionTo("comment" /* comment */); 9122 } 9123 }, 9124 commentEnd: function () { 9125 var char = this.consume(); 9126 if (char === '>') { 9127 this.delegate.finishComment(); 9128 this.transitionTo("beforeData" /* beforeData */); 9129 } 9130 else { 9131 this.delegate.appendToCommentData('--' + char); 9132 this.transitionTo("comment" /* comment */); 9133 } 9134 }, 9135 tagName: function () { 9136 var char = this.consume(); 9137 if (isSpace(char)) { 9138 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 9139 } 9140 else if (char === '/') { 9141 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 9142 } 9143 else if (char === '>') { 9144 this.delegate.finishTag(); 9145 this.transitionTo("beforeData" /* beforeData */); 9146 } 9147 else { 9148 this.appendToTagName(char); 9149 } 9150 }, 9151 endTagName: function () { 9152 var char = this.consume(); 9153 if (isSpace(char)) { 9154 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 9155 this.tagNameBuffer = ''; 9156 } 9157 else if (char === '/') { 9158 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 9159 this.tagNameBuffer = ''; 9160 } 9161 else if (char === '>') { 9162 this.delegate.finishTag(); 9163 this.transitionTo("beforeData" /* beforeData */); 9164 this.tagNameBuffer = ''; 9165 } 9166 else { 9167 this.appendToTagName(char); 9168 } 9169 }, 9170 beforeAttributeName: function () { 9171 var char = this.peek(); 9172 if (isSpace(char)) { 9173 this.consume(); 9174 return; 9175 } 9176 else if (char === '/') { 9177 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 9178 this.consume(); 9179 } 9180 else if (char === '>') { 9181 this.consume(); 9182 this.delegate.finishTag(); 9183 this.transitionTo("beforeData" /* beforeData */); 9184 } 9185 else if (char === '=') { 9186 this.delegate.reportSyntaxError('attribute name cannot start with equals sign'); 9187 this.transitionTo("attributeName" /* attributeName */); 9188 this.delegate.beginAttribute(); 9189 this.consume(); 9190 this.delegate.appendToAttributeName(char); 9191 } 9192 else { 9193 this.transitionTo("attributeName" /* attributeName */); 9194 this.delegate.beginAttribute(); 9195 } 9196 }, 9197 attributeName: function () { 9198 var char = this.peek(); 9199 if (isSpace(char)) { 9200 this.transitionTo("afterAttributeName" /* afterAttributeName */); 9201 this.consume(); 9202 } 9203 else if (char === '/') { 9204 this.delegate.beginAttributeValue(false); 9205 this.delegate.finishAttributeValue(); 9206 this.consume(); 9207 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 9208 } 9209 else if (char === '=') { 9210 this.transitionTo("beforeAttributeValue" /* beforeAttributeValue */); 9211 this.consume(); 9212 } 9213 else if (char === '>') { 9214 this.delegate.beginAttributeValue(false); 9215 this.delegate.finishAttributeValue(); 9216 this.consume(); 9217 this.delegate.finishTag(); 9218 this.transitionTo("beforeData" /* beforeData */); 9219 } 9220 else if (char === '"' || char === "'" || char === '<') { 9221 this.delegate.reportSyntaxError(char + ' is not a valid character within attribute names'); 9222 this.consume(); 9223 this.delegate.appendToAttributeName(char); 9224 } 9225 else { 9226 this.consume(); 9227 this.delegate.appendToAttributeName(char); 9228 } 9229 }, 9230 afterAttributeName: function () { 9231 var char = this.peek(); 9232 if (isSpace(char)) { 9233 this.consume(); 9234 return; 9235 } 9236 else if (char === '/') { 9237 this.delegate.beginAttributeValue(false); 9238 this.delegate.finishAttributeValue(); 9239 this.consume(); 9240 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 9241 } 9242 else if (char === '=') { 9243 this.consume(); 9244 this.transitionTo("beforeAttributeValue" /* beforeAttributeValue */); 9245 } 9246 else if (char === '>') { 9247 this.delegate.beginAttributeValue(false); 9248 this.delegate.finishAttributeValue(); 9249 this.consume(); 9250 this.delegate.finishTag(); 9251 this.transitionTo("beforeData" /* beforeData */); 9252 } 9253 else { 9254 this.delegate.beginAttributeValue(false); 9255 this.delegate.finishAttributeValue(); 9256 this.transitionTo("attributeName" /* attributeName */); 9257 this.delegate.beginAttribute(); 9258 this.consume(); 9259 this.delegate.appendToAttributeName(char); 9260 } 9261 }, 9262 beforeAttributeValue: function () { 9263 var char = this.peek(); 9264 if (isSpace(char)) { 9265 this.consume(); 9266 } 9267 else if (char === '"') { 9268 this.transitionTo("attributeValueDoubleQuoted" /* attributeValueDoubleQuoted */); 9269 this.delegate.beginAttributeValue(true); 9270 this.consume(); 9271 } 9272 else if (char === "'") { 9273 this.transitionTo("attributeValueSingleQuoted" /* attributeValueSingleQuoted */); 9274 this.delegate.beginAttributeValue(true); 9275 this.consume(); 9276 } 9277 else if (char === '>') { 9278 this.delegate.beginAttributeValue(false); 9279 this.delegate.finishAttributeValue(); 9280 this.consume(); 9281 this.delegate.finishTag(); 9282 this.transitionTo("beforeData" /* beforeData */); 9283 } 9284 else { 9285 this.transitionTo("attributeValueUnquoted" /* attributeValueUnquoted */); 9286 this.delegate.beginAttributeValue(false); 9287 this.consume(); 9288 this.delegate.appendToAttributeValue(char); 9289 } 9290 }, 9291 attributeValueDoubleQuoted: function () { 9292 var char = this.consume(); 9293 if (char === '"') { 9294 this.delegate.finishAttributeValue(); 9295 this.transitionTo("afterAttributeValueQuoted" /* afterAttributeValueQuoted */); 9296 } 9297 else if (char === '&') { 9298 this.delegate.appendToAttributeValue(this.consumeCharRef() || '&'); 9299 } 9300 else { 9301 this.delegate.appendToAttributeValue(char); 9302 } 9303 }, 9304 attributeValueSingleQuoted: function () { 9305 var char = this.consume(); 9306 if (char === "'") { 9307 this.delegate.finishAttributeValue(); 9308 this.transitionTo("afterAttributeValueQuoted" /* afterAttributeValueQuoted */); 9309 } 9310 else if (char === '&') { 9311 this.delegate.appendToAttributeValue(this.consumeCharRef() || '&'); 9312 } 9313 else { 9314 this.delegate.appendToAttributeValue(char); 9315 } 9316 }, 9317 attributeValueUnquoted: function () { 9318 var char = this.peek(); 9319 if (isSpace(char)) { 9320 this.delegate.finishAttributeValue(); 9321 this.consume(); 9322 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 9323 } 9324 else if (char === '/') { 9325 this.delegate.finishAttributeValue(); 9326 this.consume(); 9327 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 9328 } 9329 else if (char === '&') { 9330 this.consume(); 9331 this.delegate.appendToAttributeValue(this.consumeCharRef() || '&'); 9332 } 9333 else if (char === '>') { 9334 this.delegate.finishAttributeValue(); 9335 this.consume(); 9336 this.delegate.finishTag(); 9337 this.transitionTo("beforeData" /* beforeData */); 9338 } 9339 else { 9340 this.consume(); 9341 this.delegate.appendToAttributeValue(char); 9342 } 9343 }, 9344 afterAttributeValueQuoted: function () { 9345 var char = this.peek(); 9346 if (isSpace(char)) { 9347 this.consume(); 9348 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 9349 } 9350 else if (char === '/') { 9351 this.consume(); 9352 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 9353 } 9354 else if (char === '>') { 9355 this.consume(); 9356 this.delegate.finishTag(); 9357 this.transitionTo("beforeData" /* beforeData */); 9358 } 9359 else { 9360 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 9361 } 9362 }, 9363 selfClosingStartTag: function () { 9364 var char = this.peek(); 9365 if (char === '>') { 9366 this.consume(); 9367 this.delegate.markTagAsSelfClosing(); 9368 this.delegate.finishTag(); 9369 this.transitionTo("beforeData" /* beforeData */); 9370 } 9371 else { 9372 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 9373 } 9374 }, 9375 endTagOpen: function () { 9376 var char = this.consume(); 9377 if (char === '@' || char === ':' || isAlpha(char)) { 9378 this.transitionTo("endTagName" /* endTagName */); 9379 this.tagNameBuffer = ''; 9380 this.delegate.beginEndTag(); 9381 this.appendToTagName(char); 9382 } 9383 } 9384 }; 9385 this.reset(); 9386 } 9387 EventedTokenizer.prototype.reset = function () { 9388 this.transitionTo("beforeData" /* beforeData */); 9389 this.input = ''; 9390 this.tagNameBuffer = ''; 9391 this.index = 0; 9392 this.line = 1; 9393 this.column = 0; 9394 this.delegate.reset(); 9395 }; 9396 EventedTokenizer.prototype.transitionTo = function (state) { 9397 this.state = state; 9398 }; 9399 EventedTokenizer.prototype.tokenize = function (input) { 9400 this.reset(); 9401 this.tokenizePart(input); 9402 this.tokenizeEOF(); 9403 }; 9404 EventedTokenizer.prototype.tokenizePart = function (input) { 9405 this.input += preprocessInput(input); 9406 while (this.index < this.input.length) { 9407 var handler = this.states[this.state]; 9408 if (handler !== undefined) { 9409 handler.call(this); 9410 } 9411 else { 9412 throw new Error("unhandled state " + this.state); 9413 } 9414 } 9415 }; 9416 EventedTokenizer.prototype.tokenizeEOF = function () { 9417 this.flushData(); 9418 }; 9419 EventedTokenizer.prototype.flushData = function () { 9420 if (this.state === 'data') { 9421 this.delegate.finishData(); 9422 this.transitionTo("beforeData" /* beforeData */); 9423 } 9424 }; 9425 EventedTokenizer.prototype.peek = function () { 9426 return this.input.charAt(this.index); 9427 }; 9428 EventedTokenizer.prototype.consume = function () { 9429 var char = this.peek(); 9430 this.index++; 9431 if (char === '\n') { 9432 this.line++; 9433 this.column = 0; 9434 } 9435 else { 9436 this.column++; 9437 } 9438 return char; 9439 }; 9440 EventedTokenizer.prototype.consumeCharRef = function () { 9441 var endIndex = this.input.indexOf(';', this.index); 9442 if (endIndex === -1) { 9443 return; 9444 } 9445 var entity = this.input.slice(this.index, endIndex); 9446 var chars = this.entityParser.parse(entity); 9447 if (chars) { 9448 var count = entity.length; 9449 // consume the entity chars 9450 while (count) { 9451 this.consume(); 9452 count--; 9453 } 9454 // consume the `;` 9455 this.consume(); 9456 return chars; 9457 } 9458 }; 9459 EventedTokenizer.prototype.markTagStart = function () { 9460 this.delegate.tagOpen(); 9461 }; 9462 EventedTokenizer.prototype.appendToTagName = function (char) { 9463 this.tagNameBuffer += char; 9464 this.delegate.appendToTagName(char); 9465 }; 9466 EventedTokenizer.prototype.isIgnoredEndTag = function () { 9467 var tag = this.tagNameBuffer; 9468 return (tag === 'title' && this.input.substring(this.index, this.index + 8) !== '</title>') || 9469 (tag === 'style' && this.input.substring(this.index, this.index + 8) !== '</style>') || 9470 (tag === 'script' && this.input.substring(this.index, this.index + 9) !== '</script>'); 9471 }; 9472 return EventedTokenizer; 9473 }()); 9474 9475 var Tokenizer = /** @class */ (function () { 9476 function Tokenizer(entityParser, options) { 9477 if (options === void 0) { options = {}; } 9478 this.options = options; 9479 this.token = null; 9480 this.startLine = 1; 9481 this.startColumn = 0; 9482 this.tokens = []; 9483 this.tokenizer = new EventedTokenizer(this, entityParser, options.mode); 9484 this._currentAttribute = undefined; 9485 } 9486 Tokenizer.prototype.tokenize = function (input) { 9487 this.tokens = []; 9488 this.tokenizer.tokenize(input); 9489 return this.tokens; 9490 }; 9491 Tokenizer.prototype.tokenizePart = function (input) { 9492 this.tokens = []; 9493 this.tokenizer.tokenizePart(input); 9494 return this.tokens; 9495 }; 9496 Tokenizer.prototype.tokenizeEOF = function () { 9497 this.tokens = []; 9498 this.tokenizer.tokenizeEOF(); 9499 return this.tokens[0]; 9500 }; 9501 Tokenizer.prototype.reset = function () { 9502 this.token = null; 9503 this.startLine = 1; 9504 this.startColumn = 0; 9505 }; 9506 Tokenizer.prototype.current = function () { 9507 var token = this.token; 9508 if (token === null) { 9509 throw new Error('token was unexpectedly null'); 9510 } 9511 if (arguments.length === 0) { 9512 return token; 9513 } 9514 for (var i = 0; i < arguments.length; i++) { 9515 if (token.type === arguments[i]) { 9516 return token; 9517 } 9518 } 9519 throw new Error("token type was unexpectedly " + token.type); 9520 }; 9521 Tokenizer.prototype.push = function (token) { 9522 this.token = token; 9523 this.tokens.push(token); 9524 }; 9525 Tokenizer.prototype.currentAttribute = function () { 9526 return this._currentAttribute; 9527 }; 9528 Tokenizer.prototype.addLocInfo = function () { 9529 if (this.options.loc) { 9530 this.current().loc = { 9531 start: { 9532 line: this.startLine, 9533 column: this.startColumn 9534 }, 9535 end: { 9536 line: this.tokenizer.line, 9537 column: this.tokenizer.column 9538 } 9539 }; 9540 } 9541 this.startLine = this.tokenizer.line; 9542 this.startColumn = this.tokenizer.column; 9543 }; 9544 // Data 9545 Tokenizer.prototype.beginDoctype = function () { 9546 this.push({ 9547 type: "Doctype" /* Doctype */, 9548 name: '', 9549 }); 9550 }; 9551 Tokenizer.prototype.appendToDoctypeName = function (char) { 9552 this.current("Doctype" /* Doctype */).name += char; 9553 }; 9554 Tokenizer.prototype.appendToDoctypePublicIdentifier = function (char) { 9555 var doctype = this.current("Doctype" /* Doctype */); 9556 if (doctype.publicIdentifier === undefined) { 9557 doctype.publicIdentifier = char; 9558 } 9559 else { 9560 doctype.publicIdentifier += char; 9561 } 9562 }; 9563 Tokenizer.prototype.appendToDoctypeSystemIdentifier = function (char) { 9564 var doctype = this.current("Doctype" /* Doctype */); 9565 if (doctype.systemIdentifier === undefined) { 9566 doctype.systemIdentifier = char; 9567 } 9568 else { 9569 doctype.systemIdentifier += char; 9570 } 9571 }; 9572 Tokenizer.prototype.endDoctype = function () { 9573 this.addLocInfo(); 9574 }; 9575 Tokenizer.prototype.beginData = function () { 9576 this.push({ 9577 type: "Chars" /* Chars */, 9578 chars: '' 9579 }); 9580 }; 9581 Tokenizer.prototype.appendToData = function (char) { 9582 this.current("Chars" /* Chars */).chars += char; 9583 }; 9584 Tokenizer.prototype.finishData = function () { 9585 this.addLocInfo(); 9586 }; 9587 // Comment 9588 Tokenizer.prototype.beginComment = function () { 9589 this.push({ 9590 type: "Comment" /* Comment */, 9591 chars: '' 9592 }); 9593 }; 9594 Tokenizer.prototype.appendToCommentData = function (char) { 9595 this.current("Comment" /* Comment */).chars += char; 9596 }; 9597 Tokenizer.prototype.finishComment = function () { 9598 this.addLocInfo(); 9599 }; 9600 // Tags - basic 9601 Tokenizer.prototype.tagOpen = function () { }; 9602 Tokenizer.prototype.beginStartTag = function () { 9603 this.push({ 9604 type: "StartTag" /* StartTag */, 9605 tagName: '', 9606 attributes: [], 9607 selfClosing: false 9608 }); 9609 }; 9610 Tokenizer.prototype.beginEndTag = function () { 9611 this.push({ 9612 type: "EndTag" /* EndTag */, 9613 tagName: '' 9614 }); 9615 }; 9616 Tokenizer.prototype.finishTag = function () { 9617 this.addLocInfo(); 9618 }; 9619 Tokenizer.prototype.markTagAsSelfClosing = function () { 9620 this.current("StartTag" /* StartTag */).selfClosing = true; 9621 }; 9622 // Tags - name 9623 Tokenizer.prototype.appendToTagName = function (char) { 9624 this.current("StartTag" /* StartTag */, "EndTag" /* EndTag */).tagName += char; 9625 }; 9626 // Tags - attributes 9627 Tokenizer.prototype.beginAttribute = function () { 9628 this._currentAttribute = ['', '', false]; 9629 }; 9630 Tokenizer.prototype.appendToAttributeName = function (char) { 9631 this.currentAttribute()[0] += char; 9632 }; 9633 Tokenizer.prototype.beginAttributeValue = function (isQuoted) { 9634 this.currentAttribute()[2] = isQuoted; 9635 }; 9636 Tokenizer.prototype.appendToAttributeValue = function (char) { 9637 this.currentAttribute()[1] += char; 9638 }; 9639 Tokenizer.prototype.finishAttributeValue = function () { 9640 this.current("StartTag" /* StartTag */).attributes.push(this._currentAttribute); 9641 }; 9642 Tokenizer.prototype.reportSyntaxError = function (message) { 9643 this.current().syntaxError = message; 9644 }; 9645 return Tokenizer; 9646 }()); 9647 9648 function tokenize(input, options) { 9649 var tokenizer = new Tokenizer(new EntityParser(namedCharRefs), options); 9650 return tokenizer.tokenize(input); 9651 } 9652 9653 9654 9655 ;// CONCATENATED MODULE: external ["wp","deprecated"] 9656 var external_wp_deprecated_namespaceObject = window["wp"]["deprecated"]; 9657 var external_wp_deprecated_default = /*#__PURE__*/__webpack_require__.n(external_wp_deprecated_namespaceObject); 9658 ;// CONCATENATED MODULE: external ["wp","htmlEntities"] 9659 var external_wp_htmlEntities_namespaceObject = window["wp"]["htmlEntities"]; 9660 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/validation/logger.js 9661 /** 9662 * @typedef LoggerItem 9663 * @property {Function} log Which logger recorded the message 9664 * @property {Array<any>} args White arguments were supplied to the logger 9665 */ 9666 function createLogger() { 9667 /** 9668 * Creates a log handler with block validation prefix. 9669 * 9670 * @param {Function} logger Original logger function. 9671 * 9672 * @return {Function} Augmented logger function. 9673 */ 9674 function createLogHandler(logger) { 9675 let log = function (message) { 9676 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { 9677 args[_key - 1] = arguments[_key]; 9678 } 9679 9680 return logger('Block validation: ' + message, ...args); 9681 }; // In test environments, pre-process string substitutions to improve 9682 // readability of error messages. We'd prefer to avoid pulling in this 9683 // dependency in runtime environments, and it can be dropped by a combo 9684 // of Webpack env substitution + UglifyJS dead code elimination. 9685 9686 9687 if (false) {} 9688 9689 return log; 9690 } 9691 9692 return { 9693 // eslint-disable-next-line no-console 9694 error: createLogHandler(console.error), 9695 // eslint-disable-next-line no-console 9696 warning: createLogHandler(console.warn), 9697 9698 getItems() { 9699 return []; 9700 } 9701 9702 }; 9703 } 9704 function createQueuedLogger() { 9705 /** 9706 * The list of enqueued log actions to print. 9707 * 9708 * @type {Array<LoggerItem>} 9709 */ 9710 const queue = []; 9711 const logger = createLogger(); 9712 return { 9713 error() { 9714 for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { 9715 args[_key2] = arguments[_key2]; 9716 } 9717 9718 queue.push({ 9719 log: logger.error, 9720 args 9721 }); 9722 }, 9723 9724 warning() { 9725 for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { 9726 args[_key3] = arguments[_key3]; 9727 } 9728 9729 queue.push({ 9730 log: logger.warning, 9731 args 9732 }); 9733 }, 9734 9735 getItems() { 9736 return queue; 9737 } 9738 9739 }; 9740 } 9741 9742 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/validation/index.js 9743 /** 9744 * External dependencies 9745 */ 9746 9747 9748 /** 9749 * WordPress dependencies 9750 */ 9751 9752 9753 9754 /** 9755 * Internal dependencies 9756 */ 9757 9758 9759 9760 9761 9762 /** @typedef {import('../parser').WPBlock} WPBlock */ 9763 9764 /** @typedef {import('../registration').WPBlockType} WPBlockType */ 9765 9766 /** @typedef {import('./logger').LoggerItem} LoggerItem */ 9767 9768 /** 9769 * Globally matches any consecutive whitespace 9770 * 9771 * @type {RegExp} 9772 */ 9773 9774 const REGEXP_WHITESPACE = /[\t\n\r\v\f ]+/g; 9775 /** 9776 * Matches a string containing only whitespace 9777 * 9778 * @type {RegExp} 9779 */ 9780 9781 const REGEXP_ONLY_WHITESPACE = /^[\t\n\r\v\f ]*$/; 9782 /** 9783 * Matches a CSS URL type value 9784 * 9785 * @type {RegExp} 9786 */ 9787 9788 const REGEXP_STYLE_URL_TYPE = /^url\s*\(['"\s]*(.*?)['"\s]*\)$/; 9789 /** 9790 * Boolean attributes are attributes whose presence as being assigned is 9791 * meaningful, even if only empty. 9792 * 9793 * See: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#boolean-attributes 9794 * Extracted from: https://html.spec.whatwg.org/multipage/indices.html#attributes-3 9795 * 9796 * Object.keys( Array.from( document.querySelectorAll( '#attributes-1 > tbody > tr' ) ) 9797 * .filter( ( tr ) => tr.lastChild.textContent.indexOf( 'Boolean attribute' ) !== -1 ) 9798 * .reduce( ( result, tr ) => Object.assign( result, { 9799 * [ tr.firstChild.textContent.trim() ]: true 9800 * } ), {} ) ).sort(); 9801 * 9802 * @type {Array} 9803 */ 9804 9805 const 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']; 9806 /** 9807 * Enumerated attributes are attributes which must be of a specific value form. 9808 * Like boolean attributes, these are meaningful if specified, even if not of a 9809 * valid enumerated value. 9810 * 9811 * See: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#enumerated-attribute 9812 * Extracted from: https://html.spec.whatwg.org/multipage/indices.html#attributes-3 9813 * 9814 * Object.keys( Array.from( document.querySelectorAll( '#attributes-1 > tbody > tr' ) ) 9815 * .filter( ( tr ) => /^("(.+?)";?\s*)+/.test( tr.lastChild.textContent.trim() ) ) 9816 * .reduce( ( result, tr ) => Object.assign( result, { 9817 * [ tr.firstChild.textContent.trim() ]: true 9818 * } ), {} ) ).sort(); 9819 * 9820 * @type {Array} 9821 */ 9822 9823 const 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']; 9824 /** 9825 * Meaningful attributes are those who cannot be safely ignored when omitted in 9826 * one HTML markup string and not another. 9827 * 9828 * @type {Array} 9829 */ 9830 9831 const MEANINGFUL_ATTRIBUTES = [...BOOLEAN_ATTRIBUTES, ...ENUMERATED_ATTRIBUTES]; 9832 /** 9833 * Array of functions which receive a text string on which to apply normalizing 9834 * behavior for consideration in text token equivalence, carefully ordered from 9835 * least-to-most expensive operations. 9836 * 9837 * @type {Array} 9838 */ 9839 9840 const TEXT_NORMALIZATIONS = [external_lodash_namespaceObject.identity, getTextWithCollapsedWhitespace]; 9841 /** 9842 * Regular expression matching a named character reference. In lieu of bundling 9843 * a full set of references, the pattern covers the minimal necessary to test 9844 * positively against the full set. 9845 * 9846 * "The ampersand must be followed by one of the names given in the named 9847 * character references section, using the same case." 9848 * 9849 * Tested aginst "12.5 Named character references": 9850 * 9851 * ``` 9852 * const references = Array.from( document.querySelectorAll( 9853 * '#named-character-references-table tr[id^=entity-] td:first-child' 9854 * ) ).map( ( code ) => code.textContent ) 9855 * references.every( ( reference ) => /^[\da-z]+$/i.test( reference ) ) 9856 * ``` 9857 * 9858 * @see https://html.spec.whatwg.org/multipage/syntax.html#character-references 9859 * @see https://html.spec.whatwg.org/multipage/named-characters.html#named-character-references 9860 * 9861 * @type {RegExp} 9862 */ 9863 9864 const REGEXP_NAMED_CHARACTER_REFERENCE = /^[\da-z]+$/i; 9865 /** 9866 * Regular expression matching a decimal character reference. 9867 * 9868 * "The ampersand must be followed by a U+0023 NUMBER SIGN character (#), 9869 * followed by one or more ASCII digits, representing a base-ten integer" 9870 * 9871 * @see https://html.spec.whatwg.org/multipage/syntax.html#character-references 9872 * 9873 * @type {RegExp} 9874 */ 9875 9876 const REGEXP_DECIMAL_CHARACTER_REFERENCE = /^#\d+$/; 9877 /** 9878 * Regular expression matching a hexadecimal character reference. 9879 * 9880 * "The ampersand must be followed by a U+0023 NUMBER SIGN character (#), which 9881 * must be followed by either a U+0078 LATIN SMALL LETTER X character (x) or a 9882 * U+0058 LATIN CAPITAL LETTER X character (X), which must then be followed by 9883 * one or more ASCII hex digits, representing a hexadecimal integer" 9884 * 9885 * @see https://html.spec.whatwg.org/multipage/syntax.html#character-references 9886 * 9887 * @type {RegExp} 9888 */ 9889 9890 const REGEXP_HEXADECIMAL_CHARACTER_REFERENCE = /^#x[\da-f]+$/i; 9891 /** 9892 * Returns true if the given string is a valid character reference segment, or 9893 * false otherwise. The text should be stripped of `&` and `;` demarcations. 9894 * 9895 * @param {string} text Text to test. 9896 * 9897 * @return {boolean} Whether text is valid character reference. 9898 */ 9899 9900 function isValidCharacterReference(text) { 9901 return REGEXP_NAMED_CHARACTER_REFERENCE.test(text) || REGEXP_DECIMAL_CHARACTER_REFERENCE.test(text) || REGEXP_HEXADECIMAL_CHARACTER_REFERENCE.test(text); 9902 } 9903 /** 9904 * Subsitute EntityParser class for `simple-html-tokenizer` which uses the 9905 * implementation of `decodeEntities` from `html-entities`, in order to avoid 9906 * bundling a massive named character reference. 9907 * 9908 * @see https://github.com/tildeio/simple-html-tokenizer/tree/HEAD/src/entity-parser.ts 9909 */ 9910 9911 class DecodeEntityParser { 9912 /** 9913 * Returns a substitute string for an entity string sequence between `&` 9914 * and `;`, or undefined if no substitution should occur. 9915 * 9916 * @param {string} entity Entity fragment discovered in HTML. 9917 * 9918 * @return {?string} Entity substitute value. 9919 */ 9920 parse(entity) { 9921 if (isValidCharacterReference(entity)) { 9922 return (0,external_wp_htmlEntities_namespaceObject.decodeEntities)('&' + entity + ';'); 9923 } 9924 } 9925 9926 } 9927 /** 9928 * Given a specified string, returns an array of strings split by consecutive 9929 * whitespace, ignoring leading or trailing whitespace. 9930 * 9931 * @param {string} text Original text. 9932 * 9933 * @return {string[]} Text pieces split on whitespace. 9934 */ 9935 9936 function getTextPiecesSplitOnWhitespace(text) { 9937 return text.trim().split(REGEXP_WHITESPACE); 9938 } 9939 /** 9940 * Given a specified string, returns a new trimmed string where all consecutive 9941 * whitespace is collapsed to a single space. 9942 * 9943 * @param {string} text Original text. 9944 * 9945 * @return {string} Trimmed text with consecutive whitespace collapsed. 9946 */ 9947 9948 function getTextWithCollapsedWhitespace(text) { 9949 // This is an overly simplified whitespace comparison. The specification is 9950 // more prescriptive of whitespace behavior in inline and block contexts. 9951 // 9952 // See: https://medium.com/@patrickbrosset/when-does-white-space-matter-in-html-b90e8a7cdd33 9953 return getTextPiecesSplitOnWhitespace(text).join(' '); 9954 } 9955 /** 9956 * Returns attribute pairs of the given StartTag token, including only pairs 9957 * where the value is non-empty or the attribute is a boolean attribute, an 9958 * enumerated attribute, or a custom data- attribute. 9959 * 9960 * @see MEANINGFUL_ATTRIBUTES 9961 * 9962 * @param {Object} token StartTag token. 9963 * 9964 * @return {Array[]} Attribute pairs. 9965 */ 9966 9967 function getMeaningfulAttributePairs(token) { 9968 return token.attributes.filter(pair => { 9969 const [key, value] = pair; 9970 return value || key.indexOf('data-') === 0 || (0,external_lodash_namespaceObject.includes)(MEANINGFUL_ATTRIBUTES, key); 9971 }); 9972 } 9973 /** 9974 * Returns true if two text tokens (with `chars` property) are equivalent, or 9975 * false otherwise. 9976 * 9977 * @param {Object} actual Actual token. 9978 * @param {Object} expected Expected token. 9979 * @param {Object} logger Validation logger object. 9980 * 9981 * @return {boolean} Whether two text tokens are equivalent. 9982 */ 9983 9984 function isEquivalentTextTokens(actual, expected) { 9985 let logger = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : createLogger(); 9986 // This function is intentionally written as syntactically "ugly" as a hot 9987 // path optimization. Text is progressively normalized in order from least- 9988 // to-most operationally expensive, until the earliest point at which text 9989 // can be confidently inferred as being equal. 9990 let actualChars = actual.chars; 9991 let expectedChars = expected.chars; 9992 9993 for (let i = 0; i < TEXT_NORMALIZATIONS.length; i++) { 9994 const normalize = TEXT_NORMALIZATIONS[i]; 9995 actualChars = normalize(actualChars); 9996 expectedChars = normalize(expectedChars); 9997 9998 if (actualChars === expectedChars) { 9999 return true; 10000 } 10001 } 10002 10003 logger.warning('Expected text `%s`, saw `%s`.', expected.chars, actual.chars); 10004 return false; 10005 } 10006 /** 10007 * Given a CSS length value, returns a normalized CSS length value for strict equality 10008 * comparison. 10009 * 10010 * @param {string} value CSS length value. 10011 * 10012 * @return {string} Normalized CSS length value. 10013 */ 10014 10015 function getNormalizedLength(value) { 10016 if (0 === parseFloat(value)) { 10017 return '0'; 10018 } // Normalize strings with floats to always include a leading zero. 10019 10020 10021 if (value.indexOf('.') === 0) { 10022 return '0' + value; 10023 } 10024 10025 return value; 10026 } 10027 /** 10028 * Given a style value, returns a normalized style value for strict equality 10029 * comparison. 10030 * 10031 * @param {string} value Style value. 10032 * 10033 * @return {string} Normalized style value. 10034 */ 10035 10036 function getNormalizedStyleValue(value) { 10037 const textPieces = getTextPiecesSplitOnWhitespace(value); 10038 const normalizedPieces = textPieces.map(getNormalizedLength); 10039 const result = normalizedPieces.join(' '); 10040 return result // Normalize URL type to omit whitespace or quotes. 10041 .replace(REGEXP_STYLE_URL_TYPE, 'url($1)'); 10042 } 10043 /** 10044 * Given a style attribute string, returns an object of style properties. 10045 * 10046 * @param {string} text Style attribute. 10047 * 10048 * @return {Object} Style properties. 10049 */ 10050 10051 function getStyleProperties(text) { 10052 const pairs = text // Trim ending semicolon (avoid including in split) 10053 .replace(/;?\s*$/, '') // Split on property assignment. 10054 .split(';') // For each property assignment... 10055 .map(style => { 10056 // ...split further into key-value pairs. 10057 const [key, ...valueParts] = style.split(':'); 10058 const value = valueParts.join(':'); 10059 return [key.trim(), getNormalizedStyleValue(value.trim())]; 10060 }); 10061 return (0,external_lodash_namespaceObject.fromPairs)(pairs); 10062 } 10063 /** 10064 * Attribute-specific equality handlers 10065 * 10066 * @type {Object} 10067 */ 10068 10069 const isEqualAttributesOfName = { 10070 class: (actual, expected) => { 10071 // Class matches if members are the same, even if out of order or 10072 // superfluous whitespace between. 10073 return !(0,external_lodash_namespaceObject.xor)(...[actual, expected].map(getTextPiecesSplitOnWhitespace)).length; 10074 }, 10075 style: (actual, expected) => { 10076 return (0,external_lodash_namespaceObject.isEqual)(...[actual, expected].map(getStyleProperties)); 10077 }, 10078 // For each boolean attribute, mere presence of attribute in both is enough 10079 // to assume equivalence. 10080 ...(0,external_lodash_namespaceObject.fromPairs)(BOOLEAN_ATTRIBUTES.map(attribute => [attribute, external_lodash_namespaceObject.stubTrue])) 10081 }; 10082 /** 10083 * Given two sets of attribute tuples, returns true if the attribute sets are 10084 * equivalent. 10085 * 10086 * @param {Array[]} actual Actual attributes tuples. 10087 * @param {Array[]} expected Expected attributes tuples. 10088 * @param {Object} logger Validation logger object. 10089 * 10090 * @return {boolean} Whether attributes are equivalent. 10091 */ 10092 10093 function isEqualTagAttributePairs(actual, expected) { 10094 let logger = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : createLogger(); 10095 10096 // Attributes is tokenized as tuples. Their lengths should match. This also 10097 // avoids us needing to check both attributes sets, since if A has any keys 10098 // which do not exist in B, we know the sets to be different. 10099 if (actual.length !== expected.length) { 10100 logger.warning('Expected attributes %o, instead saw %o.', expected, actual); 10101 return false; 10102 } // Attributes are not guaranteed to occur in the same order. For validating 10103 // actual attributes, first convert the set of expected attribute values to 10104 // an object, for lookup by key. 10105 10106 10107 const expectedAttributes = {}; 10108 10109 for (let i = 0; i < expected.length; i++) { 10110 expectedAttributes[expected[i][0].toLowerCase()] = expected[i][1]; 10111 } 10112 10113 for (let i = 0; i < actual.length; i++) { 10114 const [name, actualValue] = actual[i]; 10115 const nameLower = name.toLowerCase(); // As noted above, if missing member in B, assume different. 10116 10117 if (!expectedAttributes.hasOwnProperty(nameLower)) { 10118 logger.warning('Encountered unexpected attribute `%s`.', name); 10119 return false; 10120 } 10121 10122 const expectedValue = expectedAttributes[nameLower]; 10123 const isEqualAttributes = isEqualAttributesOfName[nameLower]; 10124 10125 if (isEqualAttributes) { 10126 // Defer custom attribute equality handling. 10127 if (!isEqualAttributes(actualValue, expectedValue)) { 10128 logger.warning('Expected attribute `%s` of value `%s`, saw `%s`.', name, expectedValue, actualValue); 10129 return false; 10130 } 10131 } else if (actualValue !== expectedValue) { 10132 // Otherwise strict inequality should bail. 10133 logger.warning('Expected attribute `%s` of value `%s`, saw `%s`.', name, expectedValue, actualValue); 10134 return false; 10135 } 10136 } 10137 10138 return true; 10139 } 10140 /** 10141 * Token-type-specific equality handlers 10142 * 10143 * @type {Object} 10144 */ 10145 10146 const isEqualTokensOfType = { 10147 StartTag: function (actual, expected) { 10148 let logger = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : createLogger(); 10149 10150 if (actual.tagName !== expected.tagName && // Optimization: Use short-circuit evaluation to defer case- 10151 // insensitive check on the assumption that the majority case will 10152 // have exactly equal tag names. 10153 actual.tagName.toLowerCase() !== expected.tagName.toLowerCase()) { 10154 logger.warning('Expected tag name `%s`, instead saw `%s`.', expected.tagName, actual.tagName); 10155 return false; 10156 } 10157 10158 return isEqualTagAttributePairs(...[actual, expected].map(getMeaningfulAttributePairs), logger); 10159 }, 10160 Chars: isEquivalentTextTokens, 10161 Comment: isEquivalentTextTokens 10162 }; 10163 /** 10164 * Given an array of tokens, returns the first token which is not purely 10165 * whitespace. 10166 * 10167 * Mutates the tokens array. 10168 * 10169 * @param {Object[]} tokens Set of tokens to search. 10170 * 10171 * @return {Object} Next non-whitespace token. 10172 */ 10173 10174 function getNextNonWhitespaceToken(tokens) { 10175 let token; 10176 10177 while (token = tokens.shift()) { 10178 if (token.type !== 'Chars') { 10179 return token; 10180 } 10181 10182 if (!REGEXP_ONLY_WHITESPACE.test(token.chars)) { 10183 return token; 10184 } 10185 } 10186 } 10187 /** 10188 * Tokenize an HTML string, gracefully handling any errors thrown during 10189 * underlying tokenization. 10190 * 10191 * @param {string} html HTML string to tokenize. 10192 * @param {Object} logger Validation logger object. 10193 * 10194 * @return {Object[]|null} Array of valid tokenized HTML elements, or null on error 10195 */ 10196 10197 function getHTMLTokens(html) { 10198 let logger = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : createLogger(); 10199 10200 try { 10201 return new Tokenizer(new DecodeEntityParser()).tokenize(html); 10202 } catch (e) { 10203 logger.warning('Malformed HTML detected: %s', html); 10204 } 10205 10206 return null; 10207 } 10208 /** 10209 * Returns true if the next HTML token closes the current token. 10210 * 10211 * @param {Object} currentToken Current token to compare with. 10212 * @param {Object|undefined} nextToken Next token to compare against. 10213 * 10214 * @return {boolean} true if `nextToken` closes `currentToken`, false otherwise 10215 */ 10216 10217 10218 function isClosedByToken(currentToken, nextToken) { 10219 // Ensure this is a self closed token. 10220 if (!currentToken.selfClosing) { 10221 return false; 10222 } // Check token names and determine if nextToken is the closing tag for currentToken. 10223 10224 10225 if (nextToken && nextToken.tagName === currentToken.tagName && nextToken.type === 'EndTag') { 10226 return true; 10227 } 10228 10229 return false; 10230 } 10231 /** 10232 * Returns true if the given HTML strings are effectively equivalent, or 10233 * false otherwise. Invalid HTML is not considered equivalent, even if the 10234 * strings directly match. 10235 * 10236 * @param {string} actual Actual HTML string. 10237 * @param {string} expected Expected HTML string. 10238 * @param {Object} logger Validation logger object. 10239 * 10240 * @return {boolean} Whether HTML strings are equivalent. 10241 */ 10242 10243 function isEquivalentHTML(actual, expected) { 10244 let logger = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : createLogger(); 10245 10246 // Short-circuit if markup is identical. 10247 if (actual === expected) { 10248 return true; 10249 } // Tokenize input content and reserialized save content. 10250 10251 10252 const [actualTokens, expectedTokens] = [actual, expected].map(html => getHTMLTokens(html, logger)); // If either is malformed then stop comparing - the strings are not equivalent. 10253 10254 if (!actualTokens || !expectedTokens) { 10255 return false; 10256 } 10257 10258 let actualToken, expectedToken; 10259 10260 while (actualToken = getNextNonWhitespaceToken(actualTokens)) { 10261 expectedToken = getNextNonWhitespaceToken(expectedTokens); // Inequal if exhausted all expected tokens. 10262 10263 if (!expectedToken) { 10264 logger.warning('Expected end of content, instead saw %o.', actualToken); 10265 return false; 10266 } // Inequal if next non-whitespace token of each set are not same type. 10267 10268 10269 if (actualToken.type !== expectedToken.type) { 10270 logger.warning('Expected token of type `%s` (%o), instead saw `%s` (%o).', expectedToken.type, expectedToken, actualToken.type, actualToken); 10271 return false; 10272 } // Defer custom token type equality handling, otherwise continue and 10273 // assume as equal. 10274 10275 10276 const isEqualTokens = isEqualTokensOfType[actualToken.type]; 10277 10278 if (isEqualTokens && !isEqualTokens(actualToken, expectedToken, logger)) { 10279 return false; 10280 } // Peek at the next tokens (actual and expected) to see if they close 10281 // a self-closing tag. 10282 10283 10284 if (isClosedByToken(actualToken, expectedTokens[0])) { 10285 // Consume the next expected token that closes the current actual 10286 // self-closing token. 10287 getNextNonWhitespaceToken(expectedTokens); 10288 } else if (isClosedByToken(expectedToken, actualTokens[0])) { 10289 // Consume the next actual token that closes the current expected 10290 // self-closing token. 10291 getNextNonWhitespaceToken(actualTokens); 10292 } 10293 } 10294 10295 if (expectedToken = getNextNonWhitespaceToken(expectedTokens)) { 10296 // If any non-whitespace tokens remain in expected token set, this 10297 // indicates inequality. 10298 logger.warning('Expected %o, instead saw end of content.', expectedToken); 10299 return false; 10300 } 10301 10302 return true; 10303 } 10304 /** 10305 * Returns an object with `isValid` property set to `true` if the parsed block 10306 * is valid given the input content. A block is considered valid if, when serialized 10307 * with assumed attributes, the content matches the original value. If block is 10308 * invalid, this function returns all validations issues as well. 10309 * 10310 * @param {string|Object} blockTypeOrName Block type. 10311 * @param {Object} attributes Parsed block attributes. 10312 * @param {string} originalBlockContent Original block content. 10313 * @param {Object} logger Validation logger object. 10314 * 10315 * @return {Object} Whether block is valid and contains validation messages. 10316 */ 10317 10318 /** 10319 * Returns an object with `isValid` property set to `true` if the parsed block 10320 * is valid given the input content. A block is considered valid if, when serialized 10321 * with assumed attributes, the content matches the original value. If block is 10322 * invalid, this function returns all validations issues as well. 10323 * 10324 * @param {WPBlock} block block object. 10325 * @param {WPBlockType|string} [blockTypeOrName = block.name] Block type or name, inferred from block if not given. 10326 * 10327 * @return {[boolean,Array<LoggerItem>]} validation results. 10328 */ 10329 10330 function validateBlock(block) { 10331 let blockTypeOrName = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : block.name; 10332 const isFallbackBlock = block.name === getFreeformContentHandlerName() || block.name === getUnregisteredTypeHandlerName(); // Shortcut to avoid costly validation. 10333 10334 if (isFallbackBlock) { 10335 return [true, []]; 10336 } 10337 10338 const logger = createQueuedLogger(); 10339 const blockType = normalizeBlockType(blockTypeOrName); 10340 let generatedBlockContent; 10341 10342 try { 10343 generatedBlockContent = getSaveContent(blockType, block.attributes); 10344 } catch (error) { 10345 logger.error('Block validation failed because an error occurred while generating block content:\n\n%s', error.toString()); 10346 return [false, logger.getItems()]; 10347 } 10348 10349 const isValid = isEquivalentHTML(block.originalContent, generatedBlockContent, logger); 10350 10351 if (!isValid) { 10352 logger.error('Block validation failed for `%s` (%o).\n\nContent generated by `save` function:\n\n%s\n\nContent retrieved from post body:\n\n%s', blockType.name, blockType, generatedBlockContent, block.originalContent); 10353 } 10354 10355 return [isValid, logger.getItems()]; 10356 } 10357 /** 10358 * Returns true if the parsed block is valid given the input content. A block 10359 * is considered valid if, when serialized with assumed attributes, the content 10360 * matches the original value. 10361 * 10362 * Logs to console in development environments when invalid. 10363 * 10364 * @deprecated Use validateBlock instead to avoid data loss. 10365 * 10366 * @param {string|Object} blockTypeOrName Block type. 10367 * @param {Object} attributes Parsed block attributes. 10368 * @param {string} originalBlockContent Original block content. 10369 * 10370 * @return {boolean} Whether block is valid. 10371 */ 10372 10373 function isValidBlockContent(blockTypeOrName, attributes, originalBlockContent) { 10374 external_wp_deprecated_default()('isValidBlockContent introduces opportunity for data loss', { 10375 since: '12.6', 10376 plugin: 'Gutenberg', 10377 alternative: 'validateBlock' 10378 }); 10379 const blockType = normalizeBlockType(blockTypeOrName); 10380 const block = { 10381 name: blockType.name, 10382 attributes, 10383 innerBlocks: [], 10384 originalContent: originalBlockContent 10385 }; 10386 const [isValid] = validateBlock(block, blockType); 10387 return isValid; 10388 } 10389 10390 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/parser/convert-legacy-block.js 10391 /** 10392 * Convert legacy blocks to their canonical form. This function is used 10393 * both in the parser level for previous content and to convert such blocks 10394 * used in Custom Post Types templates. 10395 * 10396 * @param {string} name The block's name 10397 * @param {Object} attributes The block's attributes 10398 * 10399 * @return {[string, Object]} The block's name and attributes, changed accordingly if a match was found 10400 */ 10401 function convertLegacyBlockNameAndAttributes(name, attributes) { 10402 const newAttributes = { ...attributes 10403 }; // Convert 'core/cover-image' block in existing content to 'core/cover'. 10404 10405 if ('core/cover-image' === name) { 10406 name = 'core/cover'; 10407 } // Convert 'core/text' blocks in existing content to 'core/paragraph'. 10408 10409 10410 if ('core/text' === name || 'core/cover-text' === name) { 10411 name = 'core/paragraph'; 10412 } // Convert derivative blocks such as 'core/social-link-wordpress' to the 10413 // canonical form 'core/social-link'. 10414 10415 10416 if (name && name.indexOf('core/social-link-') === 0) { 10417 // Capture `social-link-wordpress` into `{"service":"wordpress"}` 10418 newAttributes.service = name.substring(17); 10419 name = 'core/social-link'; 10420 } // Convert derivative blocks such as 'core-embed/instagram' to the 10421 // canonical form 'core/embed'. 10422 10423 10424 if (name && name.indexOf('core-embed/') === 0) { 10425 // Capture `core-embed/instagram` into `{"providerNameSlug":"instagram"}` 10426 const providerSlug = name.substring(11); 10427 const deprecated = { 10428 speaker: 'speaker-deck', 10429 polldaddy: 'crowdsignal' 10430 }; 10431 newAttributes.providerNameSlug = providerSlug in deprecated ? deprecated[providerSlug] : providerSlug; // This is needed as the `responsive` attribute was passed 10432 // in a different way before the refactoring to block variations. 10433 10434 if (!['amazon-kindle', 'wordpress'].includes(providerSlug)) { 10435 newAttributes.responsive = true; 10436 } 10437 10438 name = 'core/embed'; 10439 } // Convert 'core/query-loop' blocks in existing content to 'core/post-template'. 10440 // TODO: Remove this check when WordPress 5.9 is released. 10441 10442 10443 if (name === 'core/query-loop') { 10444 name = 'core/post-template'; 10445 } // Convert Post Comment blocks in existing content to Comment blocks. 10446 // TODO: Remove these checks when WordPress 6.0 is released. 10447 10448 10449 if (name === 'core/post-comment-author') { 10450 name = 'core/comment-author-name'; 10451 } 10452 10453 if (name === 'core/post-comment-content') { 10454 name = 'core/comment-content'; 10455 } 10456 10457 if (name === 'core/post-comment-date') { 10458 name = 'core/comment-date'; 10459 } 10460 10461 return [name, newAttributes]; 10462 } 10463 10464 ;// CONCATENATED MODULE: ./node_modules/hpq/es/get-path.js 10465 /** 10466 * Given object and string of dot-delimited path segments, returns value at 10467 * path or undefined if path cannot be resolved. 10468 * 10469 * @param {Object} object Lookup object 10470 * @param {string} path Path to resolve 10471 * @return {?*} Resolved value 10472 */ 10473 function getPath(object, path) { 10474 var segments = path.split('.'); 10475 var segment; 10476 10477 while (segment = segments.shift()) { 10478 if (!(segment in object)) { 10479 return; 10480 } 10481 10482 object = object[segment]; 10483 } 10484 10485 return object; 10486 } 10487 ;// CONCATENATED MODULE: ./node_modules/hpq/es/index.js 10488 /** 10489 * Internal dependencies 10490 */ 10491 10492 /** 10493 * Function returning a DOM document created by `createHTMLDocument`. The same 10494 * document is returned between invocations. 10495 * 10496 * @return {Document} DOM document. 10497 */ 10498 10499 var getDocument = function () { 10500 var doc; 10501 return function () { 10502 if (!doc) { 10503 doc = document.implementation.createHTMLDocument(''); 10504 } 10505 10506 return doc; 10507 }; 10508 }(); 10509 /** 10510 * Given a markup string or DOM element, creates an object aligning with the 10511 * shape of the matchers object, or the value returned by the matcher. 10512 * 10513 * @param {(string|Element)} source Source content 10514 * @param {(Object|Function)} matchers Matcher function or object of matchers 10515 * @return {(Object|*)} Matched value(s), shaped by object 10516 */ 10517 10518 10519 function parse(source, matchers) { 10520 if (!matchers) { 10521 return; 10522 } // Coerce to element 10523 10524 10525 if ('string' === typeof source) { 10526 var doc = getDocument(); 10527 doc.body.innerHTML = source; 10528 source = doc.body; 10529 } // Return singular value 10530 10531 10532 if ('function' === typeof matchers) { 10533 return matchers(source); 10534 } // Bail if we can't handle matchers 10535 10536 10537 if (Object !== matchers.constructor) { 10538 return; 10539 } // Shape result by matcher object 10540 10541 10542 return Object.keys(matchers).reduce(function (memo, key) { 10543 memo[key] = parse(source, matchers[key]); 10544 return memo; 10545 }, {}); 10546 } 10547 /** 10548 * Generates a function which matches node of type selector, returning an 10549 * attribute by property if the attribute exists. If no selector is passed, 10550 * returns property of the query element. 10551 * 10552 * @param {?string} selector Optional selector 10553 * @param {string} name Property name 10554 * @return {*} Property value 10555 */ 10556 10557 function prop(selector, name) { 10558 if (1 === arguments.length) { 10559 name = selector; 10560 selector = undefined; 10561 } 10562 10563 return function (node) { 10564 var match = node; 10565 10566 if (selector) { 10567 match = node.querySelector(selector); 10568 } 10569 10570 if (match) { 10571 return getPath(match, name); 10572 } 10573 }; 10574 } 10575 /** 10576 * Generates a function which matches node of type selector, returning an 10577 * attribute by name if the attribute exists. If no selector is passed, 10578 * returns attribute of the query element. 10579 * 10580 * @param {?string} selector Optional selector 10581 * @param {string} name Attribute name 10582 * @return {?string} Attribute value 10583 */ 10584 10585 function attr(selector, name) { 10586 if (1 === arguments.length) { 10587 name = selector; 10588 selector = undefined; 10589 } 10590 10591 return function (node) { 10592 var attributes = prop(selector, 'attributes')(node); 10593 10594 if (attributes && attributes.hasOwnProperty(name)) { 10595 return attributes[name].value; 10596 } 10597 }; 10598 } 10599 /** 10600 * Convenience for `prop( selector, 'innerHTML' )`. 10601 * 10602 * @see prop() 10603 * 10604 * @param {?string} selector Optional selector 10605 * @return {string} Inner HTML 10606 */ 10607 10608 function html(selector) { 10609 return prop(selector, 'innerHTML'); 10610 } 10611 /** 10612 * Convenience for `prop( selector, 'textContent' )`. 10613 * 10614 * @see prop() 10615 * 10616 * @param {?string} selector Optional selector 10617 * @return {string} Text content 10618 */ 10619 10620 function es_text(selector) { 10621 return prop(selector, 'textContent'); 10622 } 10623 /** 10624 * Creates a new matching context by first finding elements matching selector 10625 * using querySelectorAll before then running another `parse` on `matchers` 10626 * scoped to the matched elements. 10627 * 10628 * @see parse() 10629 * 10630 * @param {string} selector Selector to match 10631 * @param {(Object|Function)} matchers Matcher function or object of matchers 10632 * @return {Array.<*,Object>} Array of matched value(s) 10633 */ 10634 10635 function query(selector, matchers) { 10636 return function (node) { 10637 var matches = node.querySelectorAll(selector); 10638 return [].map.call(matches, function (match) { 10639 return parse(match, matchers); 10640 }); 10641 }; 10642 } 10643 // EXTERNAL MODULE: ./node_modules/memize/index.js 10644 var memize = __webpack_require__(9756); 10645 var memize_default = /*#__PURE__*/__webpack_require__.n(memize); 10646 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/matchers.js 10647 /** 10648 * External dependencies 10649 */ 10650 10651 /** 10652 * Internal dependencies 10653 */ 10654 10655 10656 10657 function matchers_html(selector, multilineTag) { 10658 return domNode => { 10659 let match = domNode; 10660 10661 if (selector) { 10662 match = domNode.querySelector(selector); 10663 } 10664 10665 if (!match) { 10666 return ''; 10667 } 10668 10669 if (multilineTag) { 10670 let value = ''; 10671 const length = match.children.length; 10672 10673 for (let index = 0; index < length; index++) { 10674 const child = match.children[index]; 10675 10676 if (child.nodeName.toLowerCase() !== multilineTag) { 10677 continue; 10678 } 10679 10680 value += child.outerHTML; 10681 } 10682 10683 return value; 10684 } 10685 10686 return match.innerHTML; 10687 }; 10688 } 10689 10690 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/node.js 10691 /** 10692 * Internal dependencies 10693 */ 10694 10695 /** 10696 * A representation of a single node within a block's rich text value. If 10697 * representing a text node, the value is simply a string of the node value. 10698 * As representing an element node, it is an object of: 10699 * 10700 * 1. `type` (string): Tag name. 10701 * 2. `props` (object): Attributes and children array of WPBlockNode. 10702 * 10703 * @typedef {string|Object} WPBlockNode 10704 */ 10705 10706 /** 10707 * Given a single node and a node type (e.g. `'br'`), returns true if the node 10708 * corresponds to that type, false otherwise. 10709 * 10710 * @param {WPBlockNode} node Block node to test 10711 * @param {string} type Node to type to test against. 10712 * 10713 * @return {boolean} Whether node is of intended type. 10714 */ 10715 10716 function isNodeOfType(node, type) { 10717 return node && node.type === type; 10718 } 10719 /** 10720 * Given an object implementing the NamedNodeMap interface, returns a plain 10721 * object equivalent value of name, value key-value pairs. 10722 * 10723 * @see https://dom.spec.whatwg.org/#interface-namednodemap 10724 * 10725 * @param {NamedNodeMap} nodeMap NamedNodeMap to convert to object. 10726 * 10727 * @return {Object} Object equivalent value of NamedNodeMap. 10728 */ 10729 10730 10731 function getNamedNodeMapAsObject(nodeMap) { 10732 const result = {}; 10733 10734 for (let i = 0; i < nodeMap.length; i++) { 10735 const { 10736 name, 10737 value 10738 } = nodeMap[i]; 10739 result[name] = value; 10740 } 10741 10742 return result; 10743 } 10744 /** 10745 * Given a DOM Element or Text node, returns an equivalent block node. Throws 10746 * if passed any node type other than element or text. 10747 * 10748 * @throws {TypeError} If non-element/text node is passed. 10749 * 10750 * @param {Node} domNode DOM node to convert. 10751 * 10752 * @return {WPBlockNode} Block node equivalent to DOM node. 10753 */ 10754 10755 function fromDOM(domNode) { 10756 if (domNode.nodeType === domNode.TEXT_NODE) { 10757 return domNode.nodeValue; 10758 } 10759 10760 if (domNode.nodeType !== domNode.ELEMENT_NODE) { 10761 throw new TypeError('A block node can only be created from a node of type text or ' + 'element.'); 10762 } 10763 10764 return { 10765 type: domNode.nodeName.toLowerCase(), 10766 props: { ...getNamedNodeMapAsObject(domNode.attributes), 10767 children: children_fromDOM(domNode.childNodes) 10768 } 10769 }; 10770 } 10771 /** 10772 * Given a block node, returns its HTML string representation. 10773 * 10774 * @param {WPBlockNode} node Block node to convert to string. 10775 * 10776 * @return {string} String HTML representation of block node. 10777 */ 10778 10779 function toHTML(node) { 10780 return children_toHTML([node]); 10781 } 10782 /** 10783 * Given a selector, returns an hpq matcher generating a WPBlockNode value 10784 * matching the selector result. 10785 * 10786 * @param {string} selector DOM selector. 10787 * 10788 * @return {Function} hpq matcher. 10789 */ 10790 10791 function node_matcher(selector) { 10792 return domNode => { 10793 let match = domNode; 10794 10795 if (selector) { 10796 match = domNode.querySelector(selector); 10797 } 10798 10799 try { 10800 return fromDOM(match); 10801 } catch (error) { 10802 return null; 10803 } 10804 }; 10805 } 10806 /** 10807 * Object of utility functions used in managing block attribute values of 10808 * source `node`. 10809 * 10810 * @see https://github.com/WordPress/gutenberg/pull/10439 10811 * 10812 * @deprecated since 4.0. The `node` source should not be used, and can be 10813 * replaced by the `html` source. 10814 * 10815 * @private 10816 */ 10817 10818 /* harmony default export */ var node = ({ 10819 isNodeOfType, 10820 fromDOM, 10821 toHTML, 10822 matcher: node_matcher 10823 }); 10824 10825 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/children.js 10826 /** 10827 * External dependencies 10828 */ 10829 10830 /** 10831 * WordPress dependencies 10832 */ 10833 10834 10835 /** 10836 * Internal dependencies 10837 */ 10838 10839 10840 /** 10841 * A representation of a block's rich text value. 10842 * 10843 * @typedef {WPBlockNode[]} WPBlockChildren 10844 */ 10845 10846 /** 10847 * Given block children, returns a serialize-capable WordPress element. 10848 * 10849 * @param {WPBlockChildren} children Block children object to convert. 10850 * 10851 * @return {WPElement} A serialize-capable element. 10852 */ 10853 10854 function getSerializeCapableElement(children) { 10855 // The fact that block children are compatible with the element serializer is 10856 // merely an implementation detail that currently serves to be true, but 10857 // should not be mistaken as being a guarantee on the external API. The 10858 // public API only offers guarantees to work with strings (toHTML) and DOM 10859 // elements (fromDOM), and should provide utilities to manipulate the value 10860 // rather than expect consumers to inspect or construct its shape (concat). 10861 return children; 10862 } 10863 /** 10864 * Given block children, returns an array of block nodes. 10865 * 10866 * @param {WPBlockChildren} children Block children object to convert. 10867 * 10868 * @return {Array<WPBlockNode>} An array of individual block nodes. 10869 */ 10870 10871 function getChildrenArray(children) { 10872 // The fact that block children are compatible with the element serializer 10873 // is merely an implementation detail that currently serves to be true, but 10874 // should not be mistaken as being a guarantee on the external API. 10875 return children; 10876 } 10877 /** 10878 * Given two or more block nodes, returns a new block node representing a 10879 * concatenation of its values. 10880 * 10881 * @param {...WPBlockChildren} blockNodes Block nodes to concatenate. 10882 * 10883 * @return {WPBlockChildren} Concatenated block node. 10884 */ 10885 10886 10887 function concat() { 10888 const result = []; 10889 10890 for (let i = 0; i < arguments.length; i++) { 10891 const blockNode = (0,external_lodash_namespaceObject.castArray)(i < 0 || arguments.length <= i ? undefined : arguments[i]); 10892 10893 for (let j = 0; j < blockNode.length; j++) { 10894 const child = blockNode[j]; 10895 const canConcatToPreviousString = typeof child === 'string' && typeof result[result.length - 1] === 'string'; 10896 10897 if (canConcatToPreviousString) { 10898 result[result.length - 1] += child; 10899 } else { 10900 result.push(child); 10901 } 10902 } 10903 } 10904 10905 return result; 10906 } 10907 /** 10908 * Given an iterable set of DOM nodes, returns equivalent block children. 10909 * Ignores any non-element/text nodes included in set. 10910 * 10911 * @param {Iterable.<Node>} domNodes Iterable set of DOM nodes to convert. 10912 * 10913 * @return {WPBlockChildren} Block children equivalent to DOM nodes. 10914 */ 10915 10916 function children_fromDOM(domNodes) { 10917 const result = []; 10918 10919 for (let i = 0; i < domNodes.length; i++) { 10920 try { 10921 result.push(fromDOM(domNodes[i])); 10922 } catch (error) {// Simply ignore if DOM node could not be converted. 10923 } 10924 } 10925 10926 return result; 10927 } 10928 /** 10929 * Given a block node, returns its HTML string representation. 10930 * 10931 * @param {WPBlockChildren} children Block node(s) to convert to string. 10932 * 10933 * @return {string} String HTML representation of block node. 10934 */ 10935 10936 function children_toHTML(children) { 10937 const element = getSerializeCapableElement(children); 10938 return (0,external_wp_element_namespaceObject.renderToString)(element); 10939 } 10940 /** 10941 * Given a selector, returns an hpq matcher generating a WPBlockChildren value 10942 * matching the selector result. 10943 * 10944 * @param {string} selector DOM selector. 10945 * 10946 * @return {Function} hpq matcher. 10947 */ 10948 10949 function children_matcher(selector) { 10950 return domNode => { 10951 let match = domNode; 10952 10953 if (selector) { 10954 match = domNode.querySelector(selector); 10955 } 10956 10957 if (match) { 10958 return children_fromDOM(match.childNodes); 10959 } 10960 10961 return []; 10962 }; 10963 } 10964 /** 10965 * Object of utility functions used in managing block attribute values of 10966 * source `children`. 10967 * 10968 * @see https://github.com/WordPress/gutenberg/pull/10439 10969 * 10970 * @deprecated since 4.0. The `children` source should not be used, and can be 10971 * replaced by the `html` source. 10972 * 10973 * @private 10974 */ 10975 10976 /* harmony default export */ var children = ({ 10977 concat, 10978 getChildrenArray, 10979 fromDOM: children_fromDOM, 10980 toHTML: children_toHTML, 10981 matcher: children_matcher 10982 }); 10983 10984 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/parser/get-block-attributes.js 10985 /** 10986 * External dependencies 10987 */ 10988 10989 10990 10991 /** 10992 * WordPress dependencies 10993 */ 10994 10995 10996 /** 10997 * Internal dependencies 10998 */ 10999 11000 11001 11002 /** 11003 * Higher-order hpq matcher which enhances an attribute matcher to return true 11004 * or false depending on whether the original matcher returns undefined. This 11005 * is useful for boolean attributes (e.g. disabled) whose attribute values may 11006 * be technically falsey (empty string), though their mere presence should be 11007 * enough to infer as true. 11008 * 11009 * @param {Function} matcher Original hpq matcher. 11010 * 11011 * @return {Function} Enhanced hpq matcher. 11012 */ 11013 11014 const toBooleanAttributeMatcher = matcher => (0,external_lodash_namespaceObject.flow)([matcher, // Expected values from `attr( 'disabled' )`: 11015 // 11016 // <input> 11017 // - Value: `undefined` 11018 // - Transformed: `false` 11019 // 11020 // <input disabled> 11021 // - Value: `''` 11022 // - Transformed: `true` 11023 // 11024 // <input disabled="disabled"> 11025 // - Value: `'disabled'` 11026 // - Transformed: `true` 11027 value => value !== undefined]); 11028 /** 11029 * Returns true if value is of the given JSON schema type, or false otherwise. 11030 * 11031 * @see http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.25 11032 * 11033 * @param {*} value Value to test. 11034 * @param {string} type Type to test. 11035 * 11036 * @return {boolean} Whether value is of type. 11037 */ 11038 11039 function isOfType(value, type) { 11040 switch (type) { 11041 case 'string': 11042 return typeof value === 'string'; 11043 11044 case 'boolean': 11045 return typeof value === 'boolean'; 11046 11047 case 'object': 11048 return !!value && value.constructor === Object; 11049 11050 case 'null': 11051 return value === null; 11052 11053 case 'array': 11054 return Array.isArray(value); 11055 11056 case 'integer': 11057 case 'number': 11058 return typeof value === 'number'; 11059 } 11060 11061 return true; 11062 } 11063 /** 11064 * Returns true if value is of an array of given JSON schema types, or false 11065 * otherwise. 11066 * 11067 * @see http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.25 11068 * 11069 * @param {*} value Value to test. 11070 * @param {string[]} types Types to test. 11071 * 11072 * @return {boolean} Whether value is of types. 11073 */ 11074 11075 function isOfTypes(value, types) { 11076 return types.some(type => isOfType(value, type)); 11077 } 11078 /** 11079 * Given an attribute key, an attribute's schema, a block's raw content and the 11080 * commentAttributes returns the attribute value depending on its source 11081 * definition of the given attribute key. 11082 * 11083 * @param {string} attributeKey Attribute key. 11084 * @param {Object} attributeSchema Attribute's schema. 11085 * @param {string|Node} innerHTML Block's raw content. 11086 * @param {Object} commentAttributes Block's comment attributes. 11087 * 11088 * @return {*} Attribute value. 11089 */ 11090 11091 function getBlockAttribute(attributeKey, attributeSchema, innerHTML, commentAttributes) { 11092 let value; 11093 11094 switch (attributeSchema.source) { 11095 // An undefined source means that it's an attribute serialized to the 11096 // block's "comment". 11097 case undefined: 11098 value = commentAttributes ? commentAttributes[attributeKey] : undefined; 11099 break; 11100 11101 case 'attribute': 11102 case 'property': 11103 case 'html': 11104 case 'text': 11105 case 'children': 11106 case 'node': 11107 case 'query': 11108 case 'tag': 11109 value = parseWithAttributeSchema(innerHTML, attributeSchema); 11110 break; 11111 } 11112 11113 if (!isValidByType(value, attributeSchema.type) || !isValidByEnum(value, attributeSchema.enum)) { 11114 // Reject the value if it is not valid. Reverting to the undefined 11115 // value ensures the default is respected, if applicable. 11116 value = undefined; 11117 } 11118 11119 if (value === undefined) { 11120 value = attributeSchema.default; 11121 } 11122 11123 return value; 11124 } 11125 /** 11126 * Returns true if value is valid per the given block attribute schema type 11127 * definition, or false otherwise. 11128 * 11129 * @see https://json-schema.org/latest/json-schema-validation.html#rfc.section.6.1.1 11130 * 11131 * @param {*} value Value to test. 11132 * @param {?(Array<string>|string)} type Block attribute schema type. 11133 * 11134 * @return {boolean} Whether value is valid. 11135 */ 11136 11137 function isValidByType(value, type) { 11138 return type === undefined || isOfTypes(value, (0,external_lodash_namespaceObject.castArray)(type)); 11139 } 11140 /** 11141 * Returns true if value is valid per the given block attribute schema enum 11142 * definition, or false otherwise. 11143 * 11144 * @see https://json-schema.org/latest/json-schema-validation.html#rfc.section.6.1.2 11145 * 11146 * @param {*} value Value to test. 11147 * @param {?Array} enumSet Block attribute schema enum. 11148 * 11149 * @return {boolean} Whether value is valid. 11150 */ 11151 11152 function isValidByEnum(value, enumSet) { 11153 return !Array.isArray(enumSet) || enumSet.includes(value); 11154 } 11155 /** 11156 * Returns an hpq matcher given a source object. 11157 * 11158 * @param {Object} sourceConfig Attribute Source object. 11159 * 11160 * @return {Function} A hpq Matcher. 11161 */ 11162 11163 const matcherFromSource = memize_default()(sourceConfig => { 11164 switch (sourceConfig.source) { 11165 case 'attribute': 11166 let matcher = attr(sourceConfig.selector, sourceConfig.attribute); 11167 11168 if (sourceConfig.type === 'boolean') { 11169 matcher = toBooleanAttributeMatcher(matcher); 11170 } 11171 11172 return matcher; 11173 11174 case 'html': 11175 return matchers_html(sourceConfig.selector, sourceConfig.multiline); 11176 11177 case 'text': 11178 return es_text(sourceConfig.selector); 11179 11180 case 'children': 11181 return children_matcher(sourceConfig.selector); 11182 11183 case 'node': 11184 return node_matcher(sourceConfig.selector); 11185 11186 case 'query': 11187 const subMatchers = (0,external_lodash_namespaceObject.mapValues)(sourceConfig.query, matcherFromSource); 11188 return query(sourceConfig.selector, subMatchers); 11189 11190 case 'tag': 11191 return (0,external_lodash_namespaceObject.flow)([prop(sourceConfig.selector, 'nodeName'), nodeName => nodeName ? nodeName.toLowerCase() : undefined]); 11192 11193 default: 11194 // eslint-disable-next-line no-console 11195 console.error(`Unknown source type "$sourceConfig.source}"`); 11196 } 11197 }); 11198 /** 11199 * Parse a HTML string into DOM tree. 11200 * 11201 * @param {string|Node} innerHTML HTML string or already parsed DOM node. 11202 * 11203 * @return {Node} Parsed DOM node. 11204 */ 11205 11206 function parseHtml(innerHTML) { 11207 return parse(innerHTML, h => h); 11208 } 11209 /** 11210 * Given a block's raw content and an attribute's schema returns the attribute's 11211 * value depending on its source. 11212 * 11213 * @param {string|Node} innerHTML Block's raw content. 11214 * @param {Object} attributeSchema Attribute's schema. 11215 * 11216 * @return {*} Attribute value. 11217 */ 11218 11219 11220 function parseWithAttributeSchema(innerHTML, attributeSchema) { 11221 return matcherFromSource(attributeSchema)(parseHtml(innerHTML)); 11222 } 11223 /** 11224 * Returns the block attributes of a registered block node given its type. 11225 * 11226 * @param {string|Object} blockTypeOrName Block type or name. 11227 * @param {string|Node} innerHTML Raw block content. 11228 * @param {?Object} attributes Known block attributes (from delimiters). 11229 * 11230 * @return {Object} All block attributes. 11231 */ 11232 11233 function getBlockAttributes(blockTypeOrName, innerHTML) { 11234 let attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; 11235 const doc = parseHtml(innerHTML); 11236 const blockType = normalizeBlockType(blockTypeOrName); 11237 const blockAttributes = (0,external_lodash_namespaceObject.mapValues)(blockType.attributes, (schema, key) => getBlockAttribute(key, schema, doc, attributes)); 11238 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getBlockAttributes', blockAttributes, blockType, innerHTML, attributes); 11239 } 11240 11241 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/parser/fix-custom-classname.js 11242 /** 11243 * External dependencies 11244 */ 11245 11246 /** 11247 * Internal dependencies 11248 */ 11249 11250 11251 11252 11253 const CLASS_ATTR_SCHEMA = { 11254 type: 'string', 11255 source: 'attribute', 11256 selector: '[data-custom-class-name] > *', 11257 attribute: 'class' 11258 }; 11259 /** 11260 * Given an HTML string, returns an array of class names assigned to the root 11261 * element in the markup. 11262 * 11263 * @param {string} innerHTML Markup string from which to extract classes. 11264 * 11265 * @return {string[]} Array of class names assigned to the root element. 11266 */ 11267 11268 function getHTMLRootElementClasses(innerHTML) { 11269 const parsed = parseWithAttributeSchema(`<div data-custom-class-name>$innerHTML}</div>`, CLASS_ATTR_SCHEMA); 11270 return parsed ? parsed.trim().split(/\s+/) : []; 11271 } 11272 /** 11273 * Given a parsed set of block attributes, if the block supports custom class 11274 * names and an unknown class (per the block's serialization behavior) is 11275 * found, the unknown classes are treated as custom classes. This prevents the 11276 * block from being considered as invalid. 11277 * 11278 * @param {Object} blockAttributes Original block attributes. 11279 * @param {Object} blockType Block type settings. 11280 * @param {string} innerHTML Original block markup. 11281 * 11282 * @return {Object} Filtered block attributes. 11283 */ 11284 11285 function fixCustomClassname(blockAttributes, blockType, innerHTML) { 11286 if (registration_hasBlockSupport(blockType, 'customClassName', true)) { 11287 // To determine difference, serialize block given the known set of 11288 // attributes, with the exception of `className`. This will determine 11289 // the default set of classes. From there, any difference in innerHTML 11290 // can be considered as custom classes. 11291 const attributesSansClassName = (0,external_lodash_namespaceObject.omit)(blockAttributes, ['className']); 11292 const serialized = getSaveContent(blockType, attributesSansClassName); 11293 const defaultClasses = getHTMLRootElementClasses(serialized); 11294 const actualClasses = getHTMLRootElementClasses(innerHTML); 11295 const customClasses = (0,external_lodash_namespaceObject.difference)(actualClasses, defaultClasses); 11296 11297 if (customClasses.length) { 11298 blockAttributes.className = customClasses.join(' '); 11299 } else if (serialized) { 11300 delete blockAttributes.className; 11301 } 11302 } 11303 11304 return blockAttributes; 11305 } 11306 11307 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/parser/apply-built-in-validation-fixes.js 11308 /** 11309 * Internal dependencies 11310 */ 11311 11312 /** 11313 * Attempts to fix block invalidation by applying build-in validation fixes 11314 * like moving all extra classNames to the className attribute. 11315 * 11316 * @param {WPBlock} block block object. 11317 * @param {import('../registration').WPBlockType} blockType Block type. This is normalize not necessary and 11318 * can be inferred from the block name, 11319 * but it's here for performance reasons. 11320 * 11321 * @return {WPBlock} Fixed block object 11322 */ 11323 11324 function applyBuiltInValidationFixes(block, blockType) { 11325 const updatedBlockAttributes = fixCustomClassname(block.attributes, blockType, block.originalContent); 11326 return { ...block, 11327 attributes: updatedBlockAttributes 11328 }; 11329 } 11330 11331 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/parser/apply-block-deprecated-versions.js 11332 /** 11333 * External dependencies 11334 */ 11335 11336 /** 11337 * Internal dependencies 11338 */ 11339 11340 11341 11342 11343 11344 /** 11345 * Given a block object, returns a new copy of the block with any applicable 11346 * deprecated migrations applied, or the original block if it was both valid 11347 * and no eligible migrations exist. 11348 * 11349 * @param {import(".").WPBlock} block Parsed and invalid block object. 11350 * @param {import(".").WPRawBlock} rawBlock Raw block object. 11351 * @param {import('../registration').WPBlockType} blockType Block type. This is normalize not necessary and 11352 * can be inferred from the block name, 11353 * but it's here for performance reasons. 11354 * 11355 * @return {import(".").WPBlock} Migrated block object. 11356 */ 11357 11358 function applyBlockDeprecatedVersions(block, rawBlock, blockType) { 11359 const parsedAttributes = rawBlock.attrs; 11360 const { 11361 deprecated: deprecatedDefinitions 11362 } = blockType; // Bail early if there are no registered deprecations to be handled. 11363 11364 if (!deprecatedDefinitions || !deprecatedDefinitions.length) { 11365 return block; 11366 } // By design, blocks lack any sort of version tracking. Instead, to process 11367 // outdated content the system operates a queue out of all the defined 11368 // attribute shapes and tries each definition until the input produces a 11369 // valid result. This mechanism seeks to avoid polluting the user-space with 11370 // machine-specific code. An invalid block is thus a block that could not be 11371 // matched successfully with any of the registered deprecation definitions. 11372 11373 11374 for (let i = 0; i < deprecatedDefinitions.length; i++) { 11375 // A block can opt into a migration even if the block is valid by 11376 // defining `isEligible` on its deprecation. If the block is both valid 11377 // and does not opt to migrate, skip. 11378 const { 11379 isEligible = external_lodash_namespaceObject.stubFalse 11380 } = deprecatedDefinitions[i]; 11381 11382 if (block.isValid && !isEligible(parsedAttributes, block.innerBlocks)) { 11383 continue; 11384 } // Block type properties which could impact either serialization or 11385 // parsing are not considered in the deprecated block type by default, 11386 // and must be explicitly provided. 11387 11388 11389 const deprecatedBlockType = Object.assign((0,external_lodash_namespaceObject.omit)(blockType, DEPRECATED_ENTRY_KEYS), deprecatedDefinitions[i]); 11390 let migratedBlock = { ...block, 11391 attributes: getBlockAttributes(deprecatedBlockType, block.originalContent, parsedAttributes) 11392 }; // Ignore the deprecation if it produces a block which is not valid. 11393 11394 let [isValid] = validateBlock(migratedBlock, deprecatedBlockType); // If the migrated block is not valid initially, try the built-in fixes. 11395 11396 if (!isValid) { 11397 migratedBlock = applyBuiltInValidationFixes(migratedBlock, deprecatedBlockType); 11398 [isValid] = validateBlock(migratedBlock, deprecatedBlockType); 11399 } // An invalid block does not imply incorrect HTML but the fact block 11400 // source information could be lost on re-serialization. 11401 11402 11403 if (!isValid) { 11404 continue; 11405 } 11406 11407 let migratedInnerBlocks = migratedBlock.innerBlocks; 11408 let migratedAttributes = migratedBlock.attributes; // A block may provide custom behavior to assign new attributes and/or 11409 // inner blocks. 11410 11411 const { 11412 migrate 11413 } = deprecatedBlockType; 11414 11415 if (migrate) { 11416 [migratedAttributes = parsedAttributes, migratedInnerBlocks = block.innerBlocks] = (0,external_lodash_namespaceObject.castArray)(migrate(migratedAttributes, block.innerBlocks)); 11417 } 11418 11419 block = { ...block, 11420 attributes: migratedAttributes, 11421 innerBlocks: migratedInnerBlocks, 11422 isValid: true, 11423 validationIssues: [] 11424 }; 11425 } 11426 11427 return block; 11428 } 11429 11430 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/parser/index.js 11431 /** 11432 * WordPress dependencies 11433 */ 11434 11435 11436 /** 11437 * Internal dependencies 11438 */ 11439 11440 11441 11442 11443 11444 11445 11446 11447 11448 11449 /** 11450 * The raw structure of a block includes its attributes, inner 11451 * blocks, and inner HTML. It is important to distinguish inner blocks from 11452 * the HTML content of the block as only the latter is relevant for block 11453 * validation and edit operations. 11454 * 11455 * @typedef WPRawBlock 11456 * 11457 * @property {string=} blockName Block name 11458 * @property {Object=} attrs Block raw or comment attributes. 11459 * @property {string} innerHTML HTML content of the block. 11460 * @property {(string|null)[]} innerContent Content without inner blocks. 11461 * @property {WPRawBlock[]} innerBlocks Inner Blocks. 11462 */ 11463 11464 /** 11465 * Fully parsed block object. 11466 * 11467 * @typedef WPBlock 11468 * 11469 * @property {string} name Block name 11470 * @property {Object} attributes Block raw or comment attributes. 11471 * @property {WPBlock[]} innerBlocks Inner Blocks. 11472 * @property {string} originalContent Original content of the block before validation fixes. 11473 * @property {boolean} isValid Whether the block is valid. 11474 * @property {Object[]} validationIssues Validation issues. 11475 * @property {WPRawBlock} [__unstableBlockSource] Un-processed original copy of block if created through parser. 11476 */ 11477 11478 /** 11479 * @typedef {Object} ParseOptions 11480 * @property {boolean} __unstableSkipMigrationLogs If a block is migrated from a deprecated version, skip logging the migration details. 11481 */ 11482 11483 /** 11484 * Convert legacy blocks to their canonical form. This function is used 11485 * both in the parser level for previous content and to convert such blocks 11486 * used in Custom Post Types templates. 11487 * 11488 * @param {WPRawBlock} rawBlock 11489 * 11490 * @return {WPRawBlock} The block's name and attributes, changed accordingly if a match was found 11491 */ 11492 11493 function convertLegacyBlocks(rawBlock) { 11494 const [correctName, correctedAttributes] = convertLegacyBlockNameAndAttributes(rawBlock.blockName, rawBlock.attrs); 11495 return { ...rawBlock, 11496 blockName: correctName, 11497 attrs: correctedAttributes 11498 }; 11499 } 11500 /** 11501 * Normalize the raw block by applying the fallback block name if none given, 11502 * sanitize the parsed HTML... 11503 * 11504 * @param {WPRawBlock} rawBlock The raw block object. 11505 * 11506 * @return {WPRawBlock} The normalized block object. 11507 */ 11508 11509 11510 function normalizeRawBlock(rawBlock) { 11511 const fallbackBlockName = getFreeformContentHandlerName(); // If the grammar parsing don't produce any block name, use the freeform block. 11512 11513 const rawBlockName = rawBlock.blockName || getFreeformContentHandlerName(); 11514 const rawAttributes = rawBlock.attrs || {}; 11515 const rawInnerBlocks = rawBlock.innerBlocks || []; 11516 let rawInnerHTML = rawBlock.innerHTML.trim(); // Fallback content may be upgraded from classic content expecting implicit 11517 // automatic paragraphs, so preserve them. Assumes wpautop is idempotent, 11518 // meaning there are no negative consequences to repeated autop calls. 11519 11520 if (rawBlockName === fallbackBlockName) { 11521 rawInnerHTML = (0,external_wp_autop_namespaceObject.autop)(rawInnerHTML).trim(); 11522 } 11523 11524 return { ...rawBlock, 11525 blockName: rawBlockName, 11526 attrs: rawAttributes, 11527 innerHTML: rawInnerHTML, 11528 innerBlocks: rawInnerBlocks 11529 }; 11530 } 11531 /** 11532 * Uses the "unregistered blockType" to create a block object. 11533 * 11534 * @param {WPRawBlock} rawBlock block. 11535 * 11536 * @return {WPRawBlock} The unregistered block object. 11537 */ 11538 11539 function createMissingBlockType(rawBlock) { 11540 const unregisteredFallbackBlock = getUnregisteredTypeHandlerName() || getFreeformContentHandlerName(); // Preserve undelimited content for use by the unregistered type 11541 // handler. A block node's `innerHTML` isn't enough, as that field only 11542 // carries the block's own HTML and not its nested blocks. 11543 11544 const originalUndelimitedContent = serializeRawBlock(rawBlock, { 11545 isCommentDelimited: false 11546 }); // Preserve full block content for use by the unregistered type 11547 // handler, block boundaries included. 11548 11549 const originalContent = serializeRawBlock(rawBlock, { 11550 isCommentDelimited: true 11551 }); 11552 return { 11553 blockName: unregisteredFallbackBlock, 11554 attrs: { 11555 originalName: rawBlock.blockName, 11556 originalContent, 11557 originalUndelimitedContent 11558 }, 11559 innerHTML: rawBlock.blockName ? originalContent : rawBlock.innerHTML, 11560 innerBlocks: rawBlock.innerBlocks, 11561 innerContent: rawBlock.innerContent 11562 }; 11563 } 11564 /** 11565 * Validates a block and wraps with validation meta. 11566 * 11567 * The name here is regrettable but `validateBlock` is already taken. 11568 * 11569 * @param {WPBlock} unvalidatedBlock 11570 * @param {import('../registration').WPBlockType} blockType 11571 * @return {WPBlock} validated block, with auto-fixes if initially invalid 11572 */ 11573 11574 11575 function applyBlockValidation(unvalidatedBlock, blockType) { 11576 // Attempt to validate the block. 11577 const [isValid] = validateBlock(unvalidatedBlock, blockType); 11578 11579 if (isValid) { 11580 return { ...unvalidatedBlock, 11581 isValid, 11582 validationIssues: [] 11583 }; 11584 } // If the block is invalid, attempt some built-in fixes 11585 // like custom classNames handling. 11586 11587 11588 const fixedBlock = applyBuiltInValidationFixes(unvalidatedBlock, blockType); // Attempt to validate the block once again after the built-in fixes. 11589 11590 const [isFixedValid, validationIssues] = validateBlock(unvalidatedBlock, blockType); 11591 return { ...fixedBlock, 11592 isValid: isFixedValid, 11593 validationIssues 11594 }; 11595 } 11596 /** 11597 * Given a raw block returned by grammar parsing, returns a fully parsed block. 11598 * 11599 * @param {WPRawBlock} rawBlock The raw block object. 11600 * @param {ParseOptions} options Extra options for handling block parsing. 11601 * 11602 * @return {WPBlock} Fully parsed block. 11603 */ 11604 11605 11606 function parseRawBlock(rawBlock, options) { 11607 let normalizedBlock = normalizeRawBlock(rawBlock); // During the lifecycle of the project, we renamed some old blocks 11608 // and transformed others to new blocks. To avoid breaking existing content, 11609 // we added this function to properly parse the old content. 11610 11611 normalizedBlock = convertLegacyBlocks(normalizedBlock); // Try finding the type for known block name. 11612 11613 let blockType = registration_getBlockType(normalizedBlock.blockName); // If not blockType is found for the specified name, fallback to the "unregistedBlockType". 11614 11615 if (!blockType) { 11616 normalizedBlock = createMissingBlockType(normalizedBlock); 11617 blockType = registration_getBlockType(normalizedBlock.blockName); 11618 } // If it's an empty freeform block or there's no blockType (no missing block handler) 11619 // Then, just ignore the block. 11620 // It might be a good idea to throw a warning here. 11621 // TODO: I'm unsure about the unregisteredFallbackBlock check, 11622 // it might ignore some dynamic unregistered third party blocks wrongly. 11623 11624 11625 const isFallbackBlock = normalizedBlock.blockName === getFreeformContentHandlerName() || normalizedBlock.blockName === getUnregisteredTypeHandlerName(); 11626 11627 if (!blockType || !normalizedBlock.innerHTML && isFallbackBlock) { 11628 return; 11629 } // Parse inner blocks recursively. 11630 11631 11632 const parsedInnerBlocks = normalizedBlock.innerBlocks.map(innerBlock => parseRawBlock(innerBlock, options)) // See https://github.com/WordPress/gutenberg/pull/17164. 11633 .filter(innerBlock => !!innerBlock); // Get the fully parsed block. 11634 11635 const parsedBlock = createBlock(normalizedBlock.blockName, getBlockAttributes(blockType, normalizedBlock.innerHTML, normalizedBlock.attrs), parsedInnerBlocks); 11636 parsedBlock.originalContent = normalizedBlock.innerHTML; 11637 const validatedBlock = applyBlockValidation(parsedBlock, blockType); 11638 const { 11639 validationIssues 11640 } = validatedBlock; // Run the block deprecation and migrations. 11641 // This is performed on both invalid and valid blocks because 11642 // migration using the `migrate` functions should run even 11643 // if the output is deemed valid. 11644 11645 const updatedBlock = applyBlockDeprecatedVersions(validatedBlock, normalizedBlock, blockType); 11646 11647 if (!updatedBlock.isValid) { 11648 // Preserve the original unprocessed version of the block 11649 // that we received (no fixes, no deprecations) so that 11650 // we can save it as close to exactly the same way as 11651 // we loaded it. This is important to avoid corruption 11652 // and data loss caused by block implementations trying 11653 // to process data that isn't fully recognized. 11654 updatedBlock.__unstableBlockSource = rawBlock; 11655 } 11656 11657 if (!validatedBlock.isValid && updatedBlock.isValid && !(options !== null && options !== void 0 && options.__unstableSkipMigrationLogs)) { 11658 /* eslint-disable no-console */ 11659 console.groupCollapsed('Updated Block: %s', blockType.name); 11660 console.info('Block successfully updated for `%s` (%o).\n\nNew content generated by `save` function:\n\n%s\n\nContent retrieved from post body:\n\n%s', blockType.name, blockType, getSaveContent(blockType, updatedBlock.attributes), updatedBlock.originalContent); 11661 console.groupEnd(); 11662 /* eslint-enable no-console */ 11663 } else if (!validatedBlock.isValid && !updatedBlock.isValid) { 11664 validationIssues.forEach(_ref => { 11665 let { 11666 log, 11667 args 11668 } = _ref; 11669 return log(...args); 11670 }); 11671 } 11672 11673 return updatedBlock; 11674 } 11675 /** 11676 * Utilizes an optimized token-driven parser based on the Gutenberg grammar spec 11677 * defined through a parsing expression grammar to take advantage of the regular 11678 * cadence provided by block delimiters -- composed syntactically through HTML 11679 * comments -- which, given a general HTML document as an input, returns a block 11680 * list array representation. 11681 * 11682 * This is a recursive-descent parser that scans linearly once through the input 11683 * document. Instead of directly recursing it utilizes a trampoline mechanism to 11684 * prevent stack overflow. This initial pass is mainly interested in separating 11685 * and isolating the blocks serialized in the document and manifestly not in the 11686 * content within the blocks. 11687 * 11688 * @see 11689 * https://developer.wordpress.org/block-editor/packages/packages-block-serialization-default-parser/ 11690 * 11691 * @param {string} content The post content. 11692 * @param {ParseOptions} options Extra options for handling block parsing. 11693 * 11694 * @return {Array} Block list. 11695 */ 11696 11697 function parser_parse(content, options) { 11698 return (0,external_wp_blockSerializationDefaultParser_namespaceObject.parse)(content).reduce((accumulator, rawBlock) => { 11699 const block = parseRawBlock(rawBlock, options); 11700 11701 if (block) { 11702 accumulator.push(block); 11703 } 11704 11705 return accumulator; 11706 }, []); 11707 } 11708 11709 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/get-raw-transforms.js 11710 /** 11711 * External dependencies 11712 */ 11713 11714 /** 11715 * Internal dependencies 11716 */ 11717 11718 11719 function getRawTransforms() { 11720 return (0,external_lodash_namespaceObject.filter)(getBlockTransforms('from'), { 11721 type: 'raw' 11722 }).map(transform => { 11723 return transform.isMatch ? transform : { ...transform, 11724 isMatch: node => transform.selector && node.matches(transform.selector) 11725 }; 11726 }); 11727 } 11728 11729 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/html-to-blocks.js 11730 /** 11731 * Internal dependencies 11732 */ 11733 11734 11735 11736 /** 11737 * Converts HTML directly to blocks. Looks for a matching transform for each 11738 * top-level tag. The HTML should be filtered to not have any text between 11739 * top-level tags and formatted in a way that blocks can handle the HTML. 11740 * 11741 * @param {string} html HTML to convert. 11742 * 11743 * @return {Array} An array of blocks. 11744 */ 11745 11746 function htmlToBlocks(html) { 11747 const doc = document.implementation.createHTMLDocument(''); 11748 doc.body.innerHTML = html; 11749 return Array.from(doc.body.children).flatMap(node => { 11750 const rawTransform = findTransform(getRawTransforms(), _ref => { 11751 let { 11752 isMatch 11753 } = _ref; 11754 return isMatch(node); 11755 }); 11756 11757 if (!rawTransform) { 11758 return createBlock( // Should not be hardcoded. 11759 'core/html', getBlockAttributes('core/html', node.outerHTML)); 11760 } 11761 11762 const { 11763 transform, 11764 blockName 11765 } = rawTransform; 11766 11767 if (transform) { 11768 return transform(node); 11769 } 11770 11771 return createBlock(blockName, getBlockAttributes(blockName, node.outerHTML)); 11772 }); 11773 } 11774 11775 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/normalise-blocks.js 11776 /** 11777 * WordPress dependencies 11778 */ 11779 11780 function normaliseBlocks(HTML) { 11781 const decuDoc = document.implementation.createHTMLDocument(''); 11782 const accuDoc = document.implementation.createHTMLDocument(''); 11783 const decu = decuDoc.body; 11784 const accu = accuDoc.body; 11785 decu.innerHTML = HTML; 11786 11787 while (decu.firstChild) { 11788 const node = decu.firstChild; // Text nodes: wrap in a paragraph, or append to previous. 11789 11790 if (node.nodeType === node.TEXT_NODE) { 11791 if ((0,external_wp_dom_namespaceObject.isEmpty)(node)) { 11792 decu.removeChild(node); 11793 } else { 11794 if (!accu.lastChild || accu.lastChild.nodeName !== 'P') { 11795 accu.appendChild(accuDoc.createElement('P')); 11796 } 11797 11798 accu.lastChild.appendChild(node); 11799 } // Element nodes. 11800 11801 } else if (node.nodeType === node.ELEMENT_NODE) { 11802 // BR nodes: create a new paragraph on double, or append to previous. 11803 if (node.nodeName === 'BR') { 11804 if (node.nextSibling && node.nextSibling.nodeName === 'BR') { 11805 accu.appendChild(accuDoc.createElement('P')); 11806 decu.removeChild(node.nextSibling); 11807 } // Don't append to an empty paragraph. 11808 11809 11810 if (accu.lastChild && accu.lastChild.nodeName === 'P' && accu.lastChild.hasChildNodes()) { 11811 accu.lastChild.appendChild(node); 11812 } else { 11813 decu.removeChild(node); 11814 } 11815 } else if (node.nodeName === 'P') { 11816 // Only append non-empty paragraph nodes. 11817 if ((0,external_wp_dom_namespaceObject.isEmpty)(node)) { 11818 decu.removeChild(node); 11819 } else { 11820 accu.appendChild(node); 11821 } 11822 } else if ((0,external_wp_dom_namespaceObject.isPhrasingContent)(node)) { 11823 if (!accu.lastChild || accu.lastChild.nodeName !== 'P') { 11824 accu.appendChild(accuDoc.createElement('P')); 11825 } 11826 11827 accu.lastChild.appendChild(node); 11828 } else { 11829 accu.appendChild(node); 11830 } 11831 } else { 11832 decu.removeChild(node); 11833 } 11834 } 11835 11836 return accu.innerHTML; 11837 } 11838 11839 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/special-comment-converter.js 11840 /** 11841 * WordPress dependencies 11842 */ 11843 11844 /** 11845 * Looks for `<!--nextpage-->` and `<!--more-->` comments, as well as the 11846 * `<!--more Some text-->` variant and its `<!--noteaser-->` companion, 11847 * and replaces them with a custom element representing a future block. 11848 * 11849 * The custom element is a way to bypass the rest of the `raw-handling` 11850 * transforms, which would eliminate other kinds of node with which to carry 11851 * `<!--more-->`'s data: nodes with `data` attributes, empty paragraphs, etc. 11852 * 11853 * The custom element is then expected to be recognized by any registered 11854 * block's `raw` transform. 11855 * 11856 * @param {Node} node The node to be processed. 11857 * @param {Document} doc The document of the node. 11858 * @return {void} 11859 */ 11860 11861 function specialCommentConverter(node, doc) { 11862 if (node.nodeType !== node.COMMENT_NODE) { 11863 return; 11864 } 11865 11866 if (node.nodeValue === 'nextpage') { 11867 (0,external_wp_dom_namespaceObject.replace)(node, createNextpage(doc)); 11868 return; 11869 } 11870 11871 if (node.nodeValue.indexOf('more') === 0) { 11872 // Grab any custom text in the comment. 11873 const customText = node.nodeValue.slice(4).trim(); 11874 /* 11875 * When a `<!--more-->` comment is found, we need to look for any 11876 * `<!--noteaser-->` sibling, but it may not be a direct sibling 11877 * (whitespace typically lies in between) 11878 */ 11879 11880 let sibling = node; 11881 let noTeaser = false; 11882 11883 while (sibling = sibling.nextSibling) { 11884 if (sibling.nodeType === sibling.COMMENT_NODE && sibling.nodeValue === 'noteaser') { 11885 noTeaser = true; 11886 (0,external_wp_dom_namespaceObject.remove)(sibling); 11887 break; 11888 } 11889 } 11890 11891 (0,external_wp_dom_namespaceObject.replace)(node, createMore(customText, noTeaser, doc)); 11892 } 11893 } 11894 11895 function createMore(customText, noTeaser, doc) { 11896 const node = doc.createElement('wp-block'); 11897 node.dataset.block = 'core/more'; 11898 11899 if (customText) { 11900 node.dataset.customText = customText; 11901 } 11902 11903 if (noTeaser) { 11904 // "Boolean" data attribute. 11905 node.dataset.noTeaser = ''; 11906 } 11907 11908 return node; 11909 } 11910 11911 function createNextpage(doc) { 11912 const node = doc.createElement('wp-block'); 11913 node.dataset.block = 'core/nextpage'; 11914 return node; 11915 } 11916 11917 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/list-reducer.js 11918 /** 11919 * WordPress dependencies 11920 */ 11921 11922 11923 function isList(node) { 11924 return node.nodeName === 'OL' || node.nodeName === 'UL'; 11925 } 11926 11927 function shallowTextContent(element) { 11928 return Array.from(element.childNodes).map(_ref => { 11929 let { 11930 nodeValue = '' 11931 } = _ref; 11932 return nodeValue; 11933 }).join(''); 11934 } 11935 11936 function listReducer(node) { 11937 if (!isList(node)) { 11938 return; 11939 } 11940 11941 const list = node; 11942 const prevElement = node.previousElementSibling; // Merge with previous list if: 11943 // * There is a previous list of the same type. 11944 // * There is only one list item. 11945 11946 if (prevElement && prevElement.nodeName === node.nodeName && list.children.length === 1) { 11947 // Move all child nodes, including any text nodes, if any. 11948 while (list.firstChild) { 11949 prevElement.appendChild(list.firstChild); 11950 } 11951 11952 list.parentNode.removeChild(list); 11953 } 11954 11955 const parentElement = node.parentNode; // Nested list with empty parent item. 11956 11957 if (parentElement && parentElement.nodeName === 'LI' && parentElement.children.length === 1 && !/\S/.test(shallowTextContent(parentElement))) { 11958 const parentListItem = parentElement; 11959 const prevListItem = parentListItem.previousElementSibling; 11960 const parentList = parentListItem.parentNode; 11961 11962 if (prevListItem) { 11963 prevListItem.appendChild(list); 11964 parentList.removeChild(parentListItem); 11965 } else { 11966 parentList.parentNode.insertBefore(list, parentList); 11967 parentList.parentNode.removeChild(parentList); 11968 } 11969 } // Invalid: OL/UL > OL/UL. 11970 11971 11972 if (parentElement && isList(parentElement)) { 11973 const prevListItem = node.previousElementSibling; 11974 11975 if (prevListItem) { 11976 prevListItem.appendChild(node); 11977 } else { 11978 (0,external_wp_dom_namespaceObject.unwrap)(node); 11979 } 11980 } 11981 } 11982 11983 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/blockquote-normaliser.js 11984 /** 11985 * Internal dependencies 11986 */ 11987 11988 function blockquoteNormaliser(node) { 11989 if (node.nodeName !== 'BLOCKQUOTE') { 11990 return; 11991 } 11992 11993 node.innerHTML = normaliseBlocks(node.innerHTML); 11994 } 11995 11996 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/figure-content-reducer.js 11997 /** 11998 * External dependencies 11999 */ 12000 12001 /** 12002 * WordPress dependencies 12003 */ 12004 12005 12006 /** 12007 * Whether or not the given node is figure content. 12008 * 12009 * @param {Node} node The node to check. 12010 * @param {Object} schema The schema to use. 12011 * 12012 * @return {boolean} True if figure content, false if not. 12013 */ 12014 12015 function isFigureContent(node, schema) { 12016 const tag = node.nodeName.toLowerCase(); // We are looking for tags that can be a child of the figure tag, excluding 12017 // `figcaption` and any phrasing content. 12018 12019 if (tag === 'figcaption' || (0,external_wp_dom_namespaceObject.isTextContent)(node)) { 12020 return false; 12021 } 12022 12023 return (0,external_lodash_namespaceObject.has)(schema, ['figure', 'children', tag]); 12024 } 12025 /** 12026 * Whether or not the given node can have an anchor. 12027 * 12028 * @param {Node} node The node to check. 12029 * @param {Object} schema The schema to use. 12030 * 12031 * @return {boolean} True if it can, false if not. 12032 */ 12033 12034 12035 function canHaveAnchor(node, schema) { 12036 const tag = node.nodeName.toLowerCase(); 12037 return (0,external_lodash_namespaceObject.has)(schema, ['figure', 'children', 'a', 'children', tag]); 12038 } 12039 /** 12040 * Wraps the given element in a figure element. 12041 * 12042 * @param {Element} element The element to wrap. 12043 * @param {Element} beforeElement The element before which to place the figure. 12044 */ 12045 12046 12047 function wrapFigureContent(element) { 12048 let beforeElement = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : element; 12049 const figure = element.ownerDocument.createElement('figure'); 12050 beforeElement.parentNode.insertBefore(figure, beforeElement); 12051 figure.appendChild(element); 12052 } 12053 /** 12054 * This filter takes figure content out of paragraphs, wraps it in a figure 12055 * element, and moves any anchors with it if needed. 12056 * 12057 * @param {Node} node The node to filter. 12058 * @param {Document} doc The document of the node. 12059 * @param {Object} schema The schema to use. 12060 * 12061 * @return {void} 12062 */ 12063 12064 12065 function figureContentReducer(node, doc, schema) { 12066 if (!isFigureContent(node, schema)) { 12067 return; 12068 } 12069 12070 let nodeToInsert = node; 12071 const parentNode = node.parentNode; // If the figure content can have an anchor and its parent is an anchor with 12072 // only the figure content, take the anchor out instead of just the content. 12073 12074 if (canHaveAnchor(node, schema) && parentNode.nodeName === 'A' && parentNode.childNodes.length === 1) { 12075 nodeToInsert = node.parentNode; 12076 } 12077 12078 const wrapper = nodeToInsert.closest('p,div'); // If wrapped in a paragraph or div, only extract if it's aligned or if 12079 // there is no text content. 12080 // Otherwise, if directly at the root, wrap in a figure element. 12081 12082 if (wrapper) { 12083 // In jsdom-jscore, 'node.classList' can be undefined. 12084 // In this case, default to extract as it offers a better UI experience on mobile. 12085 if (!node.classList) { 12086 wrapFigureContent(nodeToInsert, wrapper); 12087 } else if (node.classList.contains('alignright') || node.classList.contains('alignleft') || node.classList.contains('aligncenter') || !wrapper.textContent.trim()) { 12088 wrapFigureContent(nodeToInsert, wrapper); 12089 } 12090 } else if (nodeToInsert.parentNode.nodeName === 'BODY') { 12091 wrapFigureContent(nodeToInsert); 12092 } 12093 } 12094 12095 ;// CONCATENATED MODULE: external ["wp","shortcode"] 12096 var external_wp_shortcode_namespaceObject = window["wp"]["shortcode"]; 12097 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/shortcode-converter.js 12098 /** 12099 * External dependencies 12100 */ 12101 12102 /** 12103 * WordPress dependencies 12104 */ 12105 12106 12107 /** 12108 * Internal dependencies 12109 */ 12110 12111 12112 12113 12114 12115 12116 function segmentHTMLToShortcodeBlock(HTML) { 12117 let lastIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; 12118 let excludedBlockNames = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : []; 12119 // Get all matches. 12120 const transformsFrom = getBlockTransforms('from'); 12121 const transformation = findTransform(transformsFrom, transform => excludedBlockNames.indexOf(transform.blockName) === -1 && transform.type === 'shortcode' && (0,external_lodash_namespaceObject.some)((0,external_lodash_namespaceObject.castArray)(transform.tag), tag => (0,external_wp_shortcode_namespaceObject.regexp)(tag).test(HTML))); 12122 12123 if (!transformation) { 12124 return [HTML]; 12125 } 12126 12127 const transformTags = (0,external_lodash_namespaceObject.castArray)(transformation.tag); 12128 const transformTag = (0,external_lodash_namespaceObject.find)(transformTags, tag => (0,external_wp_shortcode_namespaceObject.regexp)(tag).test(HTML)); 12129 let match; 12130 const previousIndex = lastIndex; 12131 12132 if (match = (0,external_wp_shortcode_namespaceObject.next)(transformTag, HTML, lastIndex)) { 12133 lastIndex = match.index + match.content.length; 12134 const beforeHTML = HTML.substr(0, match.index); 12135 const afterHTML = HTML.substr(lastIndex); // If the shortcode content does not contain HTML and the shortcode is 12136 // not on a new line (or in paragraph from Markdown converter), 12137 // consider the shortcode as inline text, and thus skip conversion for 12138 // this segment. 12139 12140 if (!(0,external_lodash_namespaceObject.includes)(match.shortcode.content || '', '<') && !(/(\n|<p>)\s*$/.test(beforeHTML) && /^\s*(\n|<\/p>)/.test(afterHTML))) { 12141 return segmentHTMLToShortcodeBlock(HTML, lastIndex); 12142 } // If a transformation's `isMatch` predicate fails for the inbound 12143 // shortcode, try again by excluding the current block type. 12144 // 12145 // This is the only call to `segmentHTMLToShortcodeBlock` that should 12146 // ever carry over `excludedBlockNames`. Other calls in the module 12147 // should skip that argument as a way to reset the exclusion state, so 12148 // that one `isMatch` fail in an HTML fragment doesn't prevent any 12149 // valid matches in subsequent fragments. 12150 12151 12152 if (transformation.isMatch && !transformation.isMatch(match.shortcode.attrs)) { 12153 return segmentHTMLToShortcodeBlock(HTML, previousIndex, [...excludedBlockNames, transformation.blockName]); 12154 } 12155 12156 const attributes = (0,external_lodash_namespaceObject.mapValues)((0,external_lodash_namespaceObject.pickBy)(transformation.attributes, schema => schema.shortcode), // Passing all of `match` as second argument is intentionally broad 12157 // but shouldn't be too relied upon. 12158 // 12159 // See: https://github.com/WordPress/gutenberg/pull/3610#discussion_r152546926 12160 schema => schema.shortcode(match.shortcode.attrs, match)); 12161 const transformationBlockType = { ...registration_getBlockType(transformation.blockName), 12162 attributes: transformation.attributes 12163 }; 12164 let block = createBlock(transformation.blockName, getBlockAttributes(transformationBlockType, match.shortcode.content, attributes)); 12165 block.originalContent = match.shortcode.content; // Applying the built-in fixes can enhance the attributes with missing content like "className". 12166 12167 block = applyBuiltInValidationFixes(block, transformationBlockType); 12168 return [...segmentHTMLToShortcodeBlock(beforeHTML), block, ...segmentHTMLToShortcodeBlock(afterHTML)]; 12169 } 12170 12171 return [HTML]; 12172 } 12173 12174 /* harmony default export */ var shortcode_converter = (segmentHTMLToShortcodeBlock); 12175 12176 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/utils.js 12177 /** 12178 * External dependencies 12179 */ 12180 12181 /** 12182 * WordPress dependencies 12183 */ 12184 12185 12186 /** 12187 * Internal dependencies 12188 */ 12189 12190 12191 12192 function getBlockContentSchemaFromTransforms(transforms, context) { 12193 const phrasingContentSchema = (0,external_wp_dom_namespaceObject.getPhrasingContentSchema)(context); 12194 const schemaArgs = { 12195 phrasingContentSchema, 12196 isPaste: context === 'paste' 12197 }; 12198 const schemas = transforms.map(_ref => { 12199 let { 12200 isMatch, 12201 blockName, 12202 schema 12203 } = _ref; 12204 const hasAnchorSupport = registration_hasBlockSupport(blockName, 'anchor'); 12205 schema = (0,external_lodash_namespaceObject.isFunction)(schema) ? schema(schemaArgs) : schema; // If the block does not has anchor support and the transform does not 12206 // provides an isMatch we can return the schema right away. 12207 12208 if (!hasAnchorSupport && !isMatch) { 12209 return schema; 12210 } 12211 12212 return (0,external_lodash_namespaceObject.mapValues)(schema, value => { 12213 let attributes = value.attributes || []; // If the block supports the "anchor" functionality, it needs to keep its ID attribute. 12214 12215 if (hasAnchorSupport) { 12216 attributes = [...attributes, 'id']; 12217 } 12218 12219 return { ...value, 12220 attributes, 12221 isMatch: isMatch ? isMatch : undefined 12222 }; 12223 }); 12224 }); 12225 return (0,external_lodash_namespaceObject.mergeWith)({}, ...schemas, (objValue, srcValue, key) => { 12226 switch (key) { 12227 case 'children': 12228 { 12229 if (objValue === '*' || srcValue === '*') { 12230 return '*'; 12231 } 12232 12233 return { ...objValue, 12234 ...srcValue 12235 }; 12236 } 12237 12238 case 'attributes': 12239 case 'require': 12240 { 12241 return [...(objValue || []), ...(srcValue || [])]; 12242 } 12243 12244 case 'isMatch': 12245 { 12246 // If one of the values being merge is undefined (matches everything), 12247 // the result of the merge will be undefined. 12248 if (!objValue || !srcValue) { 12249 return undefined; 12250 } // When merging two isMatch functions, the result is a new function 12251 // that returns if one of the source functions returns true. 12252 12253 12254 return function () { 12255 return objValue(...arguments) || srcValue(...arguments); 12256 }; 12257 } 12258 } 12259 }); 12260 } 12261 /** 12262 * Gets the block content schema, which is extracted and merged from all 12263 * registered blocks with raw transfroms. 12264 * 12265 * @param {string} context Set to "paste" when in paste context, where the 12266 * schema is more strict. 12267 * 12268 * @return {Object} A complete block content schema. 12269 */ 12270 12271 function getBlockContentSchema(context) { 12272 return getBlockContentSchemaFromTransforms(getRawTransforms(), context); 12273 } 12274 /** 12275 * Checks whether HTML can be considered plain text. That is, it does not contain 12276 * any elements that are not line breaks. 12277 * 12278 * @param {string} HTML The HTML to check. 12279 * 12280 * @return {boolean} Whether the HTML can be considered plain text. 12281 */ 12282 12283 function isPlain(HTML) { 12284 return !/<(?!br[ />])/i.test(HTML); 12285 } 12286 /** 12287 * Given node filters, deeply filters and mutates a NodeList. 12288 * 12289 * @param {NodeList} nodeList The nodeList to filter. 12290 * @param {Array} filters An array of functions that can mutate with the provided node. 12291 * @param {Document} doc The document of the nodeList. 12292 * @param {Object} schema The schema to use. 12293 */ 12294 12295 function deepFilterNodeList(nodeList, filters, doc, schema) { 12296 Array.from(nodeList).forEach(node => { 12297 deepFilterNodeList(node.childNodes, filters, doc, schema); 12298 filters.forEach(item => { 12299 // Make sure the node is still attached to the document. 12300 if (!doc.contains(node)) { 12301 return; 12302 } 12303 12304 item(node, doc, schema); 12305 }); 12306 }); 12307 } 12308 /** 12309 * Given node filters, deeply filters HTML tags. 12310 * Filters from the deepest nodes to the top. 12311 * 12312 * @param {string} HTML The HTML to filter. 12313 * @param {Array} filters An array of functions that can mutate with the provided node. 12314 * @param {Object} schema The schema to use. 12315 * 12316 * @return {string} The filtered HTML. 12317 */ 12318 12319 function deepFilterHTML(HTML) { 12320 let filters = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; 12321 let schema = arguments.length > 2 ? arguments[2] : undefined; 12322 const doc = document.implementation.createHTMLDocument(''); 12323 doc.body.innerHTML = HTML; 12324 deepFilterNodeList(doc.body.childNodes, filters, doc, schema); 12325 return doc.body.innerHTML; 12326 } 12327 /** 12328 * Gets a sibling within text-level context. 12329 * 12330 * @param {Element} node The subject node. 12331 * @param {string} which "next" or "previous". 12332 */ 12333 12334 function getSibling(node, which) { 12335 const sibling = node[`$which}Sibling`]; 12336 12337 if (sibling && (0,external_wp_dom_namespaceObject.isPhrasingContent)(sibling)) { 12338 return sibling; 12339 } 12340 12341 const { 12342 parentNode 12343 } = node; 12344 12345 if (!parentNode || !(0,external_wp_dom_namespaceObject.isPhrasingContent)(parentNode)) { 12346 return; 12347 } 12348 12349 return getSibling(parentNode, which); 12350 } 12351 12352 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/index.js 12353 /** 12354 * External dependencies 12355 */ 12356 12357 /** 12358 * WordPress dependencies 12359 */ 12360 12361 12362 12363 /** 12364 * Internal dependencies 12365 */ 12366 12367 12368 12369 12370 12371 12372 12373 12374 12375 12376 12377 function deprecatedGetPhrasingContentSchema(context) { 12378 external_wp_deprecated_default()('wp.blocks.getPhrasingContentSchema', { 12379 since: '5.6', 12380 alternative: 'wp.dom.getPhrasingContentSchema' 12381 }); 12382 return (0,external_wp_dom_namespaceObject.getPhrasingContentSchema)(context); 12383 } 12384 /** 12385 * Converts an HTML string to known blocks. 12386 * 12387 * @param {Object} $1 12388 * @param {string} $1.HTML The HTML to convert. 12389 * 12390 * @return {Array} A list of blocks. 12391 */ 12392 12393 function rawHandler(_ref) { 12394 let { 12395 HTML = '' 12396 } = _ref; 12397 12398 // If we detect block delimiters, parse entirely as blocks. 12399 if (HTML.indexOf('<!-- wp:') !== -1) { 12400 return parser_parse(HTML); 12401 } // An array of HTML strings and block objects. The blocks replace matched 12402 // shortcodes. 12403 12404 12405 const pieces = shortcode_converter(HTML); 12406 const blockContentSchema = getBlockContentSchema(); 12407 return (0,external_lodash_namespaceObject.compact)((0,external_lodash_namespaceObject.flatMap)(pieces, piece => { 12408 // Already a block from shortcode. 12409 if (typeof piece !== 'string') { 12410 return piece; 12411 } // These filters are essential for some blocks to be able to transform 12412 // from raw HTML. These filters move around some content or add 12413 // additional tags, they do not remove any content. 12414 12415 12416 const filters = [// Needed to adjust invalid lists. 12417 listReducer, // Needed to create more and nextpage blocks. 12418 specialCommentConverter, // Needed to create media blocks. 12419 figureContentReducer, // Needed to create the quote block, which cannot handle text 12420 // without wrapper paragraphs. 12421 blockquoteNormaliser]; 12422 piece = deepFilterHTML(piece, filters, blockContentSchema); 12423 piece = normaliseBlocks(piece); 12424 return htmlToBlocks(piece); 12425 })); 12426 } 12427 12428 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/comment-remover.js 12429 /** 12430 * WordPress dependencies 12431 */ 12432 12433 /** 12434 * Looks for comments, and removes them. 12435 * 12436 * @param {Node} node The node to be processed. 12437 * @return {void} 12438 */ 12439 12440 function commentRemover(node) { 12441 if (node.nodeType === node.COMMENT_NODE) { 12442 (0,external_wp_dom_namespaceObject.remove)(node); 12443 } 12444 } 12445 12446 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/is-inline-content.js 12447 /** 12448 * External dependencies 12449 */ 12450 12451 /** 12452 * WordPress dependencies 12453 */ 12454 12455 12456 /** 12457 * Checks if the given node should be considered inline content, optionally 12458 * depending on a context tag. 12459 * 12460 * @param {Node} node Node name. 12461 * @param {string} contextTag Tag name. 12462 * 12463 * @return {boolean} True if the node is inline content, false if nohe. 12464 */ 12465 12466 function isInline(node, contextTag) { 12467 if ((0,external_wp_dom_namespaceObject.isTextContent)(node)) { 12468 return true; 12469 } 12470 12471 if (!contextTag) { 12472 return false; 12473 } 12474 12475 const tag = node.nodeName.toLowerCase(); 12476 const inlineAllowedTagGroups = [['ul', 'li', 'ol'], ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']]; 12477 return inlineAllowedTagGroups.some(tagGroup => (0,external_lodash_namespaceObject.difference)([tag, contextTag], tagGroup).length === 0); 12478 } 12479 12480 function deepCheck(nodes, contextTag) { 12481 return nodes.every(node => isInline(node, contextTag) && deepCheck(Array.from(node.children), contextTag)); 12482 } 12483 12484 function isDoubleBR(node) { 12485 return node.nodeName === 'BR' && node.previousSibling && node.previousSibling.nodeName === 'BR'; 12486 } 12487 12488 function isInlineContent(HTML, contextTag) { 12489 const doc = document.implementation.createHTMLDocument(''); 12490 doc.body.innerHTML = HTML; 12491 const nodes = Array.from(doc.body.children); 12492 return !nodes.some(isDoubleBR) && deepCheck(nodes, contextTag); 12493 } 12494 12495 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/phrasing-content-reducer.js 12496 /** 12497 * External dependencies 12498 */ 12499 12500 /** 12501 * WordPress dependencies 12502 */ 12503 12504 12505 function phrasingContentReducer(node, doc) { 12506 // In jsdom-jscore, 'node.style' can be null. 12507 // TODO: Explore fixing this by patching jsdom-jscore. 12508 if (node.nodeName === 'SPAN' && node.style) { 12509 const { 12510 fontWeight, 12511 fontStyle, 12512 textDecorationLine, 12513 textDecoration, 12514 verticalAlign 12515 } = node.style; 12516 12517 if (fontWeight === 'bold' || fontWeight === '700') { 12518 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('strong'), node); 12519 } 12520 12521 if (fontStyle === 'italic') { 12522 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('em'), node); 12523 } // Some DOM implementations (Safari, JSDom) don't support 12524 // style.textDecorationLine, so we check style.textDecoration as a 12525 // fallback. 12526 12527 12528 if (textDecorationLine === 'line-through' || (0,external_lodash_namespaceObject.includes)(textDecoration, 'line-through')) { 12529 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('s'), node); 12530 } 12531 12532 if (verticalAlign === 'super') { 12533 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('sup'), node); 12534 } else if (verticalAlign === 'sub') { 12535 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('sub'), node); 12536 } 12537 } else if (node.nodeName === 'B') { 12538 node = (0,external_wp_dom_namespaceObject.replaceTag)(node, 'strong'); 12539 } else if (node.nodeName === 'I') { 12540 node = (0,external_wp_dom_namespaceObject.replaceTag)(node, 'em'); 12541 } else if (node.nodeName === 'A') { 12542 // In jsdom-jscore, 'node.target' can be null. 12543 // TODO: Explore fixing this by patching jsdom-jscore. 12544 if (node.target && node.target.toLowerCase() === '_blank') { 12545 node.rel = 'noreferrer noopener'; 12546 } else { 12547 node.removeAttribute('target'); 12548 node.removeAttribute('rel'); 12549 } // Saves anchor elements name attribute as id 12550 12551 12552 if (node.name && !node.id) { 12553 node.id = node.name; 12554 } // Keeps id only if there is an internal link pointing to it 12555 12556 12557 if (node.id && !node.ownerDocument.querySelector(`[href="#$node.id}"]`)) { 12558 node.removeAttribute('id'); 12559 } 12560 } 12561 } 12562 12563 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/head-remover.js 12564 function headRemover(node) { 12565 if (node.nodeName !== 'SCRIPT' && node.nodeName !== 'NOSCRIPT' && node.nodeName !== 'TEMPLATE' && node.nodeName !== 'STYLE') { 12566 return; 12567 } 12568 12569 node.parentNode.removeChild(node); 12570 } 12571 12572 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/ms-list-converter.js 12573 /** 12574 * Browser dependencies 12575 */ 12576 const { 12577 parseInt: ms_list_converter_parseInt 12578 } = window; 12579 12580 function ms_list_converter_isList(node) { 12581 return node.nodeName === 'OL' || node.nodeName === 'UL'; 12582 } 12583 12584 function msListConverter(node, doc) { 12585 if (node.nodeName !== 'P') { 12586 return; 12587 } 12588 12589 const style = node.getAttribute('style'); 12590 12591 if (!style) { 12592 return; 12593 } // Quick check. 12594 12595 12596 if (style.indexOf('mso-list') === -1) { 12597 return; 12598 } 12599 12600 const matches = /mso-list\s*:[^;]+level([0-9]+)/i.exec(style); 12601 12602 if (!matches) { 12603 return; 12604 } 12605 12606 let level = ms_list_converter_parseInt(matches[1], 10) - 1 || 0; 12607 const prevNode = node.previousElementSibling; // Add new list if no previous. 12608 12609 if (!prevNode || !ms_list_converter_isList(prevNode)) { 12610 // See https://html.spec.whatwg.org/multipage/grouping-content.html#attr-ol-type. 12611 const type = node.textContent.trim().slice(0, 1); 12612 const isNumeric = /[1iIaA]/.test(type); 12613 const newListNode = doc.createElement(isNumeric ? 'ol' : 'ul'); 12614 12615 if (isNumeric) { 12616 newListNode.setAttribute('type', type); 12617 } 12618 12619 node.parentNode.insertBefore(newListNode, node); 12620 } 12621 12622 const listNode = node.previousElementSibling; 12623 const listType = listNode.nodeName; 12624 const listItem = doc.createElement('li'); 12625 let receivingNode = listNode; // Remove the first span with list info. 12626 12627 node.removeChild(node.firstChild); // Add content. 12628 12629 while (node.firstChild) { 12630 listItem.appendChild(node.firstChild); 12631 } // Change pointer depending on indentation level. 12632 12633 12634 while (level--) { 12635 receivingNode = receivingNode.lastChild || receivingNode; // If it's a list, move pointer to the last item. 12636 12637 if (ms_list_converter_isList(receivingNode)) { 12638 receivingNode = receivingNode.lastChild || receivingNode; 12639 } 12640 } // Make sure we append to a list. 12641 12642 12643 if (!ms_list_converter_isList(receivingNode)) { 12644 receivingNode = receivingNode.appendChild(doc.createElement(listType)); 12645 } // Append the list item to the list. 12646 12647 12648 receivingNode.appendChild(listItem); // Remove the wrapper paragraph. 12649 12650 node.parentNode.removeChild(node); 12651 } 12652 12653 ;// CONCATENATED MODULE: external ["wp","blob"] 12654 var external_wp_blob_namespaceObject = window["wp"]["blob"]; 12655 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/image-corrector.js 12656 /** 12657 * WordPress dependencies 12658 */ 12659 12660 /** 12661 * Browser dependencies 12662 */ 12663 12664 const { 12665 atob, 12666 File 12667 } = window; 12668 function imageCorrector(node) { 12669 if (node.nodeName !== 'IMG') { 12670 return; 12671 } 12672 12673 if (node.src.indexOf('file:') === 0) { 12674 node.src = ''; 12675 } // This piece cannot be tested outside a browser env. 12676 12677 12678 if (node.src.indexOf('data:') === 0) { 12679 const [properties, data] = node.src.split(','); 12680 const [type] = properties.slice(5).split(';'); 12681 12682 if (!data || !type) { 12683 node.src = ''; 12684 return; 12685 } 12686 12687 let decoded; // Can throw DOMException! 12688 12689 try { 12690 decoded = atob(data); 12691 } catch (e) { 12692 node.src = ''; 12693 return; 12694 } 12695 12696 const uint8Array = new Uint8Array(decoded.length); 12697 12698 for (let i = 0; i < uint8Array.length; i++) { 12699 uint8Array[i] = decoded.charCodeAt(i); 12700 } 12701 12702 const name = type.replace('/', '.'); 12703 const file = new File([uint8Array], name, { 12704 type 12705 }); 12706 node.src = (0,external_wp_blob_namespaceObject.createBlobURL)(file); 12707 } // Remove trackers and hardly visible images. 12708 12709 12710 if (node.height === 1 || node.width === 1) { 12711 node.parentNode.removeChild(node); 12712 } 12713 } 12714 12715 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/div-normaliser.js 12716 /** 12717 * Internal dependencies 12718 */ 12719 12720 function divNormaliser(node) { 12721 if (node.nodeName !== 'DIV') { 12722 return; 12723 } 12724 12725 node.innerHTML = normaliseBlocks(node.innerHTML); 12726 } 12727 12728 // EXTERNAL MODULE: ./node_modules/showdown/dist/showdown.js 12729 var showdown = __webpack_require__(7308); 12730 var showdown_default = /*#__PURE__*/__webpack_require__.n(showdown); 12731 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/markdown-converter.js 12732 /** 12733 * External dependencies 12734 */ 12735 // Reuse the same showdown converter. 12736 12737 const converter = new (showdown_default()).Converter({ 12738 noHeaderId: true, 12739 tables: true, 12740 literalMidWordUnderscores: true, 12741 omitExtraWLInCodeBlocks: true, 12742 simpleLineBreaks: true, 12743 strikethrough: true 12744 }); 12745 /** 12746 * Corrects the Slack Markdown variant of the code block. 12747 * If uncorrected, it will be converted to inline code. 12748 * 12749 * @see https://get.slack.help/hc/en-us/articles/202288908-how-can-i-add-formatting-to-my-messages-#code-blocks 12750 * 12751 * @param {string} text The potential Markdown text to correct. 12752 * 12753 * @return {string} The corrected Markdown. 12754 */ 12755 12756 function slackMarkdownVariantCorrector(text) { 12757 return text.replace(/((?:^|\n)```)([^\n`]+)(```(?:$|\n))/, (match, p1, p2, p3) => `$p1}\n$p2}\n$p3}`); 12758 } 12759 /** 12760 * Converts a piece of text into HTML based on any Markdown present. 12761 * Also decodes any encoded HTML. 12762 * 12763 * @param {string} text The plain text to convert. 12764 * 12765 * @return {string} HTML. 12766 */ 12767 12768 12769 function markdownConverter(text) { 12770 return converter.makeHtml(slackMarkdownVariantCorrector(text)); 12771 } 12772 12773 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/iframe-remover.js 12774 /** 12775 * Removes iframes. 12776 * 12777 * @param {Node} node The node to check. 12778 * 12779 * @return {void} 12780 */ 12781 function iframeRemover(node) { 12782 if (node.nodeName === 'IFRAME') { 12783 const text = node.ownerDocument.createTextNode(node.src); 12784 node.parentNode.replaceChild(text, node); 12785 } 12786 } 12787 12788 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/google-docs-uid-remover.js 12789 /** 12790 * WordPress dependencies 12791 */ 12792 12793 function googleDocsUIdRemover(node) { 12794 if (!node.id || node.id.indexOf('docs-internal-guid-') !== 0) { 12795 return; 12796 } 12797 12798 (0,external_wp_dom_namespaceObject.unwrap)(node); 12799 } 12800 12801 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/html-formatting-remover.js 12802 /** 12803 * Internal dependencies 12804 */ 12805 12806 12807 function isFormattingSpace(character) { 12808 return character === ' ' || character === '\r' || character === '\n' || character === '\t'; 12809 } 12810 /** 12811 * Removes spacing that formats HTML. 12812 * 12813 * @see https://www.w3.org/TR/css-text-3/#white-space-processing 12814 * 12815 * @param {Node} node The node to be processed. 12816 * @return {void} 12817 */ 12818 12819 12820 function htmlFormattingRemover(node) { 12821 if (node.nodeType !== node.TEXT_NODE) { 12822 return; 12823 } // Ignore pre content. Note that this does not use Element#closest due to 12824 // a combination of (a) node may not be Element and (b) node.parentElement 12825 // does not have full support in all browsers (Internet Exporer). 12826 // 12827 // See: https://developer.mozilla.org/en-US/docs/Web/API/Node/parentElement#Browser_compatibility 12828 12829 /** @type {Node?} */ 12830 12831 12832 let parent = node; 12833 12834 while (parent = parent.parentNode) { 12835 if (parent.nodeType === parent.ELEMENT_NODE && parent.nodeName === 'PRE') { 12836 return; 12837 } 12838 } // First, replace any sequence of HTML formatting space with a single space. 12839 12840 12841 let newData = node.data.replace(/[ \r\n\t]+/g, ' '); // Remove the leading space if the text element is at the start of a block, 12842 // is preceded by a line break element, or has a space in the previous 12843 // node. 12844 12845 if (newData[0] === ' ') { 12846 const previousSibling = getSibling(node, 'previous'); 12847 12848 if (!previousSibling || previousSibling.nodeName === 'BR' || previousSibling.textContent.slice(-1) === ' ') { 12849 newData = newData.slice(1); 12850 } 12851 } // Remove the trailing space if the text element is at the end of a block, 12852 // is succeded by a line break element, or has a space in the next text 12853 // node. 12854 12855 12856 if (newData[newData.length - 1] === ' ') { 12857 const nextSibling = getSibling(node, 'next'); 12858 12859 if (!nextSibling || nextSibling.nodeName === 'BR' || nextSibling.nodeType === nextSibling.TEXT_NODE && isFormattingSpace(nextSibling.textContent[0])) { 12860 newData = newData.slice(0, -1); 12861 } 12862 } // If there's no data left, remove the node, so `previousSibling` stays 12863 // accurate. Otherwise, update the node data. 12864 12865 12866 if (!newData) { 12867 node.parentNode.removeChild(node); 12868 } else { 12869 node.data = newData; 12870 } 12871 } 12872 12873 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/br-remover.js 12874 /** 12875 * Internal dependencies 12876 */ 12877 12878 /** 12879 * Removes trailing br elements from text-level content. 12880 * 12881 * @param {Element} node Node to check. 12882 */ 12883 12884 function brRemover(node) { 12885 if (node.nodeName !== 'BR') { 12886 return; 12887 } 12888 12889 if (getSibling(node, 'next')) { 12890 return; 12891 } 12892 12893 node.parentNode.removeChild(node); 12894 } 12895 12896 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/empty-paragraph-remover.js 12897 /** 12898 * Removes empty paragraph elements. 12899 * 12900 * @param {Element} node Node to check. 12901 */ 12902 function emptyParagraphRemover(node) { 12903 if (node.nodeName !== 'P') { 12904 return; 12905 } 12906 12907 if (node.hasChildNodes()) { 12908 return; 12909 } 12910 12911 node.parentNode.removeChild(node); 12912 } 12913 12914 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/raw-handling/paste-handler.js 12915 /** 12916 * External dependencies 12917 */ 12918 12919 /** 12920 * WordPress dependencies 12921 */ 12922 12923 12924 /** 12925 * Internal dependencies 12926 */ 12927 12928 12929 12930 12931 12932 12933 12934 12935 12936 12937 12938 12939 12940 12941 12942 12943 12944 12945 12946 12947 12948 12949 12950 12951 12952 /** 12953 * Browser dependencies 12954 */ 12955 12956 const { 12957 console: paste_handler_console 12958 } = window; 12959 /** 12960 * Filters HTML to only contain phrasing content. 12961 * 12962 * @param {string} HTML The HTML to filter. 12963 * @param {boolean} preserveWhiteSpace Whether or not to preserve consequent white space. 12964 * 12965 * @return {string} HTML only containing phrasing content. 12966 */ 12967 12968 function filterInlineHTML(HTML, preserveWhiteSpace) { 12969 HTML = deepFilterHTML(HTML, [googleDocsUIdRemover, phrasingContentReducer, commentRemover]); 12970 HTML = (0,external_wp_dom_namespaceObject.removeInvalidHTML)(HTML, (0,external_wp_dom_namespaceObject.getPhrasingContentSchema)('paste'), { 12971 inline: true 12972 }); 12973 12974 if (!preserveWhiteSpace) { 12975 HTML = deepFilterHTML(HTML, [htmlFormattingRemover, brRemover]); 12976 } // Allows us to ask for this information when we get a report. 12977 12978 12979 paste_handler_console.log('Processed inline HTML:\n\n', HTML); 12980 return HTML; 12981 } 12982 /** 12983 * Converts an HTML string to known blocks. Strips everything else. 12984 * 12985 * @param {Object} options 12986 * @param {string} [options.HTML] The HTML to convert. 12987 * @param {string} [options.plainText] Plain text version. 12988 * @param {string} [options.mode] Handle content as blocks or inline content. 12989 * * 'AUTO': Decide based on the content passed. 12990 * * 'INLINE': Always handle as inline content, and return string. 12991 * * 'BLOCKS': Always handle as blocks, and return array of blocks. 12992 * @param {Array} [options.tagName] The tag into which content will be inserted. 12993 * @param {boolean} [options.preserveWhiteSpace] Whether or not to preserve consequent white space. 12994 * 12995 * @return {Array|string} A list of blocks or a string, depending on `handlerMode`. 12996 */ 12997 12998 12999 function pasteHandler(_ref) { 13000 let { 13001 HTML = '', 13002 plainText = '', 13003 mode = 'AUTO', 13004 tagName, 13005 preserveWhiteSpace 13006 } = _ref; 13007 // First of all, strip any meta tags. 13008 HTML = HTML.replace(/<meta[^>]+>/g, ''); // Strip Windows markers. 13009 13010 HTML = HTML.replace(/^\s*<html[^>]*>\s*<body[^>]*>(?:\s*<!--\s*StartFragment\s*-->)?/i, ''); 13011 HTML = HTML.replace(/(?:<!--\s*EndFragment\s*-->\s*)?<\/body>\s*<\/html>\s*$/i, ''); // If we detect block delimiters in HTML, parse entirely as blocks. 13012 13013 if (mode !== 'INLINE') { 13014 // Check plain text if there is no HTML. 13015 const content = HTML ? HTML : plainText; 13016 13017 if (content.indexOf('<!-- wp:') !== -1) { 13018 return parser_parse(content); 13019 } 13020 } // Normalize unicode to use composed characters. 13021 // This is unsupported in IE 11 but it's a nice-to-have feature, not mandatory. 13022 // Not normalizing the content will only affect older browsers and won't 13023 // entirely break the app. 13024 // See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize 13025 // See: https://core.trac.wordpress.org/ticket/30130 13026 // See: https://github.com/WordPress/gutenberg/pull/6983#pullrequestreview-125151075 13027 13028 13029 if (String.prototype.normalize) { 13030 HTML = HTML.normalize(); 13031 } // Parse Markdown (and encoded HTML) if: 13032 // * There is a plain text version. 13033 // * There is no HTML version, or it has no formatting. 13034 13035 13036 if (plainText && (!HTML || isPlain(HTML))) { 13037 HTML = plainText; // The markdown converter (Showdown) trims whitespace. 13038 13039 if (!/^\s+$/.test(plainText)) { 13040 HTML = markdownConverter(HTML); 13041 } // Switch to inline mode if: 13042 // * The current mode is AUTO. 13043 // * The original plain text had no line breaks. 13044 // * The original plain text was not an HTML paragraph. 13045 // * The converted text is just a paragraph. 13046 13047 13048 if (mode === 'AUTO' && plainText.indexOf('\n') === -1 && plainText.indexOf('<p>') !== 0 && HTML.indexOf('<p>') === 0) { 13049 mode = 'INLINE'; 13050 } 13051 } 13052 13053 if (mode === 'INLINE') { 13054 return filterInlineHTML(HTML, preserveWhiteSpace); 13055 } // An array of HTML strings and block objects. The blocks replace matched 13056 // shortcodes. 13057 13058 13059 const pieces = shortcode_converter(HTML); // The call to shortcodeConverter will always return more than one element 13060 // if shortcodes are matched. The reason is when shortcodes are matched 13061 // empty HTML strings are included. 13062 13063 const hasShortcodes = pieces.length > 1; 13064 13065 if (mode === 'AUTO' && !hasShortcodes && isInlineContent(HTML, tagName)) { 13066 return filterInlineHTML(HTML, preserveWhiteSpace); 13067 } 13068 13069 const phrasingContentSchema = (0,external_wp_dom_namespaceObject.getPhrasingContentSchema)('paste'); 13070 const blockContentSchema = getBlockContentSchema('paste'); 13071 const blocks = (0,external_lodash_namespaceObject.compact)((0,external_lodash_namespaceObject.flatMap)(pieces, piece => { 13072 // Already a block from shortcode. 13073 if (typeof piece !== 'string') { 13074 return piece; 13075 } 13076 13077 const filters = [googleDocsUIdRemover, msListConverter, headRemover, listReducer, imageCorrector, phrasingContentReducer, specialCommentConverter, commentRemover, iframeRemover, figureContentReducer, blockquoteNormaliser, divNormaliser]; 13078 const schema = { ...blockContentSchema, 13079 // Keep top-level phrasing content, normalised by `normaliseBlocks`. 13080 ...phrasingContentSchema 13081 }; 13082 piece = deepFilterHTML(piece, filters, blockContentSchema); 13083 piece = (0,external_wp_dom_namespaceObject.removeInvalidHTML)(piece, schema); 13084 piece = normaliseBlocks(piece); 13085 piece = deepFilterHTML(piece, [htmlFormattingRemover, brRemover, emptyParagraphRemover], blockContentSchema); // Allows us to ask for this information when we get a report. 13086 13087 paste_handler_console.log('Processed HTML piece:\n\n', piece); 13088 return htmlToBlocks(piece); 13089 })); // If we're allowed to return inline content, and there is only one 13090 // inlineable block, and the original plain text content does not have any 13091 // line breaks, then treat it as inline paste. 13092 13093 if (mode === 'AUTO' && blocks.length === 1 && registration_hasBlockSupport(blocks[0].name, '__unstablePasteTextInline', false)) { 13094 // Don't catch line breaks at the start or end. 13095 const trimmedPlainText = plainText.replace(/^[\n]+|[\n]+$/g, ''); 13096 13097 if (trimmedPlainText !== '' && trimmedPlainText.indexOf('\n') === -1) { 13098 return (0,external_wp_dom_namespaceObject.removeInvalidHTML)(getBlockInnerHTML(blocks[0]), phrasingContentSchema); 13099 } 13100 } 13101 13102 return blocks; 13103 } 13104 13105 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/categories.js 13106 /** 13107 * WordPress dependencies 13108 */ 13109 13110 /** 13111 * Internal dependencies 13112 */ 13113 13114 13115 /** @typedef {import('../store/reducer').WPBlockCategory} WPBlockCategory */ 13116 13117 /** 13118 * Returns all the block categories. 13119 * 13120 * @return {WPBlockCategory[]} Block categories. 13121 */ 13122 13123 function categories_getCategories() { 13124 return (0,external_wp_data_namespaceObject.select)(store).getCategories(); 13125 } 13126 /** 13127 * Sets the block categories. 13128 * 13129 * @param {WPBlockCategory[]} categories Block categories. 13130 */ 13131 13132 function categories_setCategories(categories) { 13133 (0,external_wp_data_namespaceObject.dispatch)(store).setCategories(categories); 13134 } 13135 /** 13136 * Updates a category. 13137 * 13138 * @param {string} slug Block category slug. 13139 * @param {WPBlockCategory} category Object containing the category properties 13140 * that should be updated. 13141 */ 13142 13143 function categories_updateCategory(slug, category) { 13144 (0,external_wp_data_namespaceObject.dispatch)(store).updateCategory(slug, category); 13145 } 13146 13147 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/templates.js 13148 /** 13149 * External dependencies 13150 */ 13151 13152 /** 13153 * WordPress dependencies 13154 */ 13155 13156 13157 /** 13158 * Internal dependencies 13159 */ 13160 13161 13162 13163 13164 /** 13165 * Checks whether a list of blocks matches a template by comparing the block names. 13166 * 13167 * @param {Array} blocks Block list. 13168 * @param {Array} template Block template. 13169 * 13170 * @return {boolean} Whether the list of blocks matches a templates. 13171 */ 13172 13173 function doBlocksMatchTemplate() { 13174 let blocks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 13175 let template = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; 13176 return blocks.length === template.length && (0,external_lodash_namespaceObject.every)(template, (_ref, index) => { 13177 let [name,, innerBlocksTemplate] = _ref; 13178 const block = blocks[index]; 13179 return name === block.name && doBlocksMatchTemplate(block.innerBlocks, innerBlocksTemplate); 13180 }); 13181 } 13182 /** 13183 * Synchronize a block list with a block template. 13184 * 13185 * Synchronizing a block list with a block template means that we loop over the blocks 13186 * keep the block as is if it matches the block at the same position in the template 13187 * (If it has the same name) and if doesn't match, we create a new block based on the template. 13188 * Extra blocks not present in the template are removed. 13189 * 13190 * @param {Array} blocks Block list. 13191 * @param {Array} template Block template. 13192 * 13193 * @return {Array} Updated Block list. 13194 */ 13195 13196 function synchronizeBlocksWithTemplate() { 13197 let blocks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 13198 let template = arguments.length > 1 ? arguments[1] : undefined; 13199 13200 // If no template is provided, return blocks unmodified. 13201 if (!template) { 13202 return blocks; 13203 } 13204 13205 return (0,external_lodash_namespaceObject.map)(template, (_ref2, index) => { 13206 let [name, attributes, innerBlocksTemplate] = _ref2; 13207 const block = blocks[index]; 13208 13209 if (block && block.name === name) { 13210 const innerBlocks = synchronizeBlocksWithTemplate(block.innerBlocks, innerBlocksTemplate); 13211 return { ...block, 13212 innerBlocks 13213 }; 13214 } // To support old templates that were using the "children" format 13215 // for the attributes using "html" strings now, we normalize the template attributes 13216 // before creating the blocks. 13217 13218 13219 const blockType = registration_getBlockType(name); 13220 13221 const isHTMLAttribute = attributeDefinition => (0,external_lodash_namespaceObject.get)(attributeDefinition, ['source']) === 'html'; 13222 13223 const isQueryAttribute = attributeDefinition => (0,external_lodash_namespaceObject.get)(attributeDefinition, ['source']) === 'query'; 13224 13225 const normalizeAttributes = (schema, values) => { 13226 return (0,external_lodash_namespaceObject.mapValues)(values, (value, key) => { 13227 return normalizeAttribute(schema[key], value); 13228 }); 13229 }; 13230 13231 const normalizeAttribute = (definition, value) => { 13232 if (isHTMLAttribute(definition) && (0,external_lodash_namespaceObject.isArray)(value)) { 13233 // Introduce a deprecated call at this point 13234 // When we're confident that "children" format should be removed from the templates. 13235 return (0,external_wp_element_namespaceObject.renderToString)(value); 13236 } 13237 13238 if (isQueryAttribute(definition) && value) { 13239 return value.map(subValues => { 13240 return normalizeAttributes(definition.query, subValues); 13241 }); 13242 } 13243 13244 return value; 13245 }; 13246 13247 const normalizedAttributes = normalizeAttributes((0,external_lodash_namespaceObject.get)(blockType, ['attributes'], {}), attributes); 13248 let [blockName, blockAttributes] = convertLegacyBlockNameAndAttributes(name, normalizedAttributes); // If a Block is undefined at this point, use the core/missing block as 13249 // a placeholder for a better user experience. 13250 13251 if (undefined === registration_getBlockType(blockName)) { 13252 blockAttributes = { 13253 originalName: name, 13254 originalContent: '', 13255 originalUndelimitedContent: '' 13256 }; 13257 blockName = 'core/missing'; 13258 } 13259 13260 return createBlock(blockName, blockAttributes, synchronizeBlocksWithTemplate([], innerBlocksTemplate)); 13261 }); 13262 } 13263 13264 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/api/index.js 13265 // The blocktype is the most important concept within the block API. It defines 13266 // all aspects of the block configuration and its interfaces, including `edit` 13267 // and `save`. The transforms specification allows converting one blocktype to 13268 // another through formulas defined by either the source or the destination. 13269 // Switching a blocktype is to be considered a one-way operation implying a 13270 // transformation in the opposite way has to be handled explicitly. 13271 // The block tree is composed of a collection of block nodes. Blocks contained 13272 // within other blocks are called inner blocks. An important design 13273 // consideration is that inner blocks are -- conceptually -- not part of the 13274 // territory established by the parent block that contains them. 13275 // 13276 // This has multiple practical implications: when parsing, we can safely dispose 13277 // of any block boundary found within a block from the innerHTML property when 13278 // transfering to state. Not doing so would have a compounding effect on memory 13279 // and uncertainty over the source of truth. This can be illustrated in how, 13280 // given a tree of `n` nested blocks, the entry node would have to contain the 13281 // actual content of each block while each subsequent block node in the state 13282 // tree would replicate the entire chain `n-1`, meaning the extreme end node 13283 // would have been replicated `n` times as the tree is traversed and would 13284 // generate uncertainty as to which one is to hold the current value of the 13285 // block. For composition, it also means inner blocks can effectively be child 13286 // components whose mechanisms can be shielded from the `edit` implementation 13287 // and just passed along. 13288 13289 13290 13291 // While block transformations account for a specific surface of the API, there 13292 // are also raw transformations which handle arbitrary sources not made out of 13293 // blocks but producing block basaed on various heursitics. This includes 13294 // pasting rich text or HTML data. 13295 13296 // The process of serialization aims to deflate the internal memory of the block 13297 // editor and its state representation back into an HTML valid string. This 13298 // process restores the document integrity and inserts invisible delimiters 13299 // around each block with HTML comment boundaries which can contain any extra 13300 // attributes needed to operate with the block later on. 13301 13302 // Validation is the process of comparing a block source with its output before 13303 // there is any user input or interaction with a block. When this operation 13304 // fails -- for whatever reason -- the block is to be considered invalid. As 13305 // part of validating a block the system will attempt to run the source against 13306 // any provided deprecation definitions. 13307 // 13308 // Worth emphasizing that validation is not a case of whether the markup is 13309 // merely HTML spec-compliant but about how the editor knows to create such 13310 // markup and that its inability to create an identical result can be a strong 13311 // indicator of potential data loss (the invalidation is then a protective 13312 // measure). 13313 // 13314 // The invalidation process can also be deconstructed in phases: 1) validate the 13315 // block exists; 2) validate the source matches the output; 3) validate the 13316 // source matches deprecated outputs; 4) work through the significance of 13317 // differences. These are stacked in a way that favors performance and optimizes 13318 // for the majority of cases. That is to say, the evaluation logic can become 13319 // more sophisticated the further down it goes in the process as the cost is 13320 // accounted for. The first logic checks have to be extremely efficient since 13321 // they will be run for all valid and invalid blocks alike. However, once a 13322 // block is detected as invalid -- failing the three first steps -- it is 13323 // adequate to spend more time determining validity before throwing a conflict. 13324 13325 13326 // Blocks are inherently indifferent about where the data they operate with ends 13327 // up being saved. For example, all blocks can have a static and dynamic aspect 13328 // to them depending on the needs. The static nature of a block is the `save()` 13329 // definition that is meant to be serialized into HTML and which can be left 13330 // void. Any block can also register a `render_callback` on the server, which 13331 // makes its output dynamic either in part or in its totality. 13332 // 13333 // Child blocks are defined as a relationship that builds on top of the inner 13334 // blocks mechanism. A child block is a block node of a particular type that can 13335 // only exist within the inner block boundaries of a specific parent type. This 13336 // allows block authors to compose specific blocks that are not meant to be used 13337 // outside of a specified parent block context. Thus, child blocks extend the 13338 // concept of inner blocks to support a more direct relationship between sets of 13339 // blocks. The addition of parent–child would be a subset of the inner block 13340 // functionality under the premise that certain blocks only make sense as 13341 // children of another block. 13342 13343 13344 // Templates are, in a general sense, a basic collection of block nodes with any 13345 // given set of predefined attributes that are supplied as the initial state of 13346 // an inner blocks group. These nodes can, in turn, contain any number of nested 13347 // blocks within their definition. Templates allow both to specify a default 13348 // state for an editor session or a default set of blocks for any inner block 13349 // implementation within a specific block. 13350 13351 13352 13353 13354 13355 13356 ;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/extends.js 13357 function _extends() { 13358 _extends = Object.assign || function (target) { 13359 for (var i = 1; i < arguments.length; i++) { 13360 var source = arguments[i]; 13361 13362 for (var key in source) { 13363 if (Object.prototype.hasOwnProperty.call(source, key)) { 13364 target[key] = source[key]; 13365 } 13366 } 13367 } 13368 13369 return target; 13370 }; 13371 13372 return _extends.apply(this, arguments); 13373 } 13374 ;// CONCATENATED MODULE: external ["wp","compose"] 13375 var external_wp_compose_namespaceObject = window["wp"]["compose"]; 13376 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/block-content-provider/index.js 13377 13378 13379 13380 /** 13381 * WordPress dependencies 13382 */ 13383 13384 13385 /** 13386 * Internal dependencies 13387 */ 13388 13389 13390 const { 13391 Consumer, 13392 Provider 13393 } = (0,external_wp_element_namespaceObject.createContext)(() => {}); 13394 /** 13395 * An internal block component used in block content serialization to inject 13396 * nested block content within the `save` implementation of the ancestor 13397 * component in which it is nested. The component provides a pre-bound 13398 * `BlockContent` component via context, which is used by the developer-facing 13399 * `InnerBlocks.Content` component to render block content. 13400 * 13401 * @example 13402 * 13403 * ```jsx 13404 * <BlockContentProvider innerBlocks={ innerBlocks }> 13405 * { blockSaveElement } 13406 * </BlockContentProvider> 13407 * ``` 13408 * 13409 * @param {Object} props Component props. 13410 * @param {WPElement} props.children Block save result. 13411 * @param {Array} props.innerBlocks Block(s) to serialize. 13412 * 13413 * @return {WPComponent} Element with BlockContent injected via context. 13414 */ 13415 13416 const BlockContentProvider = _ref => { 13417 let { 13418 children, 13419 innerBlocks 13420 } = _ref; 13421 13422 const BlockContent = () => { 13423 // Value is an array of blocks, so defer to block serializer. 13424 const html = serialize(innerBlocks, { 13425 isInnerBlocks: true 13426 }); // Use special-cased raw HTML tag to avoid default escaping 13427 13428 return createElement(RawHTML, null, html); 13429 }; 13430 13431 return createElement(Provider, { 13432 value: BlockContent 13433 }, children); 13434 }; 13435 /** 13436 * A Higher Order Component used to inject BlockContent using context to the 13437 * wrapped component. 13438 * 13439 * @return {WPComponent} Enhanced component with injected BlockContent as prop. 13440 */ 13441 13442 13443 const withBlockContentContext = (0,external_wp_compose_namespaceObject.createHigherOrderComponent)(OriginalComponent => { 13444 return props => (0,external_wp_element_namespaceObject.createElement)(Consumer, null, context => (0,external_wp_element_namespaceObject.createElement)(OriginalComponent, _extends({}, props, { 13445 BlockContent: context 13446 }))); 13447 }, 'withBlockContentContext'); 13448 /* harmony default export */ var block_content_provider = ((/* unused pure expression or super */ null && (BlockContentProvider))); 13449 13450 ;// CONCATENATED MODULE: ./node_modules/@wordpress/blocks/build-module/index.js 13451 // A "block" is the abstract term used to describe units of markup that, 13452 // when composed together, form the content or layout of a page. 13453 // The API for blocks is exposed via `wp.blocks`. 13454 // 13455 // Supported blocks are registered by calling `registerBlockType`. Once registered, 13456 // the block is made available as an option to the editor interface. 13457 // 13458 // Blocks are inferred from the HTML source of a post through a parsing mechanism 13459 // and then stored as objects in state, from which it is then rendered for editing. 13460 13461 13462 13463 13464 }(); 13465 (window.wp = window.wp || {}).blocks = __webpack_exports__; 13466 /******/ })() 13467 ;
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Dec 22 01:00:02 2024 | Cross-referenced by PHPXref 0.7.1 |