vendor: 4,537 bytes, lines 1-161
1/******/ (() => { // webpackBootstrap 2/******/ var __webpack_modules__ = ({ 3 4/***/ 1919: 5/***/ ((module) => { 6 7"use strict"; 8 9 10var isMergeableObject = function isMergeableObject(value) { 11 return isNonNullObject(value) 12 && !isSpecial(value) 13}; 14 15function isNonNullObject(value) { 16 return !!value && typeof value === 'object' 17} 18 19function isSpecial(value) { 20 var stringValue = Object.prototype.toString.call(value); 21 22 return stringValue === '[object RegExp]' 23 || stringValue === '[object Date]' 24 || isReactElement(value) 25} 26 27// see https://github.com/facebook/react/blob/b5ac963fb791d1298e7f396236383bc955f916c1/src/isomorphic/classic/element/ReactElement.js#L21-L25 28var canUseSymbol = typeof Symbol === 'function' && Symbol.for; 29var REACT_ELEMENT_TYPE = canUseSymbol ? Symbol.for('react.element') : 0xeac7; 30 31function isReactElement(value) { 32 return value.$$typeof === REACT_ELEMENT_TYPE 33} 34 35function emptyTarget(val) { 36 return Array.isArray(val) ? [] : {} 37} 38 39function cloneUnlessOtherwiseSpecified(value, options) { 40 return (options.clone !== false && options.isMergeableObject(value)) 41 ? deepmerge(emptyTarget(value), value, options) 42 : value 43} 44 45function defaultArrayMerge(target, source, options) { 46 return target.concat(source).map(function(element) { 47 return cloneUnlessOtherwiseSpecified(element, options) 48 }) 49} 50 51function getMergeFunction(key, options) { 52 if (!options.customMerge) { 53 return deepmerge 54 } 55 var customMerge = options.customMerge(key); 56 return typeof customMerge === 'function' ? customMerge : deepmerge 57} 58 59function getEnumerableOwnPropertySymbols(target) { 60 return Object.getOwnPropertySymbols 61 ? Object.getOwnPropertySymbols(target).filter(function(symbol) { 62 return Object.propertyIsEnumerable.call(target, symbol) 63 }) 64 : [] 65} 66 67function getKeys(target) { 68 return Object.keys(target).concat(getEnumerableOwnPropertySymbols(target)) 69} 70 71function propertyIsOnObject(object, property) { 72 try { 73 return property in object 74 } catch(_) { 75 return false 76 } 77} 78 79// Protects from prototype poisoning and unexpected merging up the prototype chain. 80function propertyIsUnsafe(target, key) { 81 return propertyIsOnObject(target, key) // Properties are safe to merge if they don't exist in the target yet, 82 && !(Object.hasOwnProperty.call(target, key) // unsafe if they exist up the prototype chain, 83 && Object.propertyIsEnumerable.call(target, key)) // and also unsafe if they're nonenumerable. 84} 85 86function mergeObject(target, source, options) { 87 var destination = {}; 88 if (options.isMergeableObject(target)) { 89 getKeys(target).forEach(function(key) { 90 destination[key] = cloneUnlessOtherwiseSpecified(target[key], options); 91 }); 92 } 93 getKeys(source).forEach(function(key) { 94 if (propertyIsUnsafe(target, key)) { 95 return 96 } 97 98 if (propertyIsOnObject(target, key) && options.isMergeableObject(source[key])) { 99 destination[key] = getMergeFunction(key, options)(target[key], source[key], options); 100 } else { 101 destination[key] = cloneUnlessOtherwiseSpecified(source[key], options); 102 } 103 }); 104 return destination 105} 106 107function deepmerge(target, source, options) { 108 options = options || {}; 109 options.arrayMerge = options.arrayMerge || defaultArrayMerge; 110 options.isMergeableObject = options.isMergeableObject || isMergeableObject; 111 // cloneUnlessOtherwiseSpecified is added to `options` so that custom arrayMerge() 112 // implementations can use it. The caller may not replace it. 113 options.cloneUnlessOtherwiseSpecified = cloneUnlessOtherwiseSpecified; 114 115 var sourceIsArray = Array.isArray(source); 116 var targetIsArray = Array.isArray(target); 117 var sourceAndTargetTypesMatch = sourceIsArray === targetIsArray; 118 119 if (!sourceAndTargetTypesMatch) { 120 return cloneUnlessOtherwiseSpecified(source, options) 121 } else if (sourceIsArray) { 122 return options.arrayMerge(target, source, options) 123 } else { 124 return mergeObject(target, source, options) 125 } 126} 127 128deepmerge.all = function deepmergeAll(array, options) { 129 if (!Array.isArray(array)) { 130 throw new Error('first argument should be an array') 131 } 132 133 return array.reduce(function(prev, next) { 134 return deepmerge(prev, next, options) 135 }, {}) 136}; 137 138var deepmerge_1 = deepmerge; 139 140module.exports = deepmerge_1; 141 142 143/***/ }), 144 145/***/ 5619: 146/***/ ((module) => { 147 148"use strict"; 149 150 151// do not edit .js files directly - edit src/index.jst 152 153 154 var envHasBigInt64Array = typeof BigInt64Array !== 'undefined'; 155 156 157module.exports = function equal(a, b) { 158 if (a === b) return true; 159 160 if (a && b && typeof a == 'object' && typeof b == 'object') { 161 if (a.constructor !== b.constructor) return false;
162 163 var length, i, keys; 164 if (Array.isArray(a)) { 165 length = a.length; 166 if (length != b.length) return false; 167 for (i = length; i-- !== 0;) 168 if (!equal(a[i], b[i])) return false; 169 return true; 170 } 171 172 173 if ((a instanceof Map) && (b instanceof Map)) { 174 if (a.size !== b.size) return false; 175 for (i of a.entries()) 176 if (!b.has(i[0])) return false; 177 for (i of a.entries()) 178 if (!equal(i[1], b.get(i[0]))) return false; 179 return true; 180 } 181 182 if ((a instanceof Set) && (b instanceof Set)) { 183 if (a.size !== b.size) return false; 184 for (i of a.entries()) 185 if (!b.has(i[0])) return false; 186 return true; 187 } 188 189 if (ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) { 190 length = a.length; 191 if (length != b.length) return false; 192 for (i = length; i-- !== 0;) 193 if (a[i] !== b[i]) return false; 194 return true; 195 } 196 197 198 if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags; 199 if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf(); 200 if (a.toString !== Object.prototype.toString) return a.toString() === b.toString(); 201 202 keys = Object.keys(a); 203 length = keys.length; 204 if (length !== Object.keys(b).length) return false; 205 206 for (i = length; i-- !== 0;) 207 if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false; 208 209 for (i = length; i-- !== 0;) { 210 var key = keys[i]; 211 212 if (!equal(a[key], b[key])) return false; 213 } 214 215 return true; 216 } 217 218 // true if both NaN, false otherwise 219 return a!==a && b!==b; 220}; 221 222 223/***/ }), 224 225/***/ 4793: 226/***/ ((module) => { 227 228var characterMap = { 229 "Ã": "A", 230 "Ã": "A", 231 "Ã": "A", 232 "Ã": "A", 233 "Ã": "A", 234 "à ": "A", 235 "Ấ": "A", 236 "Ắ": "A", 237 "Ẳ": "A", 238 "Ẵ": "A", 239 "Ặ": "A", 240 "Ã": "AE", 241 "Ầ": "A", 242 "Ằ": "A", 243 "È": "A", 244 "Ả": "A", 245 "Ạ": "A", 246 "Ẩ": "A", 247 "Ẫ": "A", 248 "Ậ": "A", 249 "Ã": "C", 250 "á¸": "C", 251 "Ã": "E", 252 "Ã": "E", 253 "Ã": "E", 254 "Ã": "E", 255 "Ế": "E", 256 "á¸": "E", 257 "á»": "E", 258 "á¸": "E", 259 "á¸": "E", 260 "È": "E", 261 "Ẻ": "E", 262 "Ẽ": "E", 263 "Ẹ": "E", 264 "á»": "E", 265 "á»": "E", 266 "á»": "E", 267 "Ã": "I", 268 "Ã": "I", 269 "Ã": "I", 270 "Ã": "I", 271 "Ḯ": "I", 272 "È": "I", 273 "á»": "I", 274 "á»": "I", 275 "Ã": "D", 276 "Ã": "N", 277 "Ã": "O", 278 "Ã": "O", 279 "Ã": "O", 280 "Ã": "O", 281 "Ã": "O", 282 "Ã": "O", 283 "á»": "O", 284 "á¹": "O", 285 "á¹": "O", 286 "È": "O", 287 "á»": "O", 288 "á»": "O", 289 "á»": "O", 290 "á»": "O", 291 "á»": "O", 292 "á»": "O", 293 "á»": "O", 294 "á» ": "O", 295 "á»": "O", 296 "Ợ": "O", 297 "Ã": "U", 298 "Ã": "U", 299 "Ã": "U", 300 "Ã": "U", 301 "Ủ": "U", 302 "Ụ": "U", 303 "Ử": "U", 304 "á»®": "U", 305 "á»°": "U", 306 "Ã": "Y", 307 "à ": "a", 308 "á": "a", 309 "â": "a", 310 "ã": "a", 311 "ä": "a", 312 "Ã¥": "a", 313 "ấ": "a", 314 "ắ": "a", 315 "ẳ": "a", 316 "ẵ": "a", 317 "ặ": "a", 318 "æ": "ae", 319 "ầ": "a", 320 "ằ": "a", 321 "È": "a", 322 "ả": "a", 323 "ạ": "a", 324 "ẩ": "a", 325 "ẫ": "a", 326 "áº": "a", 327 "ç": "c", 328 "á¸": "c", 329 "è": "e", 330 "é": "e", 331 "ê": "e", 332 "ë": "e", 333 "ế": "e", 334 "á¸": "e", 335 "á»": "e", 336 "á¸": "e", 337 "á¸": "e", 338 "È": "e", 339 "ẻ": "e", 340 "ẽ": "e", 341 "ẹ": "e", 342 "á»": "e", 343 "á» ": "e", 344 "á»": "e", 345 "ì": "i", 346 "Ã": "i", 347 "î": "i", 348 "ï": "i", 349 "ḯ": "i", 350 "È": "i", 351 "á»": "i", 352 "á»": "i", 353 "ð": "d", 354 "ñ": "n", 355 "ò": "o", 356 "ó": "o", 357 "ô": "o", 358 "õ": "o", 359 "ö": "o", 360 "ø": "o", 361 "á»": "o", 362 "á¹": "o", 363 "á¹": "o", 364 "È": "o", 365 "á»": "o", 366 "á»": "o", 367 "á»": "o", 368 "á»": "o", 369 "á»": "o", 370 "á»": "o", 371 "á»": "o", 372 "ỡ": "o", 373 "á»": "o", 374 "ợ": "o", 375 "ù": "u", 376 "ú": "u", 377 "û": "u", 378 "ü": "u", 379 "á»§": "u", 380 "ụ": "u", 381 "á»": "u", 382 "ữ": "u", 383 "á»±": "u", 384 "ý": "y", 385 "ÿ": "y", 386 "Ä": "A", 387 "Ä": "a", 388 "Ä": "A", 389 "Ä": "a", 390 "Ä": "A", 391 "Ä ": "a", 392 "Ä": "C", 393 "Ä": "c", 394 "Ä": "C", 395 "Ä": "c", 396 "Ä": "C", 397 "Ä": "c", 398 "Ä": "C", 399 "Ä": "c", 400 "CÌ": "C", 401 "cÌ": "c", 402 "Ä": "D", 403 "Ä": "d", 404 "Ä": "D", 405 "Ä": "d", 406 "Ä": "E", 407 "Ä": "e", 408 "Ä": "E", 409 "Ä": "e", 410 "Ä": "E", 411 "Ä": "e", 412 "Ä": "E", 413 "Ä": "e", 414 "Ä": "E", 415 "Ä": "e", 416 "Ä": "G", 417 "Ç´": "G", 418 "Ä": "g", 419 "ǵ": "g", 420 "Ä": "G", 421 "Ä": "g", 422 "Ä ": "G", 423 "Ä¡": "g", 424 "Ä¢": "G", 425 "Ä£": "g", 426 "Ĥ": "H", 427 "Ä¥": "h", 428 "Ħ": "H", 429 "ħ": "h", 430 "Ḫ": "H", 431 "ḫ": "h", 432 "Ĩ": "I", 433 "Ä©": "i", 434 "Ī": "I", 435 "Ä«": "i", 436 "Ĭ": "I", 437 "Ä": "i", 438 "Ä®": "I", 439 "į": "i", 440 "İ": "I", 441 "ı": "i", 442 "IJ": "IJ", 443 "ij": "ij", 444 "Ä´": "J", 445 "ĵ": "j", 446 "Ķ": "K", 447 "Ä·": "k", 448 "Ḱ": "K", 449 "ḱ": "k", 450 "KÌ": "K", 451 "kÌ": "k", 452 "Ĺ": "L", 453 "ĺ": "l", 454 "Ä»": "L", 455 "ļ": "l", 456 "Ľ": "L", 457 "ľ": "l", 458 "Ä¿": "L", 459 "Å": "l", 460 "Å": "l", 461 "Å": "l", 462 "Ḿ": "M", 463 "ḿ": "m", 464 "MÌ": "M", 465 "mÌ": "m", 466 "Å": "N", 467 "Å": "n", 468 "Å ": "N", 469 "Å": "n", 470 "Å": "N", 471 "Å": "n", 472 "Å": "n", 473 "NÌ": "N", 474 "nÌ": "n", 475 "Å": "O", 476 "Å": "o", 477 "Å": "O", 478 "Å": "o", 479 "Å": "O", 480 "Å": "o", 481 "Å": "OE", 482 "Å": "oe", 483 "PÌ": "P", 484 "pÌ": "p", 485 "Å": "R", 486 "Å": "r", 487 "Å": "R", 488 "Å": "r", 489 "Å": "R", 490 "Å": "r", 491 "RÌ": "R", 492 "rÌ": "r", 493 "È": "R", 494 "È": "r", 495 "Å": "S", 496 "Å": "s", 497 "Å": "S", 498 "Å": "s", 499 "Å": "S", 500 "È": "S", 501 "È": "s", 502 "Å": "s", 503 "Å ": "S", 504 "Å¡": "s", 505 "Å¢": "T", 506 "Å£": "t", 507 "È": "t", 508 "È": "T", 509 "Ť": "T", 510 "Å¥": "t", 511 "Ŧ": "T", 512 "ŧ": "t", 513 "TÌ": "T", 514 "tÌ": "t", 515 "Ũ": "U", 516 "Å©": "u", 517 "Ū": "U", 518 "Å«": "u", 519 "Ŭ": "U", 520 "Å": "u", 521 "Å®": "U", 522 "ů": "u", 523 "Ű": "U", 524 "ű": "u", 525 "Ų": "U", 526 "ų": "u", 527 "È": "U", 528 "È": "u", 529 "VÌ": "V", 530 "vÌ": "v", 531 "Å´": "W", 532 "ŵ": "w", 533 "áº": "W", 534 "áº": "w", 535 "XÌ": "X", 536 "xÌ": "x", 537 "Ŷ": "Y", 538 "Å·": "y", 539 "Ÿ": "Y", 540 "YÌ": "Y", 541 "yÌ": "y", 542 "Ź": "Z", 543 "ź": "z", 544 "Å»": "Z", 545 "ż": "z", 546 "Ž": "Z", 547 "ž": "z", 548 "Å¿": "s", 549 "Æ": "f", 550 "Æ ": "O", 551 "Æ¡": "o", 552 "Ư": "U", 553 "ư": "u", 554 "Ç": "A", 555 "Ç": "a", 556 "Ç": "I", 557 "Ç": "i", 558 "Ç": "O", 559 "Ç": "o", 560 "Ç": "U", 561 "Ç": "u", 562 "Ç": "U", 563 "Ç": "u", 564 "Ç": "U", 565 "Ç": "u", 566 "Ç": "U", 567 "Ç": "u", 568 "Ç": "U", 569 "Ç": "u", 570 "Ứ": "U", 571 "ứ": "u", 572 "Ṹ": "U", 573 "á¹¹": "u", 574 "Ǻ": "A", 575 "Ç»": "a", 576 "Ǽ": "AE", 577 "ǽ": "ae", 578 "Ǿ": "O", 579 "Ç¿": "o", 580 "Ã": "TH", 581 "þ": "th", 582 "á¹": "P", 583 "á¹": "p", 584 "Ṥ": "S", 585 "á¹¥": "s", 586 "XÌ": "X", 587 "xÌ": "x", 588 "Ð": "Ð", 589 "Ñ": "г", 590 "Ð": "Ð", 591 "Ñ": "к", 592 "AÌ": "A", 593 "aÌ": "a", 594 "EÌ": "E", 595 "eÌ": "e", 596 "IÌ": "I", 597 "iÌ": "i", 598 "Ǹ": "N", 599 "ǹ": "n", 600 "á»": "O", 601 "á»": "o", 602 "á¹": "O", 603 "á¹": "o", 604 "Ừ": "U", 605 "ừ": "u", 606 "áº": "W", 607 "áº": "w", 608 "Ỳ": "Y", 609 "ỳ": "y", 610 "È": "A", 611 "È": "a", 612 "È": "E", 613 "È ": "e", 614 "È": "I", 615 "È": "i", 616 "È": "O", 617 "È": "o", 618 "È": "R", 619 "È": "r", 620 "È": "U", 621 "È": "u", 622 "BÌ": "B", 623 "bÌ": "b", 624 "ÄÌ£": "C", 625 "ÄÌ£": "c", 626 "ÃÌ": "E", 627 "êÌ": "e", 628 "FÌ": "F", 629 "fÌ": "f", 630 "Ǧ": "G", 631 "ǧ": "g", 632 "È": "H", 633 "È": "h", 634 "JÌ": "J", 635 "ǰ": "j", 636 "Ǩ": "K", 637 "Ç©": "k", 638 "MÌ": "M", 639 "mÌ": "m", 640 "PÌ": "P", 641 "pÌ": "p", 642 "QÌ": "Q", 643 "qÌ": "q", 644 "ÅÌ©": "R", 645 "ÅÌ©": "r", 646 "Ṧ": "S", 647 "á¹§": "s", 648 "VÌ": "V", 649 "vÌ": "v", 650 "WÌ": "W", 651 "wÌ": "w", 652 "XÌ": "X", 653 "xÌ": "x", 654 "YÌ": "Y", 655 "yÌ": "y", 656 "A̧": "A", 657 "a̧": "a", 658 "B̧": "B", 659 "b̧": "b", 660 "á¸": "D", 661 "á¸": "d", 662 "Ȩ": "E", 663 "È©": "e", 664 "ÆÌ§": "E", 665 "Ȩ́": "e", 666 "Ḩ": "H", 667 "ḩ": "h", 668 "I̧": "I", 669 "i̧": "i", 670 "ÆÌ§": "I", 671 "ɨ̧": "i", 672 "M̧": "M", 673 "m̧": "m", 674 "O̧": "O", 675 "o̧": "o", 676 "Q̧": "Q", 677 "q̧": "q", 678 "U̧": "U", 679 "u̧": "u", 680 "X̧": "X", 681 "x̧": "x", 682 "Z̧": "Z", 683 "z̧": "z", 684 "й":"и", 685 "Ð":"Ð", 686 "Ñ":"е", 687 "Ð":"Ð", 688}; 689 690var chars = Object.keys(characterMap).join('|'); 691var allAccents = new RegExp(chars, 'g'); 692var firstAccent = new RegExp(chars, ''); 693 694function matcher(match) { 695 return characterMap[match]; 696} 697 698var removeAccents = function(string) { 699 return string.replace(allAccents, matcher); 700}; 701 702var hasAccents = function(string) { 703 return !!string.match(firstAccent); 704}; 705 706module.exports = removeAccents; 707module.exports.has = hasAccents; 708module.exports.remove = removeAccents; 709 710 711/***/ }), 712 713/***/ 7308: 714/***/ (function(module, exports, __webpack_require__) { 715 716var __WEBPACK_AMD_DEFINE_RESULT__;;/*! showdown v 1.9.1 - 02-11-2019 */ 717(function(){ 718/** 719 * Created by Tivie on 13-07-2015. 720 */ 721 722function getDefaultOpts (simple) { 723 'use strict'; 724 725 var defaultOptions = { 726 omitExtraWLInCodeBlocks: { 727 defaultValue: false, 728 describe: 'Omit the default extra whiteline added to code blocks', 729 type: 'boolean' 730 }, 731 noHeaderId: { 732 defaultValue: false, 733 describe: 'Turn on/off generated header id', 734 type: 'boolean' 735 }, 736 prefixHeaderId: { 737 defaultValue: false, 738 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', 739 type: 'string' 740 }, 741 rawPrefixHeaderId: { 742 defaultValue: false, 743 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)', 744 type: 'boolean' 745 }, 746 ghCompatibleHeaderId: { 747 defaultValue: false, 748 describe: 'Generate header ids compatible with github style (spaces are replaced with dashes, a bunch of non alphanumeric chars are removed)', 749 type: 'boolean' 750 }, 751 rawHeaderId: { 752 defaultValue: false, 753 describe: 'Remove only spaces, \' and " from generated header ids (including prefixes), replacing them with dashes (-). WARNING: This might result in malformed ids', 754 type: 'boolean' 755 }, 756 headerLevelStart: { 757 defaultValue: false, 758 describe: 'The header blocks level start', 759 type: 'integer' 760 }, 761 parseImgDimensions: { 762 defaultValue: false, 763 describe: 'Turn on/off image dimension parsing', 764 type: 'boolean' 765 }, 766 simplifiedAutoLink: { 767 defaultValue: false, 768 describe: 'Turn on/off GFM autolink style', 769 type: 'boolean' 770 }, 771 excludeTrailingPunctuationFromURLs: { 772 defaultValue: false, 773 describe: 'Excludes trailing punctuation from links generated
vendor: 13,795 bytes, lines 773-1290
773with autoLinking', 774 type: 'boolean' 775 }, 776 literalMidWordUnderscores: { 777 defaultValue: false, 778 describe: 'Parse midword underscores as literal underscores', 779 type: 'boolean' 780 }, 781 literalMidWordAsterisks: { 782 defaultValue: false, 783 describe: 'Parse midword asterisks as literal asterisks', 784 type: 'boolean' 785 }, 786 strikethrough: { 787 defaultValue: false, 788 describe: 'Turn on/off strikethrough support', 789 type: 'boolean' 790 }, 791 tables: { 792 defaultValue: false, 793 describe: 'Turn on/off tables support', 794 type: 'boolean' 795 }, 796 tablesHeaderId: { 797 defaultValue: false, 798 describe: 'Add an id to table headers', 799 type: 'boolean' 800 }, 801 ghCodeBlocks: { 802 defaultValue: true, 803 describe: 'Turn on/off GFM fenced code blocks support', 804 type: 'boolean' 805 }, 806 tasklists: { 807 defaultValue: false, 808 describe: 'Turn on/off GFM tasklist support', 809 type: 'boolean' 810 }, 811 smoothLivePreview: { 812 defaultValue: false, 813 describe: 'Prevents weird effects in live previews due to incomplete input', 814 type: 'boolean' 815 }, 816 smartIndentationFix: { 817 defaultValue: false, 818 description: 'Tries to smartly fix indentation in es6 strings', 819 type: 'boolean' 820 }, 821 disableForced4SpacesIndentedSublists: { 822 defaultValue: false, 823 description: 'Disables the requirement of indenting nested sublists by 4 spaces', 824 type: 'boolean' 825 }, 826 simpleLineBreaks: { 827 defaultValue: false, 828 description: 'Parses simple line breaks as <br> (GFM Style)', 829 type: 'boolean' 830 }, 831 requireSpaceBeforeHeadingText: { 832 defaultValue: false, 833 description: 'Makes adding a space between `#` and the header text mandatory (GFM Style)', 834 type: 'boolean' 835 }, 836 ghMentions: { 837 defaultValue: false, 838 description: 'Enables github @mentions', 839 type: 'boolean' 840 }, 841 ghMentionsLink: { 842 defaultValue: 'https://github.com/{u}', 843 description: 'Changes the link generated by @mentions. Only applies if ghMentions option is enabled.', 844 type: 'string' 845 }, 846 encodeEmails: { 847 defaultValue: true, 848 description: 'Encode e-mail addresses through the use of Character Entities, transforming ASCII e-mail addresses into its equivalent decimal entities', 849 type: 'boolean' 850 }, 851 openLinksInNewWindow: { 852 defaultValue: false, 853 description: 'Open all links in new windows', 854 type: 'boolean' 855 }, 856 backslashEscapesHTMLTags: { 857 defaultValue: false, 858 description: 'Support for HTML Tag escaping. ex: \<div>foo\</div>', 859 type: 'boolean' 860 }, 861 emoji: { 862 defaultValue: false, 863 description: 'Enable emoji support. Ex: `this is a :smile: emoji`', 864 type: 'boolean' 865 }, 866 underline: { 867 defaultValue: false, 868 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>`', 869 type: 'boolean' 870 }, 871 completeHTMLDocument: { 872 defaultValue: false, 873 description: 'Outputs a complete html document, including `<html>`, `<head>` and `<body>` tags', 874 type: 'boolean' 875 }, 876 metadata: { 877 defaultValue: false, 878 description: 'Enable support for document metadata (defined at the top of the document between `«««` and `»»»` or between `---` and `---`).', 879 type: 'boolean' 880 }, 881 splitAdjacentBlockquotes: { 882 defaultValue: false, 883 description: 'Split adjacent blockquote blocks', 884 type: 'boolean' 885 } 886 }; 887 if (simple === false) { 888 return JSON.parse(JSON.stringify(defaultOptions)); 889 } 890 var ret = {}; 891 for (var opt in defaultOptions) { 892 if (defaultOptions.hasOwnProperty(opt)) { 893 ret[opt] = defaultOptions[opt].defaultValue; 894 } 895 } 896 return ret; 897} 898 899function allOptionsOn () { 900 'use strict'; 901 var options = getDefaultOpts(true), 902 ret = {}; 903 for (var opt in options) { 904 if (options.hasOwnProperty(opt)) { 905 ret[opt] = true; 906 } 907 } 908 return ret; 909} 910 911/** 912 * Created by Tivie on 06-01-2015. 913 */ 914 915// Private properties 916var showdown = {}, 917 parsers = {}, 918 extensions = {}, 919 globalOptions = getDefaultOpts(true), 920 setFlavor = 'vanilla', 921 flavor = { 922 github: { 923 omitExtraWLInCodeBlocks: true, 924 simplifiedAutoLink: true, 925 excludeTrailingPunctuationFromURLs: true, 926 literalMidWordUnderscores: true, 927 strikethrough: true, 928 tables: true, 929 tablesHeaderId: true, 930 ghCodeBlocks: true, 931 tasklists: true, 932 disableForced4SpacesIndentedSublists: true, 933 simpleLineBreaks: true, 934 requireSpaceBeforeHeadingText: true, 935 ghCompatibleHeaderId: true, 936 ghMentions: true, 937 backslashEscapesHTMLTags: true, 938 emoji: true, 939 splitAdjacentBlockquotes: true 940 }, 941 original: { 942 noHeaderId: true, 943 ghCodeBlocks: false 944 }, 945 ghost: { 946 omitExtraWLInCodeBlocks: true, 947 parseImgDimensions: true, 948 simplifiedAutoLink: true, 949 excludeTrailingPunctuationFromURLs: true, 950 literalMidWordUnderscores: true, 951 strikethrough: true, 952 tables: true, 953 tablesHeaderId: true, 954 ghCodeBlocks: true, 955 tasklists: true, 956 smoothLivePreview: true, 957 simpleLineBreaks: true, 958 requireSpaceBeforeHeadingText: true, 959 ghMentions: false, 960 encodeEmails: true 961 }, 962 vanilla: getDefaultOpts(true), 963 allOn: allOptionsOn() 964 }; 965 966/** 967 * helper namespace 968 * @type {{}} 969 */ 970showdown.helper = {}; 971 972/** 973 * TODO LEGACY SUPPORT CODE 974 * @type {{}} 975 */ 976showdown.extensions = {}; 977 978/** 979 * Set a global option 980 * @static 981 * @param {string} key 982 * @param {*} value 983 * @returns {showdown} 984 */ 985showdown.setOption = function (key, value) { 986 'use strict'; 987 globalOptions[key] = value; 988 return this; 989}; 990 991/** 992 * Get a global option 993 * @static 994 * @param {string} key 995 * @returns {*} 996 */ 997showdown.getOption = function (key) { 998 'use strict'; 999 return globalOptions[key]; 1000}; 1001 1002/** 1003 * Get the global options 1004 * @static 1005 * @returns {{}} 1006 */ 1007showdown.getOptions = function () { 1008 'use strict'; 1009 return globalOptions; 1010}; 1011 1012/** 1013 * Reset global options to the default values 1014 * @static 1015 */ 1016showdown.resetOptions = function () { 1017 'use strict'; 1018 globalOptions = getDefaultOpts(true); 1019}; 1020 1021/** 1022 * Set the flavor showdown should use as default 1023 * @param {string} name 1024 */ 1025showdown.setFlavor = function (name) { 1026 'use strict'; 1027 if (!flavor.hasOwnProperty(name)) { 1028 throw Error(name + ' flavor was not found'); 1029 } 1030 showdown.resetOptions(); 1031 var preset = flavor[name]; 1032 setFlavor = name; 1033 for (var option in preset) { 1034 if (preset.hasOwnProperty(option)) { 1035 globalOptions[option] = preset[option]; 1036 } 1037 } 1038}; 1039 1040/** 1041 * Get the currently set flavor 1042 * @returns {string} 1043 */ 1044showdown.getFlavor = function () { 1045 'use strict'; 1046 return setFlavor; 1047}; 1048 1049/** 1050 * Get the options of a specified flavor. Returns undefined if the flavor was not found 1051 * @param {string} name Name of the flavor 1052 * @returns {{}|undefined} 1053 */ 1054showdown.getFlavorOptions = function (name) { 1055 'use strict'; 1056 if (flavor.hasOwnProperty(name)) { 1057 return flavor[name]; 1058 } 1059}; 1060 1061/** 1062 * Get the default options 1063 * @static 1064 * @param {boolean} [simple=true] 1065 * @returns {{}} 1066 */ 1067showdown.getDefaultOptions = function (simple) { 1068 'use strict'; 1069 return getDefaultOpts(simple); 1070}; 1071 1072/** 1073 * Get or set a subParser 1074 * 1075 * subParser(name) - Get a registered subParser 1076 * subParser(name, func) - Register a subParser 1077 * @static 1078 * @param {string} name 1079 * @param {function} [func] 1080 * @returns {*} 1081 */ 1082showdown.subParser = function (name, func) { 1083 'use strict'; 1084 if (showdown.helper.isString(name)) { 1085 if (typeof func !== 'undefined') { 1086 parsers[name] = func; 1087 } else { 1088 if (parsers.hasOwnProperty(name)) { 1089 return parsers[name]; 1090 } else { 1091 throw Error('SubParser named ' + name + ' not registered!'); 1092 } 1093 } 1094 } 1095}; 1096 1097/** 1098 * Gets or registers an extension 1099 * @static 1100 * @param {string} name 1101 * @param {object|function=} ext 1102 * @returns {*} 1103 */ 1104showdown.extension = function (name, ext) { 1105 'use strict'; 1106 1107 if (!showdown.helper.isString(name)) { 1108 throw Error('Extension \'name\' must be a string'); 1109 } 1110 1111 name = showdown.helper.stdExtName(name); 1112 1113 // Getter 1114 if (showdown.helper.isUndefined(ext)) { 1115 if (!extensions.hasOwnProperty(name)) { 1116 throw Error('Extension named ' + name + ' is not registered!'); 1117 } 1118 return extensions[name]; 1119 1120 // Setter 1121 } else { 1122 // Expand extension if it's wrapped in a function 1123 if (typeof ext === 'function') { 1124 ext = ext(); 1125 } 1126 1127 // Ensure extension is an array 1128 if (!showdown.helper.isArray(ext)) { 1129 ext = [ext]; 1130 } 1131 1132 var validExtension = validate(ext, name); 1133 1134 if (validExtension.valid) { 1135 extensions[name] = ext; 1136 } else { 1137 throw Error(validExtension.error); 1138 } 1139 } 1140}; 1141 1142/** 1143 * Gets all extensions registered 1144 * @returns {{}} 1145 */ 1146showdown.getAllExtensions = function () { 1147 'use strict'; 1148 return extensions; 1149}; 1150 1151/** 1152 * Remove an extension 1153 * @param {string} name 1154 */ 1155showdown.removeExtension = function (name) { 1156 'use strict'; 1157 delete extensions[name]; 1158}; 1159 1160/** 1161 * Removes all extensions 1162 */ 1163showdown.resetExtensions = function () { 1164 'use strict'; 1165 extensions = {}; 1166}; 1167 1168/** 1169 * Validate extension 1170 * @param {array} extension 1171 * @param {string} name 1172 * @returns {{valid: boolean, error: string}} 1173 */ 1174function validate (extension, name) { 1175 'use strict'; 1176 1177 var errMsg = (name) ? 'Error in ' + name + ' extension->' : 'Error in unnamed extension', 1178 ret = { 1179 valid: true, 1180 error: '' 1181 }; 1182 1183 if (!showdown.helper.isArray(extension)) { 1184 extension = [extension]; 1185 } 1186 1187 for (var i = 0; i < extension.length; ++i) { 1188 var baseMsg = errMsg + ' sub-extension ' + i + ': ', 1189 ext = extension[i]; 1190 if (typeof ext !== 'object') { 1191 ret.valid = false; 1192 ret.error = baseMsg + 'must be an object, but ' + typeof ext + ' given'; 1193 return ret; 1194 } 1195 1196 if (!showdown.helper.isString(ext.type)) { 1197 ret.valid = false; 1198 ret.error = baseMsg + 'property "type" must be a string, but ' + typeof ext.type + ' given'; 1199 return ret; 1200 } 1201 1202 var type = ext.type = ext.type.toLowerCase(); 1203 1204 // normalize extension type 1205 if (type === 'language') { 1206 type = ext.type = 'lang'; 1207 } 1208 1209 if (type === 'html') { 1210 type = ext.type = 'output'; 1211 } 1212 1213 if (type !== 'lang' && type !== 'output' && type !== 'listener') { 1214 ret.valid = false; 1215 ret.error = baseMsg + 'type ' + type + ' is not recognized. Valid values: "lang/language", "output/html" or "listener"'; 1216 return ret; 1217 } 1218 1219 if (type === 'listener') { 1220 if (showdown.helper.isUndefined(ext.listeners)) { 1221 ret.valid = false; 1222 ret.error = baseMsg + '. Extensions of type "listener" must have a property called "listeners"'; 1223 return ret; 1224 } 1225 } else { 1226 if (showdown.helper.isUndefined(ext.filter) && showdown.helper.isUndefined(ext.regex)) { 1227 ret.valid = false; 1228 ret.error = baseMsg + type + ' extensions must define either a "regex" property or a "filter" method'; 1229 return ret; 1230 } 1231 } 1232 1233 if (ext.listeners) { 1234 if (typeof ext.listeners !== 'object') { 1235 ret.valid = false; 1236 ret.error = baseMsg + '"listeners" property must be an object but ' + typeof ext.listeners + ' given'; 1237 return ret; 1238 } 1239 for (var ln in ext.listeners) { 1240 if (ext.listeners.hasOwnProperty(ln)) { 1241 if (typeof ext.listeners[ln] !== 'function') { 1242 ret.valid = false; 1243 ret.error = baseMsg + '"listeners" property must be an hash of [event name]: [callback]. listeners.' + ln + 1244 ' must be a function but ' + typeof ext.listeners[ln] + ' given'; 1245 return ret; 1246 } 1247 } 1248 } 1249 } 1250 1251 if (ext.filter) { 1252 if (typeof ext.filter !== 'function') { 1253 ret.valid = false; 1254 ret.error = baseMsg + '"filter" must be a function, but ' + typeof ext.filter + ' given'; 1255 return ret; 1256 } 1257 } else if (ext.regex) { 1258 if (showdown.helper.isString(ext.regex)) { 1259 ext.regex = new RegExp(ext.regex, 'g'); 1260 } 1261 if (!(ext.regex instanceof RegExp)) { 1262 ret.valid = false; 1263 ret.error = baseMsg + '"regex" property must either be a string or a RegExp object, but ' + typeof ext.regex + ' given'; 1264 return ret; 1265 } 1266 if (showdown.helper.isUndefined(ext.replace)) { 1267 ret.valid = false; 1268 ret.error = baseMsg + '"regex" extensions must implement a replace string or function'; 1269 return ret; 1270 } 1271 } 1272 } 1273 return ret; 1274} 1275 1276/** 1277 * Validate extension 1278 * @param {object} ext 1279 * @returns {boolean} 1280 */ 1281showdown.validateExtension = function (ext) { 1282 'use strict'; 1283 1284 var validateExtension = validate(ext, null); 1285 if (!validateExtension.valid) { 1286 console.warn(validateExtension.error); 1287 return false; 1288 } 1289 return true; 1290};
vendor: 11,030 bytes, lines 1291-1688
1291 1292/** 1293 * showdownjs helper functions 1294 */ 1295 1296if (!showdown.hasOwnProperty('helper')) { 1297 showdown.helper = {}; 1298} 1299 1300/** 1301 * Check if var is string 1302 * @static 1303 * @param {string} a 1304 * @returns {boolean} 1305 */ 1306showdown.helper.isString = function (a) { 1307 'use strict'; 1308 return (typeof a === 'string' || a instanceof String); 1309}; 1310 1311/** 1312 * Check if var is a function 1313 * @static 1314 * @param {*} a 1315 * @returns {boolean} 1316 */ 1317showdown.helper.isFunction = function (a) { 1318 'use strict'; 1319 var getType = {}; 1320 return a && getType.toString.call(a) === '[object Function]'; 1321}; 1322 1323/** 1324 * isArray helper function 1325 * @static 1326 * @param {*} a 1327 * @returns {boolean} 1328 */ 1329showdown.helper.isArray = function (a) { 1330 'use strict'; 1331 return Array.isArray(a); 1332}; 1333 1334/** 1335 * Check if value is undefined 1336 * @static 1337 * @param {*} value The value to check. 1338 * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. 1339 */ 1340showdown.helper.isUndefined = function (value) { 1341 'use strict'; 1342 return typeof value === 'undefined'; 1343}; 1344 1345/** 1346 * ForEach helper function 1347 * Iterates over Arrays and Objects (own properties only) 1348 * @static 1349 * @param {*} obj 1350 * @param {function} callback Accepts 3 params: 1. value, 2. key, 3. the original array/object 1351 */ 1352showdown.helper.forEach = function (obj, callback) { 1353 'use strict'; 1354 // check if obj is defined 1355 if (showdown.helper.isUndefined(obj)) { 1356 throw new Error('obj param is required'); 1357 } 1358 1359 if (showdown.helper.isUndefined(callback)) { 1360 throw new Error('callback param is required'); 1361 } 1362 1363 if (!showdown.helper.isFunction(callback)) { 1364 throw new Error('callback param must be a function/closure'); 1365 } 1366 1367 if (typeof obj.forEach === 'function') { 1368 obj.forEach(callback); 1369 } else if (showdown.helper.isArray(obj)) { 1370 for (var i = 0; i < obj.length; i++) { 1371 callback(obj[i], i, obj); 1372 } 1373 } else if (typeof (obj) === 'object') { 1374 for (var prop in obj) { 1375 if (obj.hasOwnProperty(prop)) { 1376 callback(obj[prop], prop, obj); 1377 } 1378 } 1379 } else { 1380 throw new Error('obj does not seem to be an array or an iterable object'); 1381 } 1382}; 1383 1384/** 1385 * Standardidize extension name 1386 * @static 1387 * @param {string} s extension name 1388 * @returns {string} 1389 */ 1390showdown.helper.stdExtName = function (s) { 1391 'use strict'; 1392 return s.replace(/[_?*+\/\\.^-]/g, '').replace(/\s/g, '').toLowerCase(); 1393}; 1394 1395function escapeCharactersCallback (wholeMatch, m1) { 1396 'use strict'; 1397 var charCodeToEscape = m1.charCodeAt(0); 1398 return '¨E' + charCodeToEscape + 'E'; 1399} 1400 1401/** 1402 * Callback used to escape characters when passing through String.replace 1403 * @static 1404 * @param {string} wholeMatch 1405 * @param {string} m1 1406 * @returns {string} 1407 */ 1408showdown.helper.escapeCharactersCallback = escapeCharactersCallback; 1409 1410/** 1411 * Escape characters in a string 1412 * @static 1413 * @param {string} text 1414 * @param {string} charsToEscape 1415 * @param {boolean} afterBackslash 1416 * @returns {XML|string|void|*} 1417 */ 1418showdown.helper.escapeCharacters = function (text, charsToEscape, afterBackslash) { 1419 'use strict'; 1420 // First we have to escape the escape characters so that 1421 // we can build a character class out of them 1422 var regexString = '([' + charsToEscape.replace(/([\[\]\\])/g, '\\$1') + '])'; 1423 1424 if (afterBackslash) { 1425 regexString = '\\\\' + regexString; 1426 } 1427 1428 var regex = new RegExp(regexString, 'g'); 1429 text = text.replace(regex, escapeCharactersCallback); 1430 1431 return text; 1432}; 1433 1434/** 1435 * Unescape HTML entities 1436 * @param txt 1437 * @returns {string} 1438 */ 1439showdown.helper.unescapeHTMLEntities = function (txt) { 1440 'use strict'; 1441 1442 return txt 1443 .replace(/"/g, '"') 1444 .replace(/</g, '<') 1445 .replace(/>/g, '>') 1446 .replace(/&/g, '&'); 1447}; 1448 1449var rgxFindMatchPos = function (str, left, right, flags) { 1450 'use strict'; 1451 var f = flags || '', 1452 g = f.indexOf('g') > -1, 1453 x = new RegExp(left + '|' + right, 'g' + f.replace(/g/g, '')), 1454 l = new RegExp(left, f.replace(/g/g, '')), 1455 pos = [], 1456 t, s, m, start, end; 1457 1458 do { 1459 t = 0; 1460 while ((m = x.exec(str))) { 1461 if (l.test(m[0])) { 1462 if (!(t++)) { 1463 s = x.lastIndex; 1464 start = s - m[0].length; 1465 } 1466 } else if (t) { 1467 if (!--t) { 1468 end = m.index + m[0].length; 1469 var obj = { 1470 left: {start: start, end: s}, 1471 match: {start: s, end: m.index}, 1472 right: {start: m.index, end: end}, 1473 wholeMatch: {start: start, end: end} 1474 }; 1475 pos.push(obj); 1476 if (!g) { 1477 return pos; 1478 } 1479 } 1480 } 1481 } 1482 } while (t && (x.lastIndex = s)); 1483 1484 return pos; 1485}; 1486 1487/** 1488 * matchRecursiveRegExp 1489 * 1490 * (c) 2007 Steven Levithan <stevenlevithan.com> 1491 * MIT License 1492 * 1493 * Accepts a string to search, a left and right format delimiter 1494 * as regex patterns, and optional regex flags. Returns an array 1495 * of matches, allowing nested instances of left/right delimiters. 1496 * Use the "g" flag to return all matches, otherwise only the 1497 * first is returned. Be careful to ensure that the left and 1498 * right format delimiters produce mutually exclusive matches. 1499 * Backreferences are not supported within the right delimiter 1500 * due to how it is internally combined with the left delimiter. 1501 * When matching strings whose format delimiters are unbalanced 1502 * to the left or right, the output is intentionally as a 1503 * conventional regex library with recursion support would 1504 * produce, e.g. "<<x>" and "<x>>" both produce ["x"] when using 1505 * "<" and ">" as the delimiters (both strings contain a single, 1506 * balanced instance of "<x>"). 1507 * 1508 * examples: 1509 * matchRecursiveRegExp("test", "\\(", "\\)") 1510 * returns: [] 1511 * matchRecursiveRegExp("<t<<e>><s>>t<>", "<", ">", "g") 1512 * returns: ["t<<e>><s>", ""] 1513 * matchRecursiveRegExp("<div id=\"x\">test</div>", "<div\\b[^>]*>", "</div>", "gi") 1514 * returns: ["test"] 1515 */ 1516showdown.helper.matchRecursiveRegExp = function (str, left, right, flags) { 1517 'use strict'; 1518 1519 var matchPos = rgxFindMatchPos (str, left, right, flags), 1520 results = []; 1521 1522 for (var i = 0; i < matchPos.length; ++i) { 1523 results.push([ 1524 str.slice(matchPos[i].wholeMatch.start, matchPos[i].wholeMatch.end), 1525 str.slice(matchPos[i].match.start, matchPos[i].match.end), 1526 str.slice(matchPos[i].left.start, matchPos[i].left.end), 1527 str.slice(matchPos[i].right.start, matchPos[i].right.end) 1528 ]); 1529 } 1530 return results; 1531}; 1532 1533/** 1534 * 1535 * @param {string} str 1536 * @param {string|function} replacement 1537 * @param {string} left 1538 * @param {string} right 1539 * @param {string} flags 1540 * @returns {string} 1541 */ 1542showdown.helper.replaceRecursiveRegExp = function (str, replacement, left, right, flags) { 1543 'use strict'; 1544 1545 if (!showdown.helper.isFunction(replacement)) { 1546 var repStr = replacement; 1547 replacement = function () { 1548 return repStr; 1549 }; 1550 } 1551 1552 var matchPos = rgxFindMatchPos(str, left, right, flags), 1553 finalStr = str, 1554 lng = matchPos.length; 1555 1556 if (lng > 0) { 1557 var bits = []; 1558 if (matchPos[0].wholeMatch.start !== 0) { 1559 bits.push(str.slice(0, matchPos[0].wholeMatch.start)); 1560 } 1561 for (var i = 0; i < lng; ++i) { 1562 bits.push( 1563 replacement( 1564 str.slice(matchPos[i].wholeMatch.start, matchPos[i].wholeMatch.end), 1565 str.slice(matchPos[i].match.start, matchPos[i].match.end), 1566 str.slice(matchPos[i].left.start, matchPos[i].left.end), 1567 str.slice(matchPos[i].right.start, matchPos[i].right.end) 1568 ) 1569 ); 1570 if (i < lng - 1) { 1571 bits.push(str.slice(matchPos[i].wholeMatch.end, matchPos[i + 1].wholeMatch.start)); 1572 } 1573 } 1574 if (matchPos[lng - 1].wholeMatch.end < str.length) { 1575 bits.push(str.slice(matchPos[lng - 1].wholeMatch.end)); 1576 } 1577 finalStr = bits.join(''); 1578 } 1579 return finalStr; 1580}; 1581 1582/** 1583 * Returns the index within the passed String object of the first occurrence of the specified regex, 1584 * starting the search at fromIndex. Returns -1 if the value is not found. 1585 * 1586 * @param {string} str string to search 1587 * @param {RegExp} regex Regular expression to search 1588 * @param {int} [fromIndex = 0] Index to start the search 1589 * @returns {Number} 1590 * @throws InvalidArgumentError 1591 */ 1592showdown.helper.regexIndexOf = function (str, regex, fromIndex) { 1593 'use strict'; 1594 if (!showdown.helper.isString(str)) { 1595 throw 'InvalidArgumentError: first parameter of showdown.helper.regexIndexOf function must be a string'; 1596 } 1597 if (regex instanceof RegExp === false) { 1598 throw 'InvalidArgumentError: second parameter of showdown.helper.regexIndexOf function must be an instance of RegExp'; 1599 } 1600 var indexOf = str.substring(fromIndex || 0).search(regex); 1601 return (indexOf >= 0) ? (indexOf + (fromIndex || 0)) : indexOf; 1602}; 1603 1604/** 1605 * Splits the passed string object at the defined index, and returns an array composed of the two substrings 1606 * @param {string} str string to split 1607 * @param {int} index index to split string at 1608 * @returns {[string,string]} 1609 * @throws InvalidArgumentError 1610 */ 1611showdown.helper.splitAtIndex = function (str, index) { 1612 'use strict'; 1613 if (!showdown.helper.isString(str)) { 1614 throw 'InvalidArgumentError: first parameter of showdown.helper.regexIndexOf function must be a string'; 1615 } 1616 return [str.substring(0, index), str.substring(index)]; 1617}; 1618 1619/** 1620 * Obfuscate an e-mail address through the use of Character Entities, 1621 * transforming ASCII characters into their equivalent decimal or hex entities. 1622 * 1623 * Since it has a random component, subsequent calls to this function produce different results 1624 * 1625 * @param {string} mail 1626 * @returns {string} 1627 */ 1628showdown.helper.encodeEmailAddress = function (mail) { 1629 'use strict'; 1630 var encode = [ 1631 function (ch) { 1632 return '&#' + ch.charCodeAt(0) + ';'; 1633 }, 1634 function (ch) { 1635 return '&#x' + ch.charCodeAt(0).toString(16) + ';'; 1636 }, 1637 function (ch) { 1638 return ch; 1639 } 1640 ]; 1641 1642 mail = mail.replace(/./g, function (ch) { 1643 if (ch === '@') { 1644 // this *must* be encoded. I insist. 1645 ch = encode[Math.floor(Math.random() * 2)](ch); 1646 } else { 1647 var r = Math.random(); 1648 // roughly 10% raw, 45% hex, 45% dec 1649 ch = ( 1650 r > 0.9 ? encode[2](ch) : r > 0.45 ? encode[1](ch) : encode[0](ch) 1651 ); 1652 } 1653 return ch; 1654 }); 1655 1656 return mail; 1657}; 1658 1659/** 1660 * 1661 * @param str 1662 * @param targetLength 1663 * @param padString 1664 * @returns {string} 1665 */ 1666showdown.helper.padEnd = function padEnd (str, targetLength, padString) { 1667 'use strict'; 1668 /*jshint bitwise: false*/ 1669 // eslint-disable-next-line space-infix-ops 1670 targetLength = targetLength>>0; //floor if number or convert non-number to 0; 1671 /*jshint bitwise: true*/ 1672 padString = String(padString || ' '); 1673 if (str.length > targetLength) { 1674 return String(str); 1675 } else { 1676 targetLength = targetLength - str.length; 1677 if (targetLength > padString.length) { 1678 padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed 1679 } 1680 return String(str) + padString.slice(0,targetLength); 1681 } 1682}; 1683 1684/** 1685 * POLYFILLS 1686 */ 1687// use this instead of builtin is undefined for IE8 compatibility 1688if (typeof
1688console
vendor: 50,509 bytes, lines 1688-3291
1688 === 'undefined') { 1689 console = { 1690 warn: function (msg) { 1691 'use strict'; 1692 alert(msg); 1693 }, 1694 log: function (msg) { 1695 'use strict'; 1696 alert(msg); 1697 }, 1698 error: function (msg) { 1699 'use strict'; 1700 throw msg; 1701 } 1702 }; 1703} 1704 1705/** 1706 * Common regexes. 1707 * We declare some common regexes to improve performance 1708 */ 1709showdown.helper.regexes = { 1710 asteriskDashAndColon: /([*_:~])/g 1711}; 1712 1713/** 1714 * EMOJIS LIST 1715 */ 1716showdown.helper.emojis = { 1717 '+1':'\ud83d\udc4d', 1718 '-1':'\ud83d\udc4e', 1719 '100':'\ud83d\udcaf', 1720 '1234':'\ud83d\udd22', 1721 '1st_place_medal':'\ud83e\udd47', 1722 '2nd_place_medal':'\ud83e\udd48', 1723 '3rd_place_medal':'\ud83e\udd49', 1724 '8ball':'\ud83c\udfb1', 1725 'a':'\ud83c\udd70\ufe0f', 1726 'ab':'\ud83c\udd8e', 1727 'abc':'\ud83d\udd24', 1728 'abcd':'\ud83d\udd21', 1729 'accept':'\ud83c\ude51', 1730 'aerial_tramway':'\ud83d\udea1', 1731 'airplane':'\u2708\ufe0f', 1732 'alarm_clock':'\u23f0', 1733 'alembic':'\u2697\ufe0f', 1734 'alien':'\ud83d\udc7d', 1735 'ambulance':'\ud83d\ude91', 1736 'amphora':'\ud83c\udffa', 1737 'anchor':'\u2693\ufe0f', 1738 'angel':'\ud83d\udc7c', 1739 'anger':'\ud83d\udca2', 1740 'angry':'\ud83d\ude20', 1741 'anguished':'\ud83d\ude27', 1742 'ant':'\ud83d\udc1c', 1743 'apple':'\ud83c\udf4e', 1744 'aquarius':'\u2652\ufe0f', 1745 'aries':'\u2648\ufe0f', 1746 'arrow_backward':'\u25c0\ufe0f', 1747 'arrow_double_down':'\u23ec', 1748 'arrow_double_up':'\u23eb', 1749 'arrow_down':'\u2b07\ufe0f', 1750 'arrow_down_small':'\ud83d\udd3d', 1751 'arrow_forward':'\u25b6\ufe0f', 1752 'arrow_heading_down':'\u2935\ufe0f', 1753 'arrow_heading_up':'\u2934\ufe0f', 1754 'arrow_left':'\u2b05\ufe0f', 1755 'arrow_lower_left':'\u2199\ufe0f', 1756 'arrow_lower_right':'\u2198\ufe0f', 1757 'arrow_right':'\u27a1\ufe0f', 1758 'arrow_right_hook':'\u21aa\ufe0f', 1759 'arrow_up':'\u2b06\ufe0f', 1760 'arrow_up_down':'\u2195\ufe0f', 1761 'arrow_up_small':'\ud83d\udd3c', 1762 'arrow_upper_left':'\u2196\ufe0f', 1763 'arrow_upper_right':'\u2197\ufe0f', 1764 'arrows_clockwise':'\ud83d\udd03', 1765 'arrows_counterclockwise':'\ud83d\udd04', 1766 'art':'\ud83c\udfa8', 1767 'articulated_lorry':'\ud83d\ude9b', 1768 'artificial_satellite':'\ud83d\udef0', 1769 'astonished':'\ud83d\ude32', 1770 'athletic_shoe':'\ud83d\udc5f', 1771 'atm':'\ud83c\udfe7', 1772 'atom_symbol':'\u269b\ufe0f', 1773 'avocado':'\ud83e\udd51', 1774 'b':'\ud83c\udd71\ufe0f', 1775 'baby':'\ud83d\udc76', 1776 'baby_bottle':'\ud83c\udf7c', 1777 'baby_chick':'\ud83d\udc24', 1778 'baby_symbol':'\ud83d\udebc', 1779 'back':'\ud83d\udd19', 1780 'bacon':'\ud83e\udd53', 1781 'badminton':'\ud83c\udff8', 1782 'baggage_claim':'\ud83d\udec4', 1783 'baguette_bread':'\ud83e\udd56', 1784 'balance_scale':'\u2696\ufe0f', 1785 'balloon':'\ud83c\udf88', 1786 'ballot_box':'\ud83d\uddf3', 1787 'ballot_box_with_check':'\u2611\ufe0f', 1788 'bamboo':'\ud83c\udf8d', 1789 'banana':'\ud83c\udf4c', 1790 'bangbang':'\u203c\ufe0f', 1791 'bank':'\ud83c\udfe6', 1792 'bar_chart':'\ud83d\udcca', 1793 'barber':'\ud83d\udc88', 1794 'baseball':'\u26be\ufe0f', 1795 'basketball':'\ud83c\udfc0', 1796 'basketball_man':'\u26f9\ufe0f', 1797 'basketball_woman':'\u26f9\ufe0f‍\u2640\ufe0f', 1798 'bat':'\ud83e\udd87', 1799 'bath':'\ud83d\udec0', 1800 'bathtub':'\ud83d\udec1', 1801 'battery':'\ud83d\udd0b', 1802 'beach_umbrella':'\ud83c\udfd6', 1803 'bear':'\ud83d\udc3b', 1804 'bed':'\ud83d\udecf', 1805 'bee':'\ud83d\udc1d', 1806 'beer':'\ud83c\udf7a', 1807 'beers':'\ud83c\udf7b', 1808 'beetle':'\ud83d\udc1e', 1809 'beginner':'\ud83d\udd30', 1810 'bell':'\ud83d\udd14', 1811 'bellhop_bell':'\ud83d\udece', 1812 'bento':'\ud83c\udf71', 1813 'biking_man':'\ud83d\udeb4', 1814 'bike':'\ud83d\udeb2', 1815 'biking_woman':'\ud83d\udeb4‍\u2640\ufe0f', 1816 'bikini':'\ud83d\udc59', 1817 'biohazard':'\u2623\ufe0f', 1818 'bird':'\ud83d\udc26', 1819 'birthday':'\ud83c\udf82', 1820 'black_circle':'\u26ab\ufe0f', 1821 'black_flag':'\ud83c\udff4', 1822 'black_heart':'\ud83d\udda4', 1823 'black_joker':'\ud83c\udccf', 1824 'black_large_square':'\u2b1b\ufe0f', 1825 'black_medium_small_square':'\u25fe\ufe0f', 1826 'black_medium_square':'\u25fc\ufe0f', 1827 'black_nib':'\u2712\ufe0f', 1828 'black_small_square':'\u25aa\ufe0f', 1829 'black_square_button':'\ud83d\udd32', 1830 'blonde_man':'\ud83d\udc71', 1831 'blonde_woman':'\ud83d\udc71‍\u2640\ufe0f', 1832 'blossom':'\ud83c\udf3c', 1833 'blowfish':'\ud83d\udc21', 1834 'blue_book':'\ud83d\udcd8', 1835 'blue_car':'\ud83d\ude99', 1836 'blue_heart':'\ud83d\udc99', 1837 'blush':'\ud83d\ude0a', 1838 'boar':'\ud83d\udc17', 1839 'boat':'\u26f5\ufe0f', 1840 'bomb':'\ud83d\udca3', 1841 'book':'\ud83d\udcd6', 1842 'bookmark':'\ud83d\udd16', 1843 'bookmark_tabs':'\ud83d\udcd1', 1844 'books':'\ud83d\udcda', 1845 'boom':'\ud83d\udca5', 1846 'boot':'\ud83d\udc62', 1847 'bouquet':'\ud83d\udc90', 1848 'bowing_man':'\ud83d\ude47', 1849 'bow_and_arrow':'\ud83c\udff9', 1850 'bowing_woman':'\ud83d\ude47‍\u2640\ufe0f', 1851 'bowling':'\ud83c\udfb3', 1852 'boxing_glove':'\ud83e\udd4a', 1853 'boy':'\ud83d\udc66', 1854 'bread':'\ud83c\udf5e', 1855 'bride_with_veil':'\ud83d\udc70', 1856 'bridge_at_night':'\ud83c\udf09', 1857 'briefcase':'\ud83d\udcbc', 1858 'broken_heart':'\ud83d\udc94', 1859 'bug':'\ud83d\udc1b', 1860 'building_construction':'\ud83c\udfd7', 1861 'bulb':'\ud83d\udca1', 1862 'bullettrain_front':'\ud83d\ude85', 1863 'bullettrain_side':'\ud83d\ude84', 1864 'burrito':'\ud83c\udf2f', 1865 'bus':'\ud83d\ude8c', 1866 'business_suit_levitating':'\ud83d\udd74', 1867 'busstop':'\ud83d\ude8f', 1868 'bust_in_silhouette':'\ud83d\udc64', 1869 'busts_in_silhouette':'\ud83d\udc65', 1870 'butterfly':'\ud83e\udd8b', 1871 'cactus':'\ud83c\udf35', 1872 'cake':'\ud83c\udf70', 1873 'calendar':'\ud83d\udcc6', 1874 'call_me_hand':'\ud83e\udd19', 1875 'calling':'\ud83d\udcf2', 1876 'camel':'\ud83d\udc2b', 1877 'camera':'\ud83d\udcf7', 1878 'camera_flash':'\ud83d\udcf8', 1879 'camping':'\ud83c\udfd5', 1880 'cancer':'\u264b\ufe0f', 1881 'candle':'\ud83d\udd6f', 1882 'candy':'\ud83c\udf6c', 1883 'canoe':'\ud83d\udef6', 1884 'capital_abcd':'\ud83d\udd20', 1885 'capricorn':'\u2651\ufe0f', 1886 'car':'\ud83d\ude97', 1887 'card_file_box':'\ud83d\uddc3', 1888 'card_index':'\ud83d\udcc7', 1889 'card_index_dividers':'\ud83d\uddc2', 1890 'carousel_horse':'\ud83c\udfa0', 1891 'carrot':'\ud83e\udd55', 1892 'cat':'\ud83d\udc31', 1893 'cat2':'\ud83d\udc08', 1894 'cd':'\ud83d\udcbf', 1895 'chains':'\u26d3', 1896 'champagne':'\ud83c\udf7e', 1897 'chart':'\ud83d\udcb9', 1898 'chart_with_downwards_trend':'\ud83d\udcc9', 1899 'chart_with_upwards_trend':'\ud83d\udcc8', 1900 'checkered_flag':'\ud83c\udfc1', 1901 'cheese':'\ud83e\uddc0', 1902 'cherries':'\ud83c\udf52', 1903 'cherry_blossom':'\ud83c\udf38', 1904 'chestnut':'\ud83c\udf30', 1905 'chicken':'\ud83d\udc14', 1906 'children_crossing':'\ud83d\udeb8', 1907 'chipmunk':'\ud83d\udc3f', 1908 'chocolate_bar':'\ud83c\udf6b', 1909 'christmas_tree':'\ud83c\udf84', 1910 'church':'\u26ea\ufe0f', 1911 'cinema':'\ud83c\udfa6', 1912 'circus_tent':'\ud83c\udfaa', 1913 'city_sunrise':'\ud83c\udf07', 1914 'city_sunset':'\ud83c\udf06', 1915 'cityscape':'\ud83c\udfd9', 1916 'cl':'\ud83c\udd91', 1917 'clamp':'\ud83d\udddc', 1918 'clap':'\ud83d\udc4f', 1919 'clapper':'\ud83c\udfac', 1920 'classical_building':'\ud83c\udfdb', 1921 'clinking_glasses':'\ud83e\udd42', 1922 'clipboard':'\ud83d\udccb', 1923 'clock1':'\ud83d\udd50', 1924 'clock10':'\ud83d\udd59', 1925 'clock1030':'\ud83d\udd65', 1926 'clock11':'\ud83d\udd5a', 1927 'clock1130':'\ud83d\udd66', 1928 'clock12':'\ud83d\udd5b', 1929 'clock1230':'\ud83d\udd67', 1930 'clock130':'\ud83d\udd5c', 1931 'clock2':'\ud83d\udd51', 1932 'clock230':'\ud83d\udd5d', 1933 'clock3':'\ud83d\udd52', 1934 'clock330':'\ud83d\udd5e', 1935 'clock4':'\ud83d\udd53', 1936 'clock430':'\ud83d\udd5f', 1937 'clock5':'\ud83d\udd54', 1938 'clock530':'\ud83d\udd60', 1939 'clock6':'\ud83d\udd55', 1940 'clock630':'\ud83d\udd61', 1941 'clock7':'\ud83d\udd56', 1942 'clock730':'\ud83d\udd62', 1943 'clock8':'\ud83d\udd57', 1944 'clock830':'\ud83d\udd63', 1945 'clock9':'\ud83d\udd58', 1946 'clock930':'\ud83d\udd64', 1947 'closed_book':'\ud83d\udcd5', 1948 'closed_lock_with_key':'\ud83d\udd10', 1949 'closed_umbrella':'\ud83c\udf02', 1950 'cloud':'\u2601\ufe0f', 1951 'cloud_with_lightning':'\ud83c\udf29', 1952 'cloud_with_lightning_and_rain':'\u26c8', 1953 'cloud_with_rain':'\ud83c\udf27', 1954 'cloud_with_snow':'\ud83c\udf28', 1955 'clown_face':'\ud83e\udd21', 1956 'clubs':'\u2663\ufe0f', 1957 'cocktail':'\ud83c\udf78', 1958 'coffee':'\u2615\ufe0f', 1959 'coffin':'\u26b0\ufe0f', 1960 'cold_sweat':'\ud83d\ude30', 1961 'comet':'\u2604\ufe0f', 1962 'computer':'\ud83d\udcbb', 1963 'computer_mouse':'\ud83d\uddb1', 1964 'confetti_ball':'\ud83c\udf8a', 1965 'confounded':'\ud83d\ude16', 1966 'confused':'\ud83d\ude15', 1967 'congratulations':'\u3297\ufe0f', 1968 'construction':'\ud83d\udea7', 1969 'construction_worker_man':'\ud83d\udc77', 1970 'construction_worker_woman':'\ud83d\udc77‍\u2640\ufe0f', 1971 'control_knobs':'\ud83c\udf9b', 1972 'convenience_store':'\ud83c\udfea', 1973 'cookie':'\ud83c\udf6a', 1974 'cool':'\ud83c\udd92', 1975 'policeman':'\ud83d\udc6e', 1976 'copyright':'\u00a9\ufe0f', 1977 'corn':'\ud83c\udf3d', 1978 'couch_and_lamp':'\ud83d\udecb', 1979 'couple':'\ud83d\udc6b', 1980 'couple_with_heart_woman_man':'\ud83d\udc91', 1981 'couple_with_heart_man_man':'\ud83d\udc68‍\u2764\ufe0f‍\ud83d\udc68', 1982 'couple_with_heart_woman_woman':'\ud83d\udc69‍\u2764\ufe0f‍\ud83d\udc69', 1983 'couplekiss_man_man':'\ud83d\udc68‍\u2764\ufe0f‍\ud83d\udc8b‍\ud83d\udc68', 1984 'couplekiss_man_woman':'\ud83d\udc8f', 1985 'couplekiss_woman_woman':'\ud83d\udc69‍\u2764\ufe0f‍\ud83d\udc8b‍\ud83d\udc69', 1986 'cow':'\ud83d\udc2e', 1987 'cow2':'\ud83d\udc04', 1988 'cowboy_hat_face':'\ud83e\udd20', 1989 'crab':'\ud83e\udd80', 1990 'crayon':'\ud83d\udd8d', 1991 'credit_card':'\ud83d\udcb3', 1992 'crescent_moon':'\ud83c\udf19', 1993 'cricket':'\ud83c\udfcf', 1994 'crocodile':'\ud83d\udc0a', 1995 'croissant':'\ud83e\udd50', 1996 'crossed_fingers':'\ud83e\udd1e', 1997 'crossed_flags':'\ud83c\udf8c', 1998 'crossed_swords':'\u2694\ufe0f', 1999 'crown':'\ud83d\udc51', 2000 'cry':'\ud83d\ude22', 2001 'crying_cat_face':'\ud83d\ude3f', 2002 'crystal_ball':'\ud83d\udd2e', 2003 'cucumber':'\ud83e\udd52', 2004 'cupid':'\ud83d\udc98', 2005 'curly_loop':'\u27b0', 2006 'currency_exchange':'\ud83d\udcb1', 2007 'curry':'\ud83c\udf5b', 2008 'custard':'\ud83c\udf6e', 2009 'customs':'\ud83d\udec3', 2010 'cyclone':'\ud83c\udf00', 2011 'dagger':'\ud83d\udde1', 2012 'dancer':'\ud83d\udc83', 2013 'dancing_women':'\ud83d\udc6f', 2014 'dancing_men':'\ud83d\udc6f‍\u2642\ufe0f', 2015 'dango':'\ud83c\udf61', 2016 'dark_sunglasses':'\ud83d\udd76', 2017 'dart':'\ud83c\udfaf', 2018 'dash':'\ud83d\udca8', 2019 'date':'\ud83d\udcc5', 2020 'deciduous_tree':'\ud83c\udf33', 2021 'deer':'\ud83e\udd8c', 2022 'department_store':'\ud83c\udfec', 2023 'derelict_house':'\ud83c\udfda', 2024 'desert':'\ud83c\udfdc', 2025 'desert_island':'\ud83c\udfdd', 2026 'desktop_computer':'\ud83d\udda5', 2027 'male_detective':'\ud83d\udd75\ufe0f', 2028 'diamond_shape_with_a_dot_inside':'\ud83d\udca0', 2029 'diamonds':'\u2666\ufe0f', 2030 'disappointed':'\ud83d\ude1e', 2031 'disappointed_relieved':'\ud83d\ude25', 2032 'dizzy':'\ud83d\udcab', 2033 'dizzy_face':'\ud83d\ude35', 2034 'do_not_litter':'\ud83d\udeaf', 2035 'dog':'\ud83d\udc36', 2036 'dog2':'\ud83d\udc15', 2037 'dollar':'\ud83d\udcb5', 2038 'dolls':'\ud83c\udf8e', 2039 'dolphin':'\ud83d\udc2c', 2040 'door':'\ud83d\udeaa', 2041 'doughnut':'\ud83c\udf69', 2042 'dove':'\ud83d\udd4a', 2043 'dragon':'\ud83d\udc09', 2044 'dragon_face':'\ud83d\udc32', 2045 'dress':'\ud83d\udc57', 2046 'dromedary_camel':'\ud83d\udc2a', 2047 'drooling_face':'\ud83e\udd24', 2048 'droplet':'\ud83d\udca7', 2049 'drum':'\ud83e\udd41', 2050 'duck':'\ud83e\udd86', 2051 'dvd':'\ud83d\udcc0', 2052 'e-mail':'\ud83d\udce7', 2053 'eagle':'\ud83e\udd85', 2054 'ear':'\ud83d\udc42', 2055 'ear_of_rice':'\ud83c\udf3e', 2056 'earth_africa':'\ud83c\udf0d', 2057 'earth_americas':'\ud83c\udf0e', 2058 'earth_asia':'\ud83c\udf0f', 2059 'egg':'\ud83e\udd5a', 2060 'eggplant':'\ud83c\udf46', 2061 'eight_pointed_black_star':'\u2734\ufe0f', 2062 'eight_spoked_asterisk':'\u2733\ufe0f', 2063 'electric_plug':'\ud83d\udd0c', 2064 'elephant':'\ud83d\udc18', 2065 'email':'\u2709\ufe0f', 2066 'end':'\ud83d\udd1a', 2067 'envelope_with_arrow':'\ud83d\udce9', 2068 'euro':'\ud83d\udcb6', 2069 'european_castle':'\ud83c\udff0', 2070 'european_post_office':'\ud83c\udfe4', 2071 'evergreen_tree':'\ud83c\udf32', 2072 'exclamation':'\u2757\ufe0f', 2073 'expressionless':'\ud83d\ude11', 2074 'eye':'\ud83d\udc41', 2075 'eye_speech_bubble':'\ud83d\udc41‍\ud83d\udde8', 2076 'eyeglasses':'\ud83d\udc53', 2077 'eyes':'\ud83d\udc40', 2078 'face_with_head_bandage':'\ud83e\udd15', 2079 'face_with_thermometer':'\ud83e\udd12', 2080 'fist_oncoming':'\ud83d\udc4a', 2081 'factory':'\ud83c\udfed', 2082 'fallen_leaf':'\ud83c\udf42', 2083 'family_man_woman_boy':'\ud83d\udc6a', 2084 'family_man_boy':'\ud83d\udc68‍\ud83d\udc66', 2085 'family_man_boy_boy':'\ud83d\udc68‍\ud83d\udc66‍\ud83d\udc66', 2086 'family_man_girl':'\ud83d\udc68‍\ud83d\udc67', 2087 'family_man_girl_boy':'\ud83d\udc68‍\ud83d\udc67‍\ud83d\udc66', 2088 'family_man_girl_girl':'\ud83d\udc68‍\ud83d\udc67‍\ud83d\udc67', 2089 'family_man_man_boy':'\ud83d\udc68‍\ud83d\udc68‍\ud83d\udc66', 2090 'family_man_man_boy_boy':'\ud83d\udc68‍\ud83d\udc68‍\ud83d\udc66‍\ud83d\udc66', 2091 'family_man_man_girl':'\ud83d\udc68‍\ud83d\udc68‍\ud83d\udc67', 2092 'family_man_man_girl_boy':'\ud83d\udc68‍\ud83d\udc68‍\ud83d\udc67‍\ud83d\udc66', 2093 'family_man_man_girl_girl':'\ud83d\udc68‍\ud83d\udc68‍\ud83d\udc67‍\ud83d\udc67', 2094 'family_man_woman_boy_boy':'\ud83d\udc68‍\ud83d\udc69‍\ud83d\udc66‍\ud83d\udc66', 2095 'family_man_woman_girl':'\ud83d\udc68‍\ud83d\udc69‍\ud83d\udc67', 2096 'family_man_woman_girl_boy':'\ud83d\udc68‍\ud83d\udc69‍\ud83d\udc67‍\ud83d\udc66', 2097 'family_man_woman_girl_girl':'\ud83d\udc68‍\ud83d\udc69‍\ud83d\udc67‍\ud83d\udc67', 2098 'family_woman_boy':'\ud83d\udc69‍\ud83d\udc66', 2099 'family_woman_boy_boy':'\ud83d\udc69‍\ud83d\udc66‍\ud83d\udc66', 2100 'family_woman_girl':'\ud83d\udc69‍\ud83d\udc67', 2101 'family_woman_girl_boy':'\ud83d\udc69‍\ud83d\udc67‍\ud83d\udc66', 2102 'family_woman_girl_girl':'\ud83d\udc69‍\ud83d\udc67‍\ud83d\udc67', 2103 'family_woman_woman_boy':'\ud83d\udc69‍\ud83d\udc69‍\ud83d\udc66', 2104 'family_woman_woman_boy_boy':'\ud83d\udc69‍\ud83d\udc69‍\ud83d\udc66‍\ud83d\udc66', 2105 'family_woman_woman_girl':'\ud83d\udc69‍\ud83d\udc69‍\ud83d\udc67', 2106 'family_woman_woman_girl_boy':'\ud83d\udc69‍\ud83d\udc69‍\ud83d\udc67‍\ud83d\udc66', 2107 'family_woman_woman_girl_girl':'\ud83d\udc69‍\ud83d\udc69‍\ud83d\udc67‍\ud83d\udc67', 2108 'fast_forward':'\u23e9', 2109 'fax':'\ud83d\udce0', 2110 'fearful':'\ud83d\ude28', 2111 'feet':'\ud83d\udc3e', 2112 'female_detective':'\ud83d\udd75\ufe0f‍\u2640\ufe0f', 2113 'ferris_wheel':'\ud83c\udfa1', 2114 'ferry':'\u26f4', 2115 'field_hockey':'\ud83c\udfd1', 2116 'file_cabinet':'\ud83d\uddc4', 2117 'file_folder':'\ud83d\udcc1', 2118 'film_projector':'\ud83d\udcfd', 2119 'film_strip':'\ud83c\udf9e', 2120 'fire':'\ud83d\udd25', 2121 'fire_engine':'\ud83d\ude92', 2122 'fireworks':'\ud83c\udf86', 2123 'first_quarter_moon':'\ud83c\udf13', 2124 'first_quarter_moon_with_face':'\ud83c\udf1b', 2125 'fish':'\ud83d\udc1f', 2126 'fish_cake':'\ud83c\udf65', 2127 'fishing_pole_and_fish':'\ud83c\udfa3', 2128 'fist_raised':'\u270a', 2129 'fist_left':'\ud83e\udd1b', 2130 'fist_right':'\ud83e\udd1c', 2131 'flags':'\ud83c\udf8f', 2132 'flashlight':'\ud83d\udd26', 2133 'fleur_de_lis':'\u269c\ufe0f', 2134 'flight_arrival':'\ud83d\udeec', 2135 'flight_departure':'\ud83d\udeeb', 2136 'floppy_disk':'\ud83d\udcbe', 2137 'flower_playing_cards':'\ud83c\udfb4', 2138 'flushed':'\ud83d\ude33', 2139 'fog':'\ud83c\udf2b', 2140 'foggy':'\ud83c\udf01', 2141 'football':'\ud83c\udfc8', 2142 'footprints':'\ud83d\udc63', 2143 'fork_and_knife':'\ud83c\udf74', 2144 'fountain':'\u26f2\ufe0f', 2145 'fountain_pen':'\ud83d\udd8b', 2146 'four_leaf_clover':'\ud83c\udf40', 2147 'fox_face':'\ud83e\udd8a', 2148 'framed_picture':'\ud83d\uddbc', 2149 'free':'\ud83c\udd93', 2150 'fried_egg':'\ud83c\udf73', 2151 'fried_shrimp':'\ud83c\udf64', 2152 'fries':'\ud83c\udf5f', 2153 'frog':'\ud83d\udc38', 2154 'frowning':'\ud83d\ude26', 2155 'frowning_face':'\u2639\ufe0f', 2156 'frowning_man':'\ud83d\ude4d‍\u2642\ufe0f', 2157 'frowning_woman':'\ud83d\ude4d', 2158 'middle_finger':'\ud83d\udd95', 2159 'fuelpump':'\u26fd\ufe0f', 2160 'full_moon':'\ud83c\udf15', 2161 'full_moon_with_face':'\ud83c\udf1d', 2162 'funeral_urn':'\u26b1\ufe0f', 2163 'game_die':'\ud83c\udfb2', 2164 'gear':'\u2699\ufe0f', 2165 'gem':'\ud83d\udc8e', 2166 'gemini':'\u264a\ufe0f', 2167 'ghost':'\ud83d\udc7b', 2168 'gift':'\ud83c\udf81', 2169 'gift_heart':'\ud83d\udc9d', 2170 'girl':'\ud83d\udc67', 2171 'globe_with_meridians':'\ud83c\udf10', 2172 'goal_net':'\ud83e\udd45', 2173 'goat':'\ud83d\udc10', 2174 'golf':'\u26f3\ufe0f', 2175 'golfing_man':'\ud83c\udfcc\ufe0f', 2176 'golfing_woman':'\ud83c\udfcc\ufe0f‍\u2640\ufe0f', 2177 'gorilla':'\ud83e\udd8d', 2178 'grapes':'\ud83c\udf47', 2179 'green_apple':'\ud83c\udf4f', 2180 'green_book':'\ud83d\udcd7', 2181 'green_heart':'\ud83d\udc9a', 2182 'green_salad':'\ud83e\udd57', 2183 'grey_exclamation':'\u2755', 2184 'grey_question':'\u2754', 2185 'grimacing':'\ud83d\ude2c', 2186 'grin':'\ud83d\ude01', 2187 'grinning':'\ud83d\ude00', 2188 'guardsman':'\ud83d\udc82', 2189 'guardswoman':'\ud83d\udc82‍\u2640\ufe0f', 2190 'guitar':'\ud83c\udfb8', 2191 'gun':'\ud83d\udd2b', 2192 'haircut_woman':'\ud83d\udc87', 2193 'haircut_man':'\ud83d\udc87‍\u2642\ufe0f', 2194 'hamburger':'\ud83c\udf54', 2195 'hammer':'\ud83d\udd28', 2196 'hammer_and_pick':'\u2692', 2197 'hammer_and_wrench':'\ud83d\udee0', 2198 'hamster':'\ud83d\udc39', 2199 'hand':'\u270b', 2200 'handbag':'\ud83d\udc5c', 2201 'handshake':'\ud83e\udd1d', 2202 'hankey':'\ud83d\udca9', 2203 'hatched_chick':'\ud83d\udc25', 2204 'hatching_chick':'\ud83d\udc23', 2205 'headphones':'\ud83c\udfa7', 2206 'hear_no_evil':'\ud83d\ude49', 2207 'heart':'\u2764\ufe0f', 2208 'heart_decoration':'\ud83d\udc9f', 2209 'heart_eyes':'\ud83d\ude0d', 2210 'heart_eyes_cat':'\ud83d\ude3b', 2211 'heartbeat':'\ud83d\udc93', 2212 'heartpulse':'\ud83d\udc97', 2213 'hearts':'\u2665\ufe0f', 2214 'heavy_check_mark':'\u2714\ufe0f', 2215 'heavy_division_sign':'\u2797', 2216 'heavy_dollar_sign':'\ud83d\udcb2', 2217 'heavy_heart_exclamation':'\u2763\ufe0f', 2218 'heavy_minus_sign':'\u2796', 2219 'heavy_multiplication_x':'\u2716\ufe0f', 2220 'heavy_plus_sign':'\u2795', 2221 'helicopter':'\ud83d\ude81', 2222 'herb':'\ud83c\udf3f', 2223 'hibiscus':'\ud83c\udf3a', 2224 'high_brightness':'\ud83d\udd06', 2225 'high_heel':'\ud83d\udc60', 2226 'hocho':'\ud83d\udd2a', 2227 'hole':'\ud83d\udd73', 2228 'honey_pot':'\ud83c\udf6f', 2229 'horse':'\ud83d\udc34', 2230 'horse_racing':'\ud83c\udfc7', 2231 'hospital':'\ud83c\udfe5', 2232 'hot_pepper':'\ud83c\udf36', 2233 'hotdog':'\ud83c\udf2d', 2234 'hotel':'\ud83c\udfe8', 2235 'hotsprings':'\u2668\ufe0f', 2236 'hourglass':'\u231b\ufe0f', 2237 'hourglass_flowing_sand':'\u23f3', 2238 'house':'\ud83c\udfe0', 2239 'house_with_garden':'\ud83c\udfe1', 2240 'houses':'\ud83c\udfd8', 2241 'hugs':'\ud83e\udd17', 2242 'hushed':'\ud83d\ude2f', 2243 'ice_cream':'\ud83c\udf68', 2244 'ice_hockey':'\ud83c\udfd2', 2245 'ice_skate':'\u26f8', 2246 'icecream':'\ud83c\udf66', 2247 'id':'\ud83c\udd94', 2248 'ideograph_advantage':'\ud83c\ude50', 2249 'imp':'\ud83d\udc7f', 2250 'inbox_tray':'\ud83d\udce5', 2251 'incoming_envelope':'\ud83d\udce8', 2252 'tipping_hand_woman':'\ud83d\udc81', 2253 'information_source':'\u2139\ufe0f', 2254 'innocent':'\ud83d\ude07', 2255 'interrobang':'\u2049\ufe0f', 2256 'iphone':'\ud83d\udcf1', 2257 'izakaya_lantern':'\ud83c\udfee', 2258 'jack_o_lantern':'\ud83c\udf83', 2259 'japan':'\ud83d\uddfe', 2260 'japanese_castle':'\ud83c\udfef', 2261 'japanese_goblin':'\ud83d\udc7a', 2262 'japanese_ogre':'\ud83d\udc79', 2263 'jeans':'\ud83d\udc56', 2264 'joy':'\ud83d\ude02', 2265 'joy_cat':'\ud83d\ude39', 2266 'joystick':'\ud83d\udd79', 2267 'kaaba':'\ud83d\udd4b', 2268 'key':'\ud83d\udd11', 2269 'keyboard':'\u2328\ufe0f', 2270 'keycap_ten':'\ud83d\udd1f', 2271 'kick_scooter':'\ud83d\udef4', 2272 'kimono':'\ud83d\udc58', 2273 'kiss':'\ud83d\udc8b', 2274 'kissing':'\ud83d\ude17', 2275 'kissing_cat':'\ud83d\ude3d', 2276 'kissing_closed_eyes':'\ud83d\ude1a', 2277 'kissing_heart':'\ud83d\ude18', 2278 'kissing_smiling_eyes':'\ud83d\ude19', 2279 'kiwi_fruit':'\ud83e\udd5d', 2280 'koala':'\ud83d\udc28', 2281 'koko':'\ud83c\ude01', 2282 'label':'\ud83c\udff7', 2283 'large_blue_circle':'\ud83d\udd35', 2284 'large_blue_diamond':'\ud83d\udd37', 2285 'large_orange_diamond':'\ud83d\udd36', 2286 'last_quarter_moon':'\ud83c\udf17', 2287 'last_quarter_moon_with_face':'\ud83c\udf1c', 2288 'latin_cross':'\u271d\ufe0f', 2289 'laughing':'\ud83d\ude06', 2290 'leaves':'\ud83c\udf43', 2291 'ledger':'\ud83d\udcd2', 2292 'left_luggage':'\ud83d\udec5', 2293 'left_right_arrow':'\u2194\ufe0f', 2294 'leftwards_arrow_with_hook':'\u21a9\ufe0f', 2295 'lemon':'\ud83c\udf4b', 2296 'leo':'\u264c\ufe0f', 2297 'leopard':'\ud83d\udc06', 2298 'level_slider':'\ud83c\udf9a', 2299 'libra':'\u264e\ufe0f', 2300 'light_rail':'\ud83d\ude88', 2301 'link':'\ud83d\udd17', 2302 'lion':'\ud83e\udd81', 2303 'lips':'\ud83d\udc44', 2304 'lipstick':'\ud83d\udc84', 2305 'lizard':'\ud83e\udd8e', 2306 'lock':'\ud83d\udd12', 2307 'lock_with_ink_pen':'\ud83d\udd0f', 2308 'lollipop':'\ud83c\udf6d', 2309 'loop':'\u27bf', 2310 'loud_sound':'\ud83d\udd0a', 2311 'loudspeaker':'\ud83d\udce2', 2312 'love_hotel':'\ud83c\udfe9', 2313 'love_letter':'\ud83d\udc8c', 2314 'low_brightness':'\ud83d\udd05', 2315 'lying_face':'\ud83e\udd25', 2316 'm':'\u24c2\ufe0f', 2317 'mag':'\ud83d\udd0d', 2318 'mag_right':'\ud83d\udd0e', 2319 'mahjong':'\ud83c\udc04\ufe0f', 2320 'mailbox':'\ud83d\udceb', 2321 'mailbox_closed':'\ud83d\udcea', 2322 'mailbox_with_mail':'\ud83d\udcec', 2323 'mailbox_with_no_mail':'\ud83d\udced', 2324 'man':'\ud83d\udc68', 2325 'man_artist':'\ud83d\udc68‍\ud83c\udfa8', 2326 'man_astronaut':'\ud83d\udc68‍\ud83d\ude80', 2327 'man_cartwheeling':'\ud83e\udd38‍\u2642\ufe0f', 2328 'man_cook':'\ud83d\udc68‍\ud83c\udf73', 2329 'man_dancing':'\ud83d\udd7a', 2330 'man_facepalming':'\ud83e\udd26‍\u2642\ufe0f', 2331 'man_factory_worker':'\ud83d\udc68‍\ud83c\udfed', 2332 'man_farmer':'\ud83d\udc68‍\ud83c\udf3e', 2333 'man_firefighter':'\ud83d\udc68‍\ud83d\ude92', 2334 'man_health_worker':'\ud83d\udc68‍\u2695\ufe0f', 2335 'man_in_tuxedo':'\ud83e\udd35', 2336 'man_judge':'\ud83d\udc68‍\u2696\ufe0f', 2337 'man_juggling':'\ud83e\udd39‍\u2642\ufe0f', 2338 'man_mechanic':'\ud83d\udc68‍\ud83d\udd27', 2339 'man_office_worker':'\ud83d\udc68‍\ud83d\udcbc', 2340 'man_pilot':'\ud83d\udc68‍\u2708\ufe0f', 2341 'man_playing_handball':'\ud83e\udd3e‍\u2642\ufe0f', 2342 'man_playing_water_polo':'\ud83e\udd3d‍\u2642\ufe0f', 2343 'man_scientist':'\ud83d\udc68‍\ud83d\udd2c', 2344 'man_shrugging':'\ud83e\udd37‍\u2642\ufe0f', 2345 'man_singer':'\ud83d\udc68‍\ud83c\udfa4', 2346 'man_student':'\ud83d\udc68‍\ud83c\udf93', 2347 'man_teacher':'\ud83d\udc68‍\ud83c\udfeb', 2348 'man_technologist':'\ud83d\udc68‍\ud83d\udcbb', 2349 'man_with_gua_pi_mao':'\ud83d\udc72', 2350 'man_with_turban':'\ud83d\udc73', 2351 'tangerine':'\ud83c\udf4a', 2352 'mans_shoe':'\ud83d\udc5e', 2353 'mantelpiece_clock':'\ud83d\udd70', 2354 'maple_leaf':'\ud83c\udf41', 2355 'martial_arts_uniform':'\ud83e\udd4b', 2356 'mask':'\ud83d\ude37', 2357 'massage_woman':'\ud83d\udc86', 2358 'massage_man':'\ud83d\udc86‍\u2642\ufe0f', 2359 'meat_on_bone':'\ud83c\udf56', 2360 'medal_military':'\ud83c\udf96', 2361 'medal_sports':'\ud83c\udfc5', 2362 'mega':'\ud83d\udce3', 2363 'melon':'\ud83c\udf48', 2364 'memo':'\ud83d\udcdd', 2365 'men_wrestling':'\ud83e\udd3c‍\u2642\ufe0f', 2366 'menorah':'\ud83d\udd4e', 2367 'mens':'\ud83d\udeb9', 2368 'metal':'\ud83e\udd18', 2369 'metro':'\ud83d\ude87', 2370 'microphone':'\ud83c\udfa4', 2371 'microscope':'\ud83d\udd2c', 2372 'milk_glass':'\ud83e\udd5b', 2373 'milky_way':'\ud83c\udf0c', 2374 'minibus':'\ud83d\ude90', 2375 'minidisc':'\ud83d\udcbd', 2376 'mobile_phone_off':'\ud83d\udcf4', 2377 'money_mouth_face':'\ud83e\udd11', 2378 'money_with_wings':'\ud83d\udcb8', 2379 'moneybag':'\ud83d\udcb0', 2380 'monkey':'\ud83d\udc12', 2381 'monkey_face':'\ud83d\udc35', 2382 'monorail':'\ud83d\ude9d', 2383 'moon':'\ud83c\udf14', 2384 'mortar_board':'\ud83c\udf93', 2385 'mosque':'\ud83d\udd4c', 2386 'motor_boat':'\ud83d\udee5', 2387 'motor_scooter':'\ud83d\udef5', 2388 'motorcycle':'\ud83c\udfcd', 2389 'motorway':'\ud83d\udee3', 2390 'mount_fuji':'\ud83d\uddfb', 2391 'mountain':'\u26f0', 2392 'mountain_biking_man':'\ud83d\udeb5', 2393 'mountain_biking_woman':'\ud83d\udeb5‍\u2640\ufe0f', 2394 'mountain_cableway':'\ud83d\udea0', 2395 'mountain_railway':'\ud83d\ude9e', 2396 'mountain_snow':'\ud83c\udfd4', 2397 'mouse':'\ud83d\udc2d', 2398 'mouse2':'\ud83d\udc01', 2399 'movie_camera':'\ud83c\udfa5', 2400 'moyai':'\ud83d\uddff', 2401 'mrs_claus':'\ud83e\udd36', 2402 'muscle':'\ud83d\udcaa', 2403 'mushroom':'\ud83c\udf44', 2404 'musical_keyboard':'\ud83c\udfb9', 2405 'musical_note':'\ud83c\udfb5', 2406 'musical_score':'\ud83c\udfbc', 2407 'mute':'\ud83d\udd07', 2408 'nail_care':'\ud83d\udc85', 2409 'name_badge':'\ud83d\udcdb', 2410 'national_park':'\ud83c\udfde', 2411 'nauseated_face':'\ud83e\udd22', 2412 'necktie':'\ud83d\udc54', 2413 'negative_squared_cross_mark':'\u274e', 2414 'nerd_face':'\ud83e\udd13', 2415 'neutral_face':'\ud83d\ude10', 2416 'new':'\ud83c\udd95', 2417 'new_moon':'\ud83c\udf11', 2418 'new_moon_with_face':'\ud83c\udf1a', 2419 'newspaper':'\ud83d\udcf0', 2420 'newspaper_roll':'\ud83d\uddde', 2421 'next_track_button':'\u23ed', 2422 'ng':'\ud83c\udd96', 2423 'no_good_man':'\ud83d\ude45‍\u2642\ufe0f', 2424 'no_good_woman':'\ud83d\ude45', 2425 'night_with_stars':'\ud83c\udf03', 2426 'no_bell':'\ud83d\udd15', 2427 'no_bicycles':'\ud83d\udeb3', 2428 'no_entry':'\u26d4\ufe0f', 2429 'no_entry_sign':'\ud83d\udeab', 2430 'no_mobile_phones':'\ud83d\udcf5', 2431 'no_mouth':'\ud83d\ude36', 2432 'no_pedestrians':'\ud83d\udeb7', 2433 'no_smoking':'\ud83d\udead', 2434 'non-potable_water':'\ud83d\udeb1', 2435 'nose':'\ud83d\udc43', 2436 'notebook':'\ud83d\udcd3', 2437 'notebook_with_decorative_cover':'\ud83d\udcd4', 2438 'notes':'\ud83c\udfb6', 2439 'nut_and_bolt':'\ud83d\udd29', 2440 'o':'\u2b55\ufe0f', 2441 'o2':'\ud83c\udd7e\ufe0f', 2442 'ocean':'\ud83c\udf0a', 2443 'octopus':'\ud83d\udc19', 2444 'oden':'\ud83c\udf62', 2445 'office':'\ud83c\udfe2', 2446 'oil_drum':'\ud83d\udee2', 2447 'ok':'\ud83c\udd97', 2448 'ok_hand':'\ud83d\udc4c', 2449 'ok_man':'\ud83d\ude46‍\u2642\ufe0f', 2450 'ok_woman':'\ud83d\ude46', 2451 'old_key':'\ud83d\udddd', 2452 'older_man':'\ud83d\udc74', 2453 'older_woman':'\ud83d\udc75', 2454 'om':'\ud83d\udd49', 2455 'on':'\ud83d\udd1b', 2456 'oncoming_automobile':'\ud83d\ude98', 2457 'oncoming_bus':'\ud83d\ude8d', 2458 'oncoming_police_car':'\ud83d\ude94', 2459 'oncoming_taxi':'\ud83d\ude96', 2460 'open_file_folder':'\ud83d\udcc2', 2461 'open_hands':'\ud83d\udc50', 2462 'open_mouth':'\ud83d\ude2e', 2463 'open_umbrella':'\u2602\ufe0f', 2464 'ophiuchus':'\u26ce', 2465 'orange_book':'\ud83d\udcd9', 2466 'orthodox_cross':'\u2626\ufe0f', 2467 'outbox_tray':'\ud83d\udce4', 2468 'owl':'\ud83e\udd89', 2469 'ox':'\ud83d\udc02', 2470 'package':'\ud83d\udce6', 2471 'page_facing_up':'\ud83d\udcc4', 2472 'page_with_curl':'\ud83d\udcc3', 2473 'pager':'\ud83d\udcdf', 2474 'paintbrush':'\ud83d\udd8c', 2475 'palm_tree':'\ud83c\udf34', 2476 'pancakes':'\ud83e\udd5e', 2477 'panda_face':'\ud83d\udc3c', 2478 'paperclip':'\ud83d\udcce', 2479 'paperclips':'\ud83d\udd87', 2480 'parasol_on_ground':'\u26f1', 2481 'parking':'\ud83c\udd7f\ufe0f', 2482 'part_alternation_mark':'\u303d\ufe0f', 2483 'partly_sunny':'\u26c5\ufe0f', 2484 'passenger_ship':'\ud83d\udef3', 2485 'passport_control':'\ud83d\udec2', 2486 'pause_button':'\u23f8', 2487 'peace_symbol':'\u262e\ufe0f', 2488 'peach':'\ud83c\udf51', 2489 'peanuts':'\ud83e\udd5c', 2490 'pear':'\ud83c\udf50', 2491 'pen':'\ud83d\udd8a', 2492 'pencil2':'\u270f\ufe0f', 2493 'penguin':'\ud83d\udc27', 2494 'pensive':'\ud83d\ude14', 2495 'performing_arts':'\ud83c\udfad', 2496 'persevere':'\ud83d\ude23', 2497 'person_fencing':'\ud83e\udd3a', 2498 'pouting_woman':'\ud83d\ude4e', 2499 'phone':'\u260e\ufe0f', 2500 'pick':'\u26cf', 2501 'pig':'\ud83d\udc37', 2502 'pig2':'\ud83d\udc16', 2503 'pig_nose':'\ud83d\udc3d', 2504 'pill':'\ud83d\udc8a', 2505 'pineapple':'\ud83c\udf4d', 2506 'ping_pong':'\ud83c\udfd3', 2507 'pisces':'\u2653\ufe0f', 2508 'pizza':'\ud83c\udf55', 2509 'place_of_worship':'\ud83d\uded0', 2510 'plate_with_cutlery':'\ud83c\udf7d', 2511 'play_or_pause_button':'\u23ef', 2512 'point_down':'\ud83d\udc47', 2513 'point_left':'\ud83d\udc48', 2514 'point_right':'\ud83d\udc49', 2515 'point_up':'\u261d\ufe0f', 2516 'point_up_2':'\ud83d\udc46', 2517 'police_car':'\ud83d\ude93', 2518 'policewoman':'\ud83d\udc6e‍\u2640\ufe0f', 2519 'poodle':'\ud83d\udc29', 2520 'popcorn':'\ud83c\udf7f', 2521 'post_office':'\ud83c\udfe3', 2522 'postal_horn':'\ud83d\udcef', 2523 'postbox':'\ud83d\udcee', 2524 'potable_water':'\ud83d\udeb0', 2525 'potato':'\ud83e\udd54', 2526 'pouch':'\ud83d\udc5d', 2527 'poultry_leg':'\ud83c\udf57', 2528 'pound':'\ud83d\udcb7', 2529 'rage':'\ud83d\ude21', 2530 'pouting_cat':'\ud83d\ude3e', 2531 'pouting_man':'\ud83d\ude4e‍\u2642\ufe0f', 2532 'pray':'\ud83d\ude4f', 2533 'prayer_beads':'\ud83d\udcff', 2534 'pregnant_woman':'\ud83e\udd30', 2535 'previous_track_button':'\u23ee', 2536 'prince':'\ud83e\udd34', 2537 'princess':'\ud83d\udc78', 2538 'printer':'\ud83d\udda8', 2539 'purple_heart':'\ud83d\udc9c', 2540 'purse':'\ud83d\udc5b', 2541 'pushpin':'\ud83d\udccc', 2542 'put_litter_in_its_place':'\ud83d\udeae', 2543 'question':'\u2753', 2544 'rabbit':'\ud83d\udc30', 2545 'rabbit2':'\ud83d\udc07', 2546 'racehorse':'\ud83d\udc0e', 2547 'racing_car':'\ud83c\udfce', 2548 'radio':'\ud83d\udcfb', 2549 'radio_button':'\ud83d\udd18', 2550 'radioactive':'\u2622\ufe0f', 2551 'railway_car':'\ud83d\ude83', 2552 'railway_track':'\ud83d\udee4', 2553 'rainbow':'\ud83c\udf08', 2554 'rainbow_flag':'\ud83c\udff3\ufe0f‍\ud83c\udf08', 2555 'raised_back_of_hand':'\ud83e\udd1a', 2556 'raised_hand_with_fingers_splayed':'\ud83d\udd90', 2557 'raised_hands':'\ud83d\ude4c', 2558 'raising_hand_woman':'\ud83d\ude4b', 2559 'raising_hand_man':'\ud83d\ude4b‍\u2642\ufe0f', 2560 'ram':'\ud83d\udc0f', 2561 'ramen':'\ud83c\udf5c', 2562 'rat':'\ud83d\udc00', 2563 'record_button':'\u23fa', 2564 'recycle':'\u267b\ufe0f', 2565 'red_circle':'\ud83d\udd34', 2566 'registered':'\u00ae\ufe0f', 2567 'relaxed':'\u263a\ufe0f', 2568 'relieved':'\ud83d\ude0c', 2569 'reminder_ribbon':'\ud83c\udf97', 2570 'repeat':'\ud83d\udd01', 2571 'repeat_one':'\ud83d\udd02', 2572 'rescue_worker_helmet':'\u26d1', 2573 'restroom':'\ud83d\udebb', 2574 'revolving_hearts':'\ud83d\udc9e', 2575 'rewind':'\u23ea', 2576 'rhinoceros':'\ud83e\udd8f', 2577 'ribbon':'\ud83c\udf80', 2578 'rice':'\ud83c\udf5a', 2579 'rice_ball':'\ud83c\udf59', 2580 'rice_cracker':'\ud83c\udf58', 2581 'rice_scene':'\ud83c\udf91', 2582 'right_anger_bubble':'\ud83d\uddef', 2583 'ring':'\ud83d\udc8d', 2584 'robot':'\ud83e\udd16', 2585 'rocket':'\ud83d\ude80', 2586 'rofl':'\ud83e\udd23', 2587 'roll_eyes':'\ud83d\ude44', 2588 'roller_coaster':'\ud83c\udfa2', 2589 'rooster':'\ud83d\udc13', 2590 'rose':'\ud83c\udf39', 2591 'rosette':'\ud83c\udff5', 2592 'rotating_light':'\ud83d\udea8', 2593 'round_pushpin':'\ud83d\udccd', 2594 'rowing_man':'\ud83d\udea3', 2595 'rowing_woman':'\ud83d\udea3‍\u2640\ufe0f', 2596 'rugby_football':'\ud83c\udfc9', 2597 'running_man':'\ud83c\udfc3', 2598 'running_shirt_with_sash':'\ud83c\udfbd', 2599 'running_woman':'\ud83c\udfc3‍\u2640\ufe0f', 2600 'sa':'\ud83c\ude02\ufe0f', 2601 'sagittarius':'\u2650\ufe0f', 2602 'sake':'\ud83c\udf76', 2603 'sandal':'\ud83d\udc61', 2604 'santa':'\ud83c\udf85', 2605 'satellite':'\ud83d\udce1', 2606 'saxophone':'\ud83c\udfb7', 2607 'school':'\ud83c\udfeb', 2608 'school_satchel':'\ud83c\udf92', 2609 'scissors':'\u2702\ufe0f', 2610 'scorpion':'\ud83e\udd82', 2611 'scorpius':'\u264f\ufe0f', 2612 'scream':'\ud83d\ude31', 2613 'scream_cat':'\ud83d\ude40', 2614 'scroll':'\ud83d\udcdc', 2615 'seat':'\ud83d\udcba', 2616 'secret':'\u3299\ufe0f', 2617 'see_no_evil':'\ud83d\ude48', 2618 'seedling':'\ud83c\udf31', 2619 'selfie':'\ud83e\udd33', 2620 'shallow_pan_of_food':'\ud83e\udd58', 2621 'shamrock':'\u2618\ufe0f', 2622 'shark':'\ud83e\udd88', 2623 'shaved_ice':'\ud83c\udf67', 2624 'sheep':'\ud83d\udc11', 2625 'shell':'\ud83d\udc1a', 2626 'shield':'\ud83d\udee1', 2627 'shinto_shrine':'\u26e9', 2628 'ship':'\ud83d\udea2', 2629 'shirt':'\ud83d\udc55', 2630 'shopping':'\ud83d\udecd', 2631 'shopping_cart':'\ud83d\uded2', 2632 'shower':'\ud83d\udebf', 2633 'shrimp':'\ud83e\udd90', 2634 'signal_strength':'\ud83d\udcf6', 2635 'six_pointed_star':'\ud83d\udd2f', 2636 'ski':'\ud83c\udfbf', 2637 'skier':'\u26f7', 2638 'skull':'\ud83d\udc80', 2639 'skull_and_crossbones':'\u2620\ufe0f', 2640 'sleeping':'\ud83d\ude34', 2641 'sleeping_bed':'\ud83d\udecc', 2642 'sleepy':'\ud83d\ude2a', 2643 'slightly_frowning_face':'\ud83d\ude41', 2644 'slightly_smiling_face':'\ud83d\ude42', 2645 'slot_machine':'\ud83c\udfb0', 2646 'small_airplane':'\ud83d\udee9', 2647 'small_blue_diamond':'\ud83d\udd39', 2648 'small_orange_diamond':'\ud83d\udd38', 2649 'small_red_triangle':'\ud83d\udd3a', 2650 'small_red_triangle_down':'\ud83d\udd3b', 2651 'smile':'\ud83d\ude04', 2652 'smile_cat':'\ud83d\ude38', 2653 'smiley':'\ud83d\ude03', 2654 'smiley_cat':'\ud83d\ude3a', 2655 'smiling_imp':'\ud83d\ude08', 2656 'smirk':'\ud83d\ude0f', 2657 'smirk_cat':'\ud83d\ude3c', 2658 'smoking':'\ud83d\udeac', 2659 'snail':'\ud83d\udc0c', 2660 'snake':'\ud83d\udc0d', 2661 'sneezing_face':'\ud83e\udd27', 2662 'snowboarder':'\ud83c\udfc2', 2663 'snowflake':'\u2744\ufe0f', 2664 'snowman':'\u26c4\ufe0f', 2665 'snowman_with_snow':'\u2603\ufe0f', 2666 'sob':'\ud83d\ude2d', 2667 'soccer':'\u26bd\ufe0f', 2668 'soon':'\ud83d\udd1c', 2669 'sos':'\ud83c\udd98', 2670 'sound':'\ud83d\udd09', 2671 'space_invader':'\ud83d\udc7e', 2672 'spades':'\u2660\ufe0f', 2673 'spaghetti':'\ud83c\udf5d', 2674 'sparkle':'\u2747\ufe0f', 2675 'sparkler':'\ud83c\udf87', 2676 'sparkles':'\u2728', 2677 'sparkling_heart':'\ud83d\udc96', 2678 'speak_no_evil':'\ud83d\ude4a', 2679 'speaker':'\ud83d\udd08', 2680 'speaking_head':'\ud83d\udde3', 2681 'speech_balloon':'\ud83d\udcac', 2682 'speedboat':'\ud83d\udea4', 2683 'spider':'\ud83d\udd77', 2684 'spider_web':'\ud83d\udd78', 2685 'spiral_calendar':'\ud83d\uddd3', 2686 'spiral_notepad':'\ud83d\uddd2', 2687 'spoon':'\ud83e\udd44', 2688 'squid':'\ud83e\udd91', 2689 'stadium':'\ud83c\udfdf', 2690 'star':'\u2b50\ufe0f', 2691 'star2':'\ud83c\udf1f', 2692 'star_and_crescent':'\u262a\ufe0f', 2693 'star_of_david':'\u2721\ufe0f', 2694 'stars':'\ud83c\udf20', 2695 'station':'\ud83d\ude89', 2696 'statue_of_liberty':'\ud83d\uddfd', 2697 'steam_locomotive':'\ud83d\ude82', 2698 'stew':'\ud83c\udf72', 2699 'stop_button':'\u23f9', 2700 'stop_sign':'\ud83d\uded1', 2701 'stopwatch':'\u23f1', 2702 'straight_ruler':'\ud83d\udccf', 2703 'strawberry':'\ud83c\udf53', 2704 'stuck_out_tongue':'\ud83d\ude1b', 2705 'stuck_out_tongue_closed_eyes':'\ud83d\ude1d', 2706 'stuck_out_tongue_winking_eye':'\ud83d\ude1c', 2707 'studio_microphone':'\ud83c\udf99', 2708 'stuffed_flatbread':'\ud83e\udd59', 2709 'sun_behind_large_cloud':'\ud83c\udf25', 2710 'sun_behind_rain_cloud':'\ud83c\udf26', 2711 'sun_behind_small_cloud':'\ud83c\udf24', 2712 'sun_with_face':'\ud83c\udf1e', 2713 'sunflower':'\ud83c\udf3b', 2714 'sunglasses':'\ud83d\ude0e', 2715 'sunny':'\u2600\ufe0f', 2716 'sunrise':'\ud83c\udf05', 2717 'sunrise_over_mountains':'\ud83c\udf04', 2718 'surfing_man':'\ud83c\udfc4', 2719 'surfing_woman':'\ud83c\udfc4‍\u2640\ufe0f', 2720 'sushi':'\ud83c\udf63', 2721 'suspension_railway':'\ud83d\ude9f', 2722 'sweat':'\ud83d\ude13', 2723 'sweat_drops':'\ud83d\udca6', 2724 'sweat_smile':'\ud83d\ude05', 2725 'sweet_potato':'\ud83c\udf60', 2726 'swimming_man':'\ud83c\udfca', 2727 'swimming_woman':'\ud83c\udfca‍\u2640\ufe0f', 2728 'symbols':'\ud83d\udd23', 2729 'synagogue':'\ud83d\udd4d', 2730 'syringe':'\ud83d\udc89', 2731 'taco':'\ud83c\udf2e', 2732 'tada':'\ud83c\udf89', 2733 'tanabata_tree':'\ud83c\udf8b', 2734 'taurus':'\u2649\ufe0f', 2735 'taxi':'\ud83d\ude95', 2736 'tea':'\ud83c\udf75', 2737 'telephone_receiver':'\ud83d\udcde', 2738 'telescope':'\ud83d\udd2d', 2739 'tennis':'\ud83c\udfbe', 2740 'tent':'\u26fa\ufe0f', 2741 'thermometer':'\ud83c\udf21', 2742 'thinking':'\ud83e\udd14', 2743 'thought_balloon':'\ud83d\udcad', 2744 'ticket':'\ud83c\udfab', 2745 'tickets':'\ud83c\udf9f', 2746 'tiger':'\ud83d\udc2f', 2747 'tiger2':'\ud83d\udc05', 2748 'timer_clock':'\u23f2', 2749 'tipping_hand_man':'\ud83d\udc81‍\u2642\ufe0f', 2750 'tired_face':'\ud83d\ude2b', 2751 'tm':'\u2122\ufe0f', 2752 'toilet':'\ud83d\udebd', 2753 'tokyo_tower':'\ud83d\uddfc', 2754 'tomato':'\ud83c\udf45', 2755 'tongue':'\ud83d\udc45', 2756 'top':'\ud83d\udd1d', 2757 'tophat':'\ud83c\udfa9', 2758 'tornado':'\ud83c\udf2a', 2759 'trackball':'\ud83d\uddb2', 2760 'tractor':'\ud83d\ude9c', 2761 'traffic_light':'\ud83d\udea5', 2762 'train':'\ud83d\ude8b', 2763 'train2':'\ud83d\ude86', 2764 'tram':'\ud83d\ude8a', 2765 'triangular_flag_on_post':'\ud83d\udea9', 2766 'triangular_ruler':'\ud83d\udcd0', 2767 'trident':'\ud83d\udd31', 2768 'triumph':'\ud83d\ude24', 2769 'trolleybus':'\ud83d\ude8e', 2770 'trophy':'\ud83c\udfc6', 2771 'tropical_drink':'\ud83c\udf79', 2772 'tropical_fish':'\ud83d\udc20', 2773 'truck':'\ud83d\ude9a', 2774 'trumpet':'\ud83c\udfba', 2775 'tulip':'\ud83c\udf37', 2776 'tumbler_glass':'\ud83e\udd43', 2777 'turkey':'\ud83e\udd83', 2778 'turtle':'\ud83d\udc22', 2779 'tv':'\ud83d\udcfa', 2780 'twisted_rightwards_arrows':'\ud83d\udd00', 2781 'two_hearts':'\ud83d\udc95', 2782 'two_men_holding_hands':'\ud83d\udc6c', 2783 'two_women_holding_hands':'\ud83d\udc6d', 2784 'u5272':'\ud83c\ude39', 2785 'u5408':'\ud83c\ude34', 2786 'u55b6':'\ud83c\ude3a', 2787 'u6307':'\ud83c\ude2f\ufe0f', 2788 'u6708':'\ud83c\ude37\ufe0f', 2789 'u6709':'\ud83c\ude36', 2790 'u6e80':'\ud83c\ude35', 2791 'u7121':'\ud83c\ude1a\ufe0f', 2792 'u7533':'\ud83c\ude38', 2793 'u7981':'\ud83c\ude32', 2794 'u7a7a':'\ud83c\ude33', 2795 'umbrella':'\u2614\ufe0f', 2796 'unamused':'\ud83d\ude12', 2797 'underage':'\ud83d\udd1e', 2798 'unicorn':'\ud83e\udd84', 2799 'unlock':'\ud83d\udd13', 2800 'up':'\ud83c\udd99', 2801 'upside_down_face':'\ud83d\ude43', 2802 'v':'\u270c\ufe0f', 2803 'vertical_traffic_light':'\ud83d\udea6', 2804 'vhs':'\ud83d\udcfc', 2805 'vibration_mode':'\ud83d\udcf3', 2806 'video_camera':'\ud83d\udcf9', 2807 'video_game':'\ud83c\udfae', 2808 'violin':'\ud83c\udfbb', 2809 'virgo':'\u264d\ufe0f', 2810 'volcano':'\ud83c\udf0b', 2811 'volleyball':'\ud83c\udfd0', 2812 'vs':'\ud83c\udd9a', 2813 'vulcan_salute':'\ud83d\udd96', 2814 'walking_man':'\ud83d\udeb6', 2815 'walking_woman':'\ud83d\udeb6‍\u2640\ufe0f', 2816 'waning_crescent_moon':'\ud83c\udf18', 2817 'waning_gibbous_moon':'\ud83c\udf16', 2818 'warning':'\u26a0\ufe0f', 2819 'wastebasket':'\ud83d\uddd1', 2820 'watch':'\u231a\ufe0f', 2821 'water_buffalo':'\ud83d\udc03', 2822 'watermelon':'\ud83c\udf49', 2823 'wave':'\ud83d\udc4b', 2824 'wavy_dash':'\u3030\ufe0f', 2825 'waxing_crescent_moon':'\ud83c\udf12', 2826 'wc':'\ud83d\udebe', 2827 'weary':'\ud83d\ude29', 2828 'wedding':'\ud83d\udc92', 2829 'weight_lifting_man':'\ud83c\udfcb\ufe0f', 2830 'weight_lifting_woman':'\ud83c\udfcb\ufe0f‍\u2640\ufe0f', 2831 'whale':'\ud83d\udc33', 2832 'whale2':'\ud83d\udc0b', 2833 'wheel_of_dharma':'\u2638\ufe0f', 2834 'wheelchair':'\u267f\ufe0f', 2835 'white_check_mark':'\u2705', 2836 'white_circle':'\u26aa\ufe0f', 2837 'white_flag':'\ud83c\udff3\ufe0f', 2838 'white_flower':'\ud83d\udcae', 2839 'white_large_square':'\u2b1c\ufe0f', 2840 'white_medium_small_square':'\u25fd\ufe0f', 2841 'white_medium_square':'\u25fb\ufe0f', 2842 'white_small_square':'\u25ab\ufe0f', 2843 'white_square_button':'\ud83d\udd33', 2844 'wilted_flower':'\ud83e\udd40', 2845 'wind_chime':'\ud83c\udf90', 2846 'wind_face':'\ud83c\udf2c', 2847 'wine_glass':'\ud83c\udf77', 2848 'wink':'\ud83d\ude09', 2849 'wolf':'\ud83d\udc3a', 2850 'woman':'\ud83d\udc69', 2851 'woman_artist':'\ud83d\udc69‍\ud83c\udfa8', 2852 'woman_astronaut':'\ud83d\udc69‍\ud83d\ude80', 2853 'woman_cartwheeling':'\ud83e\udd38‍\u2640\ufe0f', 2854 'woman_cook':'\ud83d\udc69‍\ud83c\udf73', 2855 'woman_facepalming':'\ud83e\udd26‍\u2640\ufe0f', 2856 'woman_factory_worker':'\ud83d\udc69‍\ud83c\udfed', 2857 'woman_farmer':'\ud83d\udc69‍\ud83c\udf3e', 2858 'woman_firefighter':'\ud83d\udc69‍\ud83d\ude92', 2859 'woman_health_worker':'\ud83d\udc69‍\u2695\ufe0f', 2860 'woman_judge':'\ud83d\udc69‍\u2696\ufe0f', 2861 'woman_juggling':'\ud83e\udd39‍\u2640\ufe0f', 2862 'woman_mechanic':'\ud83d\udc69‍\ud83d\udd27', 2863 'woman_office_worker':'\ud83d\udc69‍\ud83d\udcbc', 2864 'woman_pilot':'\ud83d\udc69‍\u2708\ufe0f', 2865 'woman_playing_handball':'\ud83e\udd3e‍\u2640\ufe0f', 2866 'woman_playing_water_polo':'\ud83e\udd3d‍\u2640\ufe0f', 2867 'woman_scientist':'\ud83d\udc69‍\ud83d\udd2c', 2868 'woman_shrugging':'\ud83e\udd37‍\u2640\ufe0f', 2869 'woman_singer':'\ud83d\udc69‍\ud83c\udfa4', 2870 'woman_student':'\ud83d\udc69‍\ud83c\udf93', 2871 'woman_teacher':'\ud83d\udc69‍\ud83c\udfeb', 2872 'woman_technologist':'\ud83d\udc69‍\ud83d\udcbb', 2873 'woman_with_turban':'\ud83d\udc73‍\u2640\ufe0f', 2874 'womans_clothes':'\ud83d\udc5a', 2875 'womans_hat':'\ud83d\udc52', 2876 'women_wrestling':'\ud83e\udd3c‍\u2640\ufe0f', 2877 'womens':'\ud83d\udeba', 2878 'world_map':'\ud83d\uddfa', 2879 'worried':'\ud83d\ude1f', 2880 'wrench':'\ud83d\udd27', 2881 'writing_hand':'\u270d\ufe0f', 2882 'x':'\u274c', 2883 'yellow_heart':'\ud83d\udc9b', 2884 'yen':'\ud83d\udcb4', 2885 'yin_yang':'\u262f\ufe0f', 2886 'yum':'\ud83d\ude0b', 2887 'zap':'\u26a1\ufe0f', 2888 'zipper_mouth_face':'\ud83e\udd10', 2889 'zzz':'\ud83d\udca4', 2890 2891 /* special emojis :P */ 2892 'octocat': '<img alt=":octocat:" height="20" width="20" align="absmiddle" src="https://assets-cdn.github.com/images/icons/emoji/octocat.png">', 2893 '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>' 2894}; 2895 2896/** 2897 * Created by Estevao on 31-05-2015. 2898 */ 2899 2900/** 2901 * Showdown Converter class 2902 * @class 2903 * @param {object} [converterOptions] 2904 * @returns {Converter} 2905 */ 2906showdown.Converter = function (converterOptions) { 2907 'use strict'; 2908 2909 var 2910 /** 2911 * Options used by this converter 2912 * @private 2913 * @type {{}} 2914 */ 2915 options = {}, 2916 2917 /** 2918 * Language extensions used by this converter 2919 * @private 2920 * @type {Array} 2921 */ 2922 langExtensions = [], 2923 2924 /** 2925 * Output modifiers extensions used by this converter 2926 * @private 2927 * @type {Array} 2928 */ 2929 outputModifiers = [], 2930 2931 /** 2932 * Event listeners 2933 * @private 2934 * @type {{}} 2935 */ 2936 listeners = {}, 2937 2938 /** 2939 * The flavor set in this converter 2940 */ 2941 setConvFlavor = setFlavor, 2942 2943 /** 2944 * Metadata of the document 2945 * @type {{parsed: {}, raw: string, format: string}} 2946 */ 2947 metadata = { 2948 parsed: {}, 2949 raw: '', 2950 format: '' 2951 }; 2952 2953 _constructor(); 2954 2955 /** 2956 * Converter constructor 2957 * @private 2958 */ 2959 function _constructor () { 2960 converterOptions = converterOptions || {}; 2961 2962 for (var gOpt in globalOptions) { 2963 if (globalOptions.hasOwnProperty(gOpt)) { 2964 options[gOpt] = globalOptions[gOpt]; 2965 } 2966 } 2967 2968 // Merge options 2969 if (typeof converterOptions === 'object') { 2970 for (var opt in converterOptions) { 2971 if (converterOptions.hasOwnProperty(opt)) { 2972 options[opt] = converterOptions[opt]; 2973 } 2974 } 2975 } else { 2976 throw Error('Converter expects the passed parameter to be an object, but ' + typeof converterOptions + 2977 ' was passed instead.'); 2978 } 2979 2980 if (options.extensions) { 2981 showdown.helper.forEach(options.extensions, _parseExtension); 2982 } 2983 } 2984 2985 /** 2986 * Parse extension 2987 * @param {*} ext 2988 * @param {string} [name=''] 2989 * @private 2990 */ 2991 function _parseExtension (ext, name) { 2992 2993 name = name || null; 2994 // If it's a string, the extension was previously loaded 2995 if (showdown.helper.isString(ext)) { 2996 ext = showdown.helper.stdExtName(ext); 2997 name = ext; 2998 2999 // LEGACY_SUPPORT CODE 3000 if (showdown.extensions[ext]) { 3001 console.warn('DEPRECATION WARNING: ' + ext + ' is an old extension that uses a deprecated loading method.' + 3002 'Please inform the developer that the extension should be updated!'); 3003 legacyExtensionLoading(showdown.extensions[ext], ext); 3004 return; 3005 // END LEGACY SUPPORT CODE 3006 3007 } else if (!showdown.helper.isUndefined(extensions[ext])) { 3008 ext = extensions[ext]; 3009 3010 } else { 3011 throw Error('Extension "' + ext + '" could not be loaded. It was either not found or is not a valid extension.'); 3012 } 3013 } 3014 3015 if (typeof ext === 'function') { 3016 ext = ext(); 3017 } 3018 3019 if (!showdown.helper.isArray(ext)) { 3020 ext = [ext]; 3021 } 3022 3023 var validExt = validate(ext, name); 3024 if (!validExt.valid) { 3025 throw Error(validExt.error); 3026 } 3027 3028 for (var i = 0; i < ext.length; ++i) { 3029 switch (ext[i].type) { 3030 3031 case 'lang': 3032 langExtensions.push(ext[i]); 3033 break; 3034 3035 case 'output': 3036 outputModifiers.push(ext[i]); 3037 break; 3038 } 3039 if (ext[i].hasOwnProperty('listeners')) { 3040 for (var ln in ext[i].listeners) { 3041 if (ext[i].listeners.hasOwnProperty(ln)) { 3042 listen(ln, ext[i].listeners[ln]); 3043 } 3044 } 3045 } 3046 } 3047 3048 } 3049 3050 /** 3051 * LEGACY_SUPPORT 3052 * @param {*} ext 3053 * @param {string} name 3054 */ 3055 function legacyExtensionLoading (ext, name) { 3056 if (typeof ext === 'function') { 3057 ext = ext(new showdown.Converter()); 3058 } 3059 if (!showdown.helper.isArray(ext)) { 3060 ext = [ext]; 3061 } 3062 var valid = validate(ext, name); 3063 3064 if (!valid.valid) { 3065 throw Error(valid.error); 3066 } 3067 3068 for (var i = 0; i < ext.length; ++i) { 3069 switch (ext[i].type) { 3070 case 'lang': 3071 langExtensions.push(ext[i]); 3072 break; 3073 case 'output': 3074 outputModifiers.push(ext[i]); 3075 break; 3076 default:// should never reach here 3077 throw Error('Extension loader error: Type unrecognized!!!'); 3078 } 3079 } 3080 } 3081 3082 /** 3083 * Listen to an event 3084 * @param {string} name 3085 * @param {function} callback 3086 */ 3087 function listen (name, callback) { 3088 if (!showdown.helper.isString(name)) { 3089 throw Error('Invalid argument in converter.listen() method: name must be a string, but ' + typeof name + ' given'); 3090 } 3091 3092 if (typeof callback !== 'function') { 3093 throw Error('Invalid argument in converter.listen() method: callback must be a function, but ' + typeof callback + ' given'); 3094 } 3095 3096 if (!listeners.hasOwnProperty(name)) { 3097 listeners[name] = []; 3098 } 3099 listeners[name].push(callback); 3100 } 3101 3102 function rTrimInputText (text) { 3103 var rsp = text.match(/^\s*/)[0].length, 3104 rgx = new RegExp('^\\s{0,' + rsp + '}', 'gm'); 3105 return text.replace(rgx, ''); 3106 } 3107 3108 /** 3109 * Dispatch an event 3110 * @private 3111 * @param {string} evtName Event name 3112 * @param {string} text Text 3113 * @param {{}} options Converter Options 3114 * @param {{}} globals 3115 * @returns {string} 3116 */ 3117 this._dispatch = function dispatch (evtName, text, options, globals) { 3118 if (listeners.hasOwnProperty(evtName)) { 3119 for (var ei = 0; ei < listeners[evtName].length; ++ei) { 3120 var nText = listeners[evtName][ei](evtName, text, this, options, globals); 3121 if (nText && typeof nText !== 'undefined') { 3122 text = nText; 3123 } 3124 } 3125 } 3126 return text; 3127 }; 3128 3129 /** 3130 * Listen to an event 3131 * @param {string} name 3132 * @param {function} callback 3133 * @returns {showdown.Converter} 3134 */ 3135 this.listen = function (name, callback) { 3136 listen(name, callback); 3137 return this; 3138 }; 3139 3140 /** 3141 * Converts a markdown string into HTML 3142 * @param {string} text 3143 * @returns {*} 3144 */ 3145 this.makeHtml = function (text) { 3146 //check if text is not falsy 3147 if (!text) { 3148 return text; 3149 } 3150 3151 var globals = { 3152 gHtmlBlocks: [], 3153 gHtmlMdBlocks: [], 3154 gHtmlSpans: [], 3155 gUrls: {}, 3156 gTitles: {}, 3157 gDimensions: {}, 3158 gListLevel: 0, 3159 hashLinkCounts: {}, 3160 langExtensions: langExtensions, 3161 outputModifiers: outputModifiers, 3162 converter: this, 3163 ghCodeBlocks: [], 3164 metadata: { 3165 parsed: {}, 3166 raw: '', 3167 format: '' 3168 } 3169 }; 3170 3171 // This lets us use ¨ trema as an escape char to avoid md5 hashes 3172 // The choice of character is arbitrary; anything that isn't 3173 // magic in Markdown will work. 3174 text = text.replace(/¨/g, '¨T'); 3175 3176 // Replace $ with ¨D 3177 // RegExp interprets $ as a special character 3178 // when it's in a replacement string 3179 text = text.replace(/\$/g, '¨D'); 3180 3181 // Standardize line endings 3182 text = text.replace(/\r\n/g, '\n'); // DOS to Unix 3183 text = text.replace(/\r/g, '\n'); // Mac to Unix 3184 3185 // Stardardize line spaces 3186 text = text.replace(/\u00A0/g, ' '); 3187 3188 if (options.smartIndentationFix) { 3189 text = rTrimInputText(text); 3190 } 3191 3192 // Make sure text begins and ends with a couple of newlines: 3193 text = '\n\n' + text + '\n\n'; 3194 3195 // detab 3196 text = showdown.subParser('detab')(text, options, globals); 3197 3198 /** 3199 * Strip any lines consisting only of spaces and tabs. 3200 * This makes subsequent regexs easier to write, because we can 3201 * match consecutive blank lines with /\n+/ instead of something 3202 * contorted like /[ \t]*\n+/ 3203 */ 3204 text = text.replace(/^[ \t]+$/mg, ''); 3205 3206 //run languageExtensions 3207 showdown.helper.forEach(langExtensions, function (ext) { 3208 text = showdown.subParser('runExtension')(ext, text, options, globals); 3209 }); 3210 3211 // run the sub parsers 3212 text = showdown.subParser('metadata')(text, options, globals); 3213 text = showdown.subParser('hashPreCodeTags')(text, options, globals); 3214 text = showdown.subParser('githubCodeBlocks')(text, options, globals); 3215 text = showdown.subParser('hashHTMLBlocks')(text, options, globals); 3216 text = showdown.subParser('hashCodeTags')(text, options, globals); 3217 text = showdown.subParser('stripLinkDefinitions')(text, options, globals); 3218 text = showdown.subParser('blockGamut')(text, options, globals); 3219 text = showdown.subParser('unhashHTMLSpans')(text, options, globals); 3220 text = showdown.subParser('unescapeSpecialChars')(text, options, globals); 3221 3222 // attacklab: Restore dollar signs 3223 text = text.replace(/¨D/g, '$$'); 3224 3225 // attacklab: Restore tremas 3226 text = text.replace(/¨T/g, '¨'); 3227 3228 // render a complete html document instead of a partial if the option is enabled 3229 text = showdown.subParser('completeHTMLDocument')(text, options, globals); 3230 3231 // Run output modifiers 3232 showdown.helper.forEach(outputModifiers, function (ext) { 3233 text = showdown.subParser('runExtension')(ext, text, options, globals); 3234 }); 3235 3236 // update metadata 3237 metadata = globals.metadata; 3238 return text; 3239 }; 3240 3241 /** 3242 * Converts an HTML string into a markdown string 3243 * @param src 3244 * @param [HTMLParser] A WHATWG DOM and HTML parser, such as JSDOM. If none is supplied, window.document will be used. 3245 * @returns {string} 3246 */ 3247 this.makeMarkdown = this.makeMd = function (src, HTMLParser) { 3248 3249 // replace \r\n with \n 3250 src = src.replace(/\r\n/g, '\n'); 3251 src = src.replace(/\r/g, '\n'); // old macs 3252 3253 // due to an edge case, we need to find this: > < 3254 // to prevent removing of non silent white spaces 3255 // ex: <em>this is</em> <strong>sparta</strong> 3256 src = src.replace(/>[ \t]+</, '>¨NBSP;<'); 3257 3258 if (!HTMLParser) { 3259 if (window && window.document) { 3260 HTMLParser = window.document; 3261 } else { 3262 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'); 3263 } 3264 } 3265 3266 var doc = HTMLParser.createElement('div'); 3267 doc.innerHTML = src; 3268 3269 var globals = { 3270 preList: substitutePreCodeTags(doc) 3271 }; 3272 3273 // remove all newlines and collapse spaces 3274 clean(doc); 3275 3276 // some stuff, like accidental reference links must now be escaped 3277 // TODO 3278 // doc.innerHTML = doc.innerHTML.replace(/\[[\S\t ]]/); 3279 3280 var nodes = doc.childNodes, 3281 mdDoc = ''; 3282 3283 for (var i = 0; i < nodes.length; i++) { 3284 mdDoc += showdown.subParser('makeMarkdown.node')(nodes[i], globals); 3285 } 3286 3287 function clean (node) { 3288 for (var n = 0; n < node.childNodes.length; ++n) { 3289 var child = node.childNodes[n]; 3290 if (child.nodeType === 3) { 3291 if (!/\S/.test(child.nodeValue)
vendor: 80,525 bytes, lines 3291-5809
3291) { 3292 node.removeChild(child); 3293 --n; 3294 } else { 3295 child.nodeValue = child.nodeValue.split('\n').join(' '); 3296 child.nodeValue = child.nodeValue.replace(/(\s)+/g, '$1'); 3297 } 3298 } else if (child.nodeType === 1) { 3299 clean(child); 3300 } 3301 } 3302 } 3303 3304 // find all pre tags and replace contents with placeholder 3305 // we need this so that we can remove all indentation from html 3306 // to ease up parsing 3307 function substitutePreCodeTags (doc) { 3308 3309 var pres = doc.querySelectorAll('pre'), 3310 presPH = []; 3311 3312 for (var i = 0; i < pres.length; ++i) { 3313 3314 if (pres[i].childElementCount === 1 && pres[i].firstChild.tagName.toLowerCase() === 'code') { 3315 var content = pres[i].firstChild.innerHTML.trim(), 3316 language = pres[i].firstChild.getAttribute('data-language') || ''; 3317 3318 // if data-language attribute is not defined, then we look for class language-* 3319 if (language === '') { 3320 var classes = pres[i].firstChild.className.split(' '); 3321 for (var c = 0; c < classes.length; ++c) { 3322 var matches = classes[c].match(/^language-(.+)$/); 3323 if (matches !== null) { 3324 language = matches[1]; 3325 break; 3326 } 3327 } 3328 } 3329 3330 // unescape html entities in content 3331 content = showdown.helper.unescapeHTMLEntities(content); 3332 3333 presPH.push(content); 3334 pres[i].outerHTML = '<precode language="' + language + '" precodenum="' + i.toString() + '"></precode>'; 3335 } else { 3336 presPH.push(pres[i].innerHTML); 3337 pres[i].innerHTML = ''; 3338 pres[i].setAttribute('prenum', i.toString()); 3339 } 3340 } 3341 return presPH; 3342 } 3343 3344 return mdDoc; 3345 }; 3346 3347 /** 3348 * Set an option of this Converter instance 3349 * @param {string} key 3350 * @param {*} value 3351 */ 3352 this.setOption = function (key, value) { 3353 options[key] = value; 3354 }; 3355 3356 /** 3357 * Get the option of this Converter instance 3358 * @param {string} key 3359 * @returns {*} 3360 */ 3361 this.getOption = function (key) { 3362 return options[key]; 3363 }; 3364 3365 /** 3366 * Get the options of this Converter instance 3367 * @returns {{}} 3368 */ 3369 this.getOptions = function () { 3370 return options; 3371 }; 3372 3373 /** 3374 * Add extension to THIS converter 3375 * @param {{}} extension 3376 * @param {string} [name=null] 3377 */ 3378 this.addExtension = function (extension, name) { 3379 name = name || null; 3380 _parseExtension(extension, name); 3381 }; 3382 3383 /** 3384 * Use a global registered extension with THIS converter 3385 * @param {string} extensionName Name of the previously registered extension 3386 */ 3387 this.useExtension = function (extensionName) { 3388 _parseExtension(extensionName); 3389 }; 3390 3391 /** 3392 * Set the flavor THIS converter should use 3393 * @param {string} name 3394 */ 3395 this.setFlavor = function (name) { 3396 if (!flavor.hasOwnProperty(name)) { 3397 throw Error(name + ' flavor was not found'); 3398 } 3399 var preset = flavor[name]; 3400 setConvFlavor = name; 3401 for (var option in preset) { 3402 if (preset.hasOwnProperty(option)) { 3403 options[option] = preset[option]; 3404 } 3405 } 3406 }; 3407 3408 /** 3409 * Get the currently set flavor of this converter 3410 * @returns {string} 3411 */ 3412 this.getFlavor = function () { 3413 return setConvFlavor; 3414 }; 3415 3416 /** 3417 * Remove an extension from THIS converter. 3418 * Note: This is a costly operation. It's better to initialize a new converter 3419 * and specify the extensions you wish to use 3420 * @param {Array} extension 3421 */ 3422 this.removeExtension = function (extension) { 3423 if (!showdown.helper.isArray(extension)) { 3424 extension = [extension]; 3425 } 3426 for (var a = 0; a < extension.length; ++a) { 3427 var ext = extension[a]; 3428 for (var i = 0; i < langExtensions.length; ++i) { 3429 if (langExtensions[i] === ext) { 3430 langExtensions[i].splice(i, 1); 3431 } 3432 } 3433 for (var ii = 0; ii < outputModifiers.length; ++i) { 3434 if (outputModifiers[ii] === ext) { 3435 outputModifiers[ii].splice(i, 1); 3436 } 3437 } 3438 } 3439 }; 3440 3441 /** 3442 * Get all extension of THIS converter 3443 * @returns {{language: Array, output: Array}} 3444 */ 3445 this.getAllExtensions = function () { 3446 return { 3447 language: langExtensions, 3448 output: outputModifiers 3449 }; 3450 }; 3451 3452 /** 3453 * Get the metadata of the previously parsed document 3454 * @param raw 3455 * @returns {string|{}} 3456 */ 3457 this.getMetadata = function (raw) { 3458 if (raw) { 3459 return metadata.raw; 3460 } else { 3461 return metadata.parsed; 3462 } 3463 }; 3464 3465 /** 3466 * Get the metadata format of the previously parsed document 3467 * @returns {string} 3468 */ 3469 this.getMetadataFormat = function () { 3470 return metadata.format; 3471 }; 3472 3473 /** 3474 * Private: set a single key, value metadata pair 3475 * @param {string} key 3476 * @param {string} value 3477 */ 3478 this._setMetadataPair = function (key, value) { 3479 metadata.parsed[key] = value; 3480 }; 3481 3482 /** 3483 * Private: set metadata format 3484 * @param {string} format 3485 */ 3486 this._setMetadataFormat = function (format) { 3487 metadata.format = format; 3488 }; 3489 3490 /** 3491 * Private: set metadata raw text 3492 * @param {string} raw 3493 */ 3494 this._setMetadataRaw = function (raw) { 3495 metadata.raw = raw; 3496 }; 3497}; 3498 3499/** 3500 * Turn Markdown link shortcuts into XHTML <a> tags. 3501 */ 3502showdown.subParser('anchors', function (text, options, globals) { 3503 'use strict'; 3504 3505 text = globals.converter._dispatch('anchors.before', text, options, globals); 3506 3507 var writeAnchorTag = function (wholeMatch, linkText, linkId, url, m5, m6, title) { 3508 if (showdown.helper.isUndefined(title)) { 3509 title = ''; 3510 } 3511 linkId = linkId.toLowerCase(); 3512 3513 // Special case for explicit empty url 3514 if (wholeMatch.search(/\(<?\s*>? ?(['"].*['"])?\)$/m) > -1) { 3515 url = ''; 3516 } else if (!url) { 3517 if (!linkId) { 3518 // lower-case and turn embedded newlines into spaces 3519 linkId = linkText.toLowerCase().replace(/ ?\n/g, ' '); 3520 } 3521 url = '#' + linkId; 3522 3523 if (!showdown.helper.isUndefined(globals.gUrls[linkId])) { 3524 url = globals.gUrls[linkId]; 3525 if (!showdown.helper.isUndefined(globals.gTitles[linkId])) { 3526 title = globals.gTitles[linkId]; 3527 } 3528 } else { 3529 return wholeMatch; 3530 } 3531 } 3532 3533 //url = showdown.helper.escapeCharacters(url, '*_', false); // replaced line to improve performance 3534 url = url.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback); 3535 3536 var result = '<a href="' + url + '"'; 3537 3538 if (title !== '' && title !== null) { 3539 title = title.replace(/"/g, '"'); 3540 //title = showdown.helper.escapeCharacters(title, '*_', false); // replaced line to improve performance 3541 title = title.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback); 3542 result += ' title="' + title + '"'; 3543 } 3544 3545 // optionLinksInNewWindow only applies 3546 // to external links. Hash links (#) open in same page 3547 if (options.openLinksInNewWindow && !/^#/.test(url)) { 3548 // escaped _ 3549 result += ' rel="noopener noreferrer" target="¨E95Eblank"'; 3550 } 3551 3552 result += '>' + linkText + '</a>'; 3553 3554 return result; 3555 }; 3556 3557 // First, handle reference-style links: [link text] [id] 3558 text = text.replace(/\[((?:\[[^\]]*]|[^\[\]])*)] ?(?:\n *)?\[(.*?)]()()()()/g, writeAnchorTag); 3559 3560 // Next, inline-style links: [link text](url "optional title") 3561 // cases with crazy urls like ./image/cat1).png 3562 text = text.replace(/\[((?:\[[^\]]*]|[^\[\]])*)]()[ \t]*\([ \t]?<([^>]*)>(?:[ \t]*((["'])([^"]*?)\5))?[ \t]?\)/g, 3563 writeAnchorTag); 3564 3565 // normal cases 3566 text = text.replace(/\[((?:\[[^\]]*]|[^\[\]])*)]()[ \t]*\([ \t]?<?([\S]+?(?:\([\S]*?\)[\S]*?)?)>?(?:[ \t]*((["'])([^"]*?)\5))?[ \t]?\)/g, 3567 writeAnchorTag); 3568 3569 // handle reference-style shortcuts: [link text] 3570 // These must come last in case you've also got [link test][1] 3571 // or [link test](/foo) 3572 text = text.replace(/\[([^\[\]]+)]()()()()()/g, writeAnchorTag); 3573 3574 // Lastly handle GithubMentions if option is enabled 3575 if (options.ghMentions) { 3576 text = text.replace(/(^|\s)(\\)?(@([a-z\d]+(?:[a-z\d.-]+?[a-z\d]+)*))/gmi, function (wm, st, escape, mentions, username) { 3577 if (escape === '\\') { 3578 return st + mentions; 3579 } 3580 3581 //check if options.ghMentionsLink is a string 3582 if (!showdown.helper.isString(options.ghMentionsLink)) { 3583 throw new Error('ghMentionsLink option must be a string'); 3584 } 3585 var lnk = options.ghMentionsLink.replace(/\{u}/g, username), 3586 target = ''; 3587 if (options.openLinksInNewWindow) { 3588 target = ' rel="noopener noreferrer" target="¨E95Eblank"'; 3589 } 3590 return st + '<a href="' + lnk + '"' + target + '>' + mentions + '</a>'; 3591 }); 3592 } 3593 3594 text = globals.converter._dispatch('anchors.after', text, options, globals); 3595 return text; 3596}); 3597 3598// url allowed chars [a-z\d_.~:/?#[]@!$&'()*+,;=-] 3599 3600var simpleURLRegex = /([*~_]+|\b)(((https?|ftp|dict):\/\/|www\.)[^'">\s]+?\.[^'">\s]+?)()(\1)?(?=\s|$)(?!["<>])/gi, 3601 simpleURLRegex2 = /([*~_]+|\b)(((https?|ftp|dict):\/\/|www\.)[^'">\s]+\.[^'">\s]+?)([.!?,()\[\]])?(\1)?(?=\s|$)(?!["<>])/gi, 3602 delimUrlRegex = /()<(((https?|ftp|dict):\/\/|www\.)[^'">\s]+)()>()/gi, 3603 simpleMailRegex = /(^|\s)(?:mailto:)?([A-Za-z0-9!#$%&'*+-/=?^_`{|}~.]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)(?=$|\s)/gmi, 3604 delimMailRegex = /<()(?:mailto:)?([-.\w]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi, 3605 3606 replaceLink = function (options) { 3607 'use strict'; 3608 return function (wm, leadingMagicChars, link, m2, m3, trailingPunctuation, trailingMagicChars) { 3609 link = link.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback); 3610 var lnkTxt = link, 3611 append = '', 3612 target = '', 3613 lmc = leadingMagicChars || '', 3614 tmc = trailingMagicChars || ''; 3615 if (/^www\./i.test(link)) { 3616 link = link.replace(/^www\./i, 'http://www.'); 3617 } 3618 if (options.excludeTrailingPunctuationFromURLs && trailingPunctuation) { 3619 append = trailingPunctuation; 3620 } 3621 if (options.openLinksInNewWindow) { 3622 target = ' rel="noopener noreferrer" target="¨E95Eblank"'; 3623 } 3624 return lmc + '<a href="' + link + '"' + target + '>' + lnkTxt + '</a>' + append + tmc; 3625 }; 3626 }, 3627 3628 replaceMail = function (options, globals) { 3629 'use strict'; 3630 return function (wholeMatch, b, mail) { 3631 var href = 'mailto:'; 3632 b = b || ''; 3633 mail = showdown.subParser('unescapeSpecialChars')(mail, options, globals); 3634 if (options.encodeEmails) { 3635 href = showdown.helper.encodeEmailAddress(href + mail); 3636 mail = showdown.helper.encodeEmailAddress(mail); 3637 } else { 3638 href = href + mail; 3639 } 3640 return b + '<a href="' + href + '">' + mail + '</a>'; 3641 }; 3642 }; 3643 3644showdown.subParser('autoLinks', function (text, options, globals) { 3645 'use strict'; 3646 3647 text = globals.converter._dispatch('autoLinks.before', text, options, globals); 3648 3649 text = text.replace(delimUrlRegex, replaceLink(options)); 3650 text = text.replace(delimMailRegex, replaceMail(options, globals)); 3651 3652 text = globals.converter._dispatch('autoLinks.after', text, options, globals); 3653 3654 return text; 3655}); 3656 3657showdown.subParser('simplifiedAutoLinks', function (text, options, globals) { 3658 'use strict'; 3659 3660 if (!options.simplifiedAutoLink) { 3661 return text; 3662 } 3663 3664 text = globals.converter._dispatch('simplifiedAutoLinks.before', text, options, globals); 3665 3666 if (options.excludeTrailingPunctuationFromURLs) { 3667 text = text.replace(simpleURLRegex2, replaceLink(options)); 3668 } else { 3669 text = text.replace(simpleURLRegex, replaceLink(options)); 3670 } 3671 text = text.replace(simpleMailRegex, replaceMail(options, globals)); 3672 3673 text = globals.converter._dispatch('simplifiedAutoLinks.after', text, options, globals); 3674 3675 return text; 3676}); 3677 3678/** 3679 * These are all the transformations that form block-level 3680 * tags like paragraphs, headers, and list items. 3681 */ 3682showdown.subParser('blockGamut', function (text, options, globals) { 3683 'use strict'; 3684 3685 text = globals.converter._dispatch('blockGamut.before', text, options, globals); 3686 3687 // we parse blockquotes first so that we can have headings and hrs 3688 // inside blockquotes 3689 text = showdown.subParser('blockQuotes')(text, options, globals); 3690 text = showdown.subParser('headers')(text, options, globals); 3691 3692 // Do Horizontal Rules: 3693 text = showdown.subParser('horizontalRule')(text, options, globals); 3694 3695 text = showdown.subParser('lists')(text, options, globals); 3696 text = showdown.subParser('codeBlocks')(text, options, globals); 3697 text = showdown.subParser('tables')(text, options, globals); 3698 3699 // We already ran _HashHTMLBlocks() before, in Markdown(), but that 3700 // was to escape raw HTML in the original Markdown source. This time, 3701 // we're escaping the markup we've just created, so that we don't wrap 3702 // <p> tags around block-level tags. 3703 text = showdown.subParser('hashHTMLBlocks')(text, options, globals); 3704 text = showdown.subParser('paragraphs')(text, options, globals); 3705 3706 text = globals.converter._dispatch('blockGamut.after', text, options, globals); 3707 3708 return text; 3709}); 3710 3711showdown.subParser('blockQuotes', function (text, options, globals) { 3712 'use strict'; 3713 3714 text = globals.converter._dispatch('blockQuotes.before', text, options, globals); 3715 3716 // add a couple extra lines after the text and endtext mark 3717 text = text + '\n\n'; 3718 3719 var rgx = /(^ {0,3}>[ \t]?.+\n(.+\n)*\n*)+/gm; 3720 3721 if (options.splitAdjacentBlockquotes) { 3722 rgx = /^ {0,3}>[\s\S]*?(?:\n\n)/gm; 3723 } 3724 3725 text = text.replace(rgx, function (bq) { 3726 // attacklab: hack around Konqueror 3.5.4 bug: 3727 // "----------bug".replace(/^-/g,"") == "bug" 3728 bq = bq.replace(/^[ \t]*>[ \t]?/gm, ''); // trim one level of quoting 3729 3730 // attacklab: clean up hack 3731 bq = bq.replace(/¨0/g, ''); 3732 3733 bq = bq.replace(/^[ \t]+$/gm, ''); // trim whitespace-only lines 3734 bq = showdown.subParser('githubCodeBlocks')(bq, options, globals); 3735 bq = showdown.subParser('blockGamut')(bq, options, globals); // recurse 3736 3737 bq = bq.replace(/(^|\n)/g, '$1 '); 3738 // These leading spaces screw with <pre> content, so we need to fix that: 3739 bq = bq.replace(/(\s*<pre>[^\r]+?<\/pre>)/gm, function (wholeMatch, m1) { 3740 var pre = m1; 3741 // attacklab: hack around Konqueror 3.5.4 bug: 3742 pre = pre.replace(/^ /mg, '¨0'); 3743 pre = pre.replace(/¨0/g, ''); 3744 return pre; 3745 }); 3746 3747 return showdown.subParser('hashBlock')('<blockquote>\n' + bq + '\n</blockquote>', options, globals); 3748 }); 3749 3750 text = globals.converter._dispatch('blockQuotes.after', text, options, globals); 3751 return text; 3752}); 3753 3754/** 3755 * Process Markdown `<pre><code>` blocks. 3756 */ 3757showdown.subParser('codeBlocks', function (text, options, globals) { 3758 'use strict'; 3759 3760 text = globals.converter._dispatch('codeBlocks.before', text, options, globals); 3761 3762 // sentinel workarounds for lack of \A and \Z, safari\khtml bug 3763 text += '¨0'; 3764 3765 var pattern = /(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=¨0))/g; 3766 text = text.replace(pattern, function (wholeMatch, m1, m2) { 3767 var codeblock = m1, 3768 nextChar = m2, 3769 end = '\n'; 3770 3771 codeblock = showdown.subParser('outdent')(codeblock, options, globals); 3772 codeblock = showdown.subParser('encodeCode')(codeblock, options, globals); 3773 codeblock = showdown.subParser('detab')(codeblock, options, globals); 3774 codeblock = codeblock.replace(/^\n+/g, ''); // trim leading newlines 3775 codeblock = codeblock.replace(/\n+$/g, ''); // trim trailing newlines 3776 3777 if (options.omitExtraWLInCodeBlocks) { 3778 end = ''; 3779 } 3780 3781 codeblock = '<pre><code>' + codeblock + end + '</code></pre>'; 3782 3783 return showdown.subParser('hashBlock')(codeblock, options, globals) + nextChar; 3784 }); 3785 3786 // strip sentinel 3787 text = text.replace(/¨0/, ''); 3788 3789 text = globals.converter._dispatch('codeBlocks.after', text, options, globals); 3790 return text; 3791}); 3792 3793/** 3794 * 3795 * * Backtick quotes are used for <code></code> spans. 3796 * 3797 * * You can use multiple backticks as the delimiters if you want to 3798 * include literal backticks in the code span. So, this input: 3799 * 3800 * Just type ``foo `bar` baz`` at the prompt. 3801 * 3802 * Will translate to: 3803 * 3804 * <p>Just type <code>foo `bar` baz</code> at the prompt.</p> 3805 * 3806 * There's no arbitrary limit to the number of backticks you 3807 * can use as delimters. If you need three consecutive backticks 3808 * in your code, use four for delimiters, etc. 3809 * 3810 * * You can use spaces to get literal backticks at the edges: 3811 * 3812 * ... type `` `bar` `` ... 3813 * 3814 * Turns to: 3815 * 3816 * ... type <code>`bar`</code> ... 3817 */ 3818showdown.subParser('codeSpans', function (text, options, globals) { 3819 'use strict'; 3820 3821 text = globals.converter._dispatch('codeSpans.before', text, options, globals); 3822 3823 if (typeof text === 'undefined') { 3824 text = ''; 3825 } 3826 text = text.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm, 3827 function (wholeMatch, m1, m2, m3) { 3828 var c = m3; 3829 c = c.replace(/^([ \t]*)/g, ''); // leading whitespace 3830 c = c.replace(/[ \t]*$/g, ''); // trailing whitespace 3831 c = showdown.subParser('encodeCode')(c, options, globals); 3832 c = m1 + '<code>' + c + '</code>'; 3833 c = showdown.subParser('hashHTMLSpans')(c, options, globals); 3834 return c; 3835 } 3836 ); 3837 3838 text = globals.converter._dispatch('codeSpans.after', text, options, globals); 3839 return text; 3840}); 3841 3842/** 3843 * Create a full HTML document from the processed markdown 3844 */ 3845showdown.subParser('completeHTMLDocument', function (text, options, globals) { 3846 'use strict'; 3847 3848 if (!options.completeHTMLDocument) { 3849 return text; 3850 } 3851 3852 text = globals.converter._dispatch('completeHTMLDocument.before', text, options, globals); 3853 3854 var doctype = 'html', 3855 doctypeParsed = '<!DOCTYPE HTML>\n', 3856 title = '', 3857 charset = '<meta charset="utf-8">\n', 3858 lang = '', 3859 metadata = ''; 3860 3861 if (typeof globals.metadata.parsed.doctype !== 'undefined') { 3862 doctypeParsed = '<!DOCTYPE ' + globals.metadata.parsed.doctype + '>\n'; 3863 doctype = globals.metadata.parsed.doctype.toString().toLowerCase(); 3864 if (doctype === 'html' || doctype === 'html5') { 3865 charset = '<meta charset="utf-8">'; 3866 } 3867 } 3868 3869 for (var meta in globals.metadata.parsed) { 3870 if (globals.metadata.parsed.hasOwnProperty(meta)) { 3871 switch (meta.toLowerCase()) { 3872 case 'doctype': 3873 break; 3874 3875 case 'title': 3876 title = '<title>' + globals.metadata.parsed.title + '</title>\n'; 3877 break; 3878 3879 case 'charset': 3880 if (doctype === 'html' || doctype === 'html5') { 3881 charset = '<meta charset="' + globals.metadata.parsed.charset + '">\n'; 3882 } else { 3883 charset = '<meta name="charset" content="' + globals.metadata.parsed.charset + '">\n'; 3884 } 3885 break; 3886 3887 case 'language': 3888 case 'lang': 3889 lang = ' lang="' + globals.metadata.parsed[meta] + '"'; 3890 metadata += '<meta name="' + meta + '" content="' + globals.metadata.parsed[meta] + '">\n'; 3891 break; 3892 3893 default: 3894 metadata += '<meta name="' + meta + '" content="' + globals.metadata.parsed[meta] + '">\n'; 3895 } 3896 } 3897 } 3898 3899 text = doctypeParsed + '<html' + lang + '>\n<head>\n' + title + charset + metadata + '</head>\n<body>\n' + text.trim() + '\n</body>\n</html>'; 3900 3901 text = globals.converter._dispatch('completeHTMLDocument.after', text, options, globals); 3902 return text; 3903}); 3904 3905/** 3906 * Convert all tabs to spaces 3907 */ 3908showdown.subParser('detab', function (text, options, globals) { 3909 'use strict'; 3910 text = globals.converter._dispatch('detab.before', text, options, globals); 3911 3912 // expand first n-1 tabs 3913 text = text.replace(/\t(?=\t)/g, ' '); // g_tab_width 3914 3915 // replace the nth with two sentinels 3916 text = text.replace(/\t/g, '¨A¨B'); 3917 3918 // use the sentinel to anchor our regex so it doesn't explode 3919 text = text.replace(/¨B(.+?)¨A/g, function (wholeMatch, m1) { 3920 var leadingText = m1, 3921 numSpaces = 4 - leadingText.length % 4; // g_tab_width 3922 3923 // there *must* be a better way to do this: 3924 for (var i = 0; i < numSpaces; i++) { 3925 leadingText += ' '; 3926 } 3927 3928 return leadingText; 3929 }); 3930 3931 // clean up sentinels 3932 text = text.replace(/¨A/g, ' '); // g_tab_width 3933 text = text.replace(/¨B/g, ''); 3934 3935 text = globals.converter._dispatch('detab.after', text, options, globals); 3936 return text; 3937}); 3938 3939showdown.subParser('ellipsis', function (text, options, globals) { 3940 'use strict'; 3941 3942 text = globals.converter._dispatch('ellipsis.before', text, options, globals); 3943 3944 text = text.replace(/\.\.\./g, 'â¦'); 3945 3946 text = globals.converter._dispatch('ellipsis.after', text, options, globals); 3947 3948 return text; 3949}); 3950 3951/** 3952 * Turn emoji codes into emojis 3953 * 3954 * List of supported emojis: https://github.com/showdownjs/showdown/wiki/Emojis 3955 */ 3956showdown.subParser('emoji', function (text, options, globals) { 3957 'use strict'; 3958 3959 if (!options.emoji) { 3960 return text; 3961 } 3962 3963 text = globals.converter._dispatch('emoji.before', text, options, globals); 3964 3965 var emojiRgx = /:([\S]+?):/g; 3966 3967 text = text.replace(emojiRgx, function (wm, emojiCode) { 3968 if (showdown.helper.emojis.hasOwnProperty(emojiCode)) { 3969 return showdown.helper.emojis[emojiCode]; 3970 } 3971 return wm; 3972 }); 3973 3974 text = globals.converter._dispatch('emoji.after', text, options, globals); 3975 3976 return text; 3977}); 3978 3979/** 3980 * Smart processing for ampersands and angle brackets that need to be encoded. 3981 */ 3982showdown.subParser('encodeAmpsAndAngles', function (text, options, globals) { 3983 'use strict'; 3984 text = globals.converter._dispatch('encodeAmpsAndAngles.before', text, options, globals); 3985 3986 // Ampersand-encoding based entirely on Nat Irons's Amputator MT plugin: 3987 // http://bumppo.net/projects/amputator/ 3988 text = text.replace(/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/g, '&'); 3989 3990 // Encode naked <'s 3991 text = text.replace(/<(?![a-z\/?$!])/gi, '<'); 3992 3993 // Encode < 3994 text = text.replace(/</g, '<'); 3995 3996 // Encode > 3997 text = text.replace(/>/g, '>'); 3998 3999 text = globals.converter._dispatch('encodeAmpsAndAngles.after', text, options, globals); 4000 return text; 4001}); 4002 4003/** 4004 * Returns the string, with after processing the following backslash escape sequences. 4005 * 4006 * attacklab: The polite way to do this is with the new escapeCharacters() function: 4007 * 4008 * text = escapeCharacters(text,"\\",true); 4009 * text = escapeCharacters(text,"`*_{}[]()>#+-.!",true); 4010 * 4011 * ...but we're sidestepping its use of the (slow) RegExp constructor 4012 * as an optimization for Firefox. This function gets called a LOT. 4013 */ 4014showdown.subParser('encodeBackslashEscapes', function (text, options, globals) { 4015 'use strict'; 4016 text = globals.converter._dispatch('encodeBackslashEscapes.before', text, options, globals); 4017 4018 text = text.replace(/\\(\\)/g, showdown.helper.escapeCharactersCallback); 4019 text = text.replace(/\\([`*_{}\[\]()>#+.!~=|-])/g, showdown.helper.escapeCharactersCallback); 4020 4021 text = globals.converter._dispatch('encodeBackslashEscapes.after', text, options, globals); 4022 return text; 4023}); 4024 4025/** 4026 * Encode/escape certain characters inside Markdown code runs. 4027 * The point is that in code, these characters are literals, 4028 * and lose their special Markdown meanings. 4029 */ 4030showdown.subParser('encodeCode', function (text, options, globals) { 4031 'use strict'; 4032 4033 text = globals.converter._dispatch('encodeCode.before', text, options, globals); 4034 4035 // Encode all ampersands; HTML entities are not 4036 // entities within a Markdown code span. 4037 text = text 4038 .replace(/&/g, '&') 4039 // Do the angle bracket song and dance: 4040 .replace(/</g, '<') 4041 .replace(/>/g, '>') 4042 // Now, escape characters that are magic in Markdown: 4043 .replace(/([*_{}\[\]\\=~-])/g, showdown.helper.escapeCharactersCallback); 4044 4045 text = globals.converter._dispatch('encodeCode.after', text, options, globals); 4046 return text; 4047}); 4048 4049/** 4050 * Within tags -- meaning between < and > -- encode [\ ` * _ ~ =] so they 4051 * don't conflict with their use in Markdown for code, italics and strong. 4052 */ 4053showdown.subParser('escapeSpecialCharsWithinTagAttributes', function (text, options, globals) { 4054 'use strict'; 4055 text = globals.converter._dispatch('escapeSpecialCharsWithinTagAttributes.before', text, options, globals); 4056 4057 // Build a regex to find HTML tags. 4058 var tags = /<\/?[a-z\d_:-]+(?:[\s]+[\s\S]+?)?>/gi, 4059 comments = /<!(--(?:(?:[^>-]|-[^>])(?:[^-]|-[^-])*)--)>/gi; 4060 4061 text = text.replace(tags, function (wholeMatch) { 4062 return wholeMatch 4063 .replace(/(.)<\/?code>(?=.)/g, '$1`') 4064 .replace(/([\\`*_~=|])/g, showdown.helper.escapeCharactersCallback); 4065 }); 4066 4067 text = text.replace(comments, function (wholeMatch) { 4068 return wholeMatch 4069 .replace(/([\\`*_~=|])/g, showdown.helper.escapeCharactersCallback); 4070 }); 4071 4072 text = globals.converter._dispatch('escapeSpecialCharsWithinTagAttributes.after', text, options, globals); 4073 return text; 4074}); 4075 4076/** 4077 * Handle github codeblocks prior to running HashHTML so that 4078 * HTML contained within the codeblock gets escaped properly 4079 * Example: 4080 * ```ruby 4081 * def hello_world(x) 4082 * puts "Hello, #{x}" 4083 * end 4084 * ``` 4085 */ 4086showdown.subParser('githubCodeBlocks', function (text, options, globals) { 4087 'use strict'; 4088 4089 // early exit if option is not enabled 4090 if (!options.ghCodeBlocks) { 4091 return text; 4092 } 4093 4094 text = globals.converter._dispatch('githubCodeBlocks.before', text, options, globals); 4095 4096 text += '¨0'; 4097 4098 text = text.replace(/(?:^|\n)(?: {0,3})(```+|~~~+)(?: *)([^\s`~]*)\n([\s\S]*?)\n(?: {0,3})\1/g, function (wholeMatch, delim, language, codeblock) { 4099 var end = (options.omitExtraWLInCodeBlocks) ? '' : '\n'; 4100 4101 // First parse the github code block 4102 codeblock = showdown.subParser('encodeCode')(codeblock, options, globals); 4103 codeblock = showdown.subParser('detab')(codeblock, options, globals); 4104 codeblock = codeblock.replace(/^\n+/g, ''); // trim leading newlines 4105 codeblock = codeblock.replace(/\n+$/g, ''); // trim trailing whitespace 4106 4107 codeblock = '<pre><code' + (language ? ' class="' + language + ' language-' + language + '"' : '') + '>' + codeblock + end + '</code></pre>'; 4108 4109 codeblock = showdown.subParser('hashBlock')(codeblock, options, globals); 4110 4111 // Since GHCodeblocks can be false positives, we need to 4112 // store the primitive text and the parsed text in a global var, 4113 // and then return a token 4114 return '\n\n¨G' + (globals.ghCodeBlocks.push({text: wholeMatch, codeblock: codeblock}) - 1) + 'G\n\n'; 4115 }); 4116 4117 // attacklab: strip sentinel 4118 text = text.replace(/¨0/, ''); 4119 4120 return globals.converter._dispatch('githubCodeBlocks.after', text, options, globals); 4121}); 4122 4123showdown.subParser('hashBlock', function (text, options, globals) { 4124 'use strict'; 4125 text = globals.converter._dispatch('hashBlock.before', text, options, globals); 4126 text = text.replace(/(^\n+|\n+$)/g, ''); 4127 text = '\n\n¨K' + (globals.gHtmlBlocks.push(text) - 1) + 'K\n\n'; 4128 text = globals.converter._dispatch('hashBlock.after', text, options, globals); 4129 return text; 4130}); 4131 4132/** 4133 * Hash and escape <code> elements that should not be parsed as markdown 4134 */ 4135showdown.subParser('hashCodeTags', function (text, options, globals) { 4136 'use strict'; 4137 text = globals.converter._dispatch('hashCodeTags.before', text, options, globals); 4138 4139 var repFunc = function (wholeMatch, match, left, right) { 4140 var codeblock = left + showdown.subParser('encodeCode')(match, options, globals) + right; 4141 return '¨C' + (globals.gHtmlSpans.push(codeblock) - 1) + 'C'; 4142 }; 4143 4144 // Hash naked <code> 4145 text = showdown.helper.replaceRecursiveRegExp(text, repFunc, '<code\\b[^>]*>', '</code>', 'gim'); 4146 4147 text = globals.converter._dispatch('hashCodeTags.after', text, options, globals); 4148 return text; 4149}); 4150 4151showdown.subParser('hashElement', function (text, options, globals) { 4152 'use strict'; 4153 4154 return function (wholeMatch, m1) { 4155 var blockText = m1; 4156 4157 // Undo double lines 4158 blockText = blockText.replace(/\n\n/g, '\n'); 4159 blockText = blockText.replace(/^\n/, ''); 4160 4161 // strip trailing blank lines 4162 blockText = blockText.replace(/\n+$/g, ''); 4163 4164 // Replace the element text with a marker ("¨KxK" where x is its key) 4165 blockText = '\n\n¨K' + (globals.gHtmlBlocks.push(blockText) - 1) + 'K\n\n'; 4166 4167 return blockText; 4168 }; 4169}); 4170 4171showdown.subParser('hashHTMLBlocks', function (text, options, globals) { 4172 'use strict'; 4173 text = globals.converter._dispatch('hashHTMLBlocks.before', text, options, globals); 4174 4175 var blockTags = [ 4176 'pre', 4177 'div', 4178 'h1', 4179 'h2', 4180 'h3', 4181 'h4', 4182 'h5', 4183 'h6', 4184 'blockquote', 4185 'table', 4186 'dl', 4187 'ol', 4188 'ul', 4189 'script', 4190 'noscript', 4191 'form', 4192 'fieldset', 4193 'iframe', 4194 'math', 4195 'style', 4196 'section', 4197 'header', 4198 'footer', 4199 'nav', 4200 'article', 4201 'aside', 4202 'address', 4203 'audio', 4204 'canvas', 4205 'figure', 4206 'hgroup', 4207 'output', 4208 'video', 4209 'p' 4210 ], 4211 repFunc = function (wholeMatch, match, left, right) { 4212 var txt = wholeMatch; 4213 // check if this html element is marked as markdown 4214 // if so, it's contents should be parsed as markdown 4215 if (left.search(/\bmarkdown\b/) !== -1) { 4216 txt = left + globals.converter.makeHtml(match) + right; 4217 } 4218 return '\n\n¨K' + (globals.gHtmlBlocks.push(txt) - 1) + 'K\n\n'; 4219 }; 4220 4221 if (options.backslashEscapesHTMLTags) { 4222 // encode backslash escaped HTML tags 4223 text = text.replace(/\\<(\/?[^>]+?)>/g, function (wm, inside) { 4224 return '<' + inside + '>'; 4225 }); 4226 } 4227 4228 // hash HTML Blocks 4229 for (var i = 0; i < blockTags.length; ++i) { 4230 4231 var opTagPos, 4232 rgx1 = new RegExp('^ {0,3}(<' + blockTags[i] + '\\b[^>]*>)', 'im'), 4233 patLeft = '<' + blockTags[i] + '\\b[^>]*>', 4234 patRight = '</' + blockTags[i] + '>'; 4235 // 1. Look for the first position of the first opening HTML tag in the text 4236 while ((opTagPos = showdown.helper.regexIndexOf(text, rgx1)) !== -1) { 4237 4238 // if the HTML tag is \ escaped, we need to escape it and break 4239 4240 4241 //2. Split the text in that position 4242 var subTexts = showdown.helper.splitAtIndex(text, opTagPos), 4243 //3. Match recursively 4244 newSubText1 = showdown.helper.replaceRecursiveRegExp(subTexts[1], repFunc, patLeft, patRight, 'im'); 4245 4246 // prevent an infinite loop 4247 if (newSubText1 === subTexts[1]) { 4248 break; 4249 } 4250 text = subTexts[0].concat(newSubText1); 4251 } 4252 } 4253 // HR SPECIAL CASE 4254 text = text.replace(/(\n {0,3}(<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g, 4255 showdown.subParser('hashElement')(text, options, globals)); 4256 4257 // Special case for standalone HTML comments 4258 text = showdown.helper.replaceRecursiveRegExp(text, function (txt) { 4259 return '\n\n¨K' + (globals.gHtmlBlocks.push(txt) - 1) + 'K\n\n'; 4260 }, '^ {0,3}<!--', '-->', 'gm'); 4261 4262 // PHP and ASP-style processor instructions (<?...?> and <%...%>) 4263 text = text.replace(/(?:\n\n)( {0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g, 4264 showdown.subParser('hashElement')(text, options, globals)); 4265 4266 text = globals.converter._dispatch('hashHTMLBlocks.after', text, options, globals); 4267 return text; 4268}); 4269 4270/** 4271 * Hash span elements that should not be parsed as markdown 4272 */ 4273showdown.subParser('hashHTMLSpans', function (text, options, globals) { 4274 'use strict'; 4275 text = globals.converter._dispatch('hashHTMLSpans.before', text, options, globals); 4276 4277 function hashHTMLSpan (html) { 4278 return '¨C' + (globals.gHtmlSpans.push(html) - 1) + 'C'; 4279 } 4280 4281 // Hash Self Closing tags 4282 text = text.replace(/<[^>]+?\/>/gi, function (wm) { 4283 return hashHTMLSpan(wm); 4284 }); 4285 4286 // Hash tags without properties 4287 text = text.replace(/<([^>]+?)>[\s\S]*?<\/\1>/g, function (wm) { 4288 return hashHTMLSpan(wm); 4289 }); 4290 4291 // Hash tags with properties 4292 text = text.replace(/<([^>]+?)\s[^>]+?>[\s\S]*?<\/\1>/g, function (wm) { 4293 return hashHTMLSpan(wm); 4294 }); 4295 4296 // Hash self closing tags without /> 4297 text = text.replace(/<[^>]+?>/gi, function (wm) { 4298 return hashHTMLSpan(wm); 4299 }); 4300 4301 /*showdown.helper.matchRecursiveRegExp(text, '<code\\b[^>]*>', '</code>', 'gi');*/ 4302 4303 text = globals.converter._dispatch('hashHTMLSpans.after', text, options, globals); 4304 return text; 4305}); 4306 4307/** 4308 * Unhash HTML spans 4309 */ 4310showdown.subParser('unhashHTMLSpans', function (text, options, globals) { 4311 'use strict'; 4312 text = globals.converter._dispatch('unhashHTMLSpans.before', text, options, globals); 4313 4314 for (var i = 0; i < globals.gHtmlSpans.length; ++i) { 4315 var repText = globals.gHtmlSpans[i], 4316 // limiter to prevent infinite loop (assume 10 as limit for recurse) 4317 limit = 0; 4318 4319 while (/¨C(\d+)C/.test(repText)) { 4320 var num = RegExp.$1; 4321 repText = repText.replace('¨C' + num + 'C', globals.gHtmlSpans[num]); 4322 if (limit === 10) { 4323 console.error('maximum nesting of 10 spans reached!!!'); 4324 break; 4325 } 4326 ++limit; 4327 } 4328 text = text.replace('¨C' + i + 'C', repText); 4329 } 4330 4331 text = globals.converter._dispatch('unhashHTMLSpans.after', text, options, globals); 4332 return text; 4333}); 4334 4335/** 4336 * Hash and escape <pre><code> elements that should not be parsed as markdown 4337 */ 4338showdown.subParser('hashPreCodeTags', function (text, options, globals) { 4339 'use strict'; 4340 text = globals.converter._dispatch('hashPreCodeTags.before', text, options, globals); 4341 4342 var repFunc = function (wholeMatch, match, left, right) { 4343 // encode html entities 4344 var codeblock = left + showdown.subParser('encodeCode')(match, options, globals) + right; 4345 return '\n\n¨G' + (globals.ghCodeBlocks.push({text: wholeMatch, codeblock: codeblock}) - 1) + 'G\n\n'; 4346 }; 4347 4348 // Hash <pre><code> 4349 text = showdown.helper.replaceRecursiveRegExp(text, repFunc, '^ {0,3}<pre\\b[^>]*>\\s*<code\\b[^>]*>', '^ {0,3}</code>\\s*</pre>', 'gim'); 4350 4351 text = globals.converter._dispatch('hashPreCodeTags.after', text, options, globals); 4352 return text; 4353}); 4354 4355showdown.subParser('headers', function (text, options, globals) { 4356 'use strict'; 4357 4358 text = globals.converter._dispatch('headers.before', text, options, globals); 4359 4360 var headerLevelStart = (isNaN(parseInt(options.headerLevelStart))) ? 1 : parseInt(options.headerLevelStart), 4361 4362 // Set text-style headers: 4363 // Header 1 4364 // ======== 4365 // 4366 // Header 2 4367 // -------- 4368 // 4369 setextRegexH1 = (options.smoothLivePreview) ? /^(.+)[ \t]*\n={2,}[ \t]*\n+/gm : /^(.+)[ \t]*\n=+[ \t]*\n+/gm, 4370 setextRegexH2 = (options.smoothLivePreview) ? /^(.+)[ \t]*\n-{2,}[ \t]*\n+/gm : /^(.+)[ \t]*\n-+[ \t]*\n+/gm; 4371 4372 text = text.replace(setextRegexH1, function (wholeMatch, m1) { 4373 4374 var spanGamut = showdown.subParser('spanGamut')(m1, options, globals), 4375 hID = (options.noHeaderId) ? '' : ' id="' + headerId(m1) + '"', 4376 hLevel = headerLevelStart, 4377 hashBlock = '<h' + hLevel + hID + '>' + spanGamut + '</h' + hLevel + '>'; 4378 return showdown.subParser('hashBlock')(hashBlock, options, globals); 4379 }); 4380 4381 text = text.replace(setextRegexH2, function (matchFound, m1) { 4382 var spanGamut = showdown.subParser('spanGamut')(m1, options, globals), 4383 hID = (options.noHeaderId) ? '' : ' id="' + headerId(m1) + '"', 4384 hLevel = headerLevelStart + 1, 4385 hashBlock = '<h' + hLevel + hID + '>' + spanGamut + '</h' + hLevel + '>'; 4386 return showdown.subParser('hashBlock')(hashBlock, options, globals); 4387 }); 4388 4389 // atx-style headers: 4390 // # Header 1 4391 // ## Header 2 4392 // ## Header 2 with closing hashes ## 4393 // ... 4394 // ###### Header 6 4395 // 4396 var atxStyle = (options.requireSpaceBeforeHeadingText) ? /^(#{1,6})[ \t]+(.+?)[ \t]*#*\n+/gm : /^(#{1,6})[ \t]*(.+?)[ \t]*#*\n+/gm; 4397 4398 text = text.replace(atxStyle, function (wholeMatch, m1, m2) { 4399 var hText = m2; 4400 if (options.customizedHeaderId) { 4401 hText = m2.replace(/\s?\{([^{]+?)}\s*$/, ''); 4402 } 4403 4404 var span = showdown.subParser('spanGamut')(hText, options, globals), 4405 hID = (options.noHeaderId) ? '' : ' id="' + headerId(m2) + '"', 4406 hLevel = headerLevelStart - 1 + m1.length, 4407 header = '<h' + hLevel + hID + '>' + span + '</h' + hLevel + '>'; 4408 4409 return showdown.subParser('hashBlock')(header, options, globals); 4410 }); 4411 4412 function headerId (m) { 4413 var title, 4414 prefix; 4415 4416 // It is separate from other options to allow combining prefix and customized 4417 if (options.customizedHeaderId) { 4418 var match = m.match(/\{([^{]+?)}\s*$/); 4419 if (match && match[1]) { 4420 m = match[1]; 4421 } 4422 } 4423 4424 title = m; 4425 4426 // Prefix id to prevent causing inadvertent pre-existing style matches. 4427 if (showdown.helper.isString(options.prefixHeaderId)) { 4428 prefix = options.prefixHeaderId; 4429 } else if (options.prefixHeaderId === true) { 4430 prefix = 'section-'; 4431 } else { 4432 prefix = ''; 4433 } 4434 4435 if (!options.rawPrefixHeaderId) { 4436 title = prefix + title; 4437 } 4438 4439 if (options.ghCompatibleHeaderId) { 4440 title = title 4441 .replace(/ /g, '-') 4442 // replace previously escaped chars (&, ¨ and $) 4443 .replace(/&/g, '') 4444 .replace(/¨T/g, '') 4445 .replace(/¨D/g, '') 4446 // replace rest of the chars (&~$ are repeated as they might have been escaped) 4447 // borrowed from github's redcarpet (some they should produce similar results) 4448 .replace(/[&+$,\/:;=?@"#{}|^¨~\[\]`\\*)(%.!'<>]/g, '') 4449 .toLowerCase(); 4450 } else if (options.rawHeaderId) { 4451 title = title 4452 .replace(/ /g, '-') 4453 // replace previously escaped chars (&, ¨ and $) 4454 .replace(/&/g, '&') 4455 .replace(/¨T/g, '¨') 4456 .replace(/¨D/g, '$') 4457 // replace " and ' 4458 .replace(/["']/g, '-') 4459 .toLowerCase(); 4460 } else { 4461 title = title 4462 .replace(/[^\w]/g, '') 4463 .toLowerCase(); 4464 } 4465 4466 if (options.rawPrefixHeaderId) { 4467 title = prefix + title; 4468 } 4469 4470 if (globals.hashLinkCounts[title]) { 4471 title = title + '-' + (globals.hashLinkCounts[title]++); 4472 } else { 4473 globals.hashLinkCounts[title] = 1; 4474 } 4475 return title; 4476 } 4477 4478 text = globals.converter._dispatch('headers.after', text, options, globals); 4479 return text; 4480}); 4481 4482/** 4483 * Turn Markdown link shortcuts into XHTML <a> tags. 4484 */ 4485showdown.subParser('horizontalRule', function (text, options, globals) { 4486 'use strict'; 4487 text = globals.converter._dispatch('horizontalRule.before', text, options, globals); 4488 4489 var key = showdown.subParser('hashBlock')('<hr />', options, globals); 4490 text = text.replace(/^ {0,2}( ?-){3,}[ \t]*$/gm, key); 4491 text = text.replace(/^ {0,2}( ?\*){3,}[ \t]*$/gm, key); 4492 text = text.replace(/^ {0,2}( ?_){3,}[ \t]*$/gm, key); 4493 4494 text = globals.converter._dispatch('horizontalRule.after', text, options, globals); 4495 return text; 4496}); 4497 4498/** 4499 * Turn Markdown image shortcuts into <img> tags. 4500 */ 4501showdown.subParser('images', function (text, options, globals) { 4502 'use strict'; 4503 4504 text = globals.converter._dispatch('images.before', text, options, globals); 4505 4506 var inlineRegExp = /!\[([^\]]*?)][ \t]*()\([ \t]?<?([\S]+?(?:\([\S]*?\)[\S]*?)?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(["'])([^"]*?)\6)?[ \t]?\)/g, 4507 crazyRegExp = /!\[([^\]]*?)][ \t]*()\([ \t]?<([^>]*)>(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(?:(["'])([^"]*?)\6))?[ \t]?\)/g, 4508 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, 4509 referenceRegExp = /!\[([^\]]*?)] ?(?:\n *)?\[([\s\S]*?)]()()()()()/g, 4510 refShortcutRegExp = /!\[([^\[\]]+)]()()()()()/g; 4511 4512 function writeImageTagBase64 (wholeMatch, altText, linkId, url, width, height, m5, title) { 4513 url = url.replace(/\s/g, ''); 4514 return writeImageTag (wholeMatch, altText, linkId, url, width, height, m5, title); 4515 } 4516 4517 function writeImageTag (wholeMatch, altText, linkId, url, width, height, m5, title) { 4518 4519 var gUrls = globals.gUrls, 4520 gTitles = globals.gTitles, 4521 gDims = globals.gDimensions; 4522 4523 linkId = linkId.toLowerCase(); 4524 4525 if (!title) { 4526 title = ''; 4527 } 4528 // Special case for explicit empty url 4529 if (wholeMatch.search(/\(<?\s*>? ?(['"].*['"])?\)$/m) > -1) { 4530 url = ''; 4531 4532 } else if (url === '' || url === null) { 4533 if (linkId === '' || linkId === null) { 4534 // lower-case and turn embedded newlines into spaces 4535 linkId = altText.toLowerCase().replace(/ ?\n/g, ' '); 4536 } 4537 url = '#' + linkId; 4538 4539 if (!showdown.helper.isUndefined(gUrls[linkId])) { 4540 url = gUrls[linkId]; 4541 if (!showdown.helper.isUndefined(gTitles[linkId])) { 4542 title = gTitles[linkId]; 4543 } 4544 if (!showdown.helper.isUndefined(gDims[linkId])) { 4545 width = gDims[linkId].width; 4546 height = gDims[linkId].height; 4547 } 4548 } else { 4549 return wholeMatch; 4550 } 4551 } 4552 4553 altText = altText 4554 .replace(/"/g, '"') 4555 //altText = showdown.helper.escapeCharacters(altText, '*_', false); 4556 .replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback); 4557 //url = showdown.helper.escapeCharacters(url, '*_', false); 4558 url = url.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback); 4559 var result = '<img src="' + url + '" alt="' + altText + '"'; 4560 4561 if (title && showdown.helper.isString(title)) { 4562 title = title 4563 .replace(/"/g, '"') 4564 //title = showdown.helper.escapeCharacters(title, '*_', false); 4565 .replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback); 4566 result += ' title="' + title + '"'; 4567 } 4568 4569 if (width && height) { 4570 width = (width === '*') ? 'auto' : width; 4571 height = (height === '*') ? 'auto' : height; 4572 4573 result += ' width="' + width + '"'; 4574 result += ' height="' + height + '"'; 4575 } 4576 4577 result += ' />'; 4578 4579 return result; 4580 } 4581 4582 // First, handle reference-style labeled images: ![alt text][id] 4583 text = text.replace(referenceRegExp, writeImageTag); 4584 4585 // Next, handle inline images:  4586 4587 // base64 encoded images 4588 text = text.replace(base64RegExp, writeImageTagBase64); 4589 4590 // cases with crazy urls like ./image/cat1).png 4591 text = text.replace(crazyRegExp, writeImageTag); 4592 4593 // normal cases 4594 text = text.replace(inlineRegExp, writeImageTag); 4595 4596 // handle reference-style shortcuts: ![img text] 4597 text = text.replace(refShortcutRegExp, writeImageTag); 4598 4599 text = globals.converter._dispatch('images.after', text, options, globals); 4600 return text; 4601}); 4602 4603showdown.subParser('italicsAndBold', function (text, options, globals) { 4604 'use strict'; 4605 4606 text = globals.converter._dispatch('italicsAndBold.before', text, options, globals); 4607 4608 // it's faster to have 3 separate regexes for each case than have just one 4609 // because of backtracing, in some cases, it could lead to an exponential effect 4610 // called "catastrophic backtrace". Ominous! 4611 4612 function parseInside (txt, left, right) { 4613 /* 4614 if (options.simplifiedAutoLink) { 4615 txt = showdown.subParser('simplifiedAutoLinks')(txt, options, globals); 4616 } 4617 */ 4618 return left + txt + right; 4619 } 4620 4621 // Parse underscores 4622 if (options.literalMidWordUnderscores) { 4623 text = text.replace(/\b___(\S[\s\S]*?)___\b/g, function (wm, txt) { 4624 return parseInside (txt, '<strong><em>', '</em></strong>'); 4625 }); 4626 text = text.replace(/\b__(\S[\s\S]*?)__\b/g, function (wm, txt) { 4627 return parseInside (txt, '<strong>', '</strong>'); 4628 }); 4629 text = text.replace(/\b_(\S[\s\S]*?)_\b/g, function (wm, txt) { 4630 return parseInside (txt, '<em>', '</em>'); 4631 }); 4632 } else { 4633 text = text.replace(/___(\S[\s\S]*?)___/g, function (wm, m) { 4634 return (/\S$/.test(m)) ? parseInside (m, '<strong><em>', '</em></strong>') : wm; 4635 }); 4636 text = text.replace(/__(\S[\s\S]*?)__/g, function (wm, m) { 4637 return (/\S$/.test(m)) ? parseInside (m, '<strong>', '</strong>') : wm; 4638 }); 4639 text = text.replace(/_([^\s_][\s\S]*?)_/g, function (wm, m) { 4640 // !/^_[^_]/.test(m) - test if it doesn't start with __ (since it seems redundant, we removed it) 4641 return (/\S$/.test(m)) ? parseInside (m, '<em>', '</em>') : wm; 4642 }); 4643 } 4644 4645 // Now parse asterisks 4646 if (options.literalMidWordAsterisks) { 4647 text = text.replace(/([^*]|^)\B\*\*\*(\S[\s\S]*?)\*\*\*\B(?!\*)/g, function (wm, lead, txt) { 4648 return parseInside (txt, lead + '<strong><em>', '</em></strong>'); 4649 }); 4650 text = text.replace(/([^*]|^)\B\*\*(\S[\s\S]*?)\*\*\B(?!\*)/g, function (wm, lead, txt) { 4651 return parseInside (txt, lead + '<strong>', '</strong>'); 4652 }); 4653 text = text.replace(/([^*]|^)\B\*(\S[\s\S]*?)\*\B(?!\*)/g, function (wm, lead, txt) { 4654 return parseInside (txt, lead + '<em>', '</em>'); 4655 }); 4656 } else { 4657 text = text.replace(/\*\*\*(\S[\s\S]*?)\*\*\*/g, function (wm, m) { 4658 return (/\S$/.test(m)) ? parseInside (m, '<strong><em>', '</em></strong>') : wm; 4659 }); 4660 text = text.replace(/\*\*(\S[\s\S]*?)\*\*/g, function (wm, m) { 4661 return (/\S$/.test(m)) ? parseInside (m, '<strong>', '</strong>') : wm; 4662 }); 4663 text = text.replace(/\*([^\s*][\s\S]*?)\*/g, function (wm, m) { 4664 // !/^\*[^*]/.test(m) - test if it doesn't start with ** (since it seems redundant, we removed it) 4665 return (/\S$/.test(m)) ? parseInside (m, '<em>', '</em>') : wm; 4666 }); 4667 } 4668 4669 4670 text = globals.converter._dispatch('italicsAndBold.after', text, options, globals); 4671 return text; 4672}); 4673 4674/** 4675 * Form HTML ordered (numbered) and unordered (bulleted) lists. 4676 */ 4677showdown.subParser('lists', function (text, options, globals) { 4678 'use strict'; 4679 4680 /** 4681 * Process the contents of a single ordered or unordered list, splitting it 4682 * into individual list items. 4683 * @param {string} listStr 4684 * @param {boolean} trimTrailing 4685 * @returns {string} 4686 */ 4687 function processListItems (listStr, trimTrailing) { 4688 // The $g_list_level global keeps track of when we're inside a list. 4689 // Each time we enter a list, we increment it; when we leave a list, 4690 // we decrement. If it's zero, we're not in a list anymore. 4691 // 4692 // We do this because when we're not inside a list, we want to treat 4693 // something like this: 4694 // 4695 // I recommend upgrading to version 4696 // 8. Oops, now this line is treated 4697 // as a sub-list. 4698 // 4699 // As a single paragraph, despite the fact that the second line starts 4700 // with a digit-period-space sequence. 4701 // 4702 // Whereas when we're inside a list (or sub-list), that line will be 4703 // treated as the start of a sub-list. What a kludge, huh? This is 4704 // an aspect of Markdown's syntax that's hard to parse perfectly 4705 // without resorting to mind-reading. Perhaps the solution is to 4706 // change the syntax rules such that sub-lists must start with a 4707 // starting cardinal number; e.g. "1." or "a.". 4708 globals.gListLevel++; 4709 4710 // trim trailing blank lines: 4711 listStr = listStr.replace(/\n{2,}$/, '\n'); 4712 4713 // attacklab: add sentinel to emulate \z 4714 listStr += '¨0'; 4715 4716 var rgx = /(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0| {0,3}([*+-]|\d+[.])[ \t]+))/gm, 4717 isParagraphed = (/\n[ \t]*\n(?!¨0)/.test(listStr)); 4718 4719 // Since version 1.5, nesting sublists requires 4 spaces (or 1 tab) indentation, 4720 // which is a syntax breaking change 4721 // activating this option reverts to old behavior 4722 if (options.disableForced4SpacesIndentedSublists) { 4723 rgx = /(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0|\2([*+-]|\d+[.])[ \t]+))/gm; 4724 } 4725 4726 listStr = listStr.replace(rgx, function (wholeMatch, m1, m2, m3, m4, taskbtn, checked) { 4727 checked = (checked && checked.trim() !== ''); 4728 4729 var item = showdown.subParser('outdent')(m4, options, globals), 4730 bulletStyle = ''; 4731 4732 // Support for github tasklists 4733 if (taskbtn && options.tasklists) { 4734 bulletStyle = ' class="task-list-item" style="list-style-type: none;"'; 4735 item = item.replace(/^[ \t]*\[(x|X| )?]/m, function () { 4736 var otp = '<input type="checkbox" disabled style="margin: 0px 0.35em 0.25em -1.6em; vertical-align: middle;"'; 4737 if (checked) { 4738 otp += ' checked'; 4739 } 4740 otp += '>'; 4741 return otp; 4742 }); 4743 } 4744 4745 // ISSUE #312 4746 // This input: - - - a 4747 // causes trouble to the parser, since it interprets it as: 4748 // <ul><li><li><li>a</li></li></li></ul> 4749 // instead of: 4750 // <ul><li>- - a</li></ul> 4751 // So, to prevent it, we will put a marker (¨A)in the beginning of the line 4752 // Kind of hackish/monkey patching, but seems more effective than overcomplicating the list parser 4753 item = item.replace(/^([-*+]|\d\.)[ \t]+[\S\n ]*/g, function (wm2) { 4754 return '¨A' + wm2; 4755 }); 4756 4757 // m1 - Leading line or 4758 // Has a double return (multi paragraph) or 4759 // Has sublist 4760 if (m1 || (item.search(/\n{2,}/) > -1)) { 4761 item = showdown.subParser('githubCodeBlocks')(item, options, globals); 4762 item = showdown.subParser('blockGamut')(item, options, globals); 4763 } else { 4764 // Recursion for sub-lists: 4765 item = showdown.subParser('lists')(item, options, globals); 4766 item = item.replace(/\n$/, ''); // chomp(item) 4767 item = showdown.subParser('hashHTMLBlocks')(item, options, globals); 4768 4769 // Colapse double linebreaks 4770 item = item.replace(/\n\n+/g, '\n\n'); 4771 if (isParagraphed) { 4772 item = showdown.subParser('paragraphs')(item, options, globals); 4773 } else { 4774 item = showdown.subParser('spanGamut')(item, options, globals); 4775 } 4776 } 4777 4778 // now we need to remove the marker (¨A) 4779 item = item.replace('¨A', ''); 4780 // we can finally wrap the line in list item tags 4781 item = '<li' + bulletStyle + '>' + item + '</li>\n'; 4782 4783 return item; 4784 }); 4785 4786 // attacklab: strip sentinel 4787 listStr = listStr.replace(/¨0/g, ''); 4788 4789 globals.gListLevel--; 4790 4791 if (trimTrailing) { 4792 listStr = listStr.replace(/\s+$/, ''); 4793 } 4794 4795 return listStr; 4796 } 4797 4798 function styleStartNumber (list, listType) { 4799 // check if ol and starts by a number different than 1 4800 if (listType === 'ol') { 4801 var res = list.match(/^ *(\d+)\./); 4802 if (res && res[1] !== '1') { 4803 return ' start="' + res[1] + '"'; 4804 } 4805 } 4806 return ''; 4807 } 4808 4809 /** 4810 * Check and parse consecutive lists (better fix for issue #142) 4811 * @param {string} list 4812 * @param {string} listType 4813 * @param {boolean} trimTrailing 4814 * @returns {string} 4815 */ 4816 function parseConsecutiveLists (list, listType, trimTrailing) { 4817 // check if we caught 2 or more consecutive lists by mistake 4818 // we use the counterRgx, meaning if listType is UL we look for OL and vice versa 4819 var olRgx = (options.disableForced4SpacesIndentedSublists) ? /^ ?\d+\.[ \t]/gm : /^ {0,3}\d+\.[ \t]/gm, 4820 ulRgx = (options.disableForced4SpacesIndentedSublists) ? /^ ?[*+-][ \t]/gm : /^ {0,3}[*+-][ \t]/gm, 4821 counterRxg = (listType === 'ul') ? olRgx : ulRgx, 4822 result = ''; 4823 4824 if (list.search(counterRxg) !== -1) { 4825 (function parseCL (txt) { 4826 var pos = txt.search(counterRxg), 4827 style = styleStartNumber(list, listType); 4828 if (pos !== -1) { 4829 // slice 4830 result += '\n\n<' + listType + style + '>\n' + processListItems(txt.slice(0, pos), !!trimTrailing) + '</' + listType + '>\n'; 4831 4832 // invert counterType and listType 4833 listType = (listType === 'ul') ? 'ol' : 'ul'; 4834 counterRxg = (listType === 'ul') ? olRgx : ulRgx; 4835 4836 //recurse 4837 parseCL(txt.slice(pos)); 4838 } else { 4839 result += '\n\n<' + listType + style + '>\n' + processListItems(txt, !!trimTrailing) + '</' + listType + '>\n'; 4840 } 4841 })(list); 4842 } else { 4843 var style = styleStartNumber(list, listType); 4844 result = '\n\n<' + listType + style + '>\n' + processListItems(list, !!trimTrailing) + '</' + listType + '>\n'; 4845 } 4846 4847 return result; 4848 } 4849 4850 /** Start of list parsing **/ 4851 text = globals.converter._dispatch('lists.before', text, options, globals); 4852 // add sentinel to hack around khtml/safari bug: 4853 // http://bugs.webkit.org/show_bug.cgi?id=11231 4854 text += '¨0'; 4855 4856 if (globals.gListLevel) { 4857 text = text.replace(/^(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(¨0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm, 4858 function (wholeMatch, list, m2) { 4859 var listType = (m2.search(/[*+-]/g) > -1) ? 'ul' : 'ol'; 4860 return parseConsecutiveLists(list, listType, true); 4861 } 4862 ); 4863 } else { 4864 text = text.replace(/(\n\n|^\n?)(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(¨0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm, 4865 function (wholeMatch, m1, list, m3) { 4866 var listType = (m3.search(/[*+-]/g) > -1) ? 'ul' : 'ol'; 4867 return parseConsecutiveLists(list, listType, false); 4868 } 4869 ); 4870 } 4871 4872 // strip sentinel 4873 text = text.replace(/¨0/, ''); 4874 text = globals.converter._dispatch('lists.after', text, options, globals); 4875 return text; 4876}); 4877 4878/** 4879 * Parse metadata at the top of the document 4880 */ 4881showdown.subParser('metadata', function (text, options, globals) { 4882 'use strict'; 4883 4884 if (!options.metadata) { 4885 return text; 4886 } 4887 4888 text = globals.converter._dispatch('metadata.before', text, options, globals); 4889 4890 function parseMetadataContents (content) { 4891 // raw is raw so it's not changed in any way 4892 globals.metadata.raw = content; 4893 4894 // escape chars forbidden in html attributes 4895 // double quotes 4896 content = content 4897 // ampersand first 4898 .replace(/&/g, '&') 4899 // double quotes 4900 .replace(/"/g, '"'); 4901 4902 content = content.replace(/\n {4}/g, ' '); 4903 content.replace(/^([\S ]+): +([\s\S]+?)$/gm, function (wm, key, value) { 4904 globals.metadata.parsed[key] = value; 4905 return ''; 4906 }); 4907 } 4908 4909 text = text.replace(/^\s*«««+(\S*?)\n([\s\S]+?)\n»»»+\n/, function (wholematch, format, content) { 4910 parseMetadataContents(content); 4911 return '¨M'; 4912 }); 4913 4914 text = text.replace(/^\s*---+(\S*?)\n([\s\S]+?)\n---+\n/, function (wholematch, format, content) { 4915 if (format) { 4916 globals.metadata.format = format; 4917 } 4918 parseMetadataContents(content); 4919 return '¨M'; 4920 }); 4921 4922 text = text.replace(/¨M/g, ''); 4923 4924 text = globals.converter._dispatch('metadata.after', text, options, globals); 4925 return text; 4926}); 4927 4928/** 4929 * Remove one level of line-leading tabs or spaces 4930 */ 4931showdown.subParser('outdent', function (text, options, globals) { 4932 'use strict'; 4933 text = globals.converter._dispatch('outdent.before', text, options, globals); 4934 4935 // attacklab: hack around Konqueror 3.5.4 bug: 4936 // "----------bug".replace(/^-/g,"") == "bug" 4937 text = text.replace(/^(\t|[ ]{1,4})/gm, '¨0'); // attacklab: g_tab_width 4938 4939 // attacklab: clean up hack 4940 text = text.replace(/¨0/g, ''); 4941 4942 text = globals.converter._dispatch('outdent.after', text, options, globals); 4943 return text; 4944}); 4945 4946/** 4947 * 4948 */ 4949showdown.subParser('paragraphs', function (text, options, globals) { 4950 'use strict'; 4951 4952 text = globals.converter._dispatch('paragraphs.before', text, options, globals); 4953 // Strip leading and trailing lines: 4954 text = text.replace(/^\n+/g, ''); 4955 text = text.replace(/\n+$/g, ''); 4956 4957 var grafs = text.split(/\n{2,}/g), 4958 grafsOut = [], 4959 end = grafs.length; // Wrap <p> tags 4960 4961 for (var i = 0; i < end; i++) { 4962 var str = grafs[i]; 4963 // if this is an HTML marker, copy it 4964 if (str.search(/¨(K|G)(\d+)\1/g) >= 0) { 4965 grafsOut.push(str); 4966 4967 // test for presence of characters to prevent empty lines being parsed 4968 // as paragraphs (resulting in undesired extra empty paragraphs) 4969 } else if (str.search(/\S/) >= 0) { 4970 str = showdown.subParser('spanGamut')(str, options, globals); 4971 str = str.replace(/^([ \t]*)/g, '<p>'); 4972 str += '</p>'; 4973 grafsOut.push(str); 4974 } 4975 } 4976 4977 /** Unhashify HTML blocks */ 4978 end = grafsOut.length; 4979 for (i = 0; i < end; i++) { 4980 var blockText = '', 4981 grafsOutIt = grafsOut[i], 4982 codeFlag = false; 4983 // if this is a marker for an html block... 4984 // use RegExp.test instead of string.search because of QML bug 4985 while (/¨(K|G)(\d+)\1/.test(grafsOutIt)) { 4986 var delim = RegExp.$1, 4987 num = RegExp.$2; 4988 4989 if (delim === 'K') { 4990 blockText = globals.gHtmlBlocks[num]; 4991 } else { 4992 // we need to check if ghBlock is a false positive 4993 if (codeFlag) { 4994 // use encoded version of all text 4995 blockText = showdown.subParser('encodeCode')(globals.ghCodeBlocks[num].text, options, globals); 4996 } else { 4997 blockText = globals.ghCodeBlocks[num].codeblock; 4998 } 4999 } 5000 blockText = blockText.replace(/\$/g, '$$$$'); // Escape any dollar signs 5001 5002 grafsOutIt = grafsOutIt.replace(/(\n\n)?¨(K|G)\d+\2(\n\n)?/, blockText); 5003 // Check if grafsOutIt is a pre->code 5004 if (/^<pre\b[^>]*>\s*<code\b[^>]*>/.test(grafsOutIt)) { 5005 codeFlag = true; 5006 } 5007 } 5008 grafsOut[i] = grafsOutIt; 5009 } 5010 text = grafsOut.join('\n'); 5011 // Strip leading and trailing lines: 5012 text = text.replace(/^\n+/g, ''); 5013 text = text.replace(/\n+$/g, ''); 5014 return globals.converter._dispatch('paragraphs.after', text, options, globals); 5015}); 5016 5017/** 5018 * Run extension 5019 */ 5020showdown.subParser('runExtension', function (ext, text, options, globals) { 5021 'use strict'; 5022 5023 if (ext.filter) { 5024 text = ext.filter(text, globals.converter, options); 5025 5026 } else if (ext.regex) { 5027 // TODO remove this when old extension loading mechanism is deprecated 5028 var re = ext.regex; 5029 if (!(re instanceof RegExp)) { 5030 re = new RegExp(re, 'g'); 5031 } 5032 text = text.replace(re, ext.replace); 5033 } 5034 5035 return text; 5036}); 5037 5038/** 5039 * These are all the transformations that occur *within* block-level 5040 * tags like paragraphs, headers, and list items. 5041 */ 5042showdown.subParser('spanGamut', function (text, options, globals) { 5043 'use strict'; 5044 5045 text = globals.converter._dispatch('spanGamut.before', text, options, globals); 5046 text = showdown.subParser('codeSpans')(text, options, globals); 5047 text = showdown.subParser('escapeSpecialCharsWithinTagAttributes')(text, options, globals); 5048 text = showdown.subParser('encodeBackslashEscapes')(text, options, globals); 5049 5050 // Process anchor and image tags. Images must come first, 5051 // because ![foo][f] looks like an anchor. 5052 text = showdown.subParser('images')(text, options, globals); 5053 text = showdown.subParser('anchors')(text, options, globals); 5054 5055 // Make links out of things like `<http://example.com/>` 5056 // Must come after anchors, because you can use < and > 5057 // delimiters in inline links like [this](<url>). 5058 text = showdown.subParser('autoLinks')(text, options, globals); 5059 text = showdown.subParser('simplifiedAutoLinks')(text, options, globals); 5060 text = showdown.subParser('emoji')(text, options, globals); 5061 text = showdown.subParser('underline')(text, options, globals); 5062 text = showdown.subParser('italicsAndBold')(text, options, globals); 5063 text = showdown.subParser('strikethrough')(text, options, globals); 5064 text = showdown.subParser('ellipsis')(text, options, globals); 5065 5066 // we need to hash HTML tags inside spans 5067 text = showdown.subParser('hashHTMLSpans')(text, options, globals); 5068 5069 // now we encode amps and angles 5070 text = showdown.subParser('encodeAmpsAndAngles')(text, options, globals); 5071 5072 // Do hard breaks 5073 if (options.simpleLineBreaks) { 5074 // GFM style hard breaks 5075 // only add line breaks if the text does not contain a block (special case for lists) 5076 if (!/\n\n¨K/.test(text)) { 5077 text = text.replace(/\n+/g, '<br />\n'); 5078 } 5079 } else { 5080 // Vanilla hard breaks 5081 text = text.replace(/ +\n/g, '<br />\n'); 5082 } 5083 5084 text = globals.converter._dispatch('spanGamut.after', text, options, globals); 5085 return text; 5086}); 5087 5088showdown.subParser('strikethrough', function (text, options, globals) { 5089 'use strict'; 5090 5091 function parseInside (txt) { 5092 if (options.simplifiedAutoLink) { 5093 txt = showdown.subParser('simplifiedAutoLinks')(txt, options, globals); 5094 } 5095 return '<del>' + txt + '</del>'; 5096 } 5097 5098 if (options.strikethrough) { 5099 text = globals.converter._dispatch('strikethrough.before', text, options, globals); 5100 text = text.replace(/(?:~){2}([\s\S]+?)(?:~){2}/g, function (wm, txt) { return parseInside(txt); }); 5101 text = globals.converter._dispatch('strikethrough.after', text, options, globals); 5102 } 5103 5104 return text; 5105}); 5106 5107/** 5108 * Strips link definitions from text, stores the URLs and titles in 5109 * hash references. 5110 * Link defs are in the form: ^[id]: url "optional title" 5111 */ 5112showdown.subParser('stripLinkDefinitions', function (text, options, globals) { 5113 'use strict'; 5114 5115 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, 5116 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; 5117 5118 // attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug 5119 text += '¨0'; 5120 5121 var replaceFunc = function (wholeMatch, linkId, url, width, height, blankLines, title) { 5122 linkId = linkId.toLowerCase(); 5123 if (url.match(/^data:.+?\/.+?;base64,/)) { 5124 // remove newlines 5125 globals.gUrls[linkId] = url.replace(/\s/g, ''); 5126 } else { 5127 globals.gUrls[linkId] = showdown.subParser('encodeAmpsAndAngles')(url, options, globals); // Link IDs are case-insensitive 5128 } 5129 5130 if (blankLines) { 5131 // Oops, found blank lines, so it's not a title. 5132 // Put back the parenthetical statement we stole. 5133 return blankLines + title; 5134 5135 } else { 5136 if (title) { 5137 globals.gTitles[linkId] = title.replace(/"|'/g, '"'); 5138 } 5139 if (options.parseImgDimensions && width && height) { 5140 globals.gDimensions[linkId] = { 5141 width: width, 5142 height: height 5143 }; 5144 } 5145 } 5146 // Completely remove the definition from the text 5147 return ''; 5148 }; 5149 5150 // first we try to find base64 link references 5151 text = text.replace(base64Regex, replaceFunc); 5152 5153 text = text.replace(regex, replaceFunc); 5154 5155 // attacklab: strip sentinel 5156 text = text.replace(/¨0/, ''); 5157 5158 return text; 5159}); 5160 5161showdown.subParser('tables', function (text, options, globals) { 5162 'use strict'; 5163 5164 if (!options.tables) { 5165 return text; 5166 } 5167 5168 var tableRgx = /^ {0,3}\|?.+\|.+\n {0,3}\|?[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*:?[ \t]*(?:[-=]){2,}[\s\S]+?(?:\n\n|¨0)/gm, 5169 //singeColTblRgx = /^ {0,3}\|.+\|\n {0,3}\|[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*\n(?: {0,3}\|.+\|\n)+(?:\n\n|¨0)/gm; 5170 singeColTblRgx = /^ {0,3}\|.+\|[ \t]*\n {0,3}\|[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*\n( {0,3}\|.+\|[ \t]*\n)*(?:\n|¨0)/gm; 5171 5172 function parseStyles (sLine) { 5173 if (/^:[ \t]*--*$/.test(sLine)) { 5174 return ' style="text-align:left;"'; 5175 } else if (/^--*[ \t]*:[ \t]*$/.test(sLine)) { 5176 return ' style="text-align:right;"'; 5177 } else if (/^:[ \t]*--*[ \t]*:$/.test(sLine)) { 5178 return ' style="text-align:center;"'; 5179 } else { 5180 return ''; 5181 } 5182 } 5183 5184 function parseHeaders (header, style) { 5185 var id = ''; 5186 header = header.trim(); 5187 // support both tablesHeaderId and tableHeaderId due to error in documentation so we don't break backwards compatibility 5188 if (options.tablesHeaderId || options.tableHeaderId) { 5189 id = ' id="' + header.replace(/ /g, '_').toLowerCase() + '"'; 5190 } 5191 header = showdown.subParser('spanGamut')(header, options, globals); 5192 5193 return '<th' + id + style + '>' + header + '</th>\n'; 5194 } 5195 5196 function parseCells (cell, style) { 5197 var subText = showdown.subParser('spanGamut')(cell, options, globals); 5198 return '<td' + style + '>' + subText + '</td>\n'; 5199 } 5200 5201 function buildTable (headers, cells) { 5202 var tb = '<table>\n<thead>\n<tr>\n', 5203 tblLgn = headers.length; 5204 5205 for (var i = 0; i < tblLgn; ++i) { 5206 tb += headers[i]; 5207 } 5208 tb += '</tr>\n</thead>\n<tbody>\n'; 5209 5210 for (i = 0; i < cells.length; ++i) { 5211 tb += '<tr>\n'; 5212 for (var ii = 0; ii < tblLgn; ++ii) { 5213 tb += cells[i][ii]; 5214 } 5215 tb += '</tr>\n'; 5216 } 5217 tb += '</tbody>\n</table>\n'; 5218 return tb; 5219 } 5220 5221 function parseTable (rawTable) { 5222 var i, tableLines = rawTable.split('\n'); 5223 5224 for (i = 0; i < tableLines.length; ++i) { 5225 // strip wrong first and last column if wrapped tables are used 5226 if (/^ {0,3}\|/.test(tableLines[i])) { 5227 tableLines[i] = tableLines[i].replace(/^ {0,3}\|/, ''); 5228 } 5229 if (/\|[ \t]*$/.test(tableLines[i])) { 5230 tableLines[i] = tableLines[i].replace(/\|[ \t]*$/, ''); 5231 } 5232 // parse code spans first, but we only support one line code spans 5233 tableLines[i] = showdown.subParser('codeSpans')(tableLines[i], options, globals); 5234 } 5235 5236 var rawHeaders = tableLines[0].split('|').map(function (s) { return s.trim();}), 5237 rawStyles = tableLines[1].split('|').map(function (s) { return s.trim();}), 5238 rawCells = [], 5239 headers = [], 5240 styles = [], 5241 cells = []; 5242 5243 tableLines.shift(); 5244 tableLines.shift(); 5245 5246 for (i = 0; i < tableLines.length; ++i) { 5247 if (tableLines[i].trim() === '') { 5248 continue; 5249 } 5250 rawCells.push( 5251 tableLines[i] 5252 .split('|') 5253 .map(function (s) { 5254 return s.trim(); 5255 }) 5256 ); 5257 } 5258 5259 if (rawHeaders.length < rawStyles.length) { 5260 return rawTable; 5261 } 5262 5263 for (i = 0; i < rawStyles.length; ++i) { 5264 styles.push(parseStyles(rawStyles[i])); 5265 } 5266 5267 for (i = 0; i < rawHeaders.length; ++i) { 5268 if (showdown.helper.isUndefined(styles[i])) { 5269 styles[i] = ''; 5270 } 5271 headers.push(parseHeaders(rawHeaders[i], styles[i])); 5272 } 5273 5274 for (i = 0; i < rawCells.length; ++i) { 5275 var row = []; 5276 for (var ii = 0; ii < headers.length; ++ii) { 5277 if (showdown.helper.isUndefined(rawCells[i][ii])) { 5278 5279 } 5280 row.push(parseCells(rawCells[i][ii], styles[ii])); 5281 } 5282 cells.push(row); 5283 } 5284 5285 return buildTable(headers, cells); 5286 } 5287 5288 text = globals.converter._dispatch('tables.before', text, options, globals); 5289 5290 // find escaped pipe characters 5291 text = text.replace(/\\(\|)/g, showdown.helper.escapeCharactersCallback); 5292 5293 // parse multi column tables 5294 text = text.replace(tableRgx, parseTable); 5295 5296 // parse one column tables 5297 text = text.replace(singeColTblRgx, parseTable); 5298 5299 text = globals.converter._dispatch('tables.after', text, options, globals); 5300 5301 return text; 5302}); 5303 5304showdown.subParser('underline', function (text, options, globals) { 5305 'use strict'; 5306 5307 if (!options.underline) { 5308 return text; 5309 } 5310 5311 text = globals.converter._dispatch('underline.before', text, options, globals); 5312 5313 if (options.literalMidWordUnderscores) { 5314 text = text.replace(/\b___(\S[\s\S]*?)___\b/g, function (wm, txt) { 5315 return '<u>' + txt + '</u>'; 5316 }); 5317 text = text.replace(/\b__(\S[\s\S]*?)__\b/g, function (wm, txt) { 5318 return '<u>' + txt + '</u>'; 5319 }); 5320 } else { 5321 text = text.replace(/___(\S[\s\S]*?)___/g, function (wm, m) { 5322 return (/\S$/.test(m)) ? '<u>' + m + '</u>' : wm; 5323 }); 5324 text = text.replace(/__(\S[\s\S]*?)__/g, function (wm, m) { 5325 return (/\S$/.test(m)) ? '<u>' + m + '</u>' : wm; 5326 }); 5327 } 5328 5329 // escape remaining underscores to prevent them being parsed by italic and bold 5330 text = text.replace(/(_)/g, showdown.helper.escapeCharactersCallback); 5331 5332 text = globals.converter._dispatch('underline.after', text, options, globals); 5333 5334 return text; 5335}); 5336 5337/** 5338 * Swap back in all the special characters we've hidden. 5339 */ 5340showdown.subParser('unescapeSpecialChars', function (text, options, globals) { 5341 'use strict'; 5342 text = globals.converter._dispatch('unescapeSpecialChars.before', text, options, globals); 5343 5344 text = text.replace(/¨E(\d+)E/g, function (wholeMatch, m1) { 5345 var charCodeToReplace = parseInt(m1); 5346 return String.fromCharCode(charCodeToReplace); 5347 }); 5348 5349 text = globals.converter._dispatch('unescapeSpecialChars.after', text, options, globals); 5350 return text; 5351}); 5352 5353showdown.subParser('makeMarkdown.blockquote', function (node, globals) { 5354 'use strict'; 5355 5356 var txt = ''; 5357 if (node.hasChildNodes()) { 5358 var children = node.childNodes, 5359 childrenLength = children.length; 5360 5361 for (var i = 0; i < childrenLength; ++i) { 5362 var innerTxt = showdown.subParser('makeMarkdown.node')(children[i], globals); 5363 5364 if (innerTxt === '') { 5365 continue; 5366 } 5367 txt += innerTxt; 5368 } 5369 } 5370 // cleanup 5371 txt = txt.trim(); 5372 txt = '> ' + txt.split('\n').join('\n> '); 5373 return txt; 5374}); 5375 5376showdown.subParser('makeMarkdown.codeBlock', function (node, globals) { 5377 'use strict'; 5378 5379 var lang = node.getAttribute('language'), 5380 num = node.getAttribute('precodenum'); 5381 return '```' + lang + '\n' + globals.preList[num] + '\n```'; 5382}); 5383 5384showdown.subParser('makeMarkdown.codeSpan', function (node) { 5385 'use strict'; 5386 5387 return '`' + node.innerHTML + '`'; 5388}); 5389 5390showdown.subParser('makeMarkdown.emphasis', function (node, globals) { 5391 'use strict'; 5392 5393 var txt = ''; 5394 if (node.hasChildNodes()) { 5395 txt += '*'; 5396 var children = node.childNodes, 5397 childrenLength = children.length; 5398 for (var i = 0; i < childrenLength; ++i) { 5399 txt += showdown.subParser('makeMarkdown.node')(children[i], globals); 5400 } 5401 txt += '*'; 5402 } 5403 return txt; 5404}); 5405 5406showdown.subParser('makeMarkdown.header', function (node, globals, headerLevel) { 5407 'use strict'; 5408 5409 var headerMark = new Array(headerLevel + 1).join('#'), 5410 txt = ''; 5411 5412 if (node.hasChildNodes()) { 5413 txt = headerMark + ' '; 5414 var children = node.childNodes, 5415 childrenLength = children.length; 5416 5417 for (var i = 0; i < childrenLength; ++i) { 5418 txt += showdown.subParser('makeMarkdown.node')(children[i], globals); 5419 } 5420 } 5421 return txt; 5422}); 5423 5424showdown.subParser('makeMarkdown.hr', function () { 5425 'use strict'; 5426 5427 return '---'; 5428}); 5429 5430showdown.subParser('makeMarkdown.image', function (node) { 5431 'use strict'; 5432 5433 var txt = ''; 5434 if (node.hasAttribute('src')) { 5435 txt += ' + '>'; 5437 if (node.hasAttribute('width') && node.hasAttribute('height')) { 5438 txt += ' =' + node.getAttribute('width') + 'x' + node.getAttribute('height'); 5439 } 5440 5441 if (node.hasAttribute('title')) { 5442 txt += ' "' + node.getAttribute('title') + '"'; 5443 } 5444 txt += ')'; 5445 } 5446 return txt; 5447}); 5448 5449showdown.subParser('makeMarkdown.links', function (node, globals) { 5450 'use strict'; 5451 5452 var txt = ''; 5453 if (node.hasChildNodes() && node.hasAttribute('href')) { 5454 var children = node.childNodes, 5455 childrenLength = children.length; 5456 txt = '['; 5457 for (var i = 0; i < childrenLength; ++i) { 5458 txt += showdown.subParser('makeMarkdown.node')(children[i], globals); 5459 } 5460 txt += ']('; 5461 txt += '<' + node.getAttribute('href') + '>'; 5462 if (node.hasAttribute('title')) { 5463 txt += ' "' + node.getAttribute('title') + '"'; 5464 } 5465 txt += ')'; 5466 } 5467 return txt; 5468}); 5469 5470showdown.subParser('makeMarkdown.list', function (node, globals, type) { 5471 'use strict'; 5472 5473 var txt = ''; 5474 if (!node.hasChildNodes()) { 5475 return ''; 5476 } 5477 var listItems = node.childNodes, 5478 listItemsLenght = listItems.length, 5479 listNum = node.getAttribute('start') || 1; 5480 5481 for (var i = 0; i < listItemsLenght; ++i) { 5482 if (typeof listItems[i].tagName === 'undefined' || listItems[i].tagName.toLowerCase() !== 'li') { 5483 continue; 5484 } 5485 5486 // define the bullet to use in list 5487 var bullet = ''; 5488 if (type === 'ol') { 5489 bullet = listNum.toString() + '. '; 5490 } else { 5491 bullet = '- '; 5492 } 5493 5494 // parse list item 5495 txt += bullet + showdown.subParser('makeMarkdown.listItem')(listItems[i], globals); 5496 ++listNum; 5497 } 5498 5499 // add comment at the end to prevent consecutive lists to be parsed as one 5500 txt += '\n<!-- -->\n'; 5501 return txt.trim(); 5502}); 5503 5504showdown.subParser('makeMarkdown.listItem', function (node, globals) { 5505 'use strict'; 5506 5507 var listItemTxt = ''; 5508 5509 var children = node.childNodes, 5510 childrenLenght = children.length; 5511 5512 for (var i = 0; i < childrenLenght; ++i) { 5513 listItemTxt += showdown.subParser('makeMarkdown.node')(children[i], globals); 5514 } 5515 // if it's only one liner, we need to add a newline at the end 5516 if (!/\n$/.test(listItemTxt)) { 5517 listItemTxt += '\n'; 5518 } else { 5519 // it's multiparagraph, so we need to indent 5520 listItemTxt = listItemTxt 5521 .split('\n') 5522 .join('\n ') 5523 .replace(/^ {4}$/gm, '') 5524 .replace(/\n\n+/g, '\n\n'); 5525 } 5526 5527 return listItemTxt; 5528}); 5529 5530 5531 5532showdown.subParser('makeMarkdown.node', function (node, globals, spansOnly) { 5533 'use strict'; 5534 5535 spansOnly = spansOnly || false; 5536 5537 var txt = ''; 5538 5539 // edge case of text without wrapper paragraph 5540 if (node.nodeType === 3) { 5541 return showdown.subParser('makeMarkdown.txt')(node, globals); 5542 } 5543 5544 // HTML comment 5545 if (node.nodeType === 8) { 5546 return '<!--' + node.data + '-->\n\n'; 5547 } 5548 5549 // process only node elements 5550 if (node.nodeType !== 1) { 5551 return ''; 5552 } 5553 5554 var tagName = node.tagName.toLowerCase(); 5555 5556 switch (tagName) { 5557 5558 // 5559 // BLOCKS 5560 // 5561 case 'h1': 5562 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 1) + '\n\n'; } 5563 break; 5564 case 'h2': 5565 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 2) + '\n\n'; } 5566 break; 5567 case 'h3': 5568 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 3) + '\n\n'; } 5569 break; 5570 case 'h4': 5571 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 4) + '\n\n'; } 5572 break; 5573 case 'h5': 5574 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 5) + '\n\n'; } 5575 break; 5576 case 'h6': 5577 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 6) + '\n\n'; } 5578 break; 5579 5580 case 'p': 5581 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.paragraph')(node, globals) + '\n\n'; } 5582 break; 5583 5584 case 'blockquote': 5585 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.blockquote')(node, globals) + '\n\n'; } 5586 break; 5587 5588 case 'hr': 5589 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.hr')(node, globals) + '\n\n'; } 5590 break; 5591 5592 case 'ol': 5593 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.list')(node, globals, 'ol') + '\n\n'; } 5594 break; 5595 5596 case 'ul': 5597 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.list')(node, globals, 'ul') + '\n\n'; } 5598 break; 5599 5600 case 'precode': 5601 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.codeBlock')(node, globals) + '\n\n'; } 5602 break; 5603 5604 case 'pre': 5605 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.pre')(node, globals) + '\n\n'; } 5606 break; 5607 5608 case 'table': 5609 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.table')(node, globals) + '\n\n'; } 5610 break; 5611 5612 // 5613 // SPANS 5614 // 5615 case 'code': 5616 txt = showdown.subParser('makeMarkdown.codeSpan')(node, globals); 5617 break; 5618 5619 case 'em': 5620 case 'i': 5621 txt = showdown.subParser('makeMarkdown.emphasis')(node, globals); 5622 break; 5623 5624 case 'strong': 5625 case 'b': 5626 txt = showdown.subParser('makeMarkdown.strong')(node, globals); 5627 break; 5628 5629 case 'del': 5630 txt = showdown.subParser('makeMarkdown.strikethrough')(node, globals); 5631 break; 5632 5633 case 'a': 5634 txt = showdown.subParser('makeMarkdown.links')(node, globals); 5635 break; 5636 5637 case 'img': 5638 txt = showdown.subParser('makeMarkdown.image')(node, globals); 5639 break; 5640 5641 default: 5642 txt = node.outerHTML + '\n\n'; 5643 } 5644 5645 // common normalization 5646 // TODO eventually 5647 5648 return txt; 5649}); 5650 5651showdown.subParser('makeMarkdown.paragraph', function (node, globals) { 5652 'use strict'; 5653 5654 var txt = ''; 5655 if (node.hasChildNodes()) { 5656 var children = node.childNodes, 5657 childrenLength = children.length; 5658 for (var i = 0; i < childrenLength; ++i) { 5659 txt += showdown.subParser('makeMarkdown.node')(children[i], globals); 5660 } 5661 } 5662 5663 // some text normalization 5664 txt = txt.trim(); 5665 5666 return txt; 5667}); 5668 5669showdown.subParser('makeMarkdown.pre', function (node, globals) { 5670 'use strict'; 5671 5672 var num = node.getAttribute('prenum'); 5673 return '<pre>' + globals.preList[num] + '</pre>'; 5674}); 5675 5676showdown.subParser('makeMarkdown.strikethrough', function (node, globals) { 5677 'use strict'; 5678 5679 var txt = ''; 5680 if (node.hasChildNodes()) { 5681 txt += '~~'; 5682 var children = node.childNodes, 5683 childrenLength = children.length; 5684 for (var i = 0; i < childrenLength; ++i) { 5685 txt += showdown.subParser('makeMarkdown.node')(children[i], globals); 5686 } 5687 txt += '~~'; 5688 } 5689 return txt; 5690}); 5691 5692showdown.subParser('makeMarkdown.strong', function (node, globals) { 5693 'use strict'; 5694 5695 var txt = ''; 5696 if (node.hasChildNodes()) { 5697 txt += '**'; 5698 var children = node.childNodes, 5699 childrenLength = children.length; 5700 for (var i = 0; i < childrenLength; ++i) { 5701 txt += showdown.subParser('makeMarkdown.node')(children[i], globals); 5702 } 5703 txt += '**'; 5704 } 5705 return txt; 5706}); 5707 5708showdown.subParser('makeMarkdown.table', function (node, globals) { 5709 'use strict'; 5710 5711 var txt = '', 5712 tableArray = [[], []], 5713 headings = node.querySelectorAll('thead>tr>th'), 5714 rows = node.querySelectorAll('tbody>tr'), 5715 i, ii; 5716 for (i = 0; i < headings.length; ++i) { 5717 var headContent = showdown.subParser('makeMarkdown.tableCell')(headings[i], globals), 5718 allign = '---'; 5719 5720 if (headings[i].hasAttribute('style')) { 5721 var style = headings[i].getAttribute('style').toLowerCase().replace(/\s/g, ''); 5722 switch (style) { 5723 case 'text-align:left;': 5724 allign = ':---'; 5725 break; 5726 case 'text-align:right;': 5727 allign = '---:'; 5728 break; 5729 case 'text-align:center;': 5730 allign = ':---:'; 5731 break; 5732 } 5733 } 5734 tableArray[0][i] = headContent.trim(); 5735 tableArray[1][i] = allign; 5736 } 5737 5738 for (i = 0; i < rows.length; ++i) { 5739 var r = tableArray.push([]) - 1, 5740 cols = rows[i].getElementsByTagName('td'); 5741 5742 for (ii = 0; ii < headings.length; ++ii) { 5743 var cellContent = ' '; 5744 if (typeof cols[ii] !== 'undefined') { 5745 cellContent = showdown.subParser('makeMarkdown.tableCell')(cols[ii], globals); 5746 } 5747 tableArray[r].push(cellContent); 5748 } 5749 } 5750 5751 var cellSpacesCount = 3; 5752 for (i = 0; i < tableArray.length; ++i) { 5753 for (ii = 0; ii < tableArray[i].length; ++ii) { 5754 var strLen = tableArray[i][ii].length; 5755 if (strLen > cellSpacesCount) { 5756 cellSpacesCount = strLen; 5757 } 5758 } 5759 } 5760 5761 for (i = 0; i < tableArray.length; ++i) { 5762 for (ii = 0; ii < tableArray[i].length; ++ii) { 5763 if (i === 1) { 5764 if (tableArray[i][ii].slice(-1) === ':') { 5765 tableArray[i][ii] = showdown.helper.padEnd(tableArray[i][ii].slice(-1), cellSpacesCount - 1, '-') + ':'; 5766 } else { 5767 tableArray[i][ii] = showdown.helper.padEnd(tableArray[i][ii], cellSpacesCount, '-'); 5768 } 5769 } else { 5770 tableArray[i][ii] = showdown.helper.padEnd(tableArray[i][ii], cellSpacesCount); 5771 } 5772 } 5773 txt += '| ' + tableArray[i].join(' | ') + ' |\n'; 5774 } 5775 5776 return txt.trim(); 5777}); 5778 5779showdown.subParser('makeMarkdown.tableCell', function (node, globals) { 5780 'use strict'; 5781 5782 var txt = ''; 5783 if (!node.hasChildNodes()) { 5784 return ''; 5785 } 5786 var children = node.childNodes, 5787 childrenLength = children.length; 5788 5789 for (var i = 0; i < childrenLength; ++i) { 5790 txt += showdown.subParser('makeMarkdown.node')(children[i], globals, true); 5791 } 5792 return txt.trim(); 5793}); 5794 5795showdown.subParser('makeMarkdown.txt', function (node) { 5796 'use strict'; 5797 5798 var txt = node.nodeValue; 5799 5800 // multiple spaces are collapsed 5801 txt = txt.replace(/ +/g, ' '); 5802 5803 // replace the custom ¨NBSP; with a space 5804 txt = txt.replace(/¨NBSP;/g, ' '); 5805 5806 // ", <, > and & should replace escaped html entities 5807 txt = showdown.helper.unescapeHTMLEntities(txt); 5808 5809 // escape markdown magic characters
vendor: 4,301 bytes, lines 5810-5929
5810 // emphasis, strong and strikethrough - can appear everywhere 5811 // we also escape pipe (|) because of tables 5812 // and escape ` because of code blocks and spans 5813 txt = txt.replace(/([*_~|`])/g, '\\$1'); 5814 5815 // escape > because of blockquotes 5816 txt = txt.replace(/^(\s*)>/g, '\\$1>'); 5817 5818 // hash character, only troublesome at the beginning of a line because of headers 5819 txt = txt.replace(/^#/gm, '\\#'); 5820 5821 // horizontal rules 5822 txt = txt.replace(/^(\s*)([-=]{3,})(\s*)$/, '$1\\$2$3'); 5823 5824 // dot, because of ordered lists, only troublesome at the beginning of a line when preceded by an integer 5825 txt = txt.replace(/^( {0,3}\d+)\./gm, '$1\\.'); 5826 5827 // +, * and -, at the beginning of a line becomes a list, so we need to escape them also (asterisk was already escaped) 5828 txt = txt.replace(/^( {0,3})([+-])/gm, '$1\\$2'); 5829 5830 // images and links, ] followed by ( is problematic, so we escape it 5831 txt = txt.replace(/]([\s]*)\(/g, '\\]$1\\('); 5832 5833 // reference URIs must also be escaped 5834 txt = txt.replace(/^ {0,3}\[([\S \t]*?)]:/gm, '\\[$1]:'); 5835 5836 return txt; 5837}); 5838 5839var root = this; 5840 5841// AMD Loader 5842if (true) { 5843 !(__WEBPACK_AMD_DEFINE_RESULT__ = (function () { 5844 'use strict'; 5845 return showdown; 5846 }).call(exports, __webpack_require__, exports, module), 5847 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 5848 5849// CommonJS/nodeJS Loader 5850} else {} 5851}).call(this); 5852 5853 5854 5855 5856/***/ }) 5857 5858/******/ }); 5859/************************************************************************/ 5860/******/ // The module cache 5861/******/ var __webpack_module_cache__ = {}; 5862/******/ 5863/******/ // The require function 5864/******/ function __webpack_require__(moduleId) { 5865/******/ // Check if module is in cache 5866/******/ var cachedModule = __webpack_module_cache__[moduleId]; 5867/******/ if (cachedModule !== undefined) { 5868/******/ return cachedModule.exports; 5869/******/ } 5870/******/ // Create a new module (and put it into the cache) 5871/******/ var module = __webpack_module_cache__[moduleId] = { 5872/******/ // no module.id needed 5873/******/ // no module.loaded needed 5874/******/ exports: {} 5875/******/ }; 5876/******/ 5877/******/ // Execute the module function 5878/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__); 5879/******/ 5880/******/ // Return the exports of the module 5881/******/ return module.exports; 5882/******/ } 5883/******/ 5884/************************************************************************/ 5885/******/ /* webpack/runtime/compat get default export */ 5886/******/ (() => { 5887/******/ // getDefaultExport function for compatibility with non-harmony modules 5888/******/ __webpack_require__.n = (module) => { 5889/******/ var getter = module && module.__esModule ? 5890/******/ () => (module['default']) : 5891/******/ () => (module); 5892/******/ __webpack_require__.d(getter, { a: getter }); 5893/******/ return getter; 5894/******/ }; 5895/******/ })(); 5896/******/ 5897/******/ /* webpack/runtime/define property getters */ 5898/******/ (() => { 5899/******/ // define getter functions for harmony exports 5900/******/ __webpack_require__.d = (exports, definition) => { 5901/******/ for(var key in definition) { 5902/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { 5903/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); 5904/******/ } 5905/******/ } 5906/******/ }; 5907/******/ })(); 5908/******/ 5909/******/ /* webpack/runtime/hasOwnProperty shorthand */ 5910/******/ (() => { 5911/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) 5912/******/ })(); 5913/******/ 5914/******/ /* webpack/runtime/make namespace object */ 5915/******/ (() => { 5916/******/ // define __esModule on exports 5917/******/ __webpack_require__.r = (exports) => { 5918/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 5919/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 5920/******/ } 5921/******/ Object.defineProperty(exports, '__esModule', { value: true }); 5922/******/ }; 5923/******/ })(); 5924/******/ 5925/************************************************************************/ 5926var __webpack_exports__ = {}; 5927// This entry need to be wrapped in an IIFE because it need to be in strict mode. 5928(() => { 5929"use strict";
5930// ESM COMPAT FLAG 5931__webpack_require__.r(__webpack_exports__); 5932 5933// EXPORTS 5934__webpack_require__.d(__webpack_exports__, { 5935 "__EXPERIMENTAL_ELEMENTS": () => (/* reexport */ __EXPERIMENTAL_ELEMENTS), 5936 "__EXPERIMENTAL_PATHS_WITH_MERGE": () => (/* reexport */ __EXPERIMENTAL_PATHS_WITH_MERGE), 5937 "__EXPERIMENTAL_STYLE_PROPERTY": () => (/* reexport */ __EXPERIMENTAL_STYLE_PROPERTY), 5938 "__experimentalCloneSanitizedBlock": () => (/* reexport */ __experimentalCloneSanitizedBlock), 5939 "__experimentalGetAccessibleBlockLabel": () => (/* reexport */ getAccessibleBlockLabel), 5940 "__experimentalGetBlockAttributesNamesByRole": () => (/* reexport */ __experimentalGetBlockAttributesNamesByRole), 5941 "__experimentalGetBlockLabel": () => (/* reexport */ getBlockLabel), 5942 "__experimentalSanitizeBlockAttributes": () => (/* reexport */ __experimentalSanitizeBlockAttributes), 5943 "__unstableGetBlockProps": () => (/* reexport */ getBlockProps), 5944 "__unstableGetInnerBlocksProps": () => (/* reexport */ getInnerBlocksProps), 5945 "__unstableSerializeAndClean": () => (/* reexport */ __unstableSerializeAndClean), 5946 "children": () => (/* reexport */ children), 5947 "cloneBlock": () => (/* reexport */ cloneBlock), 5948 "createBlock": () => (/* reexport */ createBlock), 5949 "createBlocksFromInnerBlocksTemplate": () => (/* reexport */ createBlocksFromInnerBlocksTemplate), 5950 "doBlocksMatchTemplate": () => (/* reexport */ doBlocksMatchTemplate), 5951 "findTransform": () => (/* reexport */ findTransform), 5952 "getBlockAttributes": () => (/* reexport */ getBlockAttributes), 5953 "getBlockContent": () => (/* reexport */ getBlockInnerHTML), 5954 "getBlockDefaultClassName": () => (/* reexport */ getBlockDefaultClassName), 5955 "getBlockFromExample": () => (/* reexport */ getBlockFromExample), 5956 "getBlockMenuDefaultClassName": () => (/* reexport */ getBlockMenuDefaultClassName), 5957 "getBlockSupport": () => (/* reexport */ getBlockSupport), 5958 "getBlockTransforms": () => (/* reexport */ getBlockTransforms), 5959 "getBlockType": () => (/* reexport */ getBlockType), 5960 "getBlockTypes": () => (/* reexport */ getBlockTypes), 5961 "getBlockVariations": () => (/* reexport */ getBlockVariations), 5962 "getCategories": () => (/* reexport */ categories_getCategories), 5963 "getChildBlockNames": () => (/* reexport */ getChildBlockNames), 5964 "getDefaultBlockName": () => (/* reexport */ getDefaultBlockName), 5965 "getFreeformContentHandlerName": () => (/* reexport */ getFreeformContentHandlerName), 5966 "getGroupingBlockName": () => (/* reexport */ getGroupingBlockName), 5967 "getPhrasingContentSchema": () => (/* reexport */ deprecatedGetPhrasingContentSchema), 5968 "getPossibleBlockTransformations": () => (/* reexport */ getPossibleBlockTransformations), 5969 "getSaveContent": () => (/* reexport */ getSaveContent), 5970 "getSaveElement": () => (/* reexport */ getSaveElement), 5971 "getUnregisteredTypeHandlerName": () => (/* reexport */ getUnregisteredTypeHandlerName), 5972 "hasBlockSupport": () => (/* reexport */ hasBlockSupport), 5973 "hasChildBlocks": () => (/* reexport */ hasChildBlocks), 5974 "hasChildBlocksWithInserterSupport": () => (/* reexport */ hasChildBlocksWithInserterSupport), 5975 "isReusableBlock": () => (/* reexport */ isReusableBlock), 5976 "isTemplatePart": () => (/* reexport */ isTemplatePart), 5977 "isUnmodifiedBlock": () => (/* reexport */ isUnmodifiedBlock), 5978 "isUnmodifiedDefaultBlock": () => (/* reexport */ isUnmodifiedDefaultBlock), 5979 "isValidBlockContent": () => (/* reexport */ isValidBlockContent), 5980 "isValidIcon": () => (/* reexport */ isValidIcon), 5981 "node": () => (/* reexport */ node), 5982 "normalizeIconObject": () => (/* reexport */ normalizeIconObject), 5983 "parse": () => (/* reexport */ parser_parse), 5984 "parseWithAttributeSchema": () => (/* reexport */ parseWithAttributeSchema), 5985 "pasteHandler": () => (/* reexport */ pasteHandler), 5986 "rawHandler": () => (/* reexport */ rawHandler), 5987 "registerBlockCollection": () => (/* reexport */ registerBlockCollection), 5988 "registerBlockStyle": () => (/* reexport */ registerBlockStyle), 5989 "registerBlockType": () => (/* reexport */ registerBlockType), 5990 "registerBlockVariation": () => (/* reexport */ registerBlockVariation), 5991 "serialize": () => (/* reexport */ serialize), 5992 "serializeRawBlock": () => (/* reexport */ serializeRawBlock), 5993 "setCategories": () => (/* reexport */ categories_setCategories), 5994 "setDefaultBlockName": () => (/* reexport */ setDefaultBlockName), 5995 "setFreeformContentHandlerName": () => (/* reexport */ setFreeformContentHandlerName), 5996 "setGroupingBlockName": () => (/* reexport */ setGroupingBlockName), 5997 "setUnregisteredTypeHandlerName": () => (/* reexport */ setUnregisteredTypeHandlerName), 5998 "store": () => (/* reexport */ store), 5999 "switchToBlockType": () => (/* reexport */ switchToBlockType), 6000 "synchronizeBlocksWithTemplate": () => (/* reexport */ synchronizeBlocksWithTemplate), 6001 "unregisterBlockStyle": () => (/* reexport */ unregisterBlockStyle), 6002 "unregisterBlockType": () => (/* reexport */ unregisterBlockType), 6003 "unregisterBlockVariation": () => (/* reexport */ unregisterBlockVariation), 6004 "unstable__bootstrapServerSideBlockDefinitions": () => (/* reexport */ unstable__bootstrapServerSideBlockDefinitions), 6005 "updateCategory": () => (/* reexport */ categories_updateCategory), 6006 "validateBlock": () => (/* reexport */ validateBlock), 6007 "withBlockContentContext": () => (/* reexport */ withBlockContentContext) 6008}); 6009 6010// NAMESPACE OBJECT: ./packages/blocks/build-module/store/selectors.js 6011var selectors_namespaceObject = {}; 6012__webpack_require__.r(selectors_namespaceObject); 6013__webpack_require__.d(selectors_namespaceObject, { 6014 "__experimentalHasContentRoleAttribute": () => (__experimentalHasContentRoleAttribute), 6015 "getActiveBlockVariation": () => (getActiveBlockVariation), 6016 "getBlockStyles": () => (getBlockStyles), 6017 "getBlockSupport": () => (selectors_getBlockSupport), 6018 "getBlockType": () => (selectors_getBlockType), 6019 "getBlockTypes": () => (selectors_getBlockTypes), 6020 "getBlockVariations": () => (selectors_getBlockVariations), 6021 "getCategories": () => (getCategories), 6022 "getChildBlockNames": () => (selectors_getChildBlockNames), 6023 "getCollections": () => (getCollections), 6024 "getDefaultBlockName": () => (selectors_getDefaultBlockName), 6025 "getDefaultBlockVariation": () => (getDefaultBlockVariation), 6026 "getFreeformFallbackBlockName": () => (getFreeformFallbackBlockName), 6027 "getGroupingBlockName": () => (selectors_getGroupingBlockName), 6028 "getUnregisteredFallbackBlockName": () => (getUnregisteredFallbackBlockName), 6029 "hasBlockSupport": () => (selectors_hasBlockSupport), 6030 "hasChildBlocks": () => (selectors_hasChildBlocks), 6031 "hasChildBlocksWithInserterSupport": () => (selectors_hasChildBlocksWithInserterSupport), 6032 "isMatchingSearchTerm": () => (isMatchingSearchTerm) 6033}); 6034 6035// NAMESPACE OBJECT: ./packages/blocks/build-module/store/private-selectors.js 6036var private_selectors_namespaceObject = {}; 6037__webpack_require__.r(private_selectors_namespaceObject); 6038__webpack_require__.d(private_selectors_namespaceObject, { 6039 "getBootstrappedBlockType": () => (getBootstrappedBlockType),
6040 "getSupportedStyles": () => (getSupportedStyles), 6041 "getUnprocessedBlockTypes": () => (getUnprocessedBlockTypes) 6042}); 6043 6044// NAMESPACE OBJECT: ./packages/blocks/build-module/store/actions.js 6045var actions_namespaceObject = {}; 6046__webpack_require__.r(actions_namespaceObject); 6047__webpack_require__.d(actions_namespaceObject, { 6048 "__experimentalReapplyBlockFilters": () => (__experimentalReapplyBlockFilters), 6049 "addBlockCollection": () => (addBlockCollection), 6050 "addBlockStyles": () => (addBlockStyles), 6051 "addBlockTypes": () => (addBlockTypes), 6052 "addBlockVariations": () => (addBlockVariations), 6053 "reapplyBlockTypeFilters": () => (reapplyBlockTypeFilters), 6054 "removeBlockCollection": () => (removeBlockCollection), 6055 "removeBlockStyles": () => (removeBlockStyles), 6056 "removeBlockTypes": () => (removeBlockTypes), 6057 "removeBlockVariations": () => (removeBlockVariations), 6058 "setCategories": () => (setCategories), 6059 "setDefaultBlockName": () => (actions_setDefaultBlockName), 6060 "setFreeformFallbackBlockName": () => (setFreeformFallbackBlockName), 6061 "setGroupingBlockName": () => (actions_setGroupingBlockName), 6062 "setUnregisteredFallbackBlockName": () => (setUnregisteredFallbackBlockName), 6063 "updateCategory": () => (updateCategory) 6064}); 6065 6066// NAMESPACE OBJECT: ./packages/blocks/build-module/store/private-actions.js 6067var private_actions_namespaceObject = {}; 6068__webpack_require__.r(private_actions_namespaceObject); 6069__webpack_require__.d(private_actions_namespaceObject, { 6070 "addBootstrappedBlockType": () => (addBootstrappedBlockType), 6071 "addUnprocessedBlockType": () => (addUnprocessedBlockType) 6072}); 6073 6074;// CONCATENATED MODULE: external ["wp","data"] 6075const external_wp_data_namespaceObject = window["wp"]["data"]; 6076;// CONCATENATED MODULE: .
vendor: 14,781 bytes, lines 6076-6392
6076/node_modules/tslib/tslib.es6.mjs 6077/****************************************************************************** 6078Copyright (c) Microsoft Corporation. 6079 6080Permission to use, copy, modify, and/or distribute this software for any 6081purpose with or without fee is hereby granted. 6082 6083THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 6084REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 6085AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 6086INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 6087LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 6088OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 6089PERFORMANCE OF THIS SOFTWARE. 6090***************************************************************************** */ 6091/* global Reflect, Promise, SuppressedError, Symbol */ 6092 6093var extendStatics = function(d, b) { 6094 extendStatics = Object.setPrototypeOf || 6095 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || 6096 function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; 6097 return extendStatics(d, b); 6098}; 6099 6100function __extends(d, b) { 6101 if (typeof b !== "function" && b !== null) 6102 throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); 6103 extendStatics(d, b); 6104 function __() { this.constructor = d; } 6105 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6106} 6107 6108var __assign = function() { 6109 __assign = Object.assign || function __assign(t) { 6110 for (var s, i = 1, n = arguments.length; i < n; i++) { 6111 s = arguments[i]; 6112 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 6113 } 6114 return t; 6115 } 6116 return __assign.apply(this, arguments); 6117} 6118 6119function __rest(s, e) { 6120 var t = {}; 6121 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) 6122 t[p] = s[p]; 6123 if (s != null && typeof Object.getOwnPropertySymbols === "function") 6124 for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { 6125 if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) 6126 t[p[i]] = s[p[i]]; 6127 } 6128 return t; 6129} 6130 6131function __decorate(decorators, target, key, desc) { 6132 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 6133 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 6134 else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 6135 return c > 3 && r && Object.defineProperty(target, key, r), r; 6136} 6137 6138function __param(paramIndex, decorator) { 6139 return function (target, key) { decorator(target, key, paramIndex); } 6140} 6141 6142function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { 6143 function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } 6144 var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; 6145 var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; 6146 var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); 6147 var _, done = false; 6148 for (var i = decorators.length - 1; i >= 0; i--) { 6149 var context = {}; 6150 for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; 6151 for (var p in contextIn.access) context.access[p] = contextIn.access[p]; 6152 context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; 6153 var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); 6154 if (kind === "accessor") { 6155 if (result === void 0) continue; 6156 if (result === null || typeof result !== "object") throw new TypeError("Object expected"); 6157 if (_ = accept(result.get)) descriptor.get = _; 6158 if (_ = accept(result.set)) descriptor.set = _; 6159 if (_ = accept(result.init)) initializers.unshift(_); 6160 } 6161 else if (_ = accept(result)) { 6162 if (kind === "field") initializers.unshift(_); 6163 else descriptor[key] = _; 6164 } 6165 } 6166 if (target) Object.defineProperty(target, contextIn.name, descriptor); 6167 done = true; 6168}; 6169 6170function __runInitializers(thisArg, initializers, value) { 6171 var useValue = arguments.length > 2; 6172 for (var i = 0; i < initializers.length; i++) { 6173 value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); 6174 } 6175 return useValue ? value : void 0; 6176}; 6177 6178function __propKey(x) { 6179 return typeof x === "symbol" ? x : "".concat(x); 6180}; 6181 6182function __setFunctionName(f, name, prefix) { 6183 if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : ""; 6184 return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name }); 6185}; 6186 6187function __metadata(metadataKey, metadataValue) { 6188 if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); 6189} 6190 6191function __awaiter(thisArg, _arguments, P, generator) { 6192 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 6193 return new (P || (P = Promise))(function (resolve, reject) { 6194 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 6195 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 6196 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 6197 step((generator = generator.apply(thisArg, _arguments || [])).next()); 6198 }); 6199} 6200 6201function __generator(thisArg, body) { 6202 var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; 6203 return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; 6204 function verb(n) { return function (v) { return step([n, v]); }; } 6205 function step(op) { 6206 if (f) throw new TypeError("Generator is already executing."); 6207 while (g && (g = 0, op[0] && (_ = 0)), _) try { 6208 if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; 6209 if (y = 0, t) op = [op[0] & 2, t.value]; 6210 switch (op[0]) { 6211 case 0: case 1: t = op; break; 6212 case 4: _.label++; return { value: op[1], done: false }; 6213 case 5: _.label++; y = op[1]; op = [0]; continue; 6214 case 7: op = _.ops.pop(); _.trys.pop(); continue; 6215 default: 6216 if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } 6217 if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } 6218 if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } 6219 if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } 6220 if (t[2]) _.ops.pop(); 6221 _.trys.pop(); continue; 6222 } 6223 op = body.call(thisArg, _); 6224 } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } 6225 if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; 6226 } 6227} 6228 6229var __createBinding = Object.create ? (function(o, m, k, k2) { 6230 if (k2 === undefined) k2 = k; 6231 var desc = Object.getOwnPropertyDescriptor(m, k); 6232 if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6233 desc = { enumerable: true, get: function() { return m[k]; } }; 6234 } 6235 Object.defineProperty(o, k2, desc); 6236}) : (function(o, m, k, k2) { 6237 if (k2 === undefined) k2 = k; 6238 o[k2] = m[k]; 6239}); 6240 6241function __exportStar(m, o) { 6242 for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p); 6243} 6244 6245function __values(o) { 6246 var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; 6247 if (m) return m.call(o); 6248 if (o && typeof o.length === "number") return { 6249 next: function () { 6250 if (o && i >= o.length) o = void 0; 6251 return { value: o && o[i++], done: !o }; 6252 } 6253 }; 6254 throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); 6255} 6256 6257function __read(o, n) { 6258 var m = typeof Symbol === "function" && o[Symbol.iterator]; 6259 if (!m) return o; 6260 var i = m.call(o), r, ar = [], e; 6261 try { 6262 while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); 6263 } 6264 catch (error) { e = { error: error }; } 6265 finally { 6266 try { 6267 if (r && !r.done && (m = i["return"])) m.call(i); 6268 } 6269 finally { if (e) throw e.error; } 6270 } 6271 return ar; 6272} 6273 6274/** @deprecated */ 6275function __spread() { 6276 for (var ar = [], i = 0; i < arguments.length; i++) 6277 ar = ar.concat(__read(arguments[i])); 6278 return ar; 6279} 6280 6281/** @deprecated */ 6282function __spreadArrays() { 6283 for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; 6284 for (var r = Array(s), k = 0, i = 0; i < il; i++) 6285 for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) 6286 r[k] = a[j]; 6287 return r; 6288} 6289 6290function __spreadArray(to, from, pack) { 6291 if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { 6292 if (ar || !(i in from)) { 6293 if (!ar) ar = Array.prototype.slice.call(from, 0, i); 6294 ar[i] = from[i]; 6295 } 6296 } 6297 return to.concat(ar || Array.prototype.slice.call(from)); 6298} 6299 6300function __await(v) { 6301 return this instanceof __await ? (this.v = v, this) : new __await(v); 6302} 6303 6304function __asyncGenerator(thisArg, _arguments, generator) { 6305 if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); 6306 var g = generator.apply(thisArg, _arguments || []), i, q = []; 6307 return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; 6308 function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } 6309 function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } 6310 function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } 6311 function fulfill(value) { resume("next", value); } 6312 function reject(value) { resume("throw", value); } 6313 function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } 6314} 6315 6316function __asyncDelegator(o) { 6317 var i, p; 6318 return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; 6319 function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; } 6320} 6321 6322function __asyncValues(o) { 6323 if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); 6324 var m = o[Symbol.asyncIterator], i; 6325 return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); 6326 function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } 6327 function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } 6328} 6329 6330function __makeTemplateObject(cooked, raw) { 6331 if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } 6332 return cooked; 6333}; 6334 6335var __setModuleDefault = Object.create ? (function(o, v) { 6336 Object.defineProperty(o, "default", { enumerable: true, value: v }); 6337}) : function(o, v) { 6338 o["default"] = v; 6339}; 6340 6341function __importStar(mod) { 6342 if (mod && mod.__esModule) return mod; 6343 var result = {}; 6344 if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 6345 __setModuleDefault(result, mod); 6346 return result; 6347} 6348 6349function __importDefault(mod) { 6350 return (mod && mod.__esModule) ? mod : { default: mod }; 6351} 6352 6353function __classPrivateFieldGet(receiver, state, kind, f) { 6354 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); 6355 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); 6356 return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); 6357} 6358 6359function __classPrivateFieldSet(receiver, state, value, kind, f) { 6360 if (kind === "m") throw new TypeError("Private method is not writable"); 6361 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); 6362 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); 6363 return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; 6364} 6365 6366function __classPrivateFieldIn(state, receiver) { 6367 if (receiver === null || (typeof receiver !== "object" && typeof receiver !== "function")) throw new TypeError("Cannot use 'in' operator on non-object"); 6368 return typeof state === "function" ? receiver === state : state.has(receiver); 6369} 6370 6371function __addDisposableResource(env, value, async) { 6372 if (value !== null && value !== void 0) { 6373 if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected."); 6374 var dispose; 6375 if (async) { 6376 if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined."); 6377 dispose = value[Symbol.asyncDispose]; 6378 } 6379 if (dispose === void 0) { 6380 if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined."); 6381 dispose = value[Symbol.dispose]; 6382 } 6383 if (typeof dispose !== "function") throw new TypeError("Object not disposable."); 6384 env.stack.push({ value: value, dispose: dispose, async: async }); 6385 } 6386 else if (async) { 6387 env.stack.push({ async: true }); 6388 } 6389 return value; 6390} 6391 6392var _SuppressedError =
vendor: 1,130 bytes, lines 6392-6437
6392typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { 6393 var e = new Error(message); 6394 return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; 6395}; 6396 6397function __disposeResources(env) { 6398 function fail(e) { 6399 env.error = env.hasError ? new _SuppressedError(e, env.error, "An error was suppressed during disposal.") : e; 6400 env.hasError = true; 6401 } 6402 function next() { 6403 while (env.stack.length) { 6404 var rec = env.stack.pop(); 6405 try { 6406 var result = rec.dispose && rec.dispose.call(rec.value); 6407 if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); }); 6408 } 6409 catch (e) { 6410 fail(e); 6411 } 6412 } 6413 if (env.hasError) throw env.error; 6414 } 6415 return next(); 6416} 6417 6418/* harmony default export */ const tslib_es6 = ({ 6419 __extends, 6420 __assign, 6421 __rest, 6422 __decorate, 6423 __param, 6424 __metadata, 6425 __awaiter, 6426 __generator, 6427 __createBinding, 6428 __exportStar, 6429 __values, 6430 __read, 6431 __spread, 6432 __spreadArrays, 6433 __spreadArray, 6434 __await, 6435 __asyncGenerator, 6436 __asyncDelegator, 6437 __asyncValues,
6438 __makeTemplateObject, 6439 __importStar, 6440 __importDefault, 6441 __classPrivateFieldGet, 6442 __classPrivateFieldSet, 6443 __classPrivateFieldIn, 6444 __addDisposableResource, 6445 __disposeResources, 6446}); 6447 6448;// CONCATENATED MODULE: ./node_modules/lower-case/dist.es2015/index.js 6449/** 6450 * Source: ftp://ftp.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt 6451 */ 6452var SUPPORTED_LOCALE = { 6453 tr: { 6454 regexp: /\u0130|\u0049|\u0049\u0307/g, 6455 map: { 6456 İ: "\u0069", 6457 I: "\u0131", 6458 IÌ: "\u0069", 6459 }, 6460 }, 6461 az: { 6462 regexp: /\u0130/g, 6463 map: { 6464 İ: "\u0069", 6465 I: "\u0131", 6466 IÌ: "\u0069", 6467 }, 6468 }, 6469 lt: { 6470 regexp: /\u0049|\u004A|\u012E|\u00CC|\u00CD|\u0128/g, 6471 map: { 6472 I: "\u0069\u0307", 6473 J: "\u006A\u0307", 6474 Ä®: "\u012F\u0307", 6475 Ã: "\u0069\u0307\u0300", 6476 Ã: "\u0069\u0307\u0301", 6477 Ĩ: "\u0069\u0307\u0303", 6478 }, 6479 }, 6480}; 6481/** 6482 * Localized lower case. 6483 */ 6484function localeLowerCase(str, locale) {
6485 var lang = SUPPORTED_LOCALE[locale.toLowerCase()]; 6486 if (lang) 6487 return lowerCase(str.replace(lang.regexp, function (m) { return lang.map[m]; })); 6488 return lowerCase(str); 6489} 6490/** 6491 * Lower case as a function. 6492 */ 6493function lowerCase(str) { 6494 return str.toLowerCase(); 6495} 6496 6497;// CONCATENATED MODULE: ./node_modules/no-case/dist.es2015/index.js 6498 6499// Support camel case ("camelCase" -> "camel Case" and "CAMELCase" -> "CAMEL Case"). 6500var DEFAULT_SPLIT_REGEXP = [/([a-z0-9])([A-Z])/g, /([A-Z])([A-Z][a-z])/g]; 6501// Remove all non-word characters. 6502var DEFAULT_STRIP_REGEXP = /[^A-Z0-9]+/gi; 6503/** 6504 * Normalize the string into something other libraries can manipulate easier. 6505 */ 6506function noCase(input, options) { 6507 if (options === void 0) { options = {}; } 6508 var _a = options.splitRegexp, splitRegexp = _a === void 0 ? DEFAULT_SPLIT_REGEXP : _a, _b = options.stripRegexp, stripRegexp = _b === void 0 ? DEFAULT_STRIP_REGEXP : _b, _c = options.transform, transform = _c === void 0 ? lowerCase : _c, _d = options.delimiter, delimiter = _d === void 0 ? " " : _d; 6509 var result = replace(replace(input, splitRegexp, "$1\0$2"), stripRegexp, "\0"); 6510 var start = 0; 6511 var end = result.length; 6512 // Trim the delimiter from around the output string. 6513 while (result.charAt(start) === "\0") 6514 start++; 6515 while (result.charAt(end - 1) === "\0") 6516 end--; 6517 // Transform each token independently. 6518 return result.slice(start, end).split("\0").map(transform).join(delimiter); 6519} 6520/** 6521 * Replace `re` in the input string with the replacement value. 6522 */ 6523function replace(input, re, value) { 6524 if (re instanceof RegExp) 6525 return input.replace(re, value); 6526 return re.reduce(function (input, re) { return input.replace(re, value); }, input); 6527} 6528 6529;// CONCATENATED MODULE: ./node_modules/pascal-case/dist.es2015/index.js 6530 6531 6532function pascalCaseTransform(input, index) { 6533 var firstChar = input.charAt(0); 6534 var lowerChars = input.substr(1).toLowerCase(); 6535 if (index > 0 && firstChar >= "0" && firstChar <= "9") { 6536 return "_" + firstChar + lowerChars; 6537 } 6538 return "" + firstChar.toUpperCase() + lowerChars; 6539} 6540function dist_es2015_pascalCaseTransformMerge(input) { 6541 return input.charAt(0).toUpperCase() + input.slice(1).toLowerCase(); 6542} 6543function pascalCase(input, options) { 6544 if (options === void 0) { options = {}; } 6545 return noCase(input, __assign({ delimiter: "", transform: pascalCaseTransform }, options)); 6546} 6547 6548;// CONCATENATED MODULE: ./node_modules/camel-case/dist.es2015/index.js 6549 6550 6551function camelCaseTransform(input, index) { 6552 if (index === 0) 6553 return input.toLowerCase(); 6554 return pascalCaseTransform(input, index); 6555} 6556function camelCaseTransformMerge(input, index) { 6557 if (index === 0) 6558 return input.toLowerCase(); 6559 return pascalCaseTransformMerge(input); 6560} 6561function camelCase(input, options) { 6562 if (options === void 0) { options = {}; } 6563 return pascalCase(input, __assign({ transform: camelCaseTransform }, options)); 6564} 6565 6566;// CONCATENATED MODULE: external ["wp","i18n"] 6567const external_wp_i18n_namespaceObject = window["wp"]["i18n"]; 6568;// CONCATENATED MODULE: ./node_modules/colord/index.mjs 6569var 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*,\
vendor: 6,994 bytes, lines 6569-6572
6569s*([+-]?\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()})}; 6570 6571;// CONCATENATED MODULE: ./node_modules/colord/plugins/names.mjs 6572/* 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",s
6572andybrown:"#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"])} 6573 6574;// CONCATENATED MODULE: ./node_modules/colord/plugins/a11y.mjs 6575var 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}} 6576 6577;// CONCATENATED MODULE: external ["wp","element"] 6578const external_wp_element_namespaceObject = window["wp"]["element"]; 6579;// CONCATENATED MODULE: external ["wp","dom"] 6580const external_wp_dom_namespaceObject = window["wp"]["dom"]; 6581;// CONCATENATED MODULE: ./packages/blocks/build-module/api/constants.js 6582const BLOCK_ICON_DEFAULT = 'block-default'; 6583 6584/** 6585 * Array of valid keys in a block type settings deprecation object. 6586 * 6587 * @type {string[]} 6588 */ 6589const DEPRECATED_ENTRY_KEYS = ['attributes', 'supports', 'save', 'migrate', 'isEligible', 'apiVersion']; 6590const __EXPERIMENTAL_STYLE_PROPERTY = { 6591 // Kept for back-compatibility purposes. 6592 '--wp--style--color--link': { 6593 value: ['color', 'link'], 6594 support: ['color', 'link'] 6595 }, 6596 background: { 6597 value: ['color', 'gradient'], 6598 support: ['color', 'gradients'], 6599 useEngine: true 6600 }, 6601 backgroundColor: { 6602 value: ['color', 'background'], 6603 support: ['color', 'background'], 6604 requiresOptOut: true, 6605 useEngine: true 6606 }, 6607 borderColor: { 6608 value: ['border', 'color'], 6609 support: ['__experimentalBorder', 'color'], 6610 useEngine: true 6611 }, 6612 borderRadius: { 6613 value: ['border', 'radius'], 6614 support: ['__experimentalBorder', 'radius'], 6615 properties: { 6616 borderTopLeftRadius: 'topLeft', 6617 borderTopRightRadius: 'topRight', 6618 borderBottomLeftRadius: 'bottomLeft', 6619 borderBottomRightRadius: 'bottomRight' 6620 }, 6621 useEngine: true 6622 }, 6623 borderStyle: { 6624 value: ['border', 'style'], 6625 support: ['__experimentalBorder', 'style'], 6626 useEngine: true 6627 }, 6628 borderWidth: { 6629 value: ['border', 'width'], 6630 support: ['__experimentalBorder', 'width'], 6631 useEngine: true 6632 }, 6633 borderTopColor: { 6634 value: ['border', 'top', 'color'], 6635 support: ['__experimentalBorder', 'color'], 6636 useEngine: true 6637 }, 6638 borderTopStyle: { 6639 value: ['border', 'top', 'style'], 6640 support: ['__experimentalBorder', 'style'], 6641 useEngine: true 6642 }, 6643 borderTopWidth: { 6644 value: ['border', 'top', 'width'], 6645 support: ['__experimentalBorder', 'width'], 6646 useEngine: true 6647 }, 6648 borderRightColor: { 6649 value: ['border', 'right', 'color'], 6650 support: ['__experimentalBorder', 'color'], 6651 useEngine: true 6652 }, 6653 borderRightStyle: { 6654 value: ['border', 'right', 'style'], 6655 support: ['__experimentalBorder', 'style'], 6656 useEngine: true 6657 }, 6658 borderRightWidth: { 6659 value: ['border', 'right', 'width'], 6660 support: ['__experimentalBorder', 'width'], 6661 useEngine: true 6662 }, 6663 borderBottomColor: { 6664 value: ['border', 'bottom', 'color'], 6665 support: ['__experimentalBorder', 'color'], 6666 useEngine: true 6667 }, 6668 borderBottomStyle: { 6669 value: ['border', 'bottom', 'style'], 6670 support: ['__experimentalBorder', 'style'], 6671 useEngine: true 6672 }, 6673 borderBottomWidth: { 6674 value: ['border', 'bottom', 'width'], 6675 support: ['__experimentalBorder', 'width'], 6676 useEngine: true 6677 }, 6678 borderLeftColor: { 6679 value: ['border', 'left', 'color'], 6680 support: ['__experimentalBorder', 'color'], 6681 useEngine: true 6682 }, 6683 borderLeftStyle: { 6684 value: ['border', 'left', 'style'], 6685 support: ['__experimentalBorder', 'style'], 6686 useEngine: true 6687 }, 6688 borderLeftWidth: { 6689 value: ['border', 'left', 'width'], 6690 support: ['__experimentalBorder', 'width'], 6691 useEngine: true 6692 }, 6693 color: { 6694 value: ['color', 'text'], 6695 support: ['color', 'text'], 6696 requiresOptOut: true, 6697 useEngine: true 6698 }, 6699 columnCount: { 6700 value: ['typography', 'textColumns'], 6701 support: ['typography', 'textColumns'], 6702 useEngine: true 6703 }, 6704 filter: { 6705 value: ['filter', 'duotone'], 6706 support: ['filter', 'duotone'] 6707 }, 6708 linkColor: { 6709 value: ['elements', 'link', 'color', 'text'], 6710 support: ['color', 'link'] 6711 }, 6712 captionColor: { 6713 value: ['elements', 'caption', 'color', 'text'], 6714 support: ['color', 'caption'] 6715 }, 6716 buttonColor: { 6717 value: ['elements', 'button', 'color', 'text'], 6718 support: ['color', 'button'] 6719 },
6720 buttonBackgroundColor: { 6721 value: ['elements', 'button', 'color', 'background'], 6722 support: ['color', 'button'] 6723 }, 6724 headingColor: { 6725 value: ['elements', 'heading', 'color', 'text'], 6726 support: ['color', 'heading'] 6727 }, 6728 headingBackgroundColor: { 6729 value: ['elements', 'heading', 'color', 'background'], 6730 support: ['color', 'heading'] 6731 }, 6732 fontFamily: { 6733 value: ['typography', 'fontFamily'], 6734 support: ['typography', '__experimentalFontFamily'], 6735 useEngine: true 6736 }, 6737 fontSize: { 6738 value: ['typography', 'fontSize'], 6739 support: ['typography', 'fontSize'], 6740 useEngine: true 6741 }, 6742 fontStyle: { 6743 value: ['typography', 'fontStyle'], 6744 support: ['typography', '__experimentalFontStyle'], 6745 useEngine: true 6746 }, 6747 fontWeight: { 6748 value: ['typography', 'fontWeight'], 6749 support: ['typography', '__experimentalFontWeight'], 6750 useEngine: true 6751 }, 6752 lineHeight: { 6753 value: ['typography', 'lineHeight'], 6754 support: ['typography', 'lineHeight'], 6755 useEngine: true 6756 }, 6757 margin: { 6758 value: ['spacing', 'margin'], 6759 support: ['spacing', 'margin'], 6760 properties: { 6761 marginTop: 'top', 6762 marginRight: 'right', 6763 marginBottom: 'bottom', 6764 marginLeft: 'left' 6765 }, 6766 useEngine: true 6767 }, 6768 minHeight: { 6769 value: ['dimensions', 'minHeight'], 6770 support: ['dimensions', 'minHeight'], 6771 useEngine: true 6772 }, 6773 padding: { 6774 value: ['spacing', 'padding'], 6775 support: ['spacing', 'padding'], 6776 properties: { 6777 paddingTop: 'top', 6778 paddingRight: 'right', 6779 paddingBottom: 'bottom', 6780 paddingLeft: 'left' 6781 }, 6782 useEngine: true 6783 }, 6784 textDecoration: { 6785 value: ['typography', 'textDecoration'], 6786 support: ['typography', '__experimentalTextDecoration'], 6787 useEngine: true 6788 }, 6789 textTransform: { 6790 value: ['typography', 'textTransform'], 6791 support: ['typography', '__experimentalTextTransform'], 6792 useEngine: true 6793 }, 6794 letterSpacing: { 6795 value: ['typography', 'letterSpacing'], 6796 support: ['typography', '__experimentalLetterSpacing'], 6797 useEngine: true 6798 }, 6799 writingMode: { 6800 value: ['typography', 'writingMode'], 6801 support: ['typography', '__experimentalWritingMode'], 6802 useEngine: true 6803 }, 6804 '--wp--style--root--padding': { 6805 value: ['spacing', 'padding'], 6806 support: ['spacing', 'padding'], 6807 properties: { 6808 '--wp--style--root--padding-top': 'top', 6809 '--wp--style--root--padding-right': 'right', 6810 '--wp--style--root--padding-bottom': 'bottom', 6811 '--wp--style--root--padding-left': 'left' 6812 }, 6813 rootOnly: true 6814 } 6815}; 6816const __EXPERIMENTAL_ELEMENTS = { 6817 link: 'a', 6818 heading: 'h1, h2, h3, h4, h5, h6', 6819 h1: 'h1', 6820 h2: 'h2', 6821 h3: 'h3', 6822 h4: 'h4', 6823 h5: 'h5', 6824 h6: 'h6', 6825 button: '.wp-element-button, .wp-block-button__link', 6826 caption: '.wp-element-caption, .wp-block-audio figcaption, .wp-block-embed figcaption, .wp-block-gallery figcaption, .wp-block-image figcaption, .wp-block-table figcaption, .wp-block-video figcaption', 6827 cite: 'cite' 6828}; 6829const __EXPERIMENTAL_PATHS_WITH_MERGE = { 6830 'color.duotone': true, 6831 'color.gradients': true, 6832 'color.palette': true, 6833 'typography.fontFamilies': true, 6834 'typography.fontSizes': true, 6835 'spacing.spacingSizes': true 6836}; 6837 6838;// CONCATENATED MODULE: external ["wp","privateApis"] 6839const external_wp_privateApis_namespaceObject = window["wp"]["privateApis"]; 6840;// CONCATENATED MODULE: ./packages/blocks/build-module/lock-unlock.js 6841/** 6842 * WordPress dependencies 6843 */ 6844 6845const { 6846 lock, 6847 unlock 6848} = (0,external_wp_privateApis_namespaceObject.__dangerousOptInToUnstableAPIsOnlyForCoreModules)('I know using unstable features means my theme or plugin will inevitably break in the next version of WordPress.', '@wordpress/blocks'); 6849 6850;// CONCATENATED MODULE: ./packages/blocks/build-module/api/registration.js 6851/* eslint no-console: [ 'error', { allow: [ 'error', 'warn' ] } ] */ 6852 6853/** 6854 * WordPress dependencies 6855 */ 6856 6857 6858 6859/** 6860 * Internal dependencies 6861 */ 6862const i18nBlockSchema = { 6863 title: "block title", 6864 description: "block description", 6865 keywords: ["block keyword"], 6866 styles: [{ 6867 label: "block style label" 6868 }], 6869 variations: [{ 6870 title: "block variation title", 6871 description: "block variation description", 6872 keywords: ["block variation keyword"] 6873 }] 6874}; 6875 6876 6877 6878/** 6879 * An icon type definition. One of a Dashicon slug, an element, 6880 * or a component. 6881 * 6882 * @typedef {(string|WPElement|WPComponent)} WPIcon 6883 * 6884 * @see https://developer.wordpress.org/resource/dashicons/ 6885 */ 6886
6887/** 6888 * Render behavior of a block type icon; one of a Dashicon slug, an element, 6889 * or a component. 6890 * 6891 * @typedef {WPIcon} WPBlockTypeIconRender 6892 */ 6893 6894/** 6895 * An object describing a normalized block type icon. 6896 * 6897 * @typedef {Object} WPBlockTypeIconDescriptor 6898 * 6899 * @property {WPBlockTypeIconRender} src Render behavior of the icon, 6900 * one of a Dashicon slug, an 6901 * element, or a component. 6902 * @property {string} background Optimal background hex string 6903 * color when displaying icon. 6904 * @property {string} foreground Optimal foreground hex string 6905 * color when displaying icon. 6906 * @property {string} shadowColor Optimal shadow hex string 6907 * color when displaying icon. 6908 */ 6909 6910/** 6911 * Value to use to render the icon for a block type in an editor interface, 6912 * either a Dashicon slug, an element, a component, or an object describing 6913 * the icon. 6914 * 6915 * @typedef {(WPBlockTypeIconDescriptor|WPBlockTypeIconRender)} WPBlockTypeIcon 6916 */ 6917 6918/** 6919 * Named block variation scopes. 6920 * 6921 * @typedef {'block'|'inserter'|'transform'} WPBlockVariationScope 6922 */ 6923 6924/** 6925 * An object describing a variation defined for the block type. 6926 * 6927 * @typedef {Object} WPBlockVariation 6928 * 6929 * @property {string} name The unique and machine-readable name. 6930 * @property {string} title A human-readable variation title. 6931 * @property {string} [description] A detailed variation description. 6932 * @property {string} [category] Block type category classification, 6933 * used in search interfaces to arrange 6934 * block types by category. 6935 * @property {WPIcon} [icon] An icon helping to visualize the variation. 6936 * @property {boolean} [isDefault] Indicates whether the current variation is 6937 * the default one. Defaults to `false`. 6938 * @property {Object} [attributes] Values which override block attributes. 6939 * @property {Array[]} [innerBlocks] Initial configuration of nested blocks. 6940 * @property {Object} [example] Example provides structured data for 6941 * the block preview. You can set to 6942 * `undefined` to disable the preview shown 6943 * for the block type. 6944 * @property {WPBlockVariationScope[]} [scope] The list of scopes where the variation 6945 * is applicable. When not provided, it 6946 * assumes all available scopes. 6947 * @property {string[]} [keywords] An array of terms (which can be translated) 6948 * that help users discover the variation 6949 * while searching. 6950 * @property {Function|string[]} [isActive] This can be a function or an array of block attributes. 6951 * Function that accepts a block's attributes and the 6952 * variation's attributes and determines if a variation is active. 6953 * This function doesn't try to find a match dynamically based 6954 * on all block's attributes, as in many cases some attributes are irrelevant. 6955 * An example would be for `embed` block where we only care 6956 * about `providerNameSlug` attribute's value. 6957 * We can also use a `string[]` to tell which attributes 6958 * should be compared as a shorthand. Each attributes will 6959 * be matched and the variation will be active if all of them are matching. 6960 */ 6961 6962/** 6963 * Defined behavior of a block type. 6964 * 6965 * @typedef {Object} WPBlockType 6966 * 6967 * @property {string} name Block type's namespaced name. 6968 * @property {string} title Human-readable block type label. 6969 * @property {string} [description] A detailed block type description. 6970 * @property {string} [category] Block type category classification, 6971 * used in search interfaces to arrange 6972 * block types by category. 6973 * @property {WPBlockTypeIcon} [icon] Block type icon. 6974 * @property {string[]} [keywords] Additional keywords to produce block 6975 * type as result in search interfaces. 6976 * @property {Object} [attributes] Block type attributes. 6977 * @property {WPComponent} [save] Optional component describing 6978 * serialized markup structure of a 6979 * block type. 6980 * @property {WPComponent} edit Component rendering an element to 6981 * manipulate the attributes of a block 6982 * in the context of an editor. 6983 * @property {WPBlockVariation[]} [variations] The list of block variations. 6984 * @property {Object} [example] Example provides structured data for 6985 * the block preview. When not defined 6986 * then no preview is shown.
6987 */ 6988 6989function isObject(object) { 6990 return object !== null && typeof object === 'object'; 6991} 6992 6993/** 6994 * Sets the server side block definition of blocks. 6995 * 6996 * @param {Object} definitions Server-side block definitions 6997 */ 6998// eslint-disable-next-line camelcase 6999function unstable__bootstrapServerSideBlockDefinitions(definitions) { 7000 const { 7001 addBootstrappedBlockType 7002 } = unlock((0,external_wp_data_namespaceObject.dispatch)(store)); 7003 for (const [name, blockType] of Object.entries(definitions)) { 7004 addBootstrappedBlockType(name, blockType); 7005 } 7006} 7007 7008/** 7009 * Gets block settings from metadata loaded from `block.json` file. 7010 * 7011 * @param {Object} metadata Block metadata loaded from `block.json`. 7012 * @param {string} metadata.textdomain Textdomain to use with translations. 7013 * 7014 * @return {Object} Block settings. 7015 */ 7016function getBlockSettingsFromMetadata({ 7017 textdomain, 7018 ...metadata 7019}) { 7020 const allowedFields = ['apiVersion', 'title', 'category', 'parent', 'ancestor', 'icon', 'description', 'keywords', 'attributes', 'providesContext', 'usesContext', 'selectors', 'supports', 'styles', 'example', 'variations', 'blockHooks']; 7021 const settings = Object.fromEntries(Object.entries(metadata).filter(([key]) => allowedFields.includes(key))); 7022 if (textdomain) { 7023 Object.keys(i18nBlockSchema).forEach(key => { 7024 if (!settings[key]) { 7025 return; 7026 } 7027 settings[key] = translateBlockSettingUsingI18nSchema(i18nBlockSchema[key], settings[key], textdomain); 7028 }); 7029 } 7030 return settings; 7031} 7032 7033/** 7034 * Registers a new block provided a unique name and an object defining its 7035 * behavior. Once registered, the block is made available as an option to any 7036 * editor interface where blocks are implemented. 7037 * 7038 * For more in-depth information on registering a custom block see the 7039 * [Create a block tutorial](https://developer.wordpress.org/block-editor/getting-started/create-block/). 7040 * 7041 * @param {string|Object} blockNameOrMetadata Block type name or its metadata. 7042 * @param {Object} settings Block settings. 7043 * 7044 * @example 7045 * ```js 7046 * import { __ } from '@wordpress/i18n'; 7047 * import { registerBlockType } from '@wordpress/blocks' 7048 * 7049 * registerBlockType( 'namespace/block-name', { 7050 * title: __( 'My First Block' ), 7051 * edit: () => <div>{ __( 'Hello from the editor!' ) }</div>, 7052 * save: () => <div>Hello from the saved content!</div>, 7053 * } ); 7054 * ``` 7055 * 7056 * @return {WPBlockType | undefined} The block, if it has been successfully registered; 7057 * otherwise `undefined`. 7058 */ 7059function registerBlockType(blockNameOrMetadata, settings) { 7060 const name = isObject(blockNameOrMetadata) ? blockNameOrMetadata.name : blockNameOrMetadata; 7061 if (typeof name !== 'string') { 7062 console.error('Block names must be strings.'); 7063 return; 7064 } 7065 if (!/^[a-z][a-z0-9-]*\/[a-z][a-z0-9-]*$/.test(name)) { 7066 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'); 7067 return; 7068 } 7069 if ((0,external_wp_data_namespaceObject.select)(store).getBlockType(name)) { 7070 console.error('Block "' + name + '" is already registered.'); 7071 return; 7072 } 7073 const { 7074 addBootstrappedBlockType, 7075 addUnprocessedBlockType 7076 } = unlock((0,external_wp_data_namespaceObject.dispatch)(store)); 7077 if (isObject(blockNameOrMetadata)) { 7078 const metadata = getBlockSettingsFromMetadata(blockNameOrMetadata); 7079 addBootstrappedBlockType(name, metadata); 7080 } 7081 addUnprocessedBlockType(name, settings); 7082 return (0,external_wp_data_namespaceObject.select)(store).getBlockType(name); 7083} 7084 7085/** 7086 * Translates block settings provided with metadata using the i18n schema. 7087 * 7088 * @param {string|string[]|Object[]} i18nSchema I18n schema for the block setting. 7089 * @param {string|string[]|Object[]} settingValue Value for the block setting. 7090 * @param {string} textdomain Textdomain to use with translations. 7091 * 7092 * @return {string|string[]|Object[]} Translated setting. 7093 */ 7094function translateBlockSettingUsingI18nSchema(i18nSchema, settingValue, textdomain) { 7095 if (typeof i18nSchema === 'string' && typeof settingValue === 'string') { 7096 // eslint-disable-next-line @wordpress/i18n-no-variables, @wordpress/i18n-text-domain 7097 return (0,external_wp_i18n_namespaceObject._x)(settingValue, i18nSchema, textdomain); 7098 } 7099 if (Array.isArray(i18nSchema) && i18nSchema.length && Array.isArray(settingValue)) { 7100 return settingValue.map(value => translateBlockSettingUsingI18nSchema(i18nSchema[0], value, textdomain)); 7101 } 7102 if (isObject(i18nSchema) && Object.entries(i18nSchema).length && isObject(settingValue)) { 7103 return Object.keys(settingValue).reduce((accumulator, key) => { 7104 if (!i18nSchema[key]) { 7105 accumulator[key] = settingValue[key]; 7106 return accumulator; 7107 } 7108 accumulator[key] = translateBlockSettingUsingI18nSchema(i18nSchema[key], settingValue[key], textdomain); 7109 return accumulator; 7110 }, {}); 7111 } 7112 return settingValue; 7113} 7114 7115/** 7116 * Registers a new block collection to group blocks in the same namespace in the inserter. 7117 * 7118 * @param {string} namespace The namespace to group blocks by in the inserter; corresponds to the block namespace. 7119 * @param {Object} settings The block collection settings. 7120 * @param {string} settings.title The title to display in the block inserter. 7121 * @param {Object} [settings.icon] The icon to display in the block inserter. 7122 * 7123 * @example 7124 * ```js 7125 * import { __ } from '@wordpress/i18n'; 7126 * import { registerBlockCollection, registerBlockType } from '@wordpress/blocks'; 7127 * 7128 * // Register the collection. 7129 * registerBlockCollection( 'my-collection', { 7130 * title: __( 'Custom Collection' ), 7131 * } ); 7132 * 7133 * // Register a block in the same namespace to add it to the collection. 7134 * registerBlockType( 'my-collection/block-name', { 7135 * title: __( 'My First Block' ), 7136 * edit: () => <div>{ __( 'Hello from the editor!' ) }</div>, 7137 * save: () => <div>'Hello from the saved content!</div>, 7138 * } ); 7139 * ``` 7140 */ 7141function registerBlockCollection(namespace, { 7142 title, 7143 icon 7144}) { 7145 (0,external_wp_data_namespaceObject.dispatch)(store).addBlockCollection(namespace, title, icon); 7146} 7147 7148/** 7149 * Unregisters a block collection 7150 * 7151 * @param {string} namespace The namespace to group blocks by in the inserter; corresponds to the block namespace 7152 * 7153 * @example 7154 * ```js 7155 * import { unregisterBlockCollection } from '@wordpress/blocks'; 7156 * 7157 * unregisterBlockCollection( 'my-collection' ); 7158 * ``` 7159 */ 7160function unregisterBlockCollection(namespace) { 7161 dispatch(blocksStore).removeBlockCollection(namespace); 7162} 7163 7164/** 7165 * Unregisters a block. 7166 * 7167 * @param {string} name Block name. 7168 * 7169 * @example 7170 * ```js 7171 * import { __ } from '@wordpress/i18n'; 7172 * import { unregisterBlockType } from '@wordpress/blocks'; 7173 *
7174 * const ExampleComponent = () => { 7175 * return ( 7176 * <Button 7177 * onClick={ () => 7178 * unregisterBlockType( 'my-collection/block-name' ) 7179 * } 7180 * > 7181 * { __( 'Unregister my custom block.' ) } 7182 * </Button> 7183 * ); 7184 * }; 7185 * ``` 7186 * 7187 * @return {WPBlockType | undefined} The previous block value, if it has been successfully 7188 * unregistered; otherwise `undefined`. 7189 */ 7190function unregisterBlockType(name) { 7191 const oldBlock = (0,external_wp_data_namespaceObject.select)(store).getBlockType(name); 7192 if (!oldBlock) { 7193 console.error('Block "' + name + '" is not registered.'); 7194 return; 7195 } 7196 (0,external_wp_data_namespaceObject.dispatch)(store).removeBlockTypes(name); 7197 return oldBlock; 7198} 7199 7200/** 7201 * Assigns name of block for handling non-block content. 7202 * 7203 * @param {string} blockName Block name. 7204 */ 7205function setFreeformContentHandlerName(blockName) { 7206 (0,external_wp_data_namespaceObject.dispatch)(store).setFreeformFallbackBlockName(blockName); 7207} 7208 7209/** 7210 * Retrieves name of block handling non-block content, or undefined if no 7211 * handler has been defined. 7212 * 7213 * @return {?string} Block name. 7214 */ 7215function getFreeformContentHandlerName() { 7216 return (0,external_wp_data_namespaceObject.select)(store).getFreeformFallbackBlockName(); 7217} 7218 7219/** 7220 * Retrieves name of block used for handling grouping interactions. 7221 * 7222 * @return {?string} Block name. 7223 */ 7224function getGroupingBlockName() { 7225 return (0,external_wp_data_namespaceObject.select)(store).getGroupingBlockName(); 7226} 7227 7228/** 7229 * Assigns name of block handling unregistered block types. 7230 * 7231 * @param {string} blockName Block name. 7232 */ 7233function setUnregisteredTypeHandlerName(blockName) { 7234 (0,external_wp_data_namespaceObject.dispatch)(store).setUnregisteredFallbackBlockName(blockName); 7235} 7236 7237/** 7238 * Retrieves name of block handling unregistered block types, or undefined if no 7239 * handler has been defined. 7240 * 7241 * @return {?string} Block name. 7242 */ 7243function getUnregisteredTypeHandlerName() { 7244 return (0,external_wp_data_namespaceObject.select)(store).getUnregisteredFallbackBlockName(); 7245} 7246 7247/** 7248 * Assigns the default block name. 7249 * 7250 * @param {string} name Block name. 7251 * 7252 * @example 7253 * ```js 7254 * import { setDefaultBlockName } from '@wordpress/blocks'; 7255 * 7256 * const ExampleComponent = () => { 7257 * 7258 * return ( 7259 * <Button onClick={ () => setDefaultBlockName( 'core/heading' ) }> 7260 * { __( 'Set the default block to Heading' ) } 7261 * </Button> 7262 * ); 7263 * }; 7264 * ``` 7265 */ 7266function setDefaultBlockName(name) { 7267 (0,external_wp_data_namespaceObject.dispatch)(store).setDefaultBlockName(name); 7268} 7269 7270/** 7271 * Assigns name of block for handling block grouping interactions. 7272 * 7273 * This function lets you select a different block to group other blocks in instead of the 7274 * default `core/group` block. This function must be used in a component or when the DOM is fully 7275 * loaded. See https://developer.wordpress.org/block-editor/reference-guides/packages/packages-dom-ready/ 7276 * 7277 * @param {string} name Block name. 7278 * 7279 * @example 7280 * ```js 7281 * import { setGroupingBlockName } from '@wordpress/blocks'; 7282 * 7283 * const ExampleComponent = () => { 7284 * 7285 * return ( 7286 * <Button onClick={ () => setGroupingBlockName( 'core/columns' ) }> 7287 * { __( 'Wrap in columns' ) } 7288 * </Button> 7289 * ); 7290 * }; 7291 * ``` 7292 */ 7293function setGroupingBlockName(name) { 7294 (0,external_wp_data_namespaceObject.dispatch)(store).setGroupingBlockName(name); 7295} 7296 7297/** 7298 * Retrieves the default block name. 7299 * 7300 * @return {?string} Block name. 7301 */ 7302function getDefaultBlockName() { 7303 return (0,external_wp_data_namespaceObject.select)(store).getDefaultBlockName(); 7304} 7305 7306/** 7307 * Returns a registered block type. 7308 * 7309 * @param {string} name Block name. 7310 * 7311 * @return {?Object} Block type. 7312 */ 7313function getBlockType(name) { 7314 return (0,external_wp_data_namespaceObject.select)(store)?.getBlockType(name); 7315} 7316 7317/** 7318 * Returns all registered blocks. 7319 * 7320 * @return {Array} Block settings. 7321 */ 7322function getBlockTypes() { 7323 return (0,external_wp_data_namespaceObject.select)(store).getBlockTypes(); 7324} 7325 7326/** 7327 * Returns the block support value for a feature, if defined. 7328 * 7329 * @param {(string|Object)} nameOrType Block name or type object 7330 * @param {string} feature Feature to retrieve 7331 * @param {*}
7331 defaultSupports Default value to return if not 7332 * explicitly defined 7333 * 7334 * @return {?*} Block support value 7335 */ 7336function getBlockSupport(nameOrType, feature, defaultSupports) { 7337 return (0,external_wp_data_namespaceObject.select)(store).getBlockSupport(nameOrType, feature, defaultSupports); 7338} 7339 7340/** 7341 * Returns true if the block defines support for a feature, or false otherwise. 7342 * 7343 * @param {(string|Object)} nameOrType Block name or type object. 7344 * @param {string} feature Feature to test. 7345 * @param {boolean} defaultSupports Whether feature is supported by 7346 * default if not explicitly defined. 7347 * 7348 * @return {boolean} Whether block supports feature. 7349 */ 7350function hasBlockSupport(nameOrType, feature, defaultSupports) { 7351 return (0,external_wp_data_namespaceObject.select)(store).hasBlockSupport(nameOrType, feature, defaultSupports); 7352} 7353 7354/** 7355 * Determines whether or not the given block is a reusable block. This is a 7356 * special block type that is used to point to a global block stored via the 7357 * API. 7358 * 7359 * @param {Object} blockOrType Block or Block Type to test. 7360 * 7361 * @return {boolean} Whether the given block is a reusable block. 7362 */ 7363function isReusableBlock(blockOrType) { 7364 return blockOrType?.name === 'core/block'; 7365} 7366 7367/** 7368 * Determines whether or not the given block is a template part. This is a 7369 * special block type that allows composing a page template out of reusable 7370 * design elements. 7371 * 7372 * @param {Object} blockOrType Block or Block Type to test. 7373 * 7374 * @return {boolean} Whether the given block is a template part. 7375 */ 7376function isTemplatePart(blockOrType) { 7377 return blockOrType?.name === 'core/template-part'; 7378} 7379 7380/** 7381 * Returns an array with the child blocks of a given block. 7382 * 7383 * @param {string} blockName Name of block (example: âlatest-postsâ). 7384 * 7385 * @return {Array} Array of child block names. 7386 */ 7387const getChildBlockNames = blockName => { 7388 return (0,external_wp_data_namespaceObject.select)(store).getChildBlockNames(blockName); 7389}; 7390 7391/** 7392 * Returns a boolean indicating if a block has child blocks or not. 7393 * 7394 * @param {string} blockName Name of block (example: âlatest-postsâ). 7395 * 7396 * @return {boolean} True if a block contains child blocks and false otherwise. 7397 */ 7398const hasChildBlocks = blockName => { 7399 return (0,external_wp_data_namespaceObject.select)(store).hasChildBlocks(blockName); 7400}; 7401 7402/** 7403 * Returns a boolean indicating if a block has at least one child block with inserter support. 7404 * 7405 * @param {string} blockName Block type name. 7406 * 7407 * @return {boolean} True if a block contains at least one child blocks with inserter support 7408 * and false otherwise. 7409 */ 7410const hasChildBlocksWithInserterSupport = blockName => { 7411 return (0,external_wp_data_namespaceObject.select)(store).hasChildBlocksWithInserterSupport(blockName); 7412}; 7413 7414/** 7415 * Registers a new block style for the given block. 7416 * 7417 * For more information on connecting the styles with CSS 7418 * [the official documentation](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-styles/#styles). 7419 * 7420 * @param {string} blockName Name of block (example: âcore/latest-postsâ). 7421 * @param {Object} styleVariation Object containing `name` which is the class name applied to the block and `label` which identifies the variation to the user. 7422 * 7423 * @example 7424 * ```js 7425 * import { __ } from '@wordpress/i18n'; 7426 * import { registerBlockStyle } from '@wordpress/blocks'; 7427 * import { Button } from '@wordpress/components'; 7428 * 7429 * 7430 * const ExampleComponent = () => { 7431 * return ( 7432 * <Button 7433 * onClick={ () => { 7434 * registerBlockStyle( 'core/quote', { 7435 * name: 'fancy-quote', 7436 * label: __( 'Fancy Quote' ), 7437 * } ); 7438 * } } 7439 * > 7440 * { __( 'Add a new block style for core/quote' ) } 7441 * </Button> 7442 * ); 7443 * }; 7444 * ``` 7445 */ 7446const registerBlockStyle = (blockName, styleVariation) => { 7447 (0,external_wp_data_namespaceObject.dispatch)(store).addBlockStyles(blockName, styleVariation); 7448}; 7449 7450/** 7451 * Unregisters a block style for the given block. 7452 * 7453 * @param {string} blockName Name of block (example: âcore/latest-postsâ). 7454 * @param {string} styleVariationName Name of class applied to the block. 7455 * 7456 * @example 7457 * ```js 7458 * import { __ } from '@wordpress/i18n'; 7459 * import { unregisterBlockStyle } from '@wordpress/blocks'; 7460 * import { Button } from '@wordpress/components'; 7461 *
7462 * const ExampleComponent = () => { 7463 * return ( 7464 * <Button 7465 * onClick={ () => { 7466 * unregisterBlockStyle( 'core/quote', 'plain' ); 7467 * } } 7468 * > 7469 * { __( 'Remove the "Plain" block style for core/quote' ) } 7470 * </Button> 7471 * ); 7472 * }; 7473 * ``` 7474 */ 7475const unregisterBlockStyle = (blockName, styleVariationName) => { 7476 (0,external_wp_data_namespaceObject.dispatch)(store).removeBlockStyles(blockName, styleVariationName); 7477}; 7478 7479/** 7480 * Returns an array with the variations of a given block type. 7481 * Ignored from documentation as the recommended usage is via useSelect from @wordpress/data. 7482 * 7483 * @ignore 7484 * 7485 * @param {string} blockName Name of block (example: âcore/columnsâ). 7486 * @param {WPBlockVariationScope} [scope] Block variation scope name. 7487 * 7488 * @return {(WPBlockVariation[]|void)} Block variations. 7489 */ 7490const getBlockVariations = (blockName, scope) => { 7491 return (0,external_wp_data_namespaceObject.select)(store).getBlockVariations(blockName, scope); 7492}; 7493 7494/** 7495 * Registers a new block variation for the given block type. 7496 * 7497 * For more information on block variations see 7498 * [the official documentation ](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-variations/). 7499 * 7500 * @param {string} blockName Name of the block (example: âcore/columnsâ). 7501 * @param {WPBlockVariation} variation Object describing a block variation. 7502 * 7503 * @example 7504 * ```js 7505 * import { __ } from '@wordpress/i18n'; 7506 * import { registerBlockVariation } from '@wordpress/blocks'; 7507 * import { Button } from '@wordpress/components'; 7508 * 7509 * const ExampleComponent = () => { 7510 * return ( 7511 * <Button 7512 * onClick={ () => { 7513 * registerBlockVariation( 'core/embed', { 7514 * name: 'custom', 7515 * title: __( 'My Custom Embed' ), 7516 * attributes: { providerNameSlug: 'custom' }, 7517 * } ); 7518 * } } 7519 * > 7520 * __( 'Add a custom variation for core/embed' ) } 7521 * </Button> 7522 * ); 7523 * }; 7524 * ``` 7525 */ 7526const registerBlockVariation = (blockName, variation) => { 7527 (0,external_wp_data_namespaceObject.dispatch)(store).addBlockVariations(blockName, variation); 7528}; 7529 7530/** 7531 * Unregisters a block variation defined for the given block type. 7532 * 7533 * @param {string} blockName Name of the block (example: âcore/columnsâ). 7534 * @param {string} variationName Name of the variation defined for the block. 7535 * 7536 * @example 7537 * ```js 7538 * import { __ } from '@wordpress/i18n'; 7539 * import { unregisterBlockVariation } from '@wordpress/blocks'; 7540 * import { Button } from '@wordpress/components'; 7541 * 7542 * const ExampleComponent = () => { 7543 * return ( 7544 * <Button 7545 * onClick={ () => { 7546 * unregisterBlockVariation( 'core/embed', 'youtube' ); 7547 * } } 7548 * > 7549 * { __( 'Remove the YouTube variation from core/embed' ) } 7550 * </Button> 7551 * ); 7552 * }; 7553 * ``` 7554 */ 7555const unregisterBlockVariation = (blockName, variationName) => { 7556 (0,external_wp_data_namespaceObject.dispatch)(store).removeBlockVariations(blockName, variationName); 7557}; 7558 7559;// CONCATENATED MODULE: ./packages/blocks/node_modules/uuid/dist/esm-browser/rng.js 7560// Unique ID creation requires a high quality random # generator. In the browser we therefore 7561// require the crypto API and do not support built-in fallback to lower quality random number 7562// generators (like Math.random()). 7563var getRandomValues; 7564var rnds8 = new Uint8Array(16); 7565function rng() { 7566 // lazy load so that environments that need to polyfill have a chance to do so 7567 if (!getRandomValues) { 7568 // getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. Also, 7569 // find the complete implementation of crypto (msCrypto) on IE11. 7570 getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || typeof msCrypto !== 'undefined' && typeof msCrypto.getRandomValues === 'function' && msCrypto.getRandomValues.bind(msCrypto); 7571 7572 if (!getRandomValues) { 7573 throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported'); 7574 } 7575 } 7576 7577 return getRandomValues(rnds8); 7578} 7579;// CONCATENATED MODULE: ./packages/blocks/node_modules/uuid/dist/esm-browser/regex.js 7580/* harmony default export */ const 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); 7581;// CONCATENATED MODULE: ./packages/blocks/node_modules/uuid/dist/esm-browser/validate.js 7582 7583 7584function validate(uuid) { 7585 return typeof uuid === 'string' && regex.test(uuid); 7586} 7587 7588/* harmony default export */ const esm_browser_validate = (validate); 7589;// CONCATENATED MODULE: ./packages/blocks/node_modules/uuid/dist/esm-browser/stringify.js 7590 7591/** 7592 * Convert array of 16 byte values to UUID string format of the form: 7593 * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX 7594 */ 7595 7596var byteToHex = []; 7597 7598for (var stringify_i = 0; stringify_i < 256; ++stringify_i) { 7599 byteToHex.push((stringify_i + 0x100).toString(16).substr(1)); 7600} 7601 7602function stringify(arr) { 7603 var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; 7604 // Note: Be careful editing this code! It's been tuned for performance
7605 // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434 7606 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 7607 // of the following: 7608 // - One or more input array values don't map to a hex octet (leading to 7609 // "undefined" in the uuid) 7610 // - Invalid input values for the RFC `version` or `variant` fields 7611 7612 if (!esm_browser_validate(uuid)) { 7613 throw TypeError('Stringified UUID is invalid'); 7614 } 7615 7616 return uuid; 7617} 7618 7619/* harmony default export */ const esm_browser_stringify = (stringify); 7620;// CONCATENATED MODULE: ./packages/blocks/node_modules/uuid/dist/esm-browser/v4.js 7621 7622 7623 7624function v4(options, buf, offset) { 7625 options = options || {}; 7626 var rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` 7627 7628 rnds[6] = rnds[6] & 0x0f | 0x40; 7629 rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided 7630 7631 if (buf) { 7632 offset = offset || 0; 7633 7634 for (var i = 0; i < 16; ++i) { 7635 buf[offset + i] = rnds[i]; 7636 } 7637 7638 return buf; 7639 } 7640 7641 return esm_browser_stringify(rnds); 7642} 7643 7644/* harmony default export */ const esm_browser_v4 = (v4); 7645;// CONCATENATED MODULE: external ["wp","hooks"] 7646const external_wp_hooks_namespaceObject = window["wp"]["hooks"]; 7647;// CONCATENATED MODULE: ./packages/blocks/build-module/api/factory.js 7648/** 7649 * External dependencies 7650 */ 7651 7652 7653/** 7654 * WordPress dependencies 7655 */ 7656 7657 7658/** 7659 * Internal dependencies 7660 */ 7661 7662 7663 7664/** 7665 * Returns a block object given its type and attributes. 7666 * 7667 * @param {string} name Block name. 7668 * @param {Object} attributes Block attributes. 7669 * @param {?Array} innerBlocks Nested blocks. 7670 * 7671 * @return {Object} Block object. 7672 */ 7673function createBlock(name, attributes = {}, innerBlocks = []) { 7674 const sanitizedAttributes = __experimentalSanitizeBlockAttributes(name, attributes); 7675 const clientId = esm_browser_v4(); 7676 7677 // Blocks are stored with a unique ID, the assigned type name, the block 7678 // attributes, and their inner blocks. 7679 return { 7680 clientId, 7681 name, 7682 isValid: true, 7683 attributes: sanitizedAttributes, 7684 innerBlocks 7685 }; 7686} 7687 7688/** 7689 * Given an array of InnerBlocks templates or Block Objects, 7690 * returns an array of created Blocks from them. 7691 * It handles the case of having InnerBlocks as Blocks by 7692 * converting them to the proper format to continue recursively. 7693 * 7694 * @param {Array} innerBlocksOrTemplate Nested blocks or InnerBlocks templates. 7695 * 7696 * @return {Object[]} Array of Block objects. 7697 */ 7698function createBlocksFromInnerBlocksTemplate(innerBlocksOrTemplate = []) { 7699 return innerBlocksOrTemplate.map(innerBlock => { 7700 const innerBlockTemplate = Array.isArray(innerBlock) ? innerBlock : [innerBlock.name, innerBlock.attributes, innerBlock.innerBlocks]; 7701 const [name, attributes, innerBlocks = []] = innerBlockTemplate; 7702 return createBlock(name, attributes, createBlocksFromInnerBlocksTemplate(innerBlocks)); 7703 }); 7704} 7705 7706/** 7707 * Given a block object, returns a copy of the block object while sanitizing its attributes, 7708 * optionally merging new attributes and/or replacing its inner blocks. 7709 * 7710 * @param {Object} block Block instance. 7711 * @param {Object} mergeAttributes Block attributes. 7712 * @param {?Array} newInnerBlocks Nested blocks. 7713 * 7714 * @return {Object} A cloned block. 7715 */ 7716function __experimentalCloneSanitizedBlock(block, mergeAttributes = {}, newInnerBlocks) { 7717 const clientId = esm_browser_v4(); 7718 const sanitizedAttributes = __experimentalSanitizeBlockAttributes(block.name, { 7719 ...block.attributes, 7720 ...mergeAttributes 7721 }); 7722 return { 7723 ...block, 7724 clientId, 7725 attributes: sanitizedAttributes, 7726 innerBlocks: newInnerBlocks || block.innerBlocks.map(innerBlock => __experimentalCloneSanitizedBlock(innerBlock)) 7727 }; 7728} 7729 7730/** 7731 * Given a block object, returns a copy of the block object, 7732 * optionally merging new attributes and/or replacing its inner blocks. 7733 * 7734 * @param {Object} block Block instance. 7735 * @param {Object} mergeAttributes Block attributes. 7736 * @param {?Array} newInnerBlocks Nested blocks. 7737 * 7738 * @return {Object} A cloned block. 7739 */ 7740function cloneBlock(block, mergeAttributes = {}, newInnerBlocks) { 7741 const clientId = esm_browser_v4(); 7742 return { 7743 ...block, 7744 clientId, 7745 attributes: { 7746 ...block.attributes, 7747 ...mergeAttributes 7748 }, 7749 innerBlocks: newInnerBlocks || block.innerBlocks.map(innerBlock => cloneBlock(innerBlock)) 7750 }; 7751} 7752 7753/** 7754 * Returns a boolean indicating whether a transform is possible based on 7755 * various bits of context. 7756 * 7757 * @param {Object} transform The transform object to validate. 7758 * @param {string} direction Is this a 'from' or 'to' transform. 7759 * @param {Array} blocks The blocks to transform from. 7760 * 7761 * @return {boolean} Is the transform possible? 7762 */ 7763const isPossibleTransformForSource = (transform, direction, blocks) => { 7764 if (!blocks.length) { 7765 return false;
7766 } 7767 7768 // If multiple blocks are selected, only multi block transforms 7769 // or wildcard transforms are allowed. 7770 const isMultiBlock = blocks.length > 1; 7771 const firstBlockName = blocks[0].name; 7772 const isValidForMultiBlocks = isWildcardBlockTransform(transform) || !isMultiBlock || transform.isMultiBlock; 7773 if (!isValidForMultiBlocks) { 7774 return false; 7775 } 7776 7777 // Check non-wildcard transforms to ensure that transform is valid 7778 // for a block selection of multiple blocks of different types. 7779 if (!isWildcardBlockTransform(transform) && !blocks.every(block => block.name === firstBlockName)) { 7780 return false; 7781 } 7782 7783 // Only consider 'block' type transforms as valid. 7784 const isBlockType = transform.type === 'block'; 7785 if (!isBlockType) { 7786 return false; 7787 } 7788 7789 // Check if the transform's block name matches the source block (or is a wildcard) 7790 // only if this is a transform 'from'. 7791 const sourceBlock = blocks[0]; 7792 const hasMatchingName = direction !== 'from' || transform.blocks.indexOf(sourceBlock.name) !== -1 || isWildcardBlockTransform(transform); 7793 if (!hasMatchingName) { 7794 return false; 7795 } 7796 7797 // Don't allow single Grouping blocks to be transformed into 7798 // a Grouping block. 7799 if (!isMultiBlock && direction === 'from' && isContainerGroupBlock(sourceBlock.name) && isContainerGroupBlock(transform.blockName)) { 7800 return false; 7801 } 7802 7803 // If the transform has a `isMatch` function specified, check that it returns true. 7804 if (!maybeCheckTransformIsMatch(transform, blocks)) { 7805 return false; 7806 } 7807 return true; 7808}; 7809 7810/** 7811 * Returns block types that the 'blocks' can be transformed into, based on 7812 * 'from' transforms on other blocks. 7813 * 7814 * @param {Array} blocks The blocks to transform from. 7815 * 7816 * @return {Array} Block types that the blocks can be transformed into. 7817 */ 7818const getBlockTypesForPossibleFromTransforms = blocks => { 7819 if (!blocks.length) { 7820 return []; 7821 } 7822 const allBlockTypes = getBlockTypes(); 7823 7824 // filter all blocks to find those with a 'from' transform. 7825 const blockTypesWithPossibleFromTransforms = allBlockTypes.filter(blockType => { 7826 const fromTransforms = getBlockTransforms('from', blockType.name); 7827 return !!findTransform(fromTransforms, transform => { 7828 return isPossibleTransformForSource(transform, 'from', blocks); 7829 }); 7830 }); 7831 return blockTypesWithPossibleFromTransforms; 7832}; 7833 7834/** 7835 * Returns block types that the 'blocks' can be transformed into, based on 7836 * the source block's own 'to' transforms. 7837 * 7838 * @param {Array} blocks The blocks to transform from. 7839 * 7840 * @return {Array} Block types that the source can be transformed into. 7841 */ 7842const getBlockTypesForPossibleToTransforms = blocks => { 7843 if (!blocks.length) { 7844 return []; 7845 } 7846 const sourceBlock = blocks[0]; 7847 const blockType = getBlockType(sourceBlock.name); 7848 const transformsTo = blockType ? getBlockTransforms('to', blockType.name) : []; 7849 7850 // filter all 'to' transforms to find those that are possible. 7851 const possibleTransforms = transformsTo.filter(transform => { 7852 return transform && isPossibleTransformForSource(transform, 'to', blocks); 7853 }); 7854 7855 // Build a list of block names using the possible 'to' transforms. 7856 const blockNames = possibleTransforms.map(transformation => transformation.blocks).flat(); 7857 7858 // Map block names to block types. 7859 return blockNames.map(getBlockType); 7860}; 7861 7862/** 7863 * Determines whether transform is a "block" type 7864 * and if so whether it is a "wildcard" transform 7865 * ie: targets "any" block type 7866 * 7867 * @param {Object} t the Block transform object 7868 * 7869 * @return {boolean} whether transform is a wildcard transform 7870 */ 7871const isWildcardBlockTransform = t => t && t.type === 'block' && Array.isArray(t.blocks) && t.blocks.includes('*'); 7872 7873/** 7874 * Determines whether the given Block is the core Block which 7875 * acts as a container Block for other Blocks as part of the 7876 * Grouping mechanics 7877 * 7878 * @param {string} name the name of the Block to test against 7879 * 7880 * @return {boolean} whether or not the Block is the container Block type 7881 */ 7882const isContainerGroupBlock = name => name === getGroupingBlockName(); 7883 7884/**
7885 * Returns an array of block types that the set of blocks received as argument 7886 * can be transformed into. 7887 * 7888 * @param {Array} blocks Blocks array. 7889 * 7890 * @return {Array} Block types that the blocks argument can be transformed to. 7891 */ 7892function getPossibleBlockTransformations(blocks) { 7893 if (!blocks.length) { 7894 return []; 7895 } 7896 const blockTypesForFromTransforms = getBlockTypesForPossibleFromTransforms(blocks); 7897 const blockTypesForToTransforms = getBlockTypesForPossibleToTransforms(blocks); 7898 return [...new Set([...blockTypesForFromTransforms, ...blockTypesForToTransforms])]; 7899} 7900 7901/** 7902 * Given an array of transforms, returns the highest-priority transform where 7903 * the predicate function returns a truthy value. A higher-priority transform 7904 * is one with a lower priority value (i.e. first in priority order). Returns 7905 * null if the transforms set is empty or the predicate function returns a 7906 * falsey value for all entries. 7907 * 7908 * @param {Object[]} transforms Transforms to search. 7909 * @param {Function} predicate Function returning true on matching transform. 7910 * 7911 * @return {?Object} Highest-priority transform candidate. 7912 */ 7913function findTransform(transforms, predicate) { 7914 // The hooks library already has built-in mechanisms for managing priority 7915 // queue, so leverage via locally-defined instance. 7916 const hooks = (0,external_wp_hooks_namespaceObject.createHooks)(); 7917 for (let i = 0; i < transforms.length; i++) { 7918 const candidate = transforms[i]; 7919 if (predicate(candidate)) { 7920 hooks.addFilter('transform', 'transform/' + i.toString(), result => result ? result : candidate, candidate.priority); 7921 } 7922 } 7923 7924 // Filter name is arbitrarily chosen but consistent with above aggregation. 7925 return hooks.applyFilters('transform', null); 7926} 7927 7928/** 7929 * Returns normal block transforms for a given transform direction, optionally 7930 * for a specific block by name, or an empty array if there are no transforms. 7931 * If no block name is provided, returns transforms for all blocks. A normal 7932 * transform object includes `blockName` as a property. 7933 * 7934 * @param {string} direction Transform direction ("to", "from"). 7935 * @param {string|Object} blockTypeOrName Block type or name. 7936 * 7937 * @return {Array} Block transforms for direction. 7938 */ 7939function getBlockTransforms(direction, blockTypeOrName) { 7940 // When retrieving transforms for all block types, recurse into self. 7941 if (blockTypeOrName === undefined) { 7942 return getBlockTypes().map(({ 7943 name 7944 }) => getBlockTransforms(direction, name)).flat(); 7945 } 7946 7947 // Validate that block type exists and has array of direction. 7948 const blockType = normalizeBlockType(blockTypeOrName); 7949 const { 7950 name: blockName, 7951 transforms 7952 } = blockType || {}; 7953 if (!transforms || !Array.isArray(transforms[direction])) { 7954 return []; 7955 } 7956 const usingMobileTransformations = transforms.supportedMobileTransforms && Array.isArray(transforms.supportedMobileTransforms); 7957 const filteredTransforms = usingMobileTransformations ? transforms[direction].filter(t => { 7958 if (t.type === 'raw') { 7959 return true; 7960 } 7961 if (!t.blocks || !t.blocks.length) { 7962 return false; 7963 } 7964 if (isWildcardBlockTransform(t)) { 7965 return true; 7966 } 7967 return t.blocks.every(transformBlockName => transforms.supportedMobileTransforms.includes(transformBlockName)); 7968 }) : transforms[direction]; 7969 7970 // Map transforms to normal form. 7971 return filteredTransforms.map(transform => ({ 7972 ...transform, 7973 blockName, 7974 usingMobileTransformations 7975 })); 7976} 7977 7978/** 7979 * Checks that a given transforms isMatch method passes for given source blocks. 7980 * 7981 * @param {Object} transform A transform object. 7982 * @param {Array} blocks Blocks array. 7983 * 7984 * @return {boolean} True if given blocks are a match for the transform. 7985 */ 7986function maybeCheckTransformIsMatch(transform, blocks) { 7987 if (typeof transform.isMatch !== 'function') { 7988 return true; 7989 } 7990 const sourceBlock = blocks[0]; 7991 const attributes = transform.isMultiBlock ? blocks.map(block => block.attributes) : sourceBlock.attributes; 7992 const block = transform.isMultiBlock ? blocks : sourceBlock; 7993 return transform.isMatch(attributes, block); 7994} 7995 7996/** 7997 * Switch one or more blocks into one or more blocks of the new block type. 7998 * 7999 * @param {Array|Object} blocks Blocks array or block object. 8000 * @param {string} name Block name. 8001 * 8002 * @return {?Array} Array of blocks or null. 8003 */ 8004function switchToBlockType(blocks, name) { 8005 const blocksArray = Array.isArray(blocks) ? blocks : [blocks]; 8006 const isMultiBlock = blocksArray.length > 1; 8007 const firstBlock = blocksArray[0]; 8008 const sourceName = firstBlock.name; 8009 8010 // Find the right transformation by giving priority to the "to" 8011 // transformation.
8012 const transformationsFrom = getBlockTransforms('from', name); 8013 const transformationsTo = getBlockTransforms('to', sourceName); 8014 const transformation = findTransform(transformationsTo, t => t.type === 'block' && (isWildcardBlockTransform(t) || t.blocks.indexOf(name) !== -1) && (!isMultiBlock || t.isMultiBlock) && maybeCheckTransformIsMatch(t, blocksArray)) || findTransform(transformationsFrom, t => t.type === 'block' && (isWildcardBlockTransform(t) || t.blocks.indexOf(sourceName) !== -1) && (!isMultiBlock || t.isMultiBlock) && maybeCheckTransformIsMatch(t, blocksArray)); 8015 8016 // Stop if there is no valid transformation. 8017 if (!transformation) { 8018 return null; 8019 } 8020 let transformationResults; 8021 if (transformation.isMultiBlock) { 8022 if ('__experimentalConvert' in transformation) { 8023 transformationResults = transformation.__experimentalConvert(blocksArray); 8024 } else { 8025 transformationResults = transformation.transform(blocksArray.map(currentBlock => currentBlock.attributes), blocksArray.map(currentBlock => currentBlock.innerBlocks)); 8026 } 8027 } else if ('__experimentalConvert' in transformation) { 8028 transformationResults = transformation.__experimentalConvert(firstBlock); 8029 } else { 8030 transformationResults = transformation.transform(firstBlock.attributes, firstBlock.innerBlocks); 8031 } 8032 8033 // Ensure that the transformation function returned an object or an array 8034 // of objects. 8035 if (transformationResults === null || typeof transformationResults !== 'object') { 8036 return null; 8037 } 8038 8039 // If the transformation function returned a single object, we want to work 8040 // with an array instead. 8041 transformationResults = Array.isArray(transformationResults) ? transformationResults : [transformationResults]; 8042 8043 // Ensure that every block object returned by the transformation has a 8044 // valid block type. 8045 if (transformationResults.some(result => !getBlockType(result.name))) { 8046 return null; 8047 } 8048 const hasSwitchedBlock = transformationResults.some(result => result.name === name); 8049 8050 // Ensure that at least one block object returned by the transformation has 8051 // the expected "destination" block type. 8052 if (!hasSwitchedBlock) { 8053 return null; 8054 } 8055 const ret = transformationResults.map((result, index, results) => { 8056 /** 8057 * Filters an individual transform result from block transformation. 8058 * All of the original blocks are passed, since transformations are 8059 * many-to-many, not one-to-one. 8060 * 8061 * @param {Object} transformedBlock The transformed block. 8062 * @param {Object[]} blocks Original blocks transformed. 8063 * @param {Object[]} index Index of the transformed block on the array of results. 8064 * @param {Object[]} results An array all the blocks that resulted from the transformation. 8065 */ 8066 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.switchToBlockType.transformedBlock', result, blocks, index, results); 8067 }); 8068 return ret; 8069} 8070 8071/** 8072 * Create a block object from the example API. 8073 * 8074 * @param {string} name 8075 * @param {Object} example 8076 * 8077 * @return {Object} block. 8078 */ 8079const getBlockFromExample = (name, example) => { 8080 var _example$innerBlocks; 8081 return createBlock(name, example.attributes, ((_example$innerBlocks = example.innerBlocks) !== null && _example$innerBlocks !== void 0 ? _example$innerBlocks : []).map(innerBlock => getBlockFromExample(innerBlock.name, innerBlock))); 8082}; 8083 8084;// CONCATENATED MODULE: ./packages/blocks/build-module/api/utils.js 8085/** 8086 * External dependencies 8087 */ 8088 8089 8090 8091 8092/** 8093 * WordPress dependencies 8094 */ 8095 8096 8097 8098 8099/** 8100 * Internal dependencies 8101 */ 8102 8103 8104 8105k([names, a11y]); 8106 8107/** 8108 * Array of icon colors containing a color to be used if the icon color 8109 * was not explicitly set but the icon background color was. 8110 * 8111 * @type {Object} 8112 */ 8113const ICON_COLORS = ['#191e23', '#f8f9f9']; 8114 8115/** 8116 * Determines whether the block's attributes are equal to the default attributes 8117 * which means the block is unmodified. 8118 * 8119 * @param {WPBlock} block Block Object 8120 * 8121 * @return {boolean} Whether the block is an unmodified block. 8122 */ 8123function isUnmodifiedBlock(block) { 8124 var _blockType$attributes; 8125 // Cache a created default block if no cache exists or the default block 8126 // name changed. 8127 if (!isUnmodifiedBlock[block.name]) { 8128 isUnmodifiedBlock[block.name] = createBlock(block.name); 8129 } 8130 const newBlock = isUnmodifiedBlock[block.name]; 8131 const blockType = getBlockType(block.name); 8132 return Object.keys((_blockType$attributes = blockType?.attributes) !== null && _blockType$attributes !== void 0 ? _blockType$attributes : {}).every(key => newBlock.attributes[key] === block.attributes[key]); 8133} 8134 8135/** 8136 * Determines whether the block is a default block and its attributes are equal 8137 * to the default attributes which means the block is unmodified. 8138 * 8139 * @param {WPBlock} block Block Object 8140 * 8141 * @return {boolean} Whether the block is an unmodified default block. 8142 */ 8143function isUnmodifiedDefaultBlock(block) { 8144 return block.name === getDefaultBlockName() && isUnmodifiedBlock(block); 8145} 8146 8147/**
8148 * Function that checks if the parameter is a valid icon. 8149 * 8150 * @param {*} icon Parameter to be checked. 8151 * 8152 * @return {boolean} True if the parameter is a valid icon and false otherwise. 8153 */ 8154 8155function isValidIcon(icon) { 8156 return !!icon && (typeof icon === 'string' || (0,external_wp_element_namespaceObject.isValidElement)(icon) || typeof icon === 'function' || icon instanceof external_wp_element_namespaceObject.Component); 8157} 8158 8159/** 8160 * Function that receives an icon as set by the blocks during the registration 8161 * and returns a new icon object that is normalized so we can rely on just on possible icon structure 8162 * in the codebase. 8163 * 8164 * @param {WPBlockTypeIconRender} icon Render behavior of a block type icon; 8165 * one of a Dashicon slug, an element, or a 8166 * component. 8167 * 8168 * @return {WPBlockTypeIconDescriptor} Object describing the icon. 8169 */ 8170function normalizeIconObject(icon) { 8171 icon = icon || BLOCK_ICON_DEFAULT; 8172 if (isValidIcon(icon)) { 8173 return { 8174 src: icon 8175 }; 8176 } 8177 if ('background' in icon) { 8178 const colordBgColor = w(icon.background); 8179 const getColorContrast = iconColor => colordBgColor.contrast(iconColor); 8180 const maxContrast = Math.max(...ICON_COLORS.map(getColorContrast)); 8181 return { 8182 ...icon, 8183 foreground: icon.foreground ? icon.foreground : ICON_COLORS.find(iconColor => getColorContrast(iconColor) === maxContrast), 8184 shadowColor: colordBgColor.alpha(0.3).toRgbString() 8185 }; 8186 } 8187 return icon; 8188} 8189 8190/** 8191 * Normalizes block type passed as param. When string is passed then 8192 * it converts it to the matching block type object. 8193 * It passes the original object otherwise. 8194 * 8195 * @param {string|Object} blockTypeOrName Block type or name. 8196 * 8197 * @return {?Object} Block type. 8198 */ 8199function normalizeBlockType(blockTypeOrName) { 8200 if (typeof blockTypeOrName === 'string') { 8201 return getBlockType(blockTypeOrName); 8202 } 8203 return blockTypeOrName; 8204} 8205 8206/** 8207 * Get the label for the block, usually this is either the block title, 8208 * or the value of the block's `label` function when that's specified. 8209 * 8210 * @param {Object} blockType The block type. 8211 * @param {Object} attributes The values of the block's attributes. 8212 * @param {Object} context The intended use for the label. 8213 * 8214 * @return {string} The block label. 8215 */ 8216function getBlockLabel(blockType, attributes, context = 'visual') { 8217 const { 8218 __experimentalLabel: getLabel, 8219 title 8220 } = blockType; 8221 const label = getLabel && getLabel(attributes, { 8222 context 8223 }); 8224 if (!label) { 8225 return title; 8226 } 8227 8228 // Strip any HTML (i.e. RichText formatting) before returning. 8229 return (0,external_wp_dom_namespaceObject.__unstableStripHTML)(label); 8230} 8231 8232/** 8233 * Get a label for the block for use by screenreaders, this is more descriptive 8234 * than the visual label and includes the block title and the value of the 8235 * `getLabel` function if it's specified. 8236 * 8237 * @param {?Object} blockType The block type. 8238 * @param {Object} attributes The values of the block's attributes. 8239 * @param {?number} position The position of the block in the block list. 8240 * @param {string} [direction='vertical'] The direction of the block layout. 8241 * 8242 * @return {string} The block label. 8243 */ 8244function getAccessibleBlockLabel(blockType, attributes, position, direction = 'vertical') { 8245 // `title` is already localized, `label` is a user-supplied value. 8246 const title = blockType?.title; 8247 const label = blockType ? getBlockLabel(blockType, attributes, 'accessibility') : ''; 8248 const hasPosition = position !== undefined; 8249 8250 // getBlockLabel returns the block title as a fallback when there's no label, 8251 // if it did return the title, this function needs to avoid adding the 8252 // title twice within the accessible label. Use this `hasLabel` boolean to 8253 // handle that. 8254 const hasLabel = label && label !== title; 8255 if (hasPosition && direction === 'vertical') { 8256 if (hasLabel) { 8257 return (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: accessibility text. 1: The block title. 2: The block row number. 3: The block label.. */ 8258 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. Row %2$d. %3$s'), title, position, label); 8259 } 8260 return (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: accessibility text. 1: The block title. 2: The block row number. */ 8261 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. Row %2$d'), title, position); 8262 } else if (hasPosition && direction === 'horizontal') { 8263 if (hasLabel) { 8264 return (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: accessibility text. 1: The block title. 2: The block column number. 3: The block label.. */ 8265 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. Column %2$d. %3$s'), title, position, label); 8266 } 8267 return (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: accessibility text. 1: The block title. 2: The block column number. */ 8268 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. Column %2$d'), title, position); 8269 } 8270 if (hasLabel) { 8271 return (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: accessibility text. %1: The block title. %2: The block label. */ 8272 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. %2$s'), title, label); 8273 } 8274 return (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: accessibility text. %s: The block title. */ 8275 (0,external_wp_i18n_namespaceObject.__)('%s Block'), title); 8276} 8277 8278/** 8279 * Ensure attributes contains only values defined by block type, and merge 8280 * default values for missing attributes. 8281 * 8282 * @param {string} name The block's name. 8283 * @param {Object} attributes The block's attributes. 8284 * @return {Object} The sanitized attributes. 8285 */ 8286function __experimentalSanitizeBlockAttributes(name, attributes) { 8287 // Get the type definition associated with a registered block. 8288 const blockType = getBlockType(name); 8289 if (undefined === blockType) { 8290 throw new Error(`Block type '${name}' is not registered.`); 8291 } 8292 return Object.entries(blockType.attributes).reduce((accumulator, [ke
8292y, schema]) => { 8293 const value = attributes[key]; 8294 if (undefined !== value) { 8295 accumulator[key] = value; 8296 } else if (schema.hasOwnProperty('default')) { 8297 accumulator[key] = schema.default; 8298 } 8299 if (['node', 'children'].indexOf(schema.source) !== -1) { 8300 // Ensure value passed is always an array, which we're expecting in 8301 // the RichText component to handle the deprecated value. 8302 if (typeof accumulator[key] === 'string') { 8303 accumulator[key] = [accumulator[key]]; 8304 } else if (!Array.isArray(accumulator[key])) { 8305 accumulator[key] = []; 8306 } 8307 } 8308 return accumulator; 8309 }, {}); 8310} 8311 8312/** 8313 * Filter block attributes by `role` and return their names. 8314 * 8315 * @param {string} name Block attribute's name. 8316 * @param {string} role The role of a block attribute. 8317 * 8318 * @return {string[]} The attribute names that have the provided role. 8319 */ 8320function __experimentalGetBlockAttributesNamesByRole(name, role) { 8321 const attributes = getBlockType(name)?.attributes; 8322 if (!attributes) return []; 8323 const attributesNames = Object.keys(attributes); 8324 if (!role) return attributesNames; 8325 return attributesNames.filter(attributeName => attributes[attributeName]?.__experimentalRole === role); 8326} 8327 8328/** 8329 * Return a new object with the specified keys omitted. 8330 * 8331 * @param {Object} object Original object. 8332 * @param {Array} keys Keys to be omitted. 8333 * 8334 * @return {Object} Object with omitted keys. 8335 */ 8336function omit(object, keys) { 8337 return Object.fromEntries(Object.entries(object).filter(([key]) => !keys.includes(key))); 8338} 8339 8340;// CONCATENATED MODULE: ./packages/blocks/build-module/store/reducer.js 8341/** 8342 * External dependencies 8343 */ 8344 8345 8346/** 8347 * WordPress dependencies 8348 */ 8349 8350 8351 8352/** 8353 * Internal dependencies 8354 */ 8355 8356 8357/** 8358 * @typedef {Object} WPBlockCategory 8359 * 8360 * @property {string} slug Unique category slug. 8361 * @property {string} title Category label, for display in user interface. 8362 */ 8363 8364/** 8365 * Default set of categories. 8366 * 8367 * @type {WPBlockCategory[]} 8368 */ 8369const DEFAULT_CATEGORIES = [{ 8370 slug: 'text', 8371 title: (0,external_wp_i18n_namespaceObject.__)('Text') 8372}, { 8373 slug: 'media', 8374 title: (0,external_wp_i18n_namespaceObject.__)('Media') 8375}, { 8376 slug: 'design', 8377 title: (0,external_wp_i18n_namespaceObject.__)('Design') 8378}, { 8379 slug: 'widgets', 8380 title: (0,external_wp_i18n_namespaceObject.__)('Widgets') 8381}, { 8382 slug: 'theme', 8383 title: (0,external_wp_i18n_namespaceObject.__)('Theme') 8384}, { 8385 slug: 'embed', 8386 title: (0,external_wp_i18n_namespaceObject.__)('Embeds') 8387}, { 8388 slug: 'reusable', 8389 title: (0,external_wp_i18n_namespaceObject.__)('Reusable blocks') 8390}]; 8391 8392// Key block types by their name. 8393function keyBlockTypesByName(types) { 8394 return types.reduce((newBlockTypes, block) => ({ 8395 ...newBlockTypes, 8396 [block.name]: block 8397 }), {}); 8398} 8399 8400// Filter items to ensure they're unique by their name. 8401function getUniqueItemsByName(items) { 8402 return items.reduce((acc, currentItem) => { 8403 if (!acc.some(item => item.name === currentItem.name)) { 8404 acc.push(currentItem); 8405 } 8406 return acc; 8407 }, []); 8408} 8409function bootstrappedBlockTypes(state = {}, action) { 8410 switch (action.type) { 8411 case 'ADD_BOOTSTRAPPED_BLOCK_TYPE': 8412 const { 8413 name, 8414 blockType 8415 } = action; 8416 const serverDefinition = state[name]; 8417 let newDefinition; 8418 // Don't overwrite if already set. It covers the case when metadata 8419 // was initialized from the server. 8420 if (serverDefinition) { 8421 // The `selectors` prop is not yet included in the server provided 8422 // definitions and needs to be polyfilled. This can be removed when the 8423 // minimum supported WordPress is >= 6.3. 8424 if (serverDefinition.selectors === undefined && blockType.selectors) { 8425 newDefinition = { 8426 ...serverDefinition, 8427 selectors: blockType.selectors 8428 }; 8429 } 8430 8431 // The `blockHooks` prop is not yet included in the server provided 8432 // definitions and needs to be polyfilled. This can be removed when the 8433 // minimum supported WordPress is >= 6.4. 8434 if (serverDefinition.blockHooks === undefined && blockType.blockHooks) { 8435 newDefinition = { 8436 ...serverDefinition, 8437 ...newDefinition, 8438 blockHooks: blockType.blockHooks 8439 }; 8440 } 8441 } else { 8442 newDefinition = Object.fromEntries(Object.entries(blockType).filter(([, value]) => value !== null && value !== undefined).map(([key, value]) => [camelCase(key), value])); 8443 newDefinition.name = name; 8444 } 8445 if (newDefinition) { 8446 return { 8447 ...state, 8448 [name]: newDefinition 8449 }; 8450 } 8451 return state; 8452 case 'REMOVE_BLOCK_TYPES': 8453 return omit(state, action.names); 8454 } 8455 return state; 8456} 8457 8458/** 8459 * Reducer managing the unprocessed block types in a form passed when registering the by block. 8460 * It's for internal use only. It allows recomputing the processed block types on-demand after block type filters 8461 * get added or removed. 8462 * 8463 * @param {Object} state Current state. 8464 * @param {Object}
8464 action Dispatched action. 8465 * 8466 * @return {Object} Updated state. 8467 */ 8468function unprocessedBlockTypes(state = {}, action) { 8469 switch (action.type) { 8470 case 'ADD_UNPROCESSED_BLOCK_TYPE': 8471 return { 8472 ...state, 8473 [action.name]: action.blockType 8474 }; 8475 case 'REMOVE_BLOCK_TYPES': 8476 return omit(state, action.names); 8477 } 8478 return state; 8479} 8480 8481/** 8482 * Reducer managing the processed block types with all filters applied. 8483 * The state is derived from the `unprocessedBlockTypes` reducer. 8484 * 8485 * @param {Object} state Current state. 8486 * @param {Object} action Dispatched action. 8487 * 8488 * @return {Object} Updated state. 8489 */ 8490function blockTypes(state = {}, action) { 8491 switch (action.type) { 8492 case 'ADD_BLOCK_TYPES': 8493 return { 8494 ...state, 8495 ...keyBlockTypesByName(action.blockTypes) 8496 }; 8497 case 'REMOVE_BLOCK_TYPES': 8498 return omit(state, action.names); 8499 } 8500 return state; 8501} 8502 8503/** 8504 * Reducer managing the block styles. 8505 * 8506 * @param {Object} state Current state. 8507 * @param {Object} action Dispatched action. 8508 * 8509 * @return {Object} Updated state. 8510 */ 8511function blockStyles(state = {}, action) { 8512 var _state$action$blockNa, _state$action$blockNa2; 8513 switch (action.type) { 8514 case 'ADD_BLOCK_TYPES': 8515 return { 8516 ...state, 8517 ...Object.fromEntries(Object.entries(keyBlockTypesByName(action.blockTypes)).map(([name, blockType]) => { 8518 var _blockType$styles, _state$blockType$name; 8519 return [name, getUniqueItemsByName([...((_blockType$styles = blockType.styles) !== null && _blockType$styles !== void 0 ? _blockType$styles : []).map(style => ({ 8520 ...style, 8521 source: 'block' 8522 }
8522)), ...((_state$blockType$name = state[blockType.name]) !== null && _state$blockType$name !== void 0 ? _state$blockType$name : []).filter(({ 8523 source 8524 }) => 'block' !== source)])]; 8525 })) 8526 }; 8527 case 'ADD_BLOCK_STYLES': 8528 return { 8529 ...state, 8530 [action.blockName]: getUniqueItemsByName([...((_state$action$blockNa = state[action.blockName]) !== null && _state$action$blockNa !== void 0 ? _state$action$blockNa : []), ...action.styles]) 8531 }; 8532 case 'REMOVE_BLOCK_STYLES': 8533 return { 8534 ...state, 8535 [action.blockName]: ((_state$action$blockNa2 = state[action.blockName]) !== null && _state$action$blockNa2 !== void 0 ? _state$action$blockNa2 : []).filter(style => action.styleNames.indexOf(style.name) === -1) 8536 }; 8537 } 8538 return state; 8539} 8540 8541/** 8542 * Reducer managing the block variations. 8543 * 8544 * @param {Object} state Current state. 8545 * @param {Object} action Dispatched action. 8546 * 8547 * @return {Object} Updated state. 8548 */ 8549function blockVariations(state = {}, action) { 8550 var _state$action$blockNa3, _state$action$blockNa4; 8551 switch (action.type) { 8552 case 'ADD_BLOCK_TYPES': 8553 return { 8554 ...state, 8555 ...Object.fromEntries(Object.entries(keyBlockTypesByName(action.blockTypes)).map(([name, blockType]) => { 8556 var _blockType$variations, _state$blockType$name2; 8557 return [name, getUniqueItemsByName([...((_blockType$variations = blockType.variations) !== null && _blockType$variations !== void 0 ? _blockType$variations : []).map(variation => ({ 8558 ...variation, 8559 source: 'block' 8560 }
8560)), ...((_state$blockType$name2 = state[blockType.name]) !== null && _state$blockType$name2 !== void 0 ? _state$blockType$name2 : []).filter(({ 8561 source 8562 }) => 'block' !== source)])]; 8563 })) 8564 }; 8565 case 'ADD_BLOCK_VARIATIONS': 8566 return { 8567 ...state, 8568 [action.blockName]: getUniqueItemsByName([...((_state$action$blockNa3 = state[action.blockName]) !== null && _state$action$blockNa3 !== void 0 ? _state$action$blockNa3 : []), ...action.variations]) 8569 }; 8570 case 'REMOVE_BLOCK_VARIATIONS': 8571 return { 8572 ...state, 8573 [action.blockName]: ((_state$action$blockNa4 = state[action.blockName]) !== null && _state$action$blockNa4 !== void 0 ? _state$action$blockNa4 : []).filter(variation => action.variationNames.indexOf(variation.name) === -1) 8574 }; 8575 } 8576 return state; 8577} 8578 8579/** 8580 * Higher-order Reducer creating a reducer keeping track of given block name. 8581 * 8582 * @param {string} setActionType Action type. 8583 * 8584 * @return {Function} Reducer. 8585 */ 8586function createBlockNameSetterReducer(setActionType) { 8587 return (state = null, action) => { 8588 switch (action.type) { 8589 case 'REMOVE_BLOCK_TYPES': 8590 if (action.names.indexOf(state) !== -1) { 8591 return null; 8592 } 8593 return state; 8594 case setActionType: 8595 return action.name || null; 8596 } 8597 return state; 8598 }; 8599} 8600const defaultBlockName = createBlockNameSetterReducer('SET_DEFAULT_BLOCK_NAME'); 8601const freeformFallbackBlockName = createBlockNameSetterReducer('SET_FREEFORM_FALLBACK_BLOCK_NAME'); 8602const unregisteredFallbackBlockName = createBlockNameSetterReducer('SET_UNREGISTERED_FALLBACK_BLOCK_NAME'); 8603const groupingBlockName = createBlockNameSetterReducer('SET_GROUPING_BLOCK_NAME'); 8604 8605/** 8606 * Reducer managing the categories 8607 * 8608 * @param {WPBlockCategory[]} state Current state. 8609 * @param {Object} action Dispatched action. 8610 * 8611 * @return {WPBlockCategory[]} Updated state. 8612 */ 8613function categories(state = DEFAULT_CATEGORIES, action) { 8614 switch (action.type) { 8615 case 'SET_CATEGORIES': 8616 return action.categories || []; 8617 case 'UPDATE_CATEGORY': 8618 { 8619 if (!action.category || !Object.keys(action.category).length) { 8620 return state; 8621 } 8622 const categoryToChange = state.find(({ 8623 slug 8624 }) => slug === action.slug); 8625 if (categoryToChange) { 8626 return state.map(category => { 8627 if (category.slug === action.slug) { 8628 return { 8629 ...category, 8630 ...action.category 8631 }; 8632 } 8633 return category; 8634 }); 8635 } 8636 } 8637 } 8638 return state; 8639} 8640function collections(state = {}, action) { 8641 switch (action.type) { 8642 case 'ADD_BLOCK_COLLECTION': 8643 return { 8644 ...state, 8645 [action.namespace]: { 8646 title: action.title, 8647 icon: action.icon 8648 } 8649 }; 8650 case 'REMOVE_BLOCK_COLLECTION': 8651 return omit(state, action.namespace); 8652 } 8653 return state; 8654} 8655/* harmony default export */ const reducer = ((0,external_wp_data_namespaceObject.combineReducers)({ 8656 bootstrappedBlockTypes, 8657 unprocessedBlockTypes, 8658 blockTypes, 8659 blockStyles, 8660 blockVariations, 8661 defaultBlockName, 8662 freeformFallbackBlockName, 8663 unregisteredFallbackBlockName, 8664 groupingBlockName, 8665 categories, 8666 collections 8667})); 8668 8669;// CONCATENATED MODULE: ./node_modules/rememo/rememo.js 8670 8671 8672/** @typedef {(...args: any[]) => *[]} GetDependants */ 8673 8674/** @typedef {() => void} Clear */ 8675 8676/** 8677 * @typedef {{ 8678 * getDependants: GetDependants, 8679 * clear: Clear 8680 * }} EnhancedSelector 8681 */ 8682 8683/** 8684 * Internal cache entry. 8685 * 8686 * @typedef CacheNode 8687 * 8688 * @property {?CacheNode|undefined} [prev] Previous node. 8689 * @property {?CacheNode|undefined} [next] Next node. 8690 * @property {*[]} args Function arguments for cache entry. 8691 * @property {*} val Function result. 8692 */ 8693 8694/** 8695 * @typedef Cache 8696 * 8697 * @property {Clear} clear Function to clear cache. 8698 * @property {boolean} [isUniqueByDependants] Whether dependants are valid in 8699 * considering cache uniqueness. A cache is unique if dependents are all arrays 8700 * or objects. 8701 * @property {CacheNode?} [head] Cache head. 8702 * @property {*[]} [lastDependants] Dependants from previous invocation. 8703 */ 8704 8705/** 8706 * Arbitrary value used as key for referencing cache object in WeakMap tree. 8707 * 8708 * @type {{}} 8709 */ 8710var LEAF_KEY = {}; 8711 8712/** 8713 * Returns the first argument as the sole entry in an array.
8714 * 8715 * @template T 8716 * 8717 * @param {T} value Value to return. 8718 * 8719 * @return {[T]} Value returned as entry in array. 8720 */ 8721function arrayOf(value) { 8722 return [value]; 8723} 8724 8725/** 8726 * Returns true if the value passed is object-like, or false otherwise. A value 8727 * is object-like if it can support property assignment, e.g. object or array. 8728 * 8729 * @param {*} value Value to test. 8730 * 8731 * @return {boolean} Whether value is object-like. 8732 */ 8733function isObjectLike(value) { 8734 return !!value && 'object' === typeof value; 8735} 8736 8737/** 8738 * Creates and returns a new cache object. 8739 * 8740 * @return {Cache} Cache object. 8741 */ 8742function createCache() { 8743 /** @type {Cache} */ 8744 var cache = { 8745 clear: function () { 8746 cache.head = null; 8747 }, 8748 }; 8749 8750 return cache; 8751} 8752 8753/** 8754 * Returns true if entries within the two arrays are strictly equal by 8755 * reference from a starting index. 8756 * 8757 * @param {*[]} a First array. 8758 * @param {*[]} b Second array. 8759 * @param {number} fromIndex Index from which to start comparison. 8760 * 8761 * @return {boolean} Whether arrays are shallowly equal. 8762 */ 8763function isShallowEqual(a, b, fromIndex) { 8764 var i; 8765 8766 if (a.length !== b.length) { 8767 return false; 8768 } 8769 8770 for (i = fromIndex; i < a.length; i++) { 8771 if (a[i] !== b[i]) { 8772 return false; 8773 } 8774 } 8775 8776 return true; 8777} 8778 8779/** 8780 * Returns a memoized selector function. The getDependants function argument is 8781 * called before the memoized selector and is expected to return an immutable 8782 * reference or array of references on which the selector depends for computing 8783 * its own return value. The memoize cache is preserved only as long as those 8784 * dependant references remain the same. If getDependants returns a different 8785 * reference(s), the cache is cleared and the selector value regenerated. 8786 * 8787 * @template {(...args: *[]) => *} S 8788 * 8789 * @param {S} selector Selector function. 8790 * @param {GetDependants=} getDependants Dependant getter returning an array of 8791 * references used in cache bust consideration. 8792 */ 8793/* harmony default export */ function rememo(selector, getDependants) { 8794 /** @type {WeakMap<*,*>} */ 8795 var rootCache; 8796 8797 /** @type {GetDependants} */ 8798 var normalizedGetDependants = getDependants ? getDependants : arrayOf; 8799 8800 /** 8801 * Returns the cache for a given dependants array. When possible, a WeakMap 8802 * will be used to create a unique cache for each set of dependants. This 8803 * is feasible due to the nature of WeakMap in allowing garbage collection 8804 * to occur on entries where the key object is no longer referenced. Since 8805 * WeakMap requires the key to be an object, this is only possible when the 8806 * dependant is object-like. The root cache is created as a hierarchy where 8807 * each top-level key is the first entry in a dependants set, the value a 8808 * WeakMap where each key is the next dependant, and so on. This continues 8809 * so long as the dependants are object-like. If no dependants are object- 8810 * like, then the cache is shared across all invocations. 8811 * 8812 * @see isObjectLike 8813 * 8814 * @param {*[]}
8814 dependants Selector dependants. 8815 * 8816 * @return {Cache} Cache object. 8817 */ 8818 function getCache(dependants) { 8819 var caches = rootCache, 8820 isUniqueByDependants = true, 8821 i, 8822 dependant, 8823 map, 8824 cache; 8825 8826 for (i = 0; i < dependants.length; i++) { 8827 dependant = dependants[i]; 8828 8829 // Can only compose WeakMap from object-like key. 8830 if (!isObjectLike(dependant)) { 8831 isUniqueByDependants = false; 8832 break; 8833 } 8834 8835 // Does current segment of cache already have a WeakMap? 8836 if (caches.has(dependant)) { 8837 // Traverse into nested WeakMap. 8838 caches = caches.get(dependant); 8839 } else { 8840 // Create, set, and traverse into a new one. 8841 map = new WeakMap(); 8842 caches.set(dependant, map); 8843 caches = map; 8844 } 8845 } 8846 8847 // We use an arbitrary (but consistent) object as key for the last item 8848 // in the WeakMap to serve as our running cache. 8849 if (!caches.has(LEAF_KEY)) { 8850 cache = createCache(); 8851 cache.isUniqueByDependants = isUniqueByDependants; 8852 caches.set(LEAF_KEY, cache); 8853 } 8854 8855 return caches.get(LEAF_KEY); 8856 } 8857 8858 /** 8859 * Resets root memoization cache. 8860 */ 8861 function clear() { 8862 rootCache = new WeakMap(); 8863 } 8864 8865 /* eslint-disable jsdoc/check-param-names */ 8866 /** 8867 * The augmented selector call, considering first whether dependants have 8868 * changed before passing it to underlying memoize function. 8869 * 8870 * @param {*} source Source object for derivation. 8871 * @param {...*} extraArgs Additional arguments to pass to selector. 8872 * 8873 * @return {*} Selector result. 8874 */ 8875 /* eslint-enable jsdoc/check-param-names */ 8876 function callSelector(/* source, ...extraArgs */) { 8877 var len = arguments.length, 8878 cache, 8879 node, 8880 i, 8881 args, 8882 dependants; 8883 8884 // Create copy of arguments (avoid leaking deoptimization). 8885 args = new Array(len); 8886 for (i = 0; i < len; i++) { 8887 args[i] = arguments[i]; 8888 } 8889 8890 dependants = normalizedGetDependants.apply(null, args); 8891 cache = getCache(dependants); 8892 8893 // If not guaranteed uniqueness by dependants (primitive type), shallow 8894 // compare against last dependants and, if references have changed, 8895 // destroy cache to recalculate result. 8896 if (!cache.isUniqueByDependants) { 8897 if ( 8898 cache.lastDependants && 8899 !isShallowEqual(dependants, cache.lastDependants, 0) 8900 ) { 8901 cache.clear(); 8902 } 8903 8904 cache.lastDependants = dependants; 8905 } 8906 8907 node = cache.head; 8908 while (node) { 8909 // Check whether node arguments match arguments 8910 if (!isShallowEqual(node.args, args, 1)) { 8911 node = node.next; 8912 continue; 8913 } 8914 8915 // At this point we can assume we've found a match 8916 8917 // Surface matched node to head if not already 8918 if (node !== cache.head) { 8919 // Adjust siblings to point to each other. 8920 /** @type {CacheNode} */ (node.prev).next = node.next; 8921 if (node.next) { 8922 node.next.prev = node.prev; 8923 } 8924 8925 node.next = cache.head; 8926 node.prev = null; 8927 /** @type {CacheNode} */ (cache.head).prev = node; 8928 cache.head = node; 8929 } 8930 8931 // Return immediately 8932 return node.val; 8933 } 8934 8935 // No cached value found. Continue to insertion phase: 8936 8937 node = /** @type {CacheNode} */ ({ 8938 // Generate the result from original function 8939 val: selector.apply(null, args), 8940 }); 8941 8942 // Avoid including the source object in the cache. 8943 args[0] = null; 8944 node.args = args; 8945 8946 // Don't need to check whether node is already head, since it would 8947 // have been returned above already if it was 8948 8949 // Shift existing head down list 8950 if (cache.head) { 8951 cache.head.prev = node; 8952 node.next = cache.head; 8953 } 8954 8955 cache.head = node; 8956 8957 return node.val; 8958 } 8959 8960 callSelector.getDependants = normalizedGetDependants; 8961 callSelector.clear = clear; 8962 clear(); 8963 8964 return /** @type {S & EnhancedSelector} */ (callSelector); 8965} 8966 8967// EXTERNAL MODULE: ./node_modules/remove-accents/index.js 8968var remove_accents = __webpack_require__(4793); 8969var remove_accents_default = /*#__PURE__*/__webpack_require__.n(remove_accents); 8970;// CONCATENATED MODULE: external ["wp","compose"] 8971const external_wp_compose_namespaceObject = window["wp"]["compose"]; 8972;// CONCATENATED MODULE: ./packages/blocks/build-module/store/utils.js 8973/** 8974 * Helper util to return a value from a certain path of the object. 8975 * Path is specified as either: 8976 * - a string of properties, separated by dots, for example: "x.y". 8977 * - an array of properties, for example `[ 'x', 'y' ]`. 8978 * You can also specify a default value in case the result is nullish. 8979 * 8980 * @param {Object} object Input object. 8981 * @param {string|Array} path Path to the object property. 8982 * @param {*} defaultValue Default value if the value at the specified path is nullish. 8983 * @return {*} Value of the object property at the specified path. 8984 */ 8985const getValueFromObjectPath = (object, path, defaultValue) => { 8986 var _value; 8987 const normalizedPath = Array.isArray(path) ? path : path.split('.'); 8988 let value = object; 8989 normalizedPath.forEach(fieldName => { 8990 value = value?.[fieldName]; 8991 }); 8992 return (_value = value) !== null && _value !== void 0 ? _value : defaultValue; 8993}; 8994 8995;// CONCATENATED MODULE: ./packages/blocks/build-module/store/selectors.js 8996/** 8997 * External dependencies 8998 */ 8999 9000 9001 9002/** 9003 * WordPress dependencies 9004 */ 9005 9006 9007/** 9008 * Internal dependencies 9009 */ 9010 9011 9012/** @typedef {import('../api/registration').WPBlockVariation} WPBlockVariation */ 9013/** @typedef {import('../api/registration').WPBlockVariationScope} WPBlockVariationScope */ 9014/** @typedef {import('./reducer').WPBlockCategory} WPBlockCategory */ 9015 9016/** 9017 * Given a block name or block type object, returns the corresponding 9018 * normalized block type object. 9019 * 9020 * @param {Object} state Blocks state. 9021 * @param {(string|Object)} nameOrType Block name or type object 9022 * 9023 * @return {Object} Block type object. 9024 */ 9025const getNormalizedBlockType = (state, nameOrType) => 'string' === typeof nameOrType ? selectors_getBlockType(state, nameOrType) : nameOrType; 9026 9027/** 9028 * Returns all the available block types. 9029 * 9030 * @param {Object} state Data state. 9031 * 9032 * @example 9033 * ```js 9034 * import { store as blocksStore } from '@wordpress/blocks';
9035 * import { useSelect } from '@wordpress/data'; 9036 * 9037 * const ExampleComponent = () => { 9038 * const blockTypes = useSelect( 9039 * ( select ) => select( blocksStore ).getBlockTypes(), 9040 * [] 9041 * ); 9042 * 9043 * return ( 9044 * <ul> 9045 * { blockTypes.map( ( block ) => ( 9046 * <li key={ block.name }>{ block.title }</li> 9047 * ) ) } 9048 * </ul> 9049 * ); 9050 * }; 9051 * ``` 9052 * 9053 * @return {Array} Block Types. 9054 */ 9055const selectors_getBlockTypes = rememo(state => Object.values(state.blockTypes), state => [state.blockTypes]); 9056 9057/** 9058 * Returns a block type by name. 9059 * 9060 * @param {Object} state Data state. 9061 * @param {string} name Block type name. 9062 * 9063 * @example 9064 * ```js 9065 * import { store as blocksStore } from '@wordpress/blocks'; 9066 * import { useSelect } from '@wordpress/data'; 9067 * 9068 * const ExampleComponent = () => { 9069 * const paragraphBlock = useSelect( ( select ) => 9070 * ( select ) => select( blocksStore ).getBlockType( 'core/paragraph' ), 9071 * [] 9072 * ); 9073 * 9074 * return ( 9075 * <ul> 9076 * { paragraphBlock && 9077 * Object.entries( paragraphBlock.supports ).map( 9078 * ( blockSupportsEntry ) => { 9079 * const [ propertyName, value ] = blockSupportsEntry; 9080 * return ( 9081 * <li 9082 * key={ propertyName } 9083 * >{ `${ propertyName } : ${ value }` }</li> 9084 * ); 9085 * } 9086 * ) } 9087 * </ul> 9088 * ); 9089 * }; 9090 * ``` 9091 * 9092 * @return {Object?} Block Type. 9093 */ 9094function selectors_getBlockType(state, name) { 9095 return state.blockTypes[name]; 9096} 9097 9098/** 9099 * Returns block styles by block name. 9100 * 9101 * @param {Object} state Data state. 9102 * @param {string} name Block type name. 9103 * 9104 * @example 9105 * ```js 9106 * import { store as blocksStore } from '@wordpress/blocks'; 9107 * import { useSelect } from '@wordpress/data'; 9108 * 9109 * const ExampleComponent = () => { 9110 * const buttonBlockStyles = useSelect( ( select ) => 9111 * select( blocksStore ).getBlockStyles( 'core/button' ), 9112 * [] 9113 * ); 9114 * 9115 * return ( 9116 * <ul> 9117 * { buttonBlockStyles && 9118 * buttonBlockStyles.map( ( style ) => ( 9119 * <li key={ style.name }>{ style.label }</li> 9120 * ) ) } 9121 * </ul> 9122 * ); 9123 * }; 9124 * ``` 9125 * 9126 * @return {Array?} Block Styles. 9127 */ 9128function getBlockStyles(state, name) { 9129 return state.blockStyles[name]; 9130} 9131 9132/** 9133 * Returns block variations by block name. 9134 * 9135 * @param {Object} state Data state. 9136 * @param {string} blockName Block type name. 9137 * @param {WPBlockVariationScope} [scope] Block variation scope name. 9138 * 9139 * @example 9140 * ```js 9141 * import { store as blocksStore } from '@wordpress/blocks'; 9142 * import { useSelect } from '@wordpress/data'; 9143 * 9144 * const ExampleComponent = () => { 9145 * const socialLinkVariations = useSelect( ( select ) => 9146 * select( blocksStore ).getBlockVariations( 'core/social-link' ), 9147 * [] 9148 * ); 9149 * 9150 * return ( 9151 * <ul> 9152 * { socialLinkVariations && 9153 * socialLinkVariations.map( ( variation ) => ( 9154 * <li key={ variation.name }>{ variation.title }</li> 9155 * ) ) } 9156 * </ul> 9157 * ); 9158 * }; 9159 * ``` 9160 * 9161 * @return {(WPBlockVariation[]|void)} Block variations. 9162 */ 9163const selectors_getBlockVariations = rememo((state, blockName, scope) => { 9164 const variations = state.blockVariations[blockName]; 9165 if (!variations || !scope) { 9166 return variations; 9167 } 9168 return variations.filter(variation => { 9169 // For backward compatibility reasons, variation's scope defaults to 9170 // `block` and `inserter` when not set. 9171 return (variation.scope || ['block', 'inserter']).includes(scope); 9172 }); 9173}, (state, blockName) => [state.blockVariations[blockName]]); 9174 9175/** 9176 * Returns the active block variation for a given block based on its attributes. 9177 * Variations are determined by their `isActive` property. 9178 * Which is either an array of block attribute keys or a function. 9179 * 9180 * In case of an array of block attribute keys, the `attributes` are compared 9181 * to the variation's attributes using strict equality check. 9182 * 9183 * In case of function type, the function should accept a block's attributes 9184 * and the variation's attributes and determines if a variation is active. 9185 * A function that accepts a block's attributes and the variation's attributes and determines if a variation is active. 9186 * 9187 * @param {Object} state Data state. 9188 * @param {string} blockName Name of block (example: âcore/columnsâ). 9189 * @param {Object} attributes Block attributes used to determine active variation. 9190 * @param {WPBlockVariationScope} [scope] Block variation scope name. 9191 * 9192 * @example 9193 * ```js 9194 * import { __ } from '@wordpress/i18n'; 9195 * import { store as blocksStore } from '@wordpress/blocks'; 9196 * import { store as blockEditorStore } from '@wordpress/block-editor';
9197 * import { useSelect } from '@wordpress/data'; 9198 * 9199 * const ExampleComponent = () => { 9200 * // This example assumes that a core/embed block is the first block in the Block Editor. 9201 * const activeBlockVariation = useSelect( ( select ) => { 9202 * // Retrieve the list of blocks. 9203 * const [ firstBlock ] = select( blockEditorStore ).getBlocks() 9204 * 9205 * // Return the active block variation for the first block. 9206 * return select( blocksStore ).getActiveBlockVariation( 9207 * firstBlock.name, 9208 * firstBlock.attributes 9209 * ); 9210 * }, [] ); 9211 * 9212 * return activeBlockVariation && activeBlockVariation.name === 'spotify' ? ( 9213 * <p>{ __( 'Spotify variation' ) }</p> 9214 * ) : ( 9215 * <p>{ __( 'Other variation' ) }</p> 9216 * ); 9217 * }; 9218 * ``` 9219 * 9220 * @return {(WPBlockVariation|undefined)} Active block variation. 9221 */ 9222function getActiveBlockVariation(state, blockName, attributes, scope) { 9223 const variations = selectors_getBlockVariations(state, blockName, scope); 9224 const match = variations?.find(variation => { 9225 if (Array.isArray(variation.isActive)) { 9226 const blockType = selectors_getBlockType(state, blockName); 9227 const attributeKeys = Object.keys(blockType?.attributes || {}); 9228 const definedAttributes = variation.isActive.filter(attribute => attributeKeys.includes(attribute)); 9229 if (definedAttributes.length === 0) { 9230 return false; 9231 } 9232 return definedAttributes.every(attribute => attributes[attribute] === variation.attributes[attribute]); 9233 } 9234 return variation.isActive?.(attributes, variation.attributes); 9235 }); 9236 return match; 9237} 9238 9239/** 9240 * Returns the default block variation for the given block type. 9241 * When there are multiple variations annotated as the default one, 9242 * the last added item is picked. This simplifies registering overrides. 9243 * When there is no default variation set, it returns the first item. 9244 * 9245 * @param {Object} state Data state. 9246 * @param {string} blockName Block type name. 9247 * @param {WPBlockVariationScope} [scope] Block variation scope name. 9248 * 9249 * @example 9250 * ```js 9251 * import { __, sprintf } from '@wordpress/i18n'; 9252 * import { store as blocksStore } from '@wordpress/blocks'; 9253 * import { useSelect } from '@wordpress/data'; 9254 * 9255 * const ExampleComponent = () => { 9256 * const defaultEmbedBlockVariation = useSelect( ( select ) => 9257 * select( blocksStore ).getDefaultBlockVariation( 'core/embed' ), 9258 * [] 9259 * ); 9260 * 9261 * return ( 9262 * defaultEmbedBlockVariation && ( 9263 * <p> 9264 * { sprintf( 9265 * __( 'core/embed default variation: %s' ), 9266 * defaultEmbedBlockVariation.title 9267 * ) } 9268 * </p> 9269 * ) 9270 * ); 9271 * }; 9272 * ``` 9273 * 9274 * @return {?WPBlockVariation} The default block variation. 9275 */ 9276function getDefaultBlockVariation(state, blockName, scope) { 9277 const variations = selectors_getBlockVariations(state, blockName, scope); 9278 const defaultVariation = [...variations].reverse().find(({ 9279 isDefault 9280 }) => !!isDefault); 9281 return defaultVariation || variations[0]; 9282} 9283 9284/** 9285 * Returns all the available block categories. 9286 * 9287 * @param {Object} state Data state. 9288 * 9289 * @example 9290 * ```js 9291 * import { store as blocksStore } from '@wordpress/blocks'; 9292 * import { useSelect, } from '@wordpress/data'; 9293 * 9294 * const ExampleComponent = () => { 9295 * const blockCategories = useSelect( ( select ) => 9296 * select( blocksStore ).getCategories(), 9297 * [] 9298 * ); 9299 * 9300 * return ( 9301 * <ul> 9302 * { blockCategories.map( ( category ) => ( 9303 * <li key={ category.slug }>{ category.title }</li> 9304 * ) ) } 9305 * </ul> 9306 * ); 9307 * }; 9308 * ``` 9309 * 9310 * @return {WPBlockCategory[]} Categories list. 9311 */ 9312function getCategories(state) { 9313 return state.categories; 9314} 9315 9316/** 9317 * Returns all the available collections. 9318 * 9319 * @param {Object} state Data state. 9320 * 9321 * @example 9322 * ```js 9323 * import { store as blocksStore } from '@wordpress/blocks'; 9324 * import { useSelect } from '@wordpress/data'; 9325 *
9326 * const ExampleComponent = () => { 9327 * const blockCollections = useSelect( ( select ) => 9328 * select( blocksStore ).getCollections(), 9329 * [] 9330 * ); 9331 * 9332 * return ( 9333 * <ul> 9334 * { Object.values( blockCollections ).length > 0 && 9335 * Object.values( blockCollections ).map( ( collection ) => ( 9336 * <li key={ collection.title }>{ collection.title }</li> 9337 * ) ) } 9338 * </ul> 9339 * ); 9340 * }; 9341 * ``` 9342 * 9343 * @return {Object} Collections list. 9344 */ 9345function getCollections(state) { 9346 return state.collections; 9347} 9348 9349/** 9350 * Returns the name of the default block name. 9351 * 9352 * @param {Object} state Data state. 9353 * 9354 * @example 9355 * ```js 9356 * import { __, sprintf } from '@wordpress/i18n'; 9357 * import { store as blocksStore } from '@wordpress/blocks'; 9358 * import { useSelect } from '@wordpress/data'; 9359 * 9360 * const ExampleComponent = () => { 9361 * const defaultBlockName = useSelect( ( select ) => 9362 * select( blocksStore ).getDefaultBlockName(), 9363 * [] 9364 * ); 9365 * 9366 * return ( 9367 * defaultBlockName && ( 9368 * <p> 9369 * { sprintf( __( 'Default block name: %s' ), defaultBlockName ) } 9370 * </p> 9371 * ) 9372 * ); 9373 * }; 9374 * ``` 9375 * 9376 * @return {string?} Default block name. 9377 */ 9378function selectors_getDefaultBlockName(state) { 9379 return state.defaultBlockName; 9380} 9381 9382/** 9383 * Returns the name of the block for handling non-block content. 9384 * 9385 * @param {Object} state Data state. 9386 * 9387 * @example 9388 * ```js 9389 * import { __, sprintf } from '@wordpress/i18n'; 9390 * import { store as blocksStore } from '@wordpress/blocks'; 9391 * import { useSelect } from '@wordpress/data'; 9392 * 9393 * const ExampleComponent = () => { 9394 * const freeformFallbackBlockName = useSelect( ( select ) => 9395 * select( blocksStore ).getFreeformFallbackBlockName(), 9396 * [] 9397 * ); 9398 * 9399 * return ( 9400 * freeformFallbackBlockName && ( 9401 * <p> 9402 * { sprintf( __( 9403 * 'Freeform fallback block name: %s' ), 9404 * freeformFallbackBlockName 9405 * ) } 9406 * </p> 9407 * ) 9408 * ); 9409 * }; 9410 * ``` 9411 * 9412 * @return {string?} Name of the block for handling non-block content. 9413 */ 9414function getFreeformFallbackBlockName(state) { 9415 return state.freeformFallbackBlockName; 9416} 9417 9418/** 9419 * Returns the name of the block for handling unregistered blocks. 9420 * 9421 * @param {Object} state Data state. 9422 * 9423 * @example 9424 * ```js 9425 * import { __, sprintf } from '@wordpress/i18n'; 9426 * import { store as blocksStore } from '@wordpress/blocks'; 9427 * import { useSelect } from '@wordpress/data'; 9428 * 9429 * const ExampleComponent = () => { 9430 * const unregisteredFallbackBlockName = useSelect( ( select ) => 9431 * select( blocksStore ).getUnregisteredFallbackBlockName(), 9432 * [] 9433 * ); 9434 * 9435 * return ( 9436 * unregisteredFallbackBlockName && ( 9437 * <p> 9438 * { sprintf( __( 9439 * 'Unregistered fallback block name: %s' ), 9440 * unregisteredFallbackBlockName 9441 * ) } 9442 * </p> 9443 * ) 9444 * ); 9445 * }; 9446 * ``` 9447 * 9448 * @return {string?} Name of the block for handling unregistered blocks. 9449 */ 9450function getUnregisteredFallbackBlockName(state) { 9451 return state.unregisteredFallbackBlockName; 9452} 9453 9454/** 9455 * Returns the name of the block for handling the grouping of blocks. 9456 * 9457 * @param {Object} state Data state. 9458 * 9459 * @example 9460 * ```js 9461 * import { __, sprintf } from '@wordpress/i18n'; 9462 * import { store as blocksStore } from '@wordpress/blocks'; 9463 * import { useSelect } from '@wordpress/data'; 9464 * 9465 * const ExampleComponent = () => { 9466 * const groupingBlockName = useSelect( ( select ) => 9467 * select( blocksStore ).getGroupingBlockName(), 9468 * [] 9469 * ); 9470 * 9471 * return ( 9472 * groupingBlockName && ( 9473 * <p> 9474 * { sprintf( 9475 * __( 'Default grouping block name: %s' ), 9476 * groupingBlockName 9477 * ) } 9478 * </p> 9479 * ) 9480 * ); 9481 * }; 9482 * ``` 9483 * 9484 * @return {string?} Name of the block for handling the grouping of blocks. 9485 */ 9486function selectors_getGroupingBlockName(state) { 9487 return state.groupingBlockName; 9488} 9489
9490/** 9491 * Returns an array with the child blocks of a given block. 9492 * 9493 * @param {Object} state Data state. 9494 * @param {string} blockName Block type name. 9495 * 9496 * @example 9497 * ```js 9498 * import { store as blocksStore } from '@wordpress/blocks'; 9499 * import { useSelect } from '@wordpress/data'; 9500 * 9501 * const ExampleComponent = () => { 9502 * const childBlockNames = useSelect( ( select ) => 9503 * select( blocksStore ).getChildBlockNames( 'core/navigation' ), 9504 * [] 9505 * ); 9506 * 9507 * return ( 9508 * <ul> 9509 * { childBlockNames && 9510 * childBlockNames.map( ( child ) => ( 9511 * <li key={ child }>{ child }</li> 9512 * ) ) } 9513 * </ul> 9514 * ); 9515 * }; 9516 * ``` 9517 * 9518 * @return {Array} Array of child block names. 9519 */ 9520const selectors_getChildBlockNames = rememo((state, blockName) => { 9521 return selectors_getBlockTypes(state).filter(blockType => { 9522 return blockType.parent?.includes(blockName); 9523 }).map(({ 9524 name 9525 }) => name); 9526}, state => [state.blockTypes]); 9527 9528/** 9529 * Returns the block support value for a feature, if defined. 9530 * 9531 * @param {Object} state Data state. 9532 * @param {(string|Object)} nameOrType Block name or type object 9533 * @param {Array|string} feature Feature to retrieve 9534 * @param {*}
9534 defaultSupports Default value to return if not 9535 * explicitly defined 9536 * 9537 * @example 9538 * ```js 9539 * import { __, sprintf } from '@wordpress/i18n'; 9540 * import { store as blocksStore } from '@wordpress/blocks'; 9541 * import { useSelect } from '@wordpress/data'; 9542 * 9543 * const ExampleComponent = () => { 9544 * const paragraphBlockSupportValue = useSelect( ( select ) => 9545 * select( blocksStore ).getBlockSupport( 'core/paragraph', 'anchor' ), 9546 * [] 9547 * ); 9548 * 9549 * return ( 9550 * <p> 9551 * { sprintf( 9552 * __( 'core/paragraph supports.anchor value: %s' ), 9553 * paragraphBlockSupportValue 9554 * ) } 9555 * </p> 9556 * ); 9557 * }; 9558 * ``` 9559 * 9560 * @return {?*} Block support value 9561 */ 9562const selectors_getBlockSupport = (state, nameOrType, feature, defaultSupports) => { 9563 const blockType = getNormalizedBlockType(state, nameOrType); 9564 if (!blockType?.supports) { 9565 return defaultSupports; 9566 } 9567 return getValueFromObjectPath(blockType.supports, feature, defaultSupp
9567orts); 9568}; 9569 9570/** 9571 * Returns true if the block defines support for a feature, or false otherwise. 9572 * 9573 * @param {Object} state Data state. 9574 * @param {(string|Object)} nameOrType Block name or type object. 9575 * @param {string} feature Feature to test. 9576 * @param {boolean} defaultSupports Whether feature is supported by 9577 * default if not explicitly defined. 9578 * 9579 * @example 9580 * ```js 9581 * import { __, sprintf } from '@wordpress/i18n'; 9582 * import { store as blocksStore } from '@wordpress/blocks'; 9583 * import { useSelect } from '@wordpress/data'; 9584 * 9585 * const ExampleComponent = () => { 9586 * const paragraphBlockSupportClassName = useSelect( ( select ) => 9587 * select( blocksStore ).hasBlockSupport( 'core/paragraph', 'className' ), 9588 * [] 9589 * ); 9590 * 9591 * return ( 9592 * <p> 9593 * { sprintf( 9594 * __( 'core/paragraph supports custom class name?: %s' ), 9595 * paragraphBlockSupportClassName 9596 * ) } 9597 * /p> 9598 * ); 9599 * }; 9600 * ``` 9601 * 9602 * @return {boolean} Whether block supports feature. 9603 */ 9604function selectors_hasBlockSupport(state, nameOrType, feature, defaultSupp
9604orts) { 9605 return !!selectors_getBlockSupport(state, nameOrType, feature, defaultSupports); 9606} 9607 9608/** 9609 * Returns true if the block type by the given name or object value matches a 9610 * search term, or false otherwise. 9611 * 9612 * @param {Object} state Blocks state. 9613 * @param {(string|Object)} nameOrType Block name or type object. 9614 * @param {string} searchTerm Search term by which to filter. 9615 * 9616 * @example 9617 * ```js 9618 * import { __, sprintf } from '@wordpress/i18n'; 9619 * import { store as blocksStore } from '@wordpress/blocks'; 9620 * import { useSelect } from '@wordpress/data'; 9621 * 9622 * const ExampleComponent = () => { 9623 * const termFound = useSelect( 9624 * ( select ) => 9625 * select( blocksStore ).isMatchingSearchTerm( 9626 * 'core/navigation', 9627 * 'theme' 9628 * ), 9629 * [] 9630 * ); 9631 * 9632 * return ( 9633 * <p> 9634 * { sprintf( 9635 * __( 9636 * 'Search term was found in the title, keywords, category or description in block.json: %s' 9637 * ), 9638 * termFound 9639 * ) } 9640 * </p> 9641 * ); 9642 * }; 9643 * ``` 9644 * 9645 * @return {Object[]} Whether block type matches search term. 9646 */ 9647function isMatchingSearchTerm(state, nameOrType, searchTerm) { 9648 const blockType = getNormalizedBlockType(state, nameOrType); 9649 const getNormalizedSearchTerm = (0,external_wp_compose_namespaceObject.pipe)([ 9650 // Disregard diacritics. 9651 // Input: "média" 9652 term => remove_accents_default()(term !== null && term !== void 0 ? term : ''), 9653 // Lowercase. 9654 // Input: "MEDIA" 9655 term => term.toLowerCase(), 9656 // Strip leading and trailing whitespace. 9657 // Input: " media " 9658 term => term.trim()]); 9659 const normalizedSearchTerm = getNormalizedSearchTerm(searchTerm); 9660 const isSearchMatch = (0,external_wp_compose_namespaceObject.pipe)([getNormalizedSearchTerm, normalizedCandidate => normalizedCandidate.includes(normalizedSearchTerm)]); 9661 return isSearchMatch(blockType.title) || blockType.keywords?.some(isSearchMatch) || isSearchMatch(blockType.category) || typeof blockType.description === 'string' && isSearchMatch(blockType.description); 9662} 9663 9664/** 9665 * Returns a boolean indicating if a block has child blocks or not. 9666 * 9667 * @param {Object} state Data state. 9668 * @param {string} blockName Block type name. 9669 * 9670 * @example 9671 * ```js 9672 * import { __, sprintf } from '@wordpress/i18n'; 9673 * import { store as blocksStore } from '@wordpress/blocks'; 9674 * import { useSelect } from '@wordpress/data'; 9675 * 9676 * const ExampleComponent = () => { 9677 * const navigationBlockHasChildBlocks = useSelect( ( select ) => 9678 * select( blocksStore ).hasChildBlocks( 'core/navigation' ), 9679 * [] 9680 * ); 9681 * 9682 * return ( 9683 * <p> 9684 * { sprintf( 9685 * __( 'core/navigation has child blocks: %s' ), 9686 * navigationBlockHasChildBlocks 9687 * ) } 9688 * </p> 9689 * ); 9690 * }; 9691 * ``` 9692 * 9693 * @return {boolean} True if a block contains child blocks and false otherwise. 9694 */ 9695const selectors_hasChildBlocks = (state, blockName) => { 9696 return selectors_getChildBlockNames(state, blockName).length > 0; 9697}; 9698 9699/** 9700 * Returns a boolean indicating if a block has at least one child block with inserter support. 9701 * 9702 * @param {Object} state Data state. 9703 * @param {string} blockName Block type name. 9704 * 9705 * @example 9706 * ```js 9707 * import { __, sprintf } from '@wordpress/i18n'; 9708 * import { store as blocksStore } from '@wordpress/blocks'; 9709 * import { useSelect } from '@wordpress/data'; 9710 * 9711 * const ExampleComponent = () => { 9712 * const navigationBlockHasChildBlocksWithInserterSupport = useSelect( ( select ) => 9713 * select( blocksStore ).hasChildBlocksWithInserterSupport( 9714 * 'core/navigation' 9715 * ), 9716 * [] 9717 * ); 9718 * 9719 * return ( 9720 * <p> 9721 * { sprintf( 9722 * __( 'core/navigation has child blocks with inserter support: %s' ), 9723 * navigationBlockHasChildBlocksWithInserterSupport 9724 * ) } 9725 * </p> 9726 * ); 9727 * }; 9728 * ``` 9729 * 9730 * @return {boolean} True if a block contains at least one child blocks with inserter support 9731 * and false otherwise. 9732 */ 9733const selectors_hasChildBlocksWithInserterSupport = (state, blockName) => { 9734 return selectors_getChildBlockNames(state, blockName).some(childBlockName => { 9735 return selectors_hasBlockSupport(state, childBlockName, 'inserter', true); 9736 }); 9737}; 9738 9739/** 9740 * DO-NOT-USE in production. 9741 * This selector is created for internal/experimental only usage and may be 9742 * removed anytime without any warning, causing breakage on any plugin or theme invoking it. 9743 */ 9744const __experimentalHasContentRoleAttribute = rememo((state, blockTypeName) => { 9745 const blockType = selectors_getBlockType(state, blockTypeName); 9746 if (!blockType) { 9747 return false;
9748 } 9749 return Object.entries(blockType.attributes).some(([, { 9750 __experimentalRole 9751 }]) => __experimentalRole === 'content'); 9752}, (state, blockTypeName) => [state.blockTypes[blockTypeName]?.attributes]); 9753 9754;// CONCATENATED MODULE: ./packages/blocks/build-module/store/private-selectors.js 9755/** 9756 * External dependencies 9757 */ 9758 9759 9760/** 9761 * Internal dependencies 9762 */ 9763 9764 9765 9766const ROOT_BLOCK_SUPPORTS = ['background', 'backgroundColor', 'color', 'linkColor', 'captionColor', 'buttonColor', 'headingColor', 'fontFamily', 'fontSize', 'fontStyle', 'fontWeight', 'lineHeight', 'padding', 'contentSize', 'wideSize', 'blockGap', 'textDecoration', 'textTransform', 'letterSpacing']; 9767 9768/** 9769 * Filters the list of supported styles for a given element. 9770 * 9771 * @param {string[]} blockSupports list of supported styles. 9772 * @param {string|undefined} name block name. 9773 * @param {string|undefined} element element name. 9774 * 9775 * @return {string[]} filtered list of supported styles. 9776 */ 9777function filterElementBlockSupports(blockSupports, name, element) { 9778 return blockSupports.filter(support => { 9779 if (support === 'fontSize' && element === 'heading') { 9780 return false; 9781 } 9782 9783 // This is only available for links 9784 if (support === 'textDecoration' && !name && element !== 'link') { 9785 return false; 9786 } 9787 9788 // This is only available for heading 9789 if (support === 'textTransform' && !name && !['heading', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(element)) { 9790 return false; 9791 } 9792 9793 // This is only available for headings 9794 if (support === 'letterSpacing' && !name && !['heading', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(element)) { 9795 return false; 9796 } 9797 9798 // Text columns is only available for blocks. 9799 if (support === 'textColumns' && !name) { 9800 return false; 9801 } 9802 return true; 9803 }); 9804} 9805 9806/** 9807 * Returns the list of supported styles for a given block name and element. 9808 */ 9809const getSupportedStyles = rememo((state, name, element) => { 9810 if (!name) { 9811 return filterElementBlockSupports(ROOT_BLOCK_SUPPORTS, name, element); 9812 } 9813 const blockType = selectors_getBlockType(state, name); 9814 if (!blockType) { 9815 return []; 9816 } 9817 const supportKeys = []; 9818 9819 // Check for blockGap support. 9820 // Block spacing support doesn't map directly to a single style property, so needs to be handled separately. 9821 if (blockType?.supports?.spacing?.blockGap) { 9822 supportKeys.push('blockGap'); 9823 } 9824 9825 // check for shadow support 9826 if (blockType?.supports?.shadow) { 9827 supportKeys.push('shadow'); 9828 } 9829 Object.keys(__EXPERIMENTAL_STYLE_PROPERTY).forEach(styleName => { 9830 if (!__EXPERIMENTAL_STYLE_PROPERTY[styleName].support) { 9831 return; 9832 } 9833 9834 // Opting out means that, for certain support keys like background color, 9835 // blocks have to explicitly set the support value false. If the key is 9836 // unset, we still enable it. 9837 if (__EXPERIMENTAL_STYLE_PROPERTY[styleName].requiresOptOut) { 9838 if (__EXPERIMENTAL_STYLE_PROPERTY[styleName].support[0] in blockType.supports && getValueFromObjectPath(blockType.supports, __EXPERIMENTAL_STYLE_PROPERTY[styleName].support) !== false) { 9839 supportKeys.push(styleName); 9840 return; 9841 } 9842 } 9843 if (getValueFromObjectPath(blockType.supports, __EXPERIMENTAL_STYLE_PROPERTY[styleName].support, false)) { 9844 supportKeys.push(styleName); 9845 } 9846 }); 9847 return filterElementBlockSupports(supportKeys, name, element); 9848}, (state, name) => [state.blockTypes[name]]); 9849 9850/** 9851 * Returns the bootstrapped block type metadata for a give block name. 9852 * 9853 * @param {Object} state Data state. 9854 * @param {string} name Block name. 9855 * 9856 * @return {Object} Bootstrapped block type metadata for a block. 9857 */ 9858function getBootstrappedBlockType(state, name) { 9859 return state.bootstrappedBlockTypes[name]; 9860} 9861 9862/** 9863 * Returns all the unprocessed (before applying the `registerBlockType` filter) 9864 * block type settings as passed during block registration. 9865 * 9866 * @param {Object} state Data state. 9867 * 9868 * @return {Array} Unprocessed block type settings for all blocks. 9869 */ 9870function getUnprocessedBlockTypes(state) { 9871 return state.unprocessedBlockTypes; 9872} 9873 9874;
9874// CONCATENATED MODULE: external ["wp","deprecated"] 9875const external_wp_deprecated_namespaceObject = window["wp"]["deprecated"]; 9876var external_wp_deprecated_default = /*#__PURE__*/__webpack_require__.n(external_wp_deprecated_namespaceObject); 9877;// CONCATENATED MODULE: ./node_modules/is-plain-object/dist/is-plain-object.mjs 9878/*! 9879 * is-plain-object <https://github.com/jonschlinkert/is-plain-object> 9880 * 9881 * Copyright (c) 2014-2017, Jon Schlinkert. 9882 * Released under the MIT License. 9883 */ 9884 9885function is_plain_object_isObject(o) { 9886 return Object.prototype.toString.call(o) === '[object Object]'; 9887} 9888 9889function isPlainObject(o) { 9890 var ctor,prot; 9891 9892 if (is_plain_object_isObject(o) === false) return false; 9893 9894 // If has modified constructor 9895 ctor = o.constructor; 9896 if (ctor === undefined) return true; 9897 9898 // If has modified prototype 9899 prot = ctor.prototype; 9900 if (is_plain_object_isObject(prot) === false) return false; 9901 9902 // If constructor does not have an Object-specific method 9903 if (prot.hasOwnProperty('isPrototypeOf') === false) { 9904 return false; 9905 } 9906 9907 // Most likely a plain Object 9908 return true; 9909} 9910 9911 9912 9913;// CONCATENATED MODULE: ./packages/blocks/build-module/store/process-block-type.js 9914/** 9915 * External dependencies 9916 */ 9917 9918 9919/** 9920 * WordPress dependencies 9921 */ 9922 9923 9924 9925/** 9926 * Internal dependencies 9927 */ 9928 9929 9930 9931/** @typedef {import('../api/registration').WPBlockType} WPBlockType */ 9932 9933const { 9934 error, 9935 warn 9936} = window.console; 9937 9938/** 9939 * Mapping of legacy category slugs to their latest normal values, used to 9940 * accommodate updates of the default set of block categories. 9941 * 9942 * @type {Record<string,string>} 9943 */ 9944const LEGACY_CATEGORY_MAPPING = { 9945 common: 'text', 9946 formatting: 'text', 9947 layout: 'design' 9948}; 9949 9950/** 9951 * Takes the unprocessed block type settings, merges them with block type metadata 9952 * and applies all the existing filters for the registered block type. 9953 * Next, it validates all the settings and performs additional processing to the block type definition. 9954 * 9955 * @param {string} name Block name. 9956 * @param {WPBlockType} blockSettings Unprocessed block type settings. 9957 * 9958 * @return {WPBlockType | undefined} The block, if it has been processed and can be registered; otherwise `undefined`. 9959 */ 9960const processBlockType = (name, blockSettings) => ({ 9961 select 9962}) => { 9963 const blockType = { 9964 name, 9965 icon: BLOCK_ICON_DEFAULT, 9966 keywords: [], 9967 attributes: {}, 9968 providesContext: {}, 9969 usesContext: [], 9970 selectors: {}, 9971 supports: {}, 9972 styles: [], 9973 variations: [], 9974 blockHooks: {}, 9975 save: () => null, 9976 ...select.getBootstrappedBlockType(name), 9977 ...blockSettings 9978 }; 9979 const settings = (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.registerBlockType', blockType, name, null); 9980 if (settings.description && typeof settings.description !== 'string') { 9981 external_wp_deprecated_default()('Declaring non-string block descriptions', { 9982 since: '6.2' 9983 }); 9984 } 9985 if (settings.deprecated) { 9986 settings.deprecated = settings.deprecated.map(deprecation => Object.fromEntries(Object.entries( 9987 // Only keep valid deprecation keys. 9988 (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.registerBlockType', 9989 // Merge deprecation keys with pre-filter settings 9990 // so that filters that depend on specific keys being 9991 // present don't fail. 9992 { 9993 // Omit deprecation keys here so that deprecations 9994 // can opt out of specific keys like "supports". 9995 ...omit(blockType, DEPRECATED_ENTRY_KEYS), 9996 ...deprecation 9997 }, blockType.name, deprecation)).filter(([key]) => DEPRECATED_ENTRY_KEYS.includes(key)))); 9998 } 9999 if (!isPlainObject(settings)) { 10000 error('Block settings must be a valid object.'); 10001 return; 10002 } 10003 if (typeof settings.save !== 'function') { 10004 error('The "save" property must be a valid function.'); 10005 return; 10006 } 10007 if ('edit' in settings && typeof settings.edit !== 'function') { 10008 error('The "edit" property must be a valid function.'); 10009 return; 10010 } 10011 10012 // Canonicalize legacy categories to equivalent fallback. 10013 if (LEGACY_CATEGORY_MAPPING.hasOwnProperty(settings.category)) { 10014 settings.category = LEGACY_CATEGORY_MAPPING[settings.category]; 10015 } 10016 if ('category' in settings && !select.getCategories().some(({ 10017 slug 10018 }) => slug === settings.category)) {
10019 warn('The block "' + name + '" is registered with an invalid category "' + settings.category + '".'); 10020 delete settings.category; 10021 } 10022 if (!('title' in settings) || settings.title === '') { 10023 error('The block "' + name + '" must have a title.'); 10024 return; 10025 } 10026 if (typeof settings.title !== 'string') { 10027 error('Block titles must be strings.'); 10028 return; 10029 } 10030 settings.icon = normalizeIconObject(settings.icon); 10031 if (!isValidIcon(settings.icon.src)) { 10032 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'); 10033 return; 10034 } 10035 return settings; 10036}; 10037 10038;// CONCATENATED MODULE: ./packages/blocks/build-module/store/actions.js 10039/** 10040 * WordPress dependencies 10041 */ 10042 10043 10044/** 10045 * Internal dependencies 10046 */ 10047 10048 10049/** @typedef {import('../api/registration').WPBlockVariation} WPBlockVariation */ 10050/** @typedef {import('../api/registration').WPBlockType} WPBlockType */ 10051/** @typedef {import('./reducer').WPBlockCategory} WPBlockCategory */ 10052 10053/** 10054 * Returns an action object used in signalling that block types have been added. 10055 * Ignored from documentation as the recommended usage for this action through registerBlockType from @wordpress/blocks. 10056 * 10057 * @ignore 10058 * 10059 * @param {WPBlockType|WPBlockType[]} blockTypes Object or array of objects representing blocks to added. 10060 * 10061 * 10062 * @return {Object} Action object. 10063 */ 10064function addBlockTypes(blockTypes) { 10065 return { 10066 type: 'ADD_BLOCK_TYPES', 10067 blockTypes: Array.isArray(blockTypes) ? blockTypes : [blockTypes] 10068 }; 10069} 10070 10071/** 10072 * Signals that all block types should be computed again. 10073 * It uses stored unprocessed block types and all the most recent list of registered filters. 10074 * 10075 * It addresses the issue where third party block filters get registered after third party blocks. A sample sequence: 10076 * 1. Filter A. 10077 * 2. Block B. 10078 * 3. Block C. 10079 * 4. Filter D. 10080 * 5. Filter E. 10081 * 6. Block F. 10082 * 7. Filter G. 10083 * In this scenario some filters would not get applied for all blocks because they are registered too late. 10084 */ 10085function reapplyBlockTypeFilters() { 10086 return ({ 10087 dispatch, 10088 select 10089 }) => { 10090 const processedBlockTypes = []; 10091 for (const [name, settings] of Object.entries(select.getUnprocessedBlockTypes())) { 10092 const result = dispatch(processBlockType(name, settings)); 10093 if (result) { 10094 processedBlockTypes.push(result); 10095 } 10096 } 10097 if (!processedBlockTypes.length) { 10098 return; 10099 } 10100 dispatch.addBlockTypes(processedBlockTypes); 10101 }; 10102} 10103function __experimentalReapplyBlockFilters() { 10104 external_wp_deprecated_default()('wp.data.dispatch( "core/blocks" ).__experimentalReapplyBlockFilters', { 10105 since: '6.4', 10106 alternative: 'reapplyBlockFilters' 10107 }); 10108 return reapplyBlockTypeFilters(); 10109} 10110 10111/** 10112 * Returns an action object used to remove a registered block type. 10113 * Ignored from documentation as the recommended usage for this action through unregisterBlockType from @wordpress/blocks. 10114 * 10115 * @ignore 10116 * 10117 * @param {string|string[]} names Block name or array of block names to be removed. 10118 * 10119 * 10120 * @return {Object} Action object. 10121 */ 10122function removeBlockTypes(names) { 10123 return { 10124 type: 'REMOVE_BLOCK_TYPES', 10125 names: Array.isArray(names) ? names : [names] 10126 }; 10127} 10128 10129/** 10130 * Returns an action object used in signalling that new block styles have been added. 10131 * Ignored from documentation as the recommended usage for this action through registerBlockStyle from @wordpress/blocks. 10132 * 10133 * @param {string} blockName Block name. 10134 * @param {Array|Object} styles Block style object or array of block style objects. 10135 * 10136 * @ignore 10137 * 10138 * @return {Object} Action object. 10139 */ 10140function addBlockStyles(blockName, styles) { 10141 return { 10142 type: 'ADD_BLOCK_STYLES', 10143 styles: Array.isArray(styles) ? styles : [styles], 10144 blockName 10145 }; 10146} 10147 10148/** 10149 * Returns an action object used in signalling that block styles have been removed. 10150 * Ignored from documentation as the recommended usage for this action through unregisterBlockStyle from @wordpress/blocks. 10151 * 10152 * @ignore 10153 * 10154 * @param {string} blockName Block name. 10155 * @param {Array|string} styleNames Block style names or array of block style names. 10156 * 10157 * @return {Object} Action object. 10158 */ 10159function removeBlockStyles(blockName, styleNames) { 10160 return { 10161 type: 'REMOVE_BLOCK_STYLES', 10162 styleNames: Array.isArray(styleNames) ? styleNames : [styleNames], 10163 blockName 10164 }; 10165} 10166 10167/** 10168 * Returns an action object used in signalling that new block variations have been added.
10169 * Ignored from documentation as the recommended usage for this action through registerBlockVariation from @wordpress/blocks. 10170 * 10171 * @ignore 10172 * 10173 * @param {string} blockName Block name. 10174 * @param {WPBlockVariation|WPBlockVariation[]} variations Block variations. 10175 * 10176 * @return {Object} Action object. 10177 */ 10178function addBlockVariations(blockName, variations) { 10179 return { 10180 type: 'ADD_BLOCK_VARIATIONS', 10181 variations: Array.isArray(variations) ? variations : [variations], 10182 blockName 10183 }; 10184} 10185 10186/** 10187 * Returns an action object used in signalling that block variations have been removed. 10188 * Ignored from documentation as the recommended usage for this action through unregisterBlockVariation from @wordpress/blocks. 10189 * 10190 * @ignore 10191 * 10192 * @param {string} blockName Block name. 10193 * @param {string|string[]} variationNames Block variation names. 10194 * 10195 * @return {Object} Action object. 10196 */ 10197function removeBlockVariations(blockName, variationNames) { 10198 return { 10199 type: 'REMOVE_BLOCK_VARIATIONS', 10200 variationNames: Array.isArray(variationNames) ? variationNames : [variationNames], 10201 blockName 10202 }; 10203} 10204 10205/** 10206 * Returns an action object used to set the default block name. 10207 * Ignored from documentation as the recommended usage for this action through setDefaultBlockName from @wordpress/blocks. 10208 * 10209 * @ignore 10210 * 10211 * @param {string} name Block name. 10212 * 10213 * @return {Object} Action object. 10214 */ 10215function actions_setDefaultBlockName(name) { 10216 return { 10217 type: 'SET_DEFAULT_BLOCK_NAME', 10218 name 10219 }; 10220} 10221 10222/** 10223 * Returns an action object used to set the name of the block used as a fallback 10224 * for non-block content. 10225 * Ignored from documentation as the recommended usage for this action through setFreeformContentHandlerName from @wordpress/blocks. 10226 * 10227 * @ignore 10228 * 10229 * @param {string} name Block name. 10230 * 10231 * @return {Object} Action object. 10232 */ 10233function setFreeformFallbackBlockName(name) { 10234 return { 10235 type: 'SET_FREEFORM_FALLBACK_BLOCK_NAME', 10236 name 10237 }; 10238} 10239 10240/** 10241 * Returns an action object used to set the name of the block used as a fallback 10242 * for unregistered blocks. 10243 * Ignored from documentation as the recommended usage for this action through setUnregisteredTypeHandlerName from @wordpress/blocks. 10244 * 10245 * @ignore 10246 * 10247 * @param {string} name Block name. 10248 * 10249 * @return {Object} Action object. 10250 */ 10251function setUnregisteredFallbackBlockName(name) { 10252 return { 10253 type: 'SET_UNREGISTERED_FALLBACK_BLOCK_NAME', 10254 name 10255 }; 10256} 10257 10258/** 10259 * Returns an action object used to set the name of the block used 10260 * when grouping other blocks 10261 * eg: in "Group/Ungroup" interactions 10262 * Ignored from documentation as the recommended usage for this action through setGroupingBlockName from @wordpress/blocks. 10263 * 10264 * @ignore 10265 * 10266 * @param {string} name Block name. 10267 * 10268 * @return {Object} Action object. 10269 */ 10270function actions_setGroupingBlockName(name) { 10271 return { 10272 type: 'SET_GROUPING_BLOCK_NAME', 10273 name 10274 }; 10275} 10276 10277/** 10278 * Returns an action object used to set block categories. 10279 * Ignored from documentation as the recommended usage for this action through setCategories from @wordpress/blocks. 10280 * 10281 * @ignore 10282 * 10283 * @param {WPBlockCategory[]} categories Block categories. 10284 * 10285 * @return {Object} Action object. 10286 */ 10287function setCategories(categories) { 10288 return { 10289 type: 'SET_CATEGORIES', 10290 categories 10291 }; 10292} 10293 10294/** 10295 * Returns an action object used to update a category. 10296 * Ignored from documentation as the recommended usage for this action through updateCategory from @wordpress/blocks. 10297 * 10298 * @ignore 10299 * 10300 * @param {string} slug Block category slug. 10301 * @param {Object} category Object containing the category properties that should be updated. 10302 * 10303 * @return {Object} Action object. 10304 */ 10305function updateCategory(slug, category) { 10306 return { 10307 type: 'UPDATE_CATEGORY', 10308 slug, 10309 category 10310 }; 10311} 10312 10313/** 10314 * Returns an action object used to add block collections 10315 * Ignored from documentation as the recommended usage for this action through registerBlockCollection from @wordpress/blocks. 10316 * 10317 * @ignore 10318 * 10319 * @param {string} namespace The namespace of the blocks to put in the collection 10320 * @param {string} title The title to display in the block inserter 10321 * @param {Object} icon (optional) The icon to display in the block inserter 10322 * 10323 * @return {Object} Action object. 10324 */ 10325function addBlockCollection(namespace, title, icon) { 10326 return { 10327 type: 'ADD_BLOCK_COLLECTION', 10328 namespace, 10329 title, 10330 icon 10331 }; 10332} 10333 10334/** 10335 * Returns an action object used to remove block collections 10336 * Ignored from documentation as the recommended usage for this action through unregisterBlockCollection from @wordpress/blocks. 10337 * 10338 * @ignore 10339 * 10340 * @param {string} namespace The namespace of the blocks to put in the collection 10341 * 10342 * @return {Object} Action object. 10343 */ 10344function removeBlockCollection(namespace) { 10345 return { 10346 type: 'REMOVE_BLOCK_COLLECTION', 10347 namespace 10348 }; 10349} 10350 10351;// CONCATENATED MODULE: ./packages/blocks/build-module/store/private-actions.js 10352/** 10353 * Internal dependencies 10354 */ 10355 10356 10357/** @typedef {import('../api/registration').WPBlockType} WPBlockType */ 10358 10359/** 10360 * Add bootstrapped block type metadata to the store. These metadata usually come from 10361 * the `block.json` file and are either statically boostrapped from the server, or 10362 * passed as the `metadata` parameter to the `registerBlockType` function. 10363 * 10364 * @param {string} name Block name. 10365 * @param {WPBlockType} blockType Block type metadata. 10366 */ 10367function addBootstrappedBlockType(name, blockType) { 10368 return { 10369 type: 'ADD_BOOTSTRAPPED_BLOCK_TYPE', 10370 name, 10371 blockType 10372 }; 10373} 10374 10375/** 10376 * Add unprocessed block type settings to the store. These data are passed as the 10377 * `settings` parameter to the client-side `registerBlockType` function. 10378 * 10379 * @param {string} name Block name. 10380 * @param {WPBlockType} blockType Unprocessed block type settings. 10381 */ 10382function addUnprocessedBlockType(name, blockType) { 10383 return ({ 10384 dispatch 10385 }) => { 10386 dispatch({ 10387 type: 'ADD_UNPROCESSED_BLOCK_TYPE', 10388 name, 10389 blockType 10390 }); 10391 const processedBlockType = dispatch(processBlockType(name, blockType)); 10392 if (!processedBlockType) { 10393 return; 10394 } 10395 dispatch.addBlockTypes(processedBlockType); 10396 }; 10397} 10398 10399;// CONCATENATED MODULE: ./packages/blocks/build-module/store/constants.js
10400const STORE_NAME = 'core/blocks'; 10401 10402;// CONCATENATED MODULE: ./packages/blocks/build-module/store/index.js 10403/** 10404 * WordPress dependencies 10405 */ 10406 10407 10408/** 10409 * Internal dependencies 10410 */ 10411 10412 10413 10414 10415 10416 10417 10418 10419/** 10420 * Store definition for the blocks namespace. 10421 * 10422 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#createReduxStore 10423 * 10424 * @type {Object} 10425 */ 10426const store = (0,external_wp_data_namespaceObject.createReduxStore)(STORE_NAME, { 10427 reducer: reducer, 10428 selectors: selectors_namespaceObject, 10429 actions: actions_namespaceObject 10430}); 10431(0,external_wp_data_namespaceObject.register)(store); 10432unlock(store).registerPrivateSelectors(private_selectors_namespaceObject); 10433unlock(store).registerPrivateActions(private_actions_namespaceObject); 10434 10435;// CONCATENATED MODULE: external ["wp","blockSerializationDefaultParser"] 10436const external_wp_blockSerializationDefaultParser_namespaceObject = window["wp"]["blockSerializationDefaultParser"]; 10437;// CONCATENATED MODULE: external ["wp","autop"] 10438const external_wp_autop_namespaceObject = window["wp"]["autop"]; 10439;// CONCATENATED MODULE: external ["wp","isShallowEqual"] 10440const external_wp_isShallowEqual_namespaceObject = window["wp"]["isShallowEqual"]; 10441var external_wp_isShallowEqual_default = /*#__PURE__*/__webpack_require__.n(external_wp_isShallowEqual_namespaceObject); 10442;// CONCATENATED MODULE: ./packages/blocks/build-module/api/parser/serialize-raw-block.js 10443/** 10444 * Internal dependencies 10445 */ 10446 10447 10448/** 10449 * @typedef {Object} Options Serialization options. 10450 * @property {boolean} [isCommentDelimited=true] Whether to output HTML comments around blocks. 10451 */ 10452 10453/** @typedef {import("./").WPRawBlock} WPRawBlock */ 10454 10455/** 10456 * Serializes a block node into the native HTML-comment-powered block format. 10457 * CAVEAT: This function is intended for re-serializing blocks as parsed by 10458 * valid parsers and skips any validation steps. This is NOT a generic 10459 * serialization function for in-memory blocks. For most purposes, see the 10460 * following functions available in the `@wordpress/blocks` package: 10461 * 10462 * @see serializeBlock 10463 * @see serialize 10464 * 10465 * For more on the format of block nodes as returned by valid parsers: 10466 * 10467 * @see `@wordpress/block-serialization-default-parser` package 10468 * @see `@wordpress/block-serialization-spec-parser` package 10469 * 10470 * @param {WPRawBlock} rawBlock A block node as returned by a valid parser. 10471 * @param {Options} [options={}] Serialization options. 10472 * 10473 * @return {string} An HTML string representing a block. 10474 */ 10475function serializeRawBlock(rawBlock, options = {}) { 10476 const { 10477 isCommentDelimited = true 10478 } = options; 10479 const { 10480 blockName, 10481 attrs = {}, 10482 innerBlocks = [], 10483 innerContent = [] 10484 } = rawBlock; 10485 let childIndex = 0; 10486 const content = innerContent.map(item => 10487 // `null` denotes a nested block, otherwise we have an HTML fragment. 10488 item !== null ? item : serializeRawBlock(innerBlocks[childIndex++], options)).join('\n').replace(/\n+/g, '\n').trim(); 10489 return isCommentDelimited ? getCommentDelimitedContent(blockName, attrs, content) : content; 10490} 10491 10492;// CONCATENATED MODULE: ./packages/blocks/build-module/api/serializer.js 10493 10494/** 10495 * WordPress dependencies 10496 */ 10497 10498 10499 10500 10501 10502/** 10503 * Internal dependencies 10504 */ 10505 10506 10507 10508 10509/** @typedef {import('./parser').WPBlock} WPBlock */ 10510 10511/** 10512 * @typedef {Object} WPBlockSerializationOptions Serialization Options. 10513 * 10514 * @property {boolean} isInnerBlocks Whether we are serializing inner blocks. 10515 */ 10516 10517/** 10518 * Returns the block's default classname from its name. 10519 * 10520 * @param {string} blockName The block name. 10521 * 10522 * @return {string} The block's default class. 10523 */ 10524function getBlockDefaultClassName(blockName) { 10525 // Generated HTML classes for blocks follow the `wp-block-{name}` nomenclature. 10526 // Blocks provided by WordPress drop the prefixes 'core/' or 'core-' (historically used in 'core-embed/'). 10527 const className = 'wp-block-' + blockName.replace(/\//, '-').replace(/^core-/, ''); 10528 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getBlockDefaultClassName', className, blockName); 10529} 10530 10531/** 10532 * Returns the block's default menu item classname from its name. 10533 * 10534 * @param {string} blockName The block name. 10535 * 10536 * @return {string} The block's default menu item class. 10537 */ 10538function getBlockMenuDefaultClassName(blockName) { 10539 // Generated HTML classes for blocks follow the `editor-block-list-item-{name}` nomenclature. 10540 // Blocks provided by WordPress drop the prefixes 'core/' or 'core-' (historically used in 'core-embed/').
10541 const className = 'editor-block-list-item-' + blockName.replace(/\//, '-').replace(/^core-/, ''); 10542 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getBlockMenuDefaultClassName', className, blockName); 10543} 10544const blockPropsProvider = {}; 10545const innerBlocksPropsProvider = {}; 10546 10547/** 10548 * Call within a save function to get the props for the block wrapper. 10549 * 10550 * @param {Object} props Optional. Props to pass to the element. 10551 */ 10552function getBlockProps(props = {}) { 10553 const { 10554 blockType, 10555 attributes 10556 } = blockPropsProvider; 10557 return getBlockProps.skipFilters ? props : (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getSaveContent.extraProps', { 10558 ...props 10559 }, blockType, attributes); 10560} 10561 10562/** 10563 * Call within a save function to get the props for the inner blocks wrapper. 10564 * 10565 * @param {Object} props Optional. Props to pass to the element. 10566 */ 10567function getInnerBlocksProps(props = {}) { 10568 const { 10569 innerBlocks 10570 } = innerBlocksPropsProvider; 10571 // Allow a different component to be passed to getSaveElement to handle 10572 // inner blocks, bypassing the default serialisation. 10573 if (!Array.isArray(innerBlocks)) { 10574 return { 10575 ...props, 10576 children: innerBlocks 10577 }; 10578 } 10579 // Value is an array of blocks, so defer to block serializer. 10580 const html = serialize(innerBlocks, { 10581 isInnerBlocks: true 10582 }); 10583 // Use special-cased raw HTML tag to avoid default escaping. 10584 const children = (0,external_wp_element_namespaceObject.createElement)(external_wp_element_namespaceObject.RawHTML, null, html); 10585 return { 10586 ...props, 10587 children 10588 }; 10589} 10590 10591/** 10592 * Given a block type containing a save render implementation and attributes, returns the 10593 * enhanced element to be saved or string when raw HTML expected. 10594 * 10595 * @param {string|Object} blockTypeOrName Block type or name. 10596 * @param {Object} attributes Block attributes. 10597 * @param {?Array} innerBlocks Nested blocks. 10598 * 10599 * @return {Object|string} Save element or raw HTML string. 10600 */ 10601function getSaveElement(blockTypeOrName, attributes, innerBlocks = []) { 10602 const blockType = normalizeBlockType(blockTypeOrName); 10603 if (!blockType?.save) return null; 10604 let { 10605 save 10606 } = blockType; 10607 10608 // Component classes are unsupported for save since serialization must 10609 // occur synchronously. For improved interoperability with higher-order 10610 // components which often return component class, emulate basic support. 10611 if (save.prototype instanceof external_wp_element_namespaceObject.Component) { 10612 const instance = new save({ 10613 attributes 10614 }); 10615 save = instance.render.bind(instance); 10616 } 10617 blockPropsProvider.blockType = blockType; 10618 blockPropsProvider.attributes = attributes; 10619 innerBlocksPropsProvider.innerBlocks = innerBlocks; 10620 let element = save({ 10621 attributes, 10622 innerBlocks 10623 }); 10624 if (element !== null && typeof element === 'object' && (0,external_wp_hooks_namespaceObject.hasFilter)('blocks.getSaveContent.extraProps') && !(blockType.apiVersion > 1)) { 10625 /** 10626 * Filters the props applied to the block save result element. 10627 * 10628 * @param {Object} props Props applied to save element. 10629 * @param {WPBlock} blockType Block type definition. 10630 * @param {Object} attributes Block attributes. 10631 */ 10632 const props = (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getSaveContent.extraProps', { 10633 ...element.props 10634 }, blockType, attributes); 10635 if (!external_wp_isShallowEqual_default()(props, element.props)) { 10636 element = (0,external_wp_element_namespaceObject.cloneElement)(element, props); 10637 } 10638 } 10639 10640 /** 10641 * Filters the save result of a block during serialization. 10642 * 10643 * @param {WPElement} element Block save result. 10644 * @param {WPBlock} blockType Block type definition. 10645 * @param {Object} attributes Block attributes. 10646 */ 10647 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getSaveElement', element, blockType, attributes); 10648} 10649 10650/** 10651 * Given a block type containing a save render implementation and attributes, returns the 10652 * static markup to be saved. 10653 * 10654 * @param {string|Object} blockTypeOrName Block type or name. 10655 * @param {Object} attributes Block attributes. 10656 * @param {?Array} innerBlocks Nested blocks. 10657 * 10658 * @return {string} Save content. 10659 */ 10660function getSaveContent(blockTypeOrName, attributes, innerBlocks) { 10661 const blockType = normalizeBlockType(blockTypeOrName); 10662 return (0,external_wp_element_namespaceObject.renderToString)(getSaveElement(blockType, attributes, innerBlocks)); 10663} 10664 10665/** 10666 * Returns attributes which are to be saved and serialized into the block 10667 * comment delimiter. 10668 * 10669 * When a block exists in memory it contains as its attributes both those 10670 * parsed the block comment delimiter _and_ those which matched from the 10671 * contents of the block. 10672 * 10673 * This function returns only those attributes which are needed to persist and 10674 * which cannot be matched from the block content. 10675 * 10676 * @param {Object<string,*>} blockType Block type. 10677 * @param {Object<string,*>} attributes Attributes from in-memory block data. 10678 * 10679 * @return {Object<string,*>} Subset of attributes for comment serialization. 10680 */ 10681function getCommentAttributes(blockType, attributes) { 10682 var _blockType$attributes; 10683 return Object.entries((_blockType$attributes = blockType.attributes) !== null && _blockType$attributes !== void 0 ? _blockType$attributes : {}
10683).reduce((accumulator, [key, attributeSchema]) => { 10684 const value = attributes[key]; 10685 // Ignore undefined values. 10686 if (undefined === value) { 10687 return accumulator; 10688 } 10689 10690 // Ignore all attributes but the ones with an "undefined" source 10691 // "undefined" source refers to attributes saved in the block comment. 10692 if (attributeSchema.source !== undefined) { 10693 return accumulator; 10694 } 10695 10696 // Ignore default value. 10697 if ('default' in attributeSchema && JSON.stringify(attributeSchema.default) === JSON.stringify(value)) { 10698 return accumulator; 10699 } 10700 10701 // Otherwise, include in comment set. 10702 accumulator[key] = value; 10703 return accumulator; 10704 }, {}); 10705} 10706 10707/** 10708 * Given an attributes object, returns a string in the serialized attributes 10709 * format prepared for post content. 10710 * 10711 * @param {Object} attributes Attributes object. 10712 * 10713 * @return {string} Serialized attributes. 10714 */ 10715function serializeAttributes(attributes) { 10716 return JSON.stringify(attributes) 10717 // Don't break HTML comments. 10718 .replace(/--/g, '\\u002d\\u002d') 10719 10720 // Don't break non-standard-compliant tools. 10721 .replace(/</g, '\\u003c').replace(/>/g, '\\u003e').replace(/&/g, '\\u0026') 10722 10723 // Bypass server stripslashes behavior which would unescape stringify's 10724 // escaping of quotation mark. 10725 // 10726 // See: https://developer.wordpress.org/reference/functions/wp_kses_stripslashes/ 10727 .replace(/\\"/g, '\\u0022'); 10728} 10729 10730/** 10731 * Given a block object, returns the Block's Inner HTML markup. 10732 * 10733 * @param {Object} block Block instance. 10734 * 10735 * @return {string} HTML. 10736 */ 10737function getBlockInnerHTML(block) { 10738 // If block was parsed as invalid or encounters an error while generating 10739 // save content, use original content instead to avoid content loss. If a 10740 // block contains nested content, exempt it from this condition because we 10741 // otherwise have no access to its original content and content loss would 10742 // still occur. 10743 let saveContent = block.originalContent; 10744 if (block.isValid || block.innerBlocks.length) { 10745 try { 10746 saveContent = getSaveContent(block.name, block.attributes, block.innerBlocks); 10747 } catch (error) {} 10748 } 10749 return saveContent; 10750} 10751 10752/** 10753 * Returns the content of a block, including comment delimiters. 10754 * 10755 * @param {string} rawBlockName Block name. 10756 * @param {Object} attributes Block attributes. 10757 * @param {string} content Block save content. 10758 * 10759 * @return {string} Comment-delimited block content. 10760 */ 10761function getCommentDelimitedContent(rawBlockName, attributes, content) { 10762 const serializedAttributes = attributes && Object.entries(attributes).length ? serializeAttributes(attributes) + ' ' : ''; 10763 10764 // Strip core blocks of their namespace prefix. 10765 const blockName = rawBlockName?.startsWith('core/') ? rawBlockName.slice(5) : rawBlockName; 10766 10767 // @todo make the `wp:` prefix potentially configurable. 10768 10769 if (!content) { 10770 return `<!-- wp:${blockName} ${serializedAttributes}/-->`; 10771 } 10772 return `<!-- wp:${blockName} ${serializedAttributes}-->\n` + content + `\n<!-- /wp:${blockName} -->`; 10773} 10774 10775/** 10776 * Returns the content of a block, including comment delimiters, determining 10777 * serialized attributes and content form from the current state of the block. 10778 * 10779 * @param {WPBlock} block Block instance. 10780 * @param {WPBlockSerializationOptions} options Serialization options. 10781 * 10782 * @return {string} Serialized block. 10783 */ 10784function serializeBlock(block, { 10785 isInnerBlocks = false 10786} = {}) { 10787 if (!block.isValid && block.__unstableBlockSource) { 10788 return serializeRawBlock(block.__unstableBlockSource); 10789 } 10790 const blockName = block.name; 10791 const saveContent = getBlockInnerHTML(block); 10792 if (blockName === getUnregisteredTypeHandlerName() || !isInnerBlocks && blockName === getFreeformContentHandlerName()) { 10793 return saveContent; 10794 } 10795 const blockType = getBlockType(blockName); 10796 if (!blockType) { 10797 return saveContent; 10798 } 10799 const saveAttributes = getCommentAttributes(blockType, block.attributes); 10800 return getCommentDelimitedContent(blockName, saveAttributes, saveContent); 10801} 10802function __unstableSerializeAndClean(blocks) { 10803 // A single unmodified default block is assumed to 10804 // be equivalent to an empty post. 10805 if (blocks.length === 1 && isUnmodifiedDefaultBlock(blocks[0])) { 10806 blocks = []; 10807 } 10808 let content = serialize(blocks); 10809 10810 // For compatibility, treat a post consisting of a 10811 // single freeform block as legacy content and apply 10812 // pre-block-editor removep'd content formatting. 10813 if (blocks.length === 1 && blocks[0].name === getFreeformContentHandlerName() && blocks[0].name === 'core/freeform') { 10814 content = (0,external_wp_autop_namespaceObject.removep)(content); 10815 } 10816 return content; 10817} 10818
10819/** 10820 * Takes a block or set of blocks and returns the serialized post content. 10821 * 10822 * @param {Array} blocks Block(s) to serialize. 10823 * @param {WPBlockSerializationOptions} options Serialization options. 10824 * 10825 * @return {string} The post content. 10826 */ 10827function serialize(blocks, options) { 10828 const blocksArray = Array.isArray(blocks) ? blocks : [blocks]; 10829 return blocksArray.map(block => serializeBlock(block, options)).join('\n\n'); 10830} 10831 10832;// CONCATENATED MODULE: ./node_modules/simple-html-tokenizer/dist/es6/index.js 10833/** 10834 * generated from https://raw.githubusercontent.com/w3c/html/26b5126f96f736f796b9e29718138919dd513744/entities.json 10835 * do not edit 10836 */ 10837var namedCharRefs = { 10838 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: "Â
10838®", 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: "â°", esd
10838ot: "â", Esim: "⩳", esim: "â", Eta: "Î", eta: "η", ETH: "Ã", eth: "ð", Euml: "Ã", euml: "ë", euro: "â¬", excl: "!", exist: "â", Exists: "â", expectation: "â°", exponentiale: "â
", ExponentialE: "â
", fallingdotseq: "â", Fcy: "Ф", fcy: "Ñ", female: "â", ffilig: "ï¬", fflig: "ï¬", ffllig: "ï¬", Ffr: "ð", ffr: "ð£", filig: "ï¬", FilledSmallSquare: "â¼", FilledVerySmallSquare: "âª", fjlig: "fj", flat: "â", fllig: "ï¬", 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
10838: "Ä»", 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: "Å", 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
10838: "â®", 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: "%", peri
10838od: ".", 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: "â¿", tri
vendor: 20,341 bytes, lines 10838-11248
10838angleleft: "â", 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" 10839}; 10840 10841var HEXCHARCODE = /^#[xX]([A-Fa-f0-9]+)$/; 10842var CHARCODE = /^#([0-9]+)$/; 10843var NAMED = /^([A-Za-z0-9]+)$/; 10844var EntityParser = /** @class */ (function () { 10845 function EntityParser(named) { 10846 this.named = named; 10847 } 10848 EntityParser.prototype.parse = function (entity) { 10849 if (!entity) { 10850 return; 10851 } 10852 var matches = entity.match(HEXCHARCODE); 10853 if (matches) { 10854 return String.fromCharCode(parseInt(matches[1], 16)); 10855 } 10856 matches = entity.match(CHARCODE); 10857 if (matches) { 10858 return String.fromCharCode(parseInt(matches[1], 10)); 10859 } 10860 matches = entity.match(NAMED); 10861 if (matches) { 10862 return this.named[matches[1]]; 10863 } 10864 }; 10865 return EntityParser; 10866}()); 10867 10868var WSP = /[\t\n\f ]/; 10869var ALPHA = /[A-Za-z]/; 10870var CRLF = /\r\n?/g; 10871function isSpace(char) { 10872 return WSP.test(char); 10873} 10874function isAlpha(char) { 10875 return ALPHA.test(char); 10876} 10877function preprocessInput(input) { 10878 return input.replace(CRLF, '\n'); 10879} 10880 10881var EventedTokenizer = /** @class */ (function () { 10882 function EventedTokenizer(delegate, entityParser) { 10883 this.delegate = delegate; 10884 this.entityParser = entityParser; 10885 this.state = "beforeData" /* beforeData */; 10886 this.line = -1; 10887 this.column = -1; 10888 this.input = ''; 10889 this.index = -1; 10890 this.tagNameBuffer = ''; 10891 this.states = { 10892 beforeData: function () { 10893 var char = this.peek(); 10894 if (char === '<') { 10895 this.transitionTo("tagOpen" /* tagOpen */); 10896 this.markTagStart(); 10897 this.consume(); 10898 } 10899 else { 10900 if (char === '\n') { 10901 var tag = this.tagNameBuffer.toLowerCase(); 10902 if (tag === 'pre' || tag === 'textarea') { 10903 this.consume(); 10904 } 10905 } 10906 this.transitionTo("data" /* data */); 10907 this.delegate.beginData(); 10908 } 10909 }, 10910 data: function () { 10911 var char = this.peek(); 10912 if (char === '<') { 10913 this.delegate.finishData(); 10914 this.transitionTo("tagOpen" /* tagOpen */); 10915 this.markTagStart(); 10916 this.consume(); 10917 } 10918 else if (char === '&') { 10919 this.consume(); 10920 this.delegate.appendToData(this.consumeCharRef() || '&'); 10921 } 10922 else { 10923 this.consume(); 10924 this.delegate.appendToData(char); 10925 } 10926 }, 10927 tagOpen: function () { 10928 var char = this.consume(); 10929 if (char === '!') { 10930 this.transitionTo("markupDeclarationOpen" /* markupDeclarationOpen */); 10931 } 10932 else if (char === '/') { 10933 this.transitionTo("endTagOpen" /* endTagOpen */); 10934 } 10935 else if (char === '@' || char === ':' || isAlpha(char)) { 10936 this.transitionTo("tagName" /* tagName */); 10937 this.tagNameBuffer = ''; 10938 this.delegate.beginStartTag(); 10939 this.appendToTagName(char); 10940 } 10941 }, 10942 markupDeclarationOpen: function () { 10943 var char = this.consume(); 10944 if (char === '-' && this.input.charAt(this.index) === '-') { 10945 this.consume(); 10946 this.transitionTo("commentStart" /* commentStart */); 10947 this.delegate.beginComment(); 10948 } 10949 }, 10950 commentStart: function () { 10951 var char = this.consume(); 10952 if (char === '-') { 10953 this.transitionTo("commentStartDash" /* commentStartDash */); 10954 } 10955 else if (char === '>') { 10956 this.delegate.finishComment(); 10957 this.transitionTo("beforeData" /* beforeData */); 10958 } 10959 else { 10960 this.delegate.appendToCommentData(char); 10961 this.transitionTo("comment" /* comment */); 10962 } 10963 }, 10964 commentStartDash: function () { 10965 var char = this.consume(); 10966 if (char === '-') { 10967 this.transitionTo("commentEnd" /* commentEnd */); 10968 } 10969 else if (char === '>') { 10970 this.delegate.finishComment(); 10971 this.transitionTo("beforeData" /* beforeData */); 10972 } 10973 else { 10974 this.delegate.appendToCommentData('-'); 10975 this.transitionTo("comment" /* comment */); 10976 } 10977 }, 10978 comment: function () { 10979 var char = this.consume(); 10980 if (char === '-') { 10981 this.transitionTo("commentEndDash" /* commentEndDash */); 10982 } 10983 else { 10984 this.delegate.appendToCommentData(char); 10985 } 10986 }, 10987 commentEndDash: function () { 10988 var char = this.consume(); 10989 if (char === '-') { 10990 this.transitionTo("commentEnd" /* commentEnd */); 10991 } 10992 else { 10993 this.delegate.appendToCommentData('-' + char); 10994 this.transitionTo("comment" /* comment */); 10995 } 10996 }, 10997 commentEnd: function () { 10998 var char = this.consume(); 10999 if (char === '>') { 11000 this.delegate.finishComment(); 11001 this.transitionTo("beforeData" /* beforeData */); 11002 } 11003 else { 11004 this.delegate.appendToCommentData('--' + char); 11005 this.transitionTo("comment" /* comment */); 11006 } 11007 }, 11008 tagName: function () { 11009 var char = this.consume(); 11010 if (isSpace(char)) { 11011 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 11012 } 11013 else if (char === '/') { 11014 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 11015 } 11016 else if (char === '>') { 11017 this.delegate.finishTag(); 11018 this.transitionTo("beforeData" /* beforeData */); 11019 } 11020 else { 11021 this.appendToTagName(char); 11022 } 11023 }, 11024 beforeAttributeName: function () { 11025 var char = this.peek(); 11026 if (isSpace(char)) { 11027 this.consume(); 11028 return; 11029 } 11030 else if (char === '/') { 11031 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 11032 this.consume(); 11033 } 11034 else if (char === '>') { 11035 this.consume(); 11036 this.delegate.finishTag(); 11037 this.transitionTo("beforeData" /* beforeData */); 11038 } 11039 else if (char === '=') { 11040 this.delegate.reportSyntaxError('attribute name cannot start with equals sign'); 11041 this.transitionTo("attributeName" /* attributeName */); 11042 this.delegate.beginAttribute(); 11043 this.consume(); 11044 this.delegate.appendToAttributeName(char); 11045 } 11046 else { 11047 this.transitionTo("attributeName" /* attributeName */); 11048 this.delegate.beginAttribute(); 11049 } 11050 }, 11051 attributeName: function () { 11052 var char = this.peek(); 11053 if (isSpace(char)) { 11054 this.transitionTo("afterAttributeName" /* afterAttributeName */); 11055 this.consume(); 11056 } 11057 else if (char === '/') { 11058 this.delegate.beginAttributeValue(false); 11059 this.delegate.finishAttributeValue(); 11060 this.consume(); 11061 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 11062 } 11063 else if (char === '=') { 11064 this.transitionTo("beforeAttributeValue" /* beforeAttributeValue */); 11065 this.consume(); 11066 } 11067 else if (char === '>') { 11068 this.delegate.beginAttributeValue(false); 11069 this.delegate.finishAttributeValue(); 11070 this.consume(); 11071 this.delegate.finishTag(); 11072 this.transitionTo("beforeData" /* beforeData */); 11073 } 11074 else if (char === '"' || char === "'" || char === '<') { 11075 this.delegate.reportSyntaxError(char + ' is not a valid character within attribute names'); 11076 this.consume(); 11077 this.delegate.appendToAttributeName(char); 11078 } 11079 else { 11080 this.consume(); 11081 this.delegate.appendToAttributeName(char); 11082 } 11083 }, 11084 afterAttributeName: function () { 11085 var char = this.peek(); 11086 if (isSpace(char)) { 11087 this.consume(); 11088 return; 11089 } 11090 else if (char === '/') { 11091 this.delegate.beginAttributeValue(false); 11092 this.delegate.finishAttributeValue(); 11093 this.consume(); 11094 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 11095 } 11096 else if (char === '=') { 11097 this.consume(); 11098 this.transitionTo("beforeAttributeValue" /* beforeAttributeValue */); 11099 } 11100 else if (char === '>') { 11101 this.delegate.beginAttributeValue(false); 11102 this.delegate.finishAttributeValue(); 11103 this.consume(); 11104 this.delegate.finishTag(); 11105 this.transitionTo("beforeData" /* beforeData */); 11106 } 11107 else { 11108 this.delegate.beginAttributeValue(false); 11109 this.delegate.finishAttributeValue(); 11110 this.transitionTo("attributeName" /* attributeName */); 11111 this.delegate.beginAttribute(); 11112 this.consume(); 11113 this.delegate.appendToAttributeName(char); 11114 } 11115 }, 11116 beforeAttributeValue: function () { 11117 var char = this.peek(); 11118 if (isSpace(char)) { 11119 this.consume(); 11120 } 11121 else if (char === '"') { 11122 this.transitionTo("attributeValueDoubleQuoted" /* attributeValueDoubleQuoted */); 11123 this.delegate.beginAttributeValue(true); 11124 this.consume(); 11125 } 11126 else if (char === "'") { 11127 this.transitionTo("attributeValueSingleQuoted" /* attributeValueSingleQuoted */); 11128 this.delegate.beginAttributeValue(true); 11129 this.consume(); 11130 } 11131 else if (char === '>') { 11132 this.delegate.beginAttributeValue(false); 11133 this.delegate.finishAttributeValue(); 11134 this.consume(); 11135 this.delegate.finishTag(); 11136 this.transitionTo("beforeData" /* beforeData */); 11137 } 11138 else { 11139 this.transitionTo("attributeValueUnquoted" /* attributeValueUnquoted */); 11140 this.delegate.beginAttributeValue(false); 11141 this.consume(); 11142 this.delegate.appendToAttributeValue(char); 11143 } 11144 }, 11145 attributeValueDoubleQuoted: function () { 11146 var char = this.consume(); 11147 if (char === '"') { 11148 this.delegate.finishAttributeValue(); 11149 this.transitionTo("afterAttributeValueQuoted" /* afterAttributeValueQuoted */); 11150 } 11151 else if (char === '&') { 11152 this.delegate.appendToAttributeValue(this.consumeCharRef() || '&'); 11153 } 11154 else { 11155 this.delegate.appendToAttributeValue(char); 11156 } 11157 }, 11158 attributeValueSingleQuoted: function () { 11159 var char = this.consume(); 11160 if (char === "'") { 11161 this.delegate.finishAttributeValue(); 11162 this.transitionTo("afterAttributeValueQuoted" /* afterAttributeValueQuoted */); 11163 } 11164 else if (char === '&') { 11165 this.delegate.appendToAttributeValue(this.consumeCharRef() || '&'); 11166 } 11167 else { 11168 this.delegate.appendToAttributeValue(char); 11169 } 11170 }, 11171 attributeValueUnquoted: function () { 11172 var char = this.peek(); 11173 if (isSpace(char)) { 11174 this.delegate.finishAttributeValue(); 11175 this.consume(); 11176 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 11177 } 11178 else if (char === '/') { 11179 this.delegate.finishAttributeValue(); 11180 this.consume(); 11181 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 11182 } 11183 else if (char === '&') { 11184 this.consume(); 11185 this.delegate.appendToAttributeValue(this.consumeCharRef() || '&'); 11186 } 11187 else if (char === '>') { 11188 this.delegate.finishAttributeValue(); 11189 this.consume(); 11190 this.delegate.finishTag(); 11191 this.transitionTo("beforeData" /* beforeData */); 11192 } 11193 else { 11194 this.consume(); 11195 this.delegate.appendToAttributeValue(char); 11196 } 11197 }, 11198 afterAttributeValueQuoted: function () { 11199 var char = this.peek(); 11200 if (isSpace(char)) { 11201 this.consume(); 11202 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 11203 } 11204 else if (char === '/') { 11205 this.consume(); 11206 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 11207 } 11208 else if (char === '>') { 11209 this.consume(); 11210 this.delegate.finishTag(); 11211 this.transitionTo("beforeData" /* beforeData */); 11212 } 11213 else { 11214 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 11215 } 11216 }, 11217 selfClosingStartTag: function () { 11218 var char = this.peek(); 11219 if (char === '>') { 11220 this.consume(); 11221 this.delegate.markTagAsSelfClosing(); 11222 this.delegate.finishTag(); 11223 this.transitionTo("beforeData" /* beforeData */); 11224 } 11225 else { 11226 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 11227 } 11228 }, 11229 endTagOpen: function () { 11230 var char = this.consume(); 11231 if (char === '@' || char === ':' || isAlpha(char)) { 11232 this.transitionTo("tagName" /* tagName */); 11233 this.tagNameBuffer = ''; 11234 this.delegate.beginEndTag(); 11235 this.appendToTagName(char); 11236 } 11237 } 11238 }; 11239 this.reset(); 11240 } 11241 EventedTokenizer.prototype.reset = function () { 11242 this.transitionTo("beforeData" /* beforeData */); 11243 this.input = ''; 11244 this.index = 0; 11245 this.line = 1; 11246 this.column = 0; 11247 this.delegate.reset(); 11248 };
vendor: 7,203 bytes, lines 11249-11475
11249 EventedTokenizer.prototype.transitionTo = function (state) { 11250 this.state = state; 11251 }; 11252 EventedTokenizer.prototype.tokenize = function (input) { 11253 this.reset(); 11254 this.tokenizePart(input); 11255 this.tokenizeEOF(); 11256 }; 11257 EventedTokenizer.prototype.tokenizePart = function (input) { 11258 this.input += preprocessInput(input); 11259 while (this.index < this.input.length) { 11260 var handler = this.states[this.state]; 11261 if (handler !== undefined) { 11262 handler.call(this); 11263 } 11264 else { 11265 throw new Error("unhandled state " + this.state); 11266 } 11267 } 11268 }; 11269 EventedTokenizer.prototype.tokenizeEOF = function () { 11270 this.flushData(); 11271 }; 11272 EventedTokenizer.prototype.flushData = function () { 11273 if (this.state === 'data') { 11274 this.delegate.finishData(); 11275 this.transitionTo("beforeData" /* beforeData */); 11276 } 11277 }; 11278 EventedTokenizer.prototype.peek = function () { 11279 return this.input.charAt(this.index); 11280 }; 11281 EventedTokenizer.prototype.consume = function () { 11282 var char = this.peek(); 11283 this.index++; 11284 if (char === '\n') { 11285 this.line++; 11286 this.column = 0; 11287 } 11288 else { 11289 this.column++; 11290 } 11291 return char; 11292 }; 11293 EventedTokenizer.prototype.consumeCharRef = function () { 11294 var endIndex = this.input.indexOf(';', this.index); 11295 if (endIndex === -1) { 11296 return; 11297 } 11298 var entity = this.input.slice(this.index, endIndex); 11299 var chars = this.entityParser.parse(entity); 11300 if (chars) { 11301 var count = entity.length; 11302 // consume the entity chars 11303 while (count) { 11304 this.consume(); 11305 count--; 11306 } 11307 // consume the `;` 11308 this.consume(); 11309 return chars; 11310 } 11311 }; 11312 EventedTokenizer.prototype.markTagStart = function () { 11313 this.delegate.tagOpen(); 11314 }; 11315 EventedTokenizer.prototype.appendToTagName = function (char) { 11316 this.tagNameBuffer += char; 11317 this.delegate.appendToTagName(char); 11318 }; 11319 return EventedTokenizer; 11320}()); 11321 11322var Tokenizer = /** @class */ (function () { 11323 function Tokenizer(entityParser, options) { 11324 if (options === void 0) { options = {}; } 11325 this.options = options; 11326 this.token = null; 11327 this.startLine = 1; 11328 this.startColumn = 0; 11329 this.tokens = []; 11330 this.tokenizer = new EventedTokenizer(this, entityParser); 11331 this._currentAttribute = undefined; 11332 } 11333 Tokenizer.prototype.tokenize = function (input) { 11334 this.tokens = []; 11335 this.tokenizer.tokenize(input); 11336 return this.tokens; 11337 }; 11338 Tokenizer.prototype.tokenizePart = function (input) { 11339 this.tokens = []; 11340 this.tokenizer.tokenizePart(input); 11341 return this.tokens; 11342 }; 11343 Tokenizer.prototype.tokenizeEOF = function () { 11344 this.tokens = []; 11345 this.tokenizer.tokenizeEOF(); 11346 return this.tokens[0]; 11347 }; 11348 Tokenizer.prototype.reset = function () { 11349 this.token = null; 11350 this.startLine = 1; 11351 this.startColumn = 0; 11352 }; 11353 Tokenizer.prototype.current = function () { 11354 var token = this.token; 11355 if (token === null) { 11356 throw new Error('token was unexpectedly null'); 11357 } 11358 if (arguments.length === 0) { 11359 return token; 11360 } 11361 for (var i = 0; i < arguments.length; i++) { 11362 if (token.type === arguments[i]) { 11363 return token; 11364 } 11365 } 11366 throw new Error("token type was unexpectedly " + token.type); 11367 }; 11368 Tokenizer.prototype.push = function (token) { 11369 this.token = token; 11370 this.tokens.push(token); 11371 }; 11372 Tokenizer.prototype.currentAttribute = function () { 11373 return this._currentAttribute; 11374 }; 11375 Tokenizer.prototype.addLocInfo = function () { 11376 if (this.options.loc) { 11377 this.current().loc = { 11378 start: { 11379 line: this.startLine, 11380 column: this.startColumn 11381 }, 11382 end: { 11383 line: this.tokenizer.line, 11384 column: this.tokenizer.column 11385 } 11386 }; 11387 } 11388 this.startLine = this.tokenizer.line; 11389 this.startColumn = this.tokenizer.column; 11390 }; 11391 // Data 11392 Tokenizer.prototype.beginData = function () { 11393 this.push({ 11394 type: "Chars" /* Chars */, 11395 chars: '' 11396 }); 11397 }; 11398 Tokenizer.prototype.appendToData = function (char) { 11399 this.current("Chars" /* Chars */).chars += char; 11400 }; 11401 Tokenizer.prototype.finishData = function () { 11402 this.addLocInfo(); 11403 }; 11404 // Comment 11405 Tokenizer.prototype.beginComment = function () { 11406 this.push({ 11407 type: "Comment" /* Comment */, 11408 chars: '' 11409 }); 11410 }; 11411 Tokenizer.prototype.appendToCommentData = function (char) { 11412 this.current("Comment" /* Comment */).chars += char; 11413 }; 11414 Tokenizer.prototype.finishComment = function () { 11415 this.addLocInfo(); 11416 }; 11417 // Tags - basic 11418 Tokenizer.prototype.tagOpen = function () { }; 11419 Tokenizer.prototype.beginStartTag = function () { 11420 this.push({ 11421 type: "StartTag" /* StartTag */, 11422 tagName: '', 11423 attributes: [], 11424 selfClosing: false 11425 }); 11426 }; 11427 Tokenizer.prototype.beginEndTag = function () { 11428 this.push({ 11429 type: "EndTag" /* EndTag */, 11430 tagName: '' 11431 }); 11432 }; 11433 Tokenizer.prototype.finishTag = function () { 11434 this.addLocInfo(); 11435 }; 11436 Tokenizer.prototype.markTagAsSelfClosing = function () { 11437 this.current("StartTag" /* StartTag */).selfClosing = true; 11438 }; 11439 // Tags - name 11440 Tokenizer.prototype.appendToTagName = function (char) { 11441 this.current("StartTag" /* StartTag */, "EndTag" /* EndTag */).tagName += char; 11442 }; 11443 // Tags - attributes 11444 Tokenizer.prototype.beginAttribute = function () { 11445 this._currentAttribute = ['', '', false]; 11446 }; 11447 Tokenizer.prototype.appendToAttributeName = function (char) { 11448 this.currentAttribute()[0] += char; 11449 }; 11450 Tokenizer.prototype.beginAttributeValue = function (isQuoted) { 11451 this.currentAttribute()[2] = isQuoted; 11452 }; 11453 Tokenizer.prototype.appendToAttributeValue = function (char) { 11454 this.currentAttribute()[1] += char; 11455 }; 11456 Tokenizer.prototype.finishAttributeValue = function () { 11457 this.current("StartTag" /* StartTag */).attributes.push(this._currentAttribute); 11458 }; 11459 Tokenizer.prototype.reportSyntaxError = function (message) { 11460 this.current().syntaxError = message; 11461 }; 11462 return Tokenizer; 11463}()); 11464 11465function tokenize(input, options) { 11466 var tokenizer = new Tokenizer(new EntityParser(namedCharRefs), options); 11467 return tokenizer.tokenize(input); 11468} 11469 11470 11471 11472// EXTERNAL MODULE: ./node_modules/fast-deep-equal/es6/index.js 11473var es6 = __webpack_require__(5619); 11474var es6_default = /*#__PURE__*/__webpack_require__.n(es6); 11475;
11475// CONCATENATED MODULE: external ["wp","htmlEntities"] 11476const external_wp_htmlEntities_namespaceObject = window["wp"]["htmlEntities"]; 11477;// CONCATENATED MODULE: ./packages/blocks/build-module/api/validation/logger.js 11478/** 11479 * @typedef LoggerItem 11480 * @property {Function} log Which logger recorded the message 11481 * @property {Array<any>} args White arguments were supplied to the logger 11482 */ 11483 11484function createLogger() { 11485 /** 11486 * Creates a log handler with block validation prefix. 11487 * 11488 * @param {Function} logger Original logger function. 11489 * 11490 * @return {Function} Augmented logger function. 11491 */ 11492 function createLogHandler(logger) { 11493 let log = (message, ...args) => logger('Block validation: ' + message, ...args); 11494 11495 // In test environments, pre-process string substitutions to improve 11496 // readability of error messages. We'd prefer to avoid pulling in this 11497 // dependency in runtime environments, and it can be dropped by a combo 11498 // of Webpack env substitution + UglifyJS dead code elimination. 11499 if (false) {} 11500 return log; 11501 } 11502 return { 11503 // eslint-disable-next-line no-console 11504 error: createLogHandler(console.error), 11505 // eslint-disable-next-line no-console 11506 warning: createLogHandler(console.warn), 11507 getItems() { 11508 return []; 11509 } 11510 }; 11511} 11512function createQueuedLogger() { 11513 /** 11514 * The list of enqueued log actions to print. 11515 * 11516 * @type {Array<LoggerItem>} 11517 */ 11518 const queue = []; 11519 const logger = createLogger(); 11520 return { 11521 error(...args) { 11522 queue.push({ 11523 log: logger.error, 11524 args 11525 }); 11526 }, 11527 warning(...args) { 11528 queue.push({ 11529 log: logger.warning, 11530 args 11531 }); 11532 }, 11533 getItems() { 11534 return queue; 11535 } 11536 }; 11537} 11538 11539;// CONCATENATED MODULE: ./packages/blocks/build-module/api/validation/index.js 11540/** 11541 * External dependencies 11542 */ 11543 11544 11545 11546/** 11547 * WordPress dependencies 11548 */ 11549 11550 11551 11552/** 11553 * Internal dependencies 11554 */ 11555 11556 11557 11558 11559 11560/** @typedef {import('../parser').WPBlock} WPBlock */ 11561/** @typedef {import('../registration').WPBlockType} WPBlockType */ 11562/** @typedef {import('./logger').LoggerItem} LoggerItem */ 11563 11564const identity = x => x; 11565 11566/** 11567 * Globally matches any consecutive whitespace 11568 * 11569 * @type {RegExp} 11570 */ 11571const REGEXP_WHITESPACE = /[\t\n\r\v\f ]+/g; 11572 11573/** 11574 * Matches a string containing only whitespace 11575 * 11576 * @type {RegExp} 11577 */ 11578const REGEXP_ONLY_WHITESPACE = /^[\t\n\r\v\f ]*$/; 11579 11580/** 11581 * Matches a CSS URL type value 11582 * 11583 * @type {RegExp} 11584 */ 11585const REGEXP_STYLE_URL_TYPE = /^url\s*\(['"\s]*(.*?)['"\s]*\)$/; 11586 11587/** 11588 * Boolean attributes are attributes whose presence as being assigned is 11589 * meaningful, even if only empty. 11590 * 11591 * See: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#boolean-attributes 11592 * Extracted from: https://html.spec.whatwg.org/multipage/indices.html#attributes-3 11593 * 11594 * Object.keys( Array.from( document.querySelectorAll( '#attributes-1 > tbody > tr' ) ) 11595 * .filter( ( tr ) => tr.lastChild.textContent.indexOf( 'Boolean attribute' ) !== -1 ) 11596 * .reduce( ( result, tr ) => Object.assign( result, { 11597 * [ tr.firstChild.textContent.trim() ]: true 11598 * } ), {} ) ).sort(); 11599 * 11600 * @type {Array} 11601 */ 11602const 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']; 11603 11604/** 11605 * Enumerated attributes are attributes which must be of a specific value form. 11606 * Like boolean attributes, these are meaningful if specified, even if not of a 11607 * valid enumerated value. 11608 * 11609 * See: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#enumerated-attribute 11610 * Extracted from: https://html.spec.whatwg.org/multipage/indices.html#attributes-3 11611 * 11612 * Object.keys( Array.from( document.querySelectorAll( '#attributes-1 > tbody > tr' ) ) 11613 * .filter( ( tr ) => /^("(.+?)";?\s*)+/.test( tr.lastChild.textContent.trim() ) ) 11614 * .reduce( ( result, tr ) => Object.assign( result, { 11615 * [ tr.firstChild.textContent.trim() ]: true 11616 * } ), {} ) ).sort(); 11617 * 11618 * @type {Array} 11619 */ 11620const 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']; 11621 11622/** 11623 * Meaningful attributes are those who cannot be safely ignored when omitted in 11624 * one HTML markup string and not another. 11625 * 11626 * @type {Array} 11627 */ 11628const MEANINGFUL_ATTRIBUTES = [...BOOLEAN_ATTRIBUTES, ...ENUMERATED_ATTRIBUTES]; 11629 11630/**
11631 * Array of functions which receive a text string on which to apply normalizing 11632 * behavior for consideration in text token equivalence, carefully ordered from 11633 * least-to-most expensive operations. 11634 * 11635 * @type {Array} 11636 */ 11637const TEXT_NORMALIZATIONS = [identity, getTextWithCollapsedWhitespace]; 11638 11639/** 11640 * Regular expression matching a named character reference. In lieu of bundling 11641 * a full set of references, the pattern covers the minimal necessary to test 11642 * positively against the full set. 11643 * 11644 * "The ampersand must be followed by one of the names given in the named 11645 * character references section, using the same case." 11646 * 11647 * Tested aginst "12.5 Named character references": 11648 * 11649 * ``` 11650 * const references = Array.from( document.querySelectorAll( 11651 * '#named-character-references-table tr[id^=entity-] td:first-child' 11652 * ) ).map( ( code ) => code.textContent ) 11653 * references.every( ( reference ) => /^[\da-z]+$/i.test( reference ) ) 11654 * ``` 11655 * 11656 * @see https://html.spec.whatwg.org/multipage/syntax.html#character-references 11657 * @see https://html.spec.whatwg.org/multipage/named-characters.html#named-character-references 11658 * 11659 * @type {RegExp} 11660 */ 11661const REGEXP_NAMED_CHARACTER_REFERENCE = /^[\da-z]+$/i; 11662 11663/** 11664 * Regular expression matching a decimal character reference. 11665 * 11666 * "The ampersand must be followed by a U+0023 NUMBER SIGN character (#), 11667 * followed by one or more ASCII digits, representing a base-ten integer" 11668 * 11669 * @see https://html.spec.whatwg.org/multipage/syntax.html#character-references 11670 * 11671 * @type {RegExp} 11672 */ 11673const REGEXP_DECIMAL_CHARACTER_REFERENCE = /^#\d+$/; 11674 11675/** 11676 * Regular expression matching a hexadecimal character reference. 11677 * 11678 * "The ampersand must be followed by a U+0023 NUMBER SIGN character (#), which 11679 * must be followed by either a U+0078 LATIN SMALL LETTER X character (x) or a 11680 * U+0058 LATIN CAPITAL LETTER X character (X), which must then be followed by 11681 * one or more ASCII hex digits, representing a hexadecimal integer" 11682 * 11683 * @see https://html.spec.whatwg.org/multipage/syntax.html#character-references 11684 * 11685 * @type {RegExp} 11686 */ 11687const REGEXP_HEXADECIMAL_CHARACTER_REFERENCE = /^#x[\da-f]+$/i; 11688 11689/** 11690 * Returns true if the given string is a valid character reference segment, or 11691 * false otherwise. The text should be stripped of `&` and `;` demarcations. 11692 * 11693 * @param {string} text Text to test. 11694 * 11695 * @return {boolean} Whether text is valid character reference. 11696 */ 11697function isValidCharacterReference(text) { 11698 return REGEXP_NAMED_CHARACTER_REFERENCE.test(text) || REGEXP_DECIMAL_CHARACTER_REFERENCE.test(text) || REGEXP_HEXADECIMAL_CHARACTER_REFERENCE.test(text); 11699} 11700 11701/** 11702 * Subsitute EntityParser class for `simple-html-tokenizer` which uses the 11703 * implementation of `decodeEntities` from `html-entities`, in order to avoid 11704 * bundling a massive named character reference. 11705 * 11706 * @see https://github.com/tildeio/simple-html-tokenizer/tree/HEAD/src/entity-parser.ts 11707 */ 11708class DecodeEntityParser { 11709 /** 11710 * Returns a substitute string for an entity string sequence between `&` 11711 * and `;`, or undefined if no substitution should occur. 11712 * 11713 * @param {string} entity Entity fragment discovered in HTML. 11714 * 11715 * @return {string | undefined} Entity substitute value. 11716 */ 11717 parse(entity) { 11718 if (isValidCharacterReference(entity)) { 11719 return (0,external_wp_htmlEntities_namespaceObject.decodeEntities)('&' + entity + ';'); 11720 } 11721 } 11722} 11723 11724/** 11725 * Given a specified string, returns an array of strings split by consecutive 11726 * whitespace, ignoring leading or trailing whitespace. 11727 * 11728 * @param {string} text Original text. 11729 * 11730 * @return {string[]} Text pieces split on whitespace. 11731 */ 11732function getTextPiecesSplitOnWhitespace(text) { 11733 return text.trim().split(REGEXP_WHITESPACE); 11734} 11735 11736/** 11737 * Given a specified string, returns a new trimmed string where all consecutive 11738 * whitespace is collapsed to a single space. 11739 * 11740 * @param {string} text Original text. 11741 * 11742 * @return {string} Trimmed text with consecutive whitespace collapsed. 11743 */ 11744function getTextWithCollapsedWhitespace(text) { 11745 // This is an overly simplified whitespace comparison. The specification is 11746 // more prescriptive of whitespace behavior in inline and block contexts. 11747 // 11748 // See: https://medium.com/@patrickbrosset/when-does-white-space-matter-in-html-b9
117480e8a7cdd33 11749 return getTextPiecesSplitOnWhitespace(text).join(' '); 11750} 11751 11752/** 11753 * Returns attribute pairs of the given StartTag token, including only pairs 11754 * where the value is non-empty or the attribute is a boolean attribute, an 11755 * enumerated attribute, or a custom data- attribute. 11756 * 11757 * @see MEANINGFUL_ATTRIBUTES 11758 * 11759 * @param {Object} token StartTag token. 11760 * 11761 * @return {Array[]} Attribute pairs. 11762 */ 11763function getMeaningfulAttributePairs(token) { 11764 return token.attributes.filter(pair => { 11765 const [key, value] = pair; 11766 return value || key.indexOf('data-') === 0 || MEANINGFUL_ATTRIBUTES.includes(key); 11767 }); 11768} 11769 11770/** 11771 * Returns true if two text tokens (with `chars` property) are equivalent, or 11772 * false otherwise. 11773 * 11774 * @param {Object} actual Actual token. 11775 * @param {Object} expected Expected token. 11776 * @param {Object} logger Validation logger object. 11777 * 11778 * @return {boolean} Whether two text tokens are equivalent. 11779 */ 11780function isEquivalentTextTokens(actual, expected, logger = createLogger()) { 11781 // This function is intentionally written as syntactically "ugly" as a hot 11782 // path optimization. Text is progressively normalized in order from least- 11783 // to-most operationally expensive, until the earliest point at which text 11784 // can be confidently inferred as being equal. 11785 let actualChars = actual.chars; 11786 let expectedChars = expected.chars; 11787 for (let i = 0; i < TEXT_NORMALIZATIONS.length; i++) { 11788 const normalize = TEXT_NORMALIZATIONS[i]; 11789 actualChars = normalize(actualChars); 11790 expectedChars = normalize(expectedChars); 11791 if (actualChars === expectedChars) { 11792 return true; 11793 } 11794 } 11795 logger.warning('Expected text `%s`, saw `%s`.', expected.chars, actual.chars); 11796 return false; 11797} 11798 11799/** 11800 * Given a CSS length value, returns a normalized CSS length value for strict equality 11801 * comparison. 11802 * 11803 * @param {string} value CSS length value. 11804 * 11805 * @return {string} Normalized CSS length value. 11806 */ 11807function getNormalizedLength(value) { 11808 if (0 === parseFloat(value)) { 11809 return '0'; 11810 } 11811 // Normalize strings with floats to always include a leading zero. 11812 if (value.indexOf('.') === 0) { 11813 return '0' + value; 11814 } 11815 return value; 11816} 11817 11818/** 11819 * Given a style value, returns a normalized style value for strict equality 11820 * comparison. 11821 * 11822 * @param {string} value Style value. 11823 * 11824 * @return {string} Normalized style value. 11825 */ 11826function getNormalizedStyleValue(value) { 11827 const textPieces = getTextPiecesSplitOnWhitespace(value); 11828 const normalizedPieces = textPieces.map(getNormalizedLength); 11829 const result = normalizedPieces.join(' '); 11830 return result 11831 // Normalize URL type to omit whitespace or quotes. 11832 .replace(REGEXP_STYLE_URL_TYPE, 'url($1)'); 11833} 11834 11835/** 11836 * Given a style attribute string, returns an object of style properties. 11837 * 11838 * @param {string} text Style attribute. 11839 * 11840 * @return {Object} Style properties. 11841 */ 11842function getStyleProperties(text) { 11843 const pairs = text 11844 // Trim ending semicolon (avoid including in split) 11845 .replace(/;?\s*$/, '') 11846 // Split on property assignment. 11847 .split(';') 11848 // For each property assignment... 11849 .map(style => { 11850 // ...split further into key-value pairs. 11851 const [key, ...valueParts] = style.split(':'); 11852 const value = valueParts.join(':'); 11853 return [key.trim(), getNormalizedStyleValue(value.trim())]; 11854 }); 11855 return Object.fromEntries(pairs); 11856} 11857 11858/** 11859 * Attribute-specific equality handlers 11860 * 11861 * @type {Object} 11862 */ 11863const isEqualAttributesOfName = { 11864 class: (actual, expected) => { 11865 // Class matches if members are the same, even if out of order or 11866 // superfluous whitespace between. 11867 const [actualPieces, expectedPieces] = [actual, expected].map(getTextPiecesSplitOnWhitespace); 11868 const actualDiff = actualPieces.filter(c => !expectedPieces.includes(c)); 11869 const expectedDiff = expectedPieces.filter(c => !actualPieces.includes(c)); 11870 return actualDiff.length === 0 && expectedDiff.length === 0; 11871 }, 11872 style: (actual, expected) => { 11873 return es6_default()(...[actual, expected].map(getStyleProperties)); 11874 }, 11875 // For each boolean attribute, mere presence of attribute in both is enough 11876 // to assume equivalence. 11877 ...Object.fromEntries(BOOLEAN_ATTRIBUTES.map(attribute => [attribute, () => true])) 11878}; 11879 11880/** 11881 * Given two sets of attribute tuples, returns true if the attribute sets are 11882 * equivalent. 11883 * 11884 * @param {Array[]} actual Actual attributes tuples. 11885 * @param {Array[]} expected Expected attributes tuples. 11886 * @param {Object} logger Validation logger object. 11887 * 11888 * @return {boolean} Whether attributes are equivalent. 11889 */ 11890function isEqualTagAttributePairs(actual, expected, logger = createLogger()) { 11891 // Attributes is tokenized as tuples. Their lengths should match. This also 11892 // avoids us needing to check both attributes sets, since if A has any keys 11893 // which do not exist in B, we know the sets to be different. 11894 if (actual.length !== expected.length) { 11895 logger.warning('Expected attributes %o, instead saw %o.', expected, actual); 11896 return false;
11897 } 11898 11899 // Attributes are not guaranteed to occur in the same order. For validating 11900 // actual attributes, first convert the set of expected attribute values to 11901 // an object, for lookup by key. 11902 const expectedAttributes = {}; 11903 for (let i = 0; i < expected.length; i++) { 11904 expectedAttributes[expected[i][0].toLowerCase()] = expected[i][1]; 11905 } 11906 for (let i = 0; i < actual.length; i++) { 11907 const [name, actualValue] = actual[i]; 11908 const nameLower = name.toLowerCase(); 11909 11910 // As noted above, if missing member in B, assume different. 11911 if (!expectedAttributes.hasOwnProperty(nameLower)) { 11912 logger.warning('Encountered unexpected attribute `%s`.', name); 11913 return false; 11914 } 11915 const expectedValue = expectedAttributes[nameLower]; 11916 const isEqualAttributes = isEqualAttributesOfName[nameLower]; 11917 if (isEqualAttributes) { 11918 // Defer custom attribute equality handling. 11919 if (!isEqualAttributes(actualValue, expectedValue)) { 11920 logger.warning('Expected attribute `%s` of value `%s`, saw `%s`.', name, expectedValue, actualValue); 11921 return false; 11922 } 11923 } else if (actualValue !== expectedValue) { 11924 // Otherwise strict inequality should bail. 11925 logger.warning('Expected attribute `%s` of value `%s`, saw `%s`.', name, expectedValue, actualValue); 11926 return false; 11927 } 11928 } 11929 return true; 11930} 11931 11932/** 11933 * Token-type-specific equality handlers 11934 * 11935 * @type {Object} 11936 */ 11937const isEqualTokensOfType = { 11938 StartTag: (actual, expected, logger = createLogger()) => { 11939 if (actual.tagName !== expected.tagName && 11940 // Optimization: Use short-circuit evaluation to defer case- 11941 // insensitive check on the assumption that the majority case will 11942 // have exactly equal tag names. 11943 actual.tagName.toLowerCase() !== expected.tagName.toLowerCase()) { 11944 logger.warning('Expected tag name `%s`, instead saw `%s`.', expected.tagName, actual.tagName); 11945 return false; 11946 } 11947 return isEqualTagAttributePairs(...[actual, expected].map(getMeaningfulAttributePairs), logger); 11948 }, 11949 Chars: isEquivalentTextTokens, 11950 Comment: isEquivalentTextTokens 11951}; 11952 11953/** 11954 * Given an array of tokens, returns the first token which is not purely 11955 * whitespace. 11956 * 11957 * Mutates the tokens array. 11958 * 11959 * @param {Object[]} tokens Set of tokens to search. 11960 * 11961 * @return {Object | undefined} Next non-whitespace token. 11962 */ 11963function getNextNonWhitespaceToken(tokens) { 11964 let token; 11965 while (token = tokens.shift()) { 11966 if (token.type !== 'Chars') { 11967 return token; 11968 } 11969 if (!REGEXP_ONLY_WHITESPACE.test(token.chars)) { 11970 return token; 11971 } 11972 } 11973} 11974 11975/** 11976 * Tokenize an HTML string, gracefully handling any errors thrown during 11977 * underlying tokenization. 11978 * 11979 * @param {string} html HTML string to tokenize. 11980 * @param {Object} logger Validation logger object. 11981 * 11982 * @return {Object[]|null} Array of valid tokenized HTML elements, or null on error 11983 */ 11984function getHTMLTokens(html, logger = createLogger()) { 11985 try { 11986 return new Tokenizer(new DecodeEntityParser()).tokenize(html); 11987 } catch (e) { 11988 logger.warning('Malformed HTML detected: %s', html); 11989 } 11990 return null; 11991} 11992 11993/** 11994 * Returns true if the next HTML token closes the current token. 11995 * 11996 * @param {Object} currentToken Current token to compare with. 11997 * @param {Object|undefined} nextToken Next token to compare against. 11998 * 11999 * @return {boolean} true if `nextToken` closes `currentToken`, false otherwise 12000 */ 12001function isClosedByToken(currentToken, nextToken) { 12002 // Ensure this is a self closed token. 12003 if (!currentToken.selfClosing) { 12004 return false; 12005 } 12006 12007 // Check token names and determine if nextToken is the closing tag for currentToken. 12008 if (nextToken && nextToken.tagName === currentToken.tagName && nextToken.type === 'EndTag') { 12009 return true; 12010 } 12011 return false; 12012} 12013 12014/** 12015 * Returns true if the given HTML strings are effectively equivalent, or 12016 * false otherwise. Invalid HTML is not considered equivalent, even if the 12017 * strings directly match. 12018 * 12019 * @param {string} actual Actual HTML string. 12020 * @param {string} expected Expected HTML string. 12021 * @param {Object} logger Validation logger object. 12022 * 12023 * @return {boolean}
12023 Whether HTML strings are equivalent. 12024 */ 12025function isEquivalentHTML(actual, expected, logger = createLogger()) { 12026 // Short-circuit if markup is identical. 12027 if (actual === expected) { 12028 return true; 12029 } 12030 12031 // Tokenize input content and reserialized save content. 12032 const [actualTokens, expectedTokens] = [actual, expected].map(html => getHTMLTokens(html, logger)); 12033 12034 // If either is malformed then stop comparing - the strings are not equivalent. 12035 if (!actualTokens || !expectedTokens) { 12036 return false; 12037 } 12038 let actualToken, expectedToken; 12039 while (actualToken = getNextNonWhitespaceToken(actualTokens)) { 12040 expectedToken = getNextNonWhitespaceToken(expectedTokens); 12041 12042 // Inequal if exhausted all expected tokens. 12043 if (!expectedToken) { 12044 logger.warning('Expected end of content, instead saw %o.', actualToken); 12045 return false; 12046 } 12047 12048 // Inequal if next non-whitespace token of each set are not same type. 12049 if (actualToken.type !== expectedToken.type) { 12050 logger.warning('Expected token of type `%s` (%o), instead saw `%s` (%o).', expectedToken.type, expectedToken, actualToken.type, actualToken); 12051 return false; 12052 } 12053 12054 // Defer custom token type equality handling, otherwise continue and 12055 // assume as equal. 12056 const isEqualTokens = isEqualTokensOfType[actualToken.type]; 12057 if (isEqualTokens && !isEqualTokens(actualToken, expectedToken, logger)) { 12058 return false; 12059 } 12060 12061 // Peek at the next tokens (actual and expected) to see if they close 12062 // a self-closing tag. 12063 if (isClosedByToken(actualToken, expectedTokens[0])) { 12064 // Consume the next expected token that closes the current actual 12065 // self-closing token. 12066 getNextNonWhitespaceToken(expectedTokens); 12067 } else if (isClosedByToken(expectedToken, actualTokens[0])) { 12068 // Consume the next actual token that closes the current expected 12069 // self-closing token. 12070 getNextNonWhitespaceToken(actualTokens); 12071 } 12072 } 12073 if (expectedToken = getNextNonWhitespaceToken(expectedTokens)) { 12074 // If any non-whitespace tokens remain in expected token set, this 12075 // indicates inequality. 12076 logger.warning('Expected %o, instead saw end of content.', expectedToken); 12077 return false; 12078 } 12079 return true; 12080} 12081 12082/** 12083 * Returns an object with `isValid` property set to `true` if the parsed block 12084 * is valid given the input content. A block is considered valid if, when serialized 12085 * with assumed attributes, the content matches the original value. If block is 12086 * invalid, this function returns all validations issues as well. 12087 * 12088 * @param {string|Object} blockTypeOrName Block type. 12089 * @param {Object} attributes Parsed block attributes. 12090 * @param {string} originalBlockContent Original block content. 12091 * @param {Object} logger Validation logger object. 12092 * 12093 * @return {Object} Whether block is valid and contains validation messages. 12094 */ 12095 12096/** 12097 * Returns an object with `isValid` property set to `true` if the parsed block 12098 * is valid given the input content. A block is considered valid if, when serialized 12099 * with assumed attributes, the content matches the original value. If block is 12100 * invalid, this function returns all validations issues as well. 12101 * 12102 * @param {WPBlock} block block object. 12103 * @param {WPBlockType|string} [blockTypeOrName = block.name] Block type or name, inferred from block if not given. 12104 * 12105 * @return {[boolean,Array<LoggerItem>]} validation results. 12106 */ 12107function validateBlock(block, blockTypeOrName = block.name) { 12108 const isFallbackBlock = block.name === getFreeformContentHandlerName() || block.name === getUnregisteredTypeHandlerName(); 12109 12110 // Shortcut to avoid costly validation. 12111 if (isFallbackBlock) { 12112 return [true, []]; 12113 } 12114 const logger = createQueuedLogger(); 12115 const blockType = normalizeBlockType(blockTypeOrName); 12116 let generatedBlockContent; 12117 try { 12118 generatedBlockContent = getSaveContent(blockType, block.attributes); 12119 } catch (error) { 12120 logger.error('Block validation failed because an error occurred while generating block content:\n\n%s', error.toString()); 12121 return [false, logger.getItems()]; 12122 } 12123 const isValid = isEquivalentHTML(block.originalContent, generatedBlockContent, logger); 12124 if (!isValid) { 12125 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.n
12125ame, blockType, generatedBlockContent, block.originalContent); 12126 } 12127 return [isValid, logger.getItems()]; 12128} 12129 12130/** 12131 * Returns true if the parsed block is valid given the input content. A block 12132 * is considered valid if, when serialized with assumed attributes, the content 12133 * matches the original value. 12134 * 12135 * Logs to console in development environments when invalid. 12136 * 12137 * @deprecated Use validateBlock instead to avoid data loss. 12138 * 12139 * @param {string|Object} blockTypeOrName Block type. 12140 * @param {Object} attributes Parsed block attributes. 12141 * @param {string} originalBlockContent Original block content. 12142 * 12143 * @return {boolean} Whether block is valid. 12144 */ 12145function isValidBlockContent(blockTypeOrName, attributes, originalBlockContent) { 12146 external_wp_deprecated_default()('isValidBlockContent introduces opportunity for data loss', { 12147 since: '12.6', 12148 plugin: 'Gutenberg', 12149 alternative: 'validateBlock' 12150 }); 12151 const blockType = normalizeBlockType(blockTypeOrName); 12152 const block = { 12153 name: blockType.n
12153ame, 12154 attributes, 12155 innerBlocks: [], 12156 originalContent: originalBlockContent 12157 }; 12158 const [isValid] = validateBlock(block, blockType); 12159 return isValid; 12160} 12161 12162;// CONCATENATED MODULE: ./packages/blocks/build-module/api/parser/convert-legacy-block.js 12163/** 12164 * Convert legacy blocks to their canonical form. This function is used 12165 * both in the parser level for previous content and to convert such blocks 12166 * used in Custom Post Types templates. 12167 * 12168 * @param {string} name The block's name 12169 * @param {Object} attributes The block's attributes 12170 * 12171 * @return {[string, Object]} The block's name and attributes, changed accordingly if a match was found 12172 */ 12173function convertLegacyBlockNameAndAttributes(name, attributes) { 12174 const newAttributes = { 12175 ...attributes 12176 }; 12177 // Convert 'core/cover-image' block in existing content to 'core/cover'. 12178 if ('core/cover-image' === name) { 12179 name = 'core/cover'; 12180 } 12181 12182 // Convert 'core/text' blocks in existing content to 'core/paragraph'. 12183 if ('core/text' === name || 'core/cover-text' === name) { 12184 name = 'core/paragraph'; 12185 } 12186 12187 // Convert derivative blocks such as 'core/social-link-wordpress' to the 12188 // canonical form 'core/social-link'. 12189 if (name && name.indexOf('core/social-link-') === 0) { 12190 // Capture `social-link-wordpress` into `{"service":"wordpress"}` 12191 newAttributes.service = name.substring(17); 12192 name = 'core/social-link'; 12193 } 12194 12195 // Convert derivative blocks such as 'core-embed/instagram' to the 12196 // canonical form 'core/embed'. 12197 if (name && name.indexOf('core-embed/') === 0) { 12198 // Capture `core-embed/instagram` into `{"providerNameSlug":"instagram"}` 12199 const providerSlug = name.substring(11); 12200 const deprecated = { 12201 speaker: 'speaker-deck', 12202 polldaddy: 'crowdsignal' 12203 }; 12204 newAttributes.providerNameSlug = providerSlug in deprecated ? deprecated[providerSlug] : providerSlug; 12205 // This is needed as the `responsive` attribute was passed 12206 // in a different way before the refactoring to block variations. 12207 if (!['amazon-kindle', 'wordpress'].includes(providerSlug)) { 12208 newAttributes.responsive = true; 12209 } 12210 name = 'core/embed'; 12211 } 12212 12213 // Convert Post Comment blocks in existing content to Comment blocks. 12214 // TODO: Remove these checks when WordPress 6.0 is released. 12215 if (name === 'core/post-comment-author') { 12216 name = 'core/comment-author-name'; 12217 } 12218 if (name === 'core/post-comment-content') { 12219 name = 'core/comment-content'; 12220 } 12221 if (name === 'core/post-comment-date') { 12222 name = 'core/comment-date'; 12223 } 12224 if (name === 'core/comments-query-loop') { 12225 name = 'core/comments'; 12226 const { 12227 className = '' 12228 } = newAttributes; 12229 if (!className.includes('wp-block-comments-query-loop')) { 12230 newAttributes.className = ['wp-block-comments-query-loop', className].join(' '); 12231 } 12232 // Note that we also had to add a deprecation to the block in order 12233 // for the ID change to work. 12234 } 12235 12236 if (name === 'core/post-comments') { 12237 name = 'core/comments'; 12238 newAttributes.legacy = true; 12239 } 12240 return [name, newAttributes]; 12241} 12242 12243;
12243// CONCATENATED MODULE: ./node_modules/hpq/es/get-path.js 12244/** 12245 * Given object and string of dot-delimited path segments, returns value at 12246 * path or undefined if path cannot be resolved. 12247 * 12248 * @param {Object} object Lookup object 12249 * @param {string} path Path to resolve 12250 * @return {?*} Resolved value 12251 */ 12252function getPath(object, path) { 12253 var segments = path.split('.'); 12254 var segment; 12255 12256 while (segment = segments.shift()) { 12257 if (!(segment in object)) { 12258 return; 12259 } 12260 12261 object = object[segment]; 12262 } 12263 12264 return object; 12265} 12266;// CONCATENATED MODULE: ./node_modules/hpq/es/index.js 12267/** 12268 * Internal dependencies 12269 */ 12270 12271/** 12272 * Function returning a DOM document created by `createHTMLDocument`. The same 12273 * document is returned between invocations. 12274 * 12275 * @return {Document} DOM document. 12276 */ 12277 12278var getDocument = function () { 12279 var doc; 12280 return function () { 12281 if (!doc) { 12282 doc = document.implementation.createHTMLDocument(''); 12283 } 12284 12285 return doc; 12286 }; 12287}(); 12288/** 12289 * Given a markup string or DOM element, creates an object aligning with the 12290 * shape of the matchers object, or the value returned by the matcher. 12291 * 12292 * @param {(string|Element)} source Source content 12293 * @param {(Object|Function)} matchers Matcher function or object of matchers 12294 * @return {(Object|*)} Matched value(s), shaped by object 12295 */ 12296 12297 12298function parse(source, matchers) { 12299 if (!matchers) { 12300 return; 12301 } // Coerce to element 12302 12303 12304 if ('string' === typeof source) { 12305 var doc = getDocument(); 12306 doc.body.innerHTML = source; 12307 source = doc.body; 12308 } // Return singular value 12309 12310 12311 if ('function' === typeof matchers) { 12312 return matchers(source); 12313 } // Bail if we can't handle matchers 12314 12315 12316 if (Object !== matchers.constructor) { 12317 return; 12318 } // Shape result by matcher object 12319 12320 12321 return Object.keys(matchers).reduce(function (memo, key) { 12322 memo[key] = parse(source, matchers[key]); 12323 return memo; 12324 }, {}); 12325} 12326/** 12327 * Generates a function which matches node of type selector, returning an 12328 * attribute by property if the attribute exists. If no selector is passed, 12329 * returns property of the query element. 12330 * 12331 * @param {?string} selector Optional selector 12332 * @param {string} name Property name 12333 * @return {*} Property value 12334 */ 12335 12336function prop(selector, name) { 12337 if (1 === arguments.length) { 12338 name = selector; 12339 selector = undefined; 12340 } 12341 12342 return function (node) { 12343 var match = node; 12344 12345 if (selector) { 12346 match = node.querySelector(selector); 12347 } 12348 12349 if (match) { 12350 return getPath(match, name); 12351 } 12352 }; 12353} 12354/** 12355 * Generates a function which matches node of type selector, returning an 12356 * attribute by name if the attribute exists. If no selector is passed, 12357 * returns attribute of the query element. 12358 * 12359 * @param {?string} selector Optional selector 12360 * @param {string} name Attribute name 12361 * @return {?string} Attribute value 12362 */ 12363 12364function attr(selector, name) { 12365 if (1 === arguments.length) { 12366 name = selector; 12367 selector = undefined; 12368 } 12369 12370 return function (node) { 12371 var attributes = prop(selector, 'attributes')(node); 12372 12373 if (attributes && attributes.hasOwnProperty(name)) { 12374 return attributes[name].value; 12375 } 12376 }; 12377} 12378/** 12379 * Convenience for `prop( selector, 'innerHTML' )`. 12380 * 12381 * @see prop() 12382 * 12383 * @param {?string} selector Optional selector 12384 * @return {string} Inner HTML 12385 */ 12386 12387function html(selector) { 12388 return prop(selector, 'innerHTML'); 12389} 12390/** 12391 * Convenience for `prop( selector, 'textContent' )`. 12392 * 12393 * @see prop() 12394 * 12395 * @param {?string} selector Optional selector 12396 * @return {string} Text content 12397 */ 12398 12399function es_text(selector) { 12400 return prop(selector, 'textContent'); 12401} 12402/** 12403 * Creates a new matching context by first finding elements matching selector 12404 * using querySelectorAll before then running another `parse` on `matchers` 12405 * scoped to the matched elements. 12406 * 12407 * @see parse() 12408 * 12409 * @param {string} selector Selector to match 12410 * @param {(Object|Function)} matchers Matcher function or object of matchers 12411 * @return {Array.<*,Object>} Array of matched value(s) 12412 */ 12413 12414function query(selector, matchers) { 12415 return function (node) { 12416 var matches = node.querySelectorAll(selector); 12417 return [].map.call(matches, function (match) { 12418 return parse(match, matchers); 12419 }); 12420 }; 12421} 12422;// CONCATENATED MODULE: ./node_modules/memize/dist/index.js 12423/** 12424 * Memize options object. 12425 * 12426 * @typedef MemizeOptions 12427 * 12428 * @property {number} [maxSize] Maximum size of the cache. 12429 */ 12430 12431/**
12432 * Internal cache entry. 12433 * 12434 * @typedef MemizeCacheNode 12435 * 12436 * @property {?MemizeCacheNode|undefined} [prev] Previous node. 12437 * @property {?MemizeCacheNode|undefined} [next] Next node. 12438 * @property {Array<*>} args Function arguments for cache 12439 * entry. 12440 * @property {*} val Function result. 12441 */ 12442 12443/** 12444 * Properties of the enhanced function for controlling cache. 12445 * 12446 * @typedef MemizeMemoizedFunction 12447 * 12448 * @property {()=>void} clear Clear the cache. 12449 */ 12450 12451/** 12452 * Accepts a function to be memoized, and returns a new memoized function, with 12453 * optional options. 12454 * 12455 * @template {(...args: any[]) => any} F 12456 * 12457 * @param {F} fn Function to memoize. 12458 * @param {MemizeOptions} [options] Options object. 12459 * 12460 * @return {((...args: Parameters<F>) => ReturnType<F>) & MemizeMemoizedFunction} Memoized function. 12461 */ 12462function memize(fn, options) { 12463 var size = 0; 12464 12465 /** @type {?MemizeCacheNode|undefined} */ 12466 var head; 12467 12468 /** @type {?MemizeCacheNode|undefined} */ 12469 var tail; 12470 12471 options = options || {}; 12472 12473 function memoized(/* ...args */) { 12474 var node = head, 12475 len = arguments.length, 12476 args, 12477 i; 12478 12479 searchCache: while (node) { 12480 // Perform a shallow equality test to confirm that whether the node 12481 // under test is a candidate for the arguments passed. Two arrays 12482 // are shallowly equal if their length matches and each entry is 12483 // strictly equal between the two sets. Avoid abstracting to a 12484 // function which could incur an arguments leaking deoptimization. 12485 12486 // Check whether node arguments match arguments length 12487 if (node.args.length !== arguments.length) { 12488 node = node.next; 12489 continue; 12490 } 12491 12492 // Check whether node arguments match arguments values 12493 for (i = 0; i < len; i++) { 12494 if (node.args[i] !== arguments[i]) { 12495 node = node.next; 12496 continue searchCache; 12497 } 12498 } 12499 12500 // At this point we can assume we've found a match 12501 12502 // Surface matched node to head if not already 12503 if (node !== head) { 12504 // As tail, shift to previous. Must only shift if not also 12505 // head, since if both head and tail, there is no previous. 12506 if (node === tail) { 12507 tail = node.prev; 12508 } 12509 12510 // Adjust siblings to point to each other. If node was tail, 12511 // this also handles new tail's empty `next` assignment. 12512 /** @type {MemizeCacheNode} */ (node.prev).next = node.next; 12513 if (node.next) { 12514 node.next.prev = node.prev; 12515 } 12516 12517 node.next = head; 12518 node.prev = null; 12519 /** @type {MemizeCacheNode} */ (head).prev = node; 12520 head = node; 12521 } 12522 12523 // Return immediately 12524 return node.val; 12525 } 12526 12527 // No cached value found. Continue to insertion phase: 12528 12529 // Create a copy of arguments (avoid leaking deoptimization) 12530 args = new Array(len); 12531 for (i = 0; i < len; i++) { 12532 args[i] = arguments[i]; 12533 } 12534 12535 node = { 12536 args: args, 12537 12538 // Generate the result from original function 12539 val: fn.apply(null, args), 12540 }; 12541 12542 // Don't need to check whether node is already head, since it would 12543 // have been returned above already if it was 12544 12545 // Shift existing head down list 12546 if (head) { 12547 head.prev = node; 12548 node.next = head; 12549 } else { 12550 // If no head, follows that there's no tail (at initial or reset) 12551 tail = node; 12552 } 12553 12554 // Trim tail if we're reached max size and are pending cache insertion 12555 if (size === /** @type {MemizeOptions} */ (options).maxSize) { 12556 tail = /** @type {MemizeCacheNode} */ (tail).prev; 12557 /** @type {MemizeCacheNode} */ (tail).next = null; 12558 } else { 12559 size++; 12560 } 12561 12562 head = node; 12563 12564 return node.val; 12565 } 12566 12567 memoized.clear = function () { 12568 head = null; 12569 tail = null; 12570 size = 0; 12571 }; 12572 12573 // Ignore reason: There's not a clear solution to create an intersection of 12574 // the function with additional properties, where the goal is to retain the 12575 // function signature of the incoming argument and add control properties 12576 // on the return value. 12577 12578 // @ts-ignore 12579 return memoized; 12580} 12581 12582 12583 12584;// CONCATENATED MODULE: ./packages/blocks/build-module/api/matchers.js 12585/** 12586 * External dependencies 12587 */ 12588 12589 12590/** 12591 * Internal dependencies 12592 */ 12593 12594 12595function matchers_html(selector, multilineTag) { 12596 return domNode => { 12597 let match = domNode; 12598 if (selector) { 12599 match = domNode.querySelector(selector); 12600 } 12601 if (!match) { 12602 return ''; 12603 } 12604 if (multilineTag) { 12605 let value = ''; 12606 const length = match.children.length; 12607 for (let index = 0; index < length; index++) { 12608 const child = match.children[index]; 12609 if (child.nodeName.toLowerCase() !== multilineTag) { 12610 continue; 12611 } 12612 value += child.outerHTML; 12613 } 12614 return value; 12615 } 12616 return match.innerHTML; 12617 }; 12618} 12619 12620;// CONCATENATED MODULE: ./packages/blocks/build-module/api/node.js 12621/** 12622 * WordPress dependencies 12623 */ 12624 12625 12626/** 12627 * Internal dependencies 12628 */ 12629 12630 12631/** 12632 * A representation of a single node within a block's rich text value. If 12633 * representing a text node, the value is simply a string of the node value. 12634 * As representing an element node, it is an object of: 12635 * 12636 * 1. `type` (string): Tag name. 12637 * 2. `props` (object): Attributes and children array of WPBlockNode. 12638 * 12639 * @typedef {string|Object} WPBlockNode 12640 */ 12641 12642/** 12643 * Given a single node and a node type (e.g. `'br'`), returns true if the node 12644 * corresponds to that type, false otherwise. 12645 * 12646 * @param {WPBlockNode} node Block node to test 12647 * @param {string} type Node to type to test against. 12648 * 12649 * @return {boolean} Whether node is of intended type. 12650 */ 12651function isNodeOfType(node, type) { 12652 external_wp_deprecated_default()('wp.blocks.node.isNodeOfType', { 12653 since: '6.1', 12654 version: '6.3', 12655 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 12656 }); 12657 return node && node.type === type; 12658} 12659 12660/** 12661 * Given an object implementing the NamedNodeMap interface, returns a plain 12662 * object equivalent value of name, value key-value pairs. 12663 * 12664 * @see https://dom.spec.whatwg.org/#interface-namednodemap 12665 * 12666 * @param {NamedNodeMap} nodeMap NamedNodeMap to convert to object. 12667 * 12668 * @return {Object} Object equivalent value of NamedNodeMap. 12669 */ 12670function getNamedNodeMapAsObject(nodeMap) { 12671 const result = {}; 12672 for (let i = 0; i < nodeMap.length; i++) { 12673 const { 12674 name, 12675 value 12676 } = nodeMap[i]; 12677 result[name] = value; 12678 } 12679 return result; 12680} 12681 12682/** 12683 * Given a DOM Element or Text node, returns an equivalent block node. Throws
12684 * if passed any node type other than element or text. 12685 * 12686 * @throws {TypeError} If non-element/text node is passed. 12687 * 12688 * @param {Node} domNode DOM node to convert. 12689 * 12690 * @return {WPBlockNode} Block node equivalent to DOM node. 12691 */ 12692function fromDOM(domNode) { 12693 external_wp_deprecated_default()('wp.blocks.node.fromDOM', { 12694 since: '6.1', 12695 version: '6.3', 12696 alternative: 'wp.richText.create', 12697 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 12698 }); 12699 if (domNode.nodeType === domNode.TEXT_NODE) { 12700 return domNode.nodeValue; 12701 } 12702 if (domNode.nodeType !== domNode.ELEMENT_NODE) { 12703 throw new TypeError('A block node can only be created from a node of type text or ' + 'element.'); 12704 } 12705 return { 12706 type: domNode.nodeName.toLowerCase(), 12707 props: { 12708 ...getNamedNodeMapAsObject(domNode.attributes), 12709 children: children_fromDOM(domNode.childNodes) 12710 } 12711 }; 12712} 12713 12714/** 12715 * Given a block node, returns its HTML string representation. 12716 * 12717 * @param {WPBlockNode} node Block node to convert to string. 12718 * 12719 * @return {string} String HTML representation of block node. 12720 */ 12721function toHTML(node) { 12722 external_wp_deprecated_default()('wp.blocks.node.toHTML', { 12723 since: '6.1', 12724 version: '6.3', 12725 alternative: 'wp.richText.toHTMLString', 12726 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 12727 }); 12728 return children_toHTML([node]); 12729} 12730 12731/** 12732 * Given a selector, returns an hpq matcher generating a WPBlockNode value 12733 * matching the selector result. 12734 * 12735 * @param {string} selector DOM selector. 12736 * 12737 * @return {Function} hpq matcher. 12738 */ 12739function node_matcher(selector) { 12740 external_wp_deprecated_default()('wp.blocks.node.matcher', { 12741 since: '6.1', 12742 version: '6.3', 12743 alternative: 'html source', 12744 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 12745 }); 12746 return domNode => { 12747 let match = domNode; 12748 if (selector) { 12749 match = domNode.querySelector(selector); 12750 } 12751 try { 12752 return fromDOM(match); 12753 } catch (error) { 12754 return null; 12755 } 12756 }; 12757} 12758 12759/** 12760 * Object of utility functions used in managing block attribute values of 12761 * source `node`. 12762 * 12763 * @see https://github.com/WordPress/gutenberg/pull/10439 12764 * 12765 * @deprecated since 4.0. The `node` source should not be used, and can be 12766 * replaced by the `html` source. 12767 * 12768 * @private 12769 */ 12770/* harmony default export */ const node = ({ 12771 isNodeOfType, 12772 fromDOM, 12773 toHTML, 12774 matcher: node_matcher 12775}); 12776 12777;// CONCATENATED MODULE: ./packages/blocks/build-module/api/children.js 12778/** 12779 * WordPress dependencies 12780 */ 12781 12782 12783 12784/** 12785 * Internal dependencies 12786 */ 12787 12788 12789/** 12790 * A representation of a block's rich text value. 12791 * 12792 * @typedef {WPBlockNode[]} WPBlockChildren 12793 */ 12794
12795/** 12796 * Given block children, returns a serialize-capable WordPress element. 12797 * 12798 * @param {WPBlockChildren} children Block children object to convert. 12799 * 12800 * @return {WPElement} A serialize-capable element. 12801 */ 12802function getSerializeCapableElement(children) { 12803 // The fact that block children are compatible with the element serializer is 12804 // merely an implementation detail that currently serves to be true, but 12805 // should not be mistaken as being a guarantee on the external API. The 12806 // public API only offers guarantees to work with strings (toHTML) and DOM 12807 // elements (fromDOM), and should provide utilities to manipulate the value 12808 // rather than expect consumers to inspect or construct its shape (concat). 12809 return children; 12810} 12811 12812/** 12813 * Given block children, returns an array of block nodes. 12814 * 12815 * @param {WPBlockChildren} children Block children object to convert. 12816 * 12817 * @return {Array<WPBlockNode>} An array of individual block nodes. 12818 */ 12819function getChildrenArray(children) { 12820 external_wp_deprecated_default()('wp.blocks.children.getChildrenArray', { 12821 since: '6.1', 12822 version: '6.3', 12823 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 12824 }); 12825 12826 // The fact that block children are compatible with the element serializer 12827 // is merely an implementation detail that currently serves to be true, but 12828 // should not be mistaken as being a guarantee on the external API. 12829 return children; 12830} 12831 12832/** 12833 * Given two or more block nodes, returns a new block node representing a 12834 * concatenation of its values. 12835 * 12836 * @param {...WPBlockChildren} blockNodes Block nodes to concatenate. 12837 * 12838 * @return {WPBlockChildren} Concatenated block node. 12839 */ 12840function concat(...blockNodes) { 12841 external_wp_deprecated_default()('wp.blocks.children.concat', { 12842 since: '6.1', 12843 version: '6.3', 12844 alternative: 'wp.richText.concat', 12845 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 12846 }); 12847 const result = []; 12848 for (let i = 0; i < blockNodes.length; i++) { 12849 const blockNode = Array.isArray(blockNodes[i]) ? blockNodes[i] : [blockNodes[i]]; 12850 for (let j = 0; j < blockNode.length; j++) { 12851 const child = blockNode[j]; 12852 const canConcatToPreviousString = typeof child === 'string' && typeof result[result.length - 1] === 'string'; 12853 if (canConcatToPreviousString) { 12854 result[result.length - 1] += child; 12855 } else { 12856 result.push(child); 12857 } 12858 } 12859 } 12860 return result; 12861} 12862 12863/** 12864 * Given an iterable set of DOM nodes, returns equivalent block children. 12865 * Ignores any non-element/text nodes included in set. 12866 * 12867 * @param {Iterable.<Node>} domNodes Iterable set of DOM nodes to convert. 12868 * 12869 * @return {WPBlockChildren} Block children equivalent to DOM nodes. 12870 */ 12871function children_fromDOM(domNodes) { 12872 external_wp_deprecated_default()('wp.blocks.children.fromDOM', { 12873 since: '6.1', 12874 version: '6.3', 12875 alternative: 'wp.richText.create', 12876 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 12877 }); 12878 const result = []; 12879 for (let i = 0; i < domNodes.length; i++) { 12880 try { 12881 result.push(fromDOM(domNodes[i])); 12882 } catch (error) { 12883 // Simply ignore if DOM node could not be converted. 12884 } 12885 } 12886 return result; 12887} 12888 12889/** 12890 * Given a block node, returns its HTML string representation. 12891 * 12892 * @param {WPBlockChildren} children Block node(s) to convert to string. 12893 * 12894 * @return {string} String HTML representation of block node. 12895 */ 12896function children_toHTML(children) { 12897 external_wp_deprecated_default()('wp.blocks.children.toHTML', { 12898 since: '6.1', 12899 version: '6.3', 12900 alternative: 'wp.richText.toHTMLString', 12901 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 12902 }); 12903 const element = getSerializeCapableElement(children); 12904 return (0,external_wp_element_namespaceObject.renderToString)(element); 12905} 12906 12907/** 12908 * Given a selector, returns an hpq matcher generating a WPBlockChildren value 12909 * matching the selector result. 12910 * 12911 * @param {string} selector DOM selector. 12912 * 12913 * @return {Function} hpq matcher. 12914 */ 12915function children_matcher(selector) { 12916 external_wp_deprecated_default()('wp.blocks.children.matcher', { 12917 since: '6.1', 12918 version: '6.3', 12919 alternative: 'html source', 12920 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 12921 }); 12922 return domNode => { 12923 let match = domNode; 12924 if (selector) { 12925 match = domNode.querySelector(selector); 12926 } 12927 if (match) { 12928 return children_fromDOM(match.childNodes); 12929 } 12930 return []; 12931 }; 12932} 12933 12934/** 12935 * Object of utility functions used in managing block attribute values of 12936 * source `children`. 12937 * 12938 * @see https://github.com/WordPress/gutenberg/pull/10439 12939 * 12940 * @deprecated since 4.0. The `children` source should not be used, and can be 12941 * replaced by the `html` source. 12942 * 12943 * @private 12944 */ 12945/* harmony default export */ const children = ({ 12946 concat, 12947 getChildrenArray, 12948 fromDOM: children_fromDOM, 12949 toHTML: children_toHTML, 12950 matcher: children_matcher 12951}); 12952 12953;// CONCATENATED MODULE: ./packages/blocks/build-module/api/parser/get-block-attributes.js 12954/** 12955 * External dependencies 12956 */ 12957 12958 12959 12960/** 12961 * WordPress dependencies 12962 */ 12963 12964 12965 12966/** 12967 * Internal dependencies 12968 */ 12969 12970 12971 12972/** 12973 * Higher-order hpq matcher which enhances an attribute matcher to return true 12974 * or false depending on whether the original matcher returns undefined. This 12975 * is useful for boolean attributes (e.g. disabled) whose attribute values may
12976 * be technically falsey (empty string), though their mere presence should be 12977 * enough to infer as true. 12978 * 12979 * @param {Function} matcher Original hpq matcher. 12980 * 12981 * @return {Function} Enhanced hpq matcher. 12982 */ 12983const toBooleanAttributeMatcher = matcher => (0,external_wp_compose_namespaceObject.pipe)([matcher, 12984// Expected values from `attr( 'disabled' )`: 12985// 12986// <input> 12987// - Value: `undefined` 12988// - Transformed: `false` 12989// 12990// <input disabled> 12991// - Value: `''` 12992// - Transformed: `true` 12993// 12994// <input disabled="disabled"> 12995// - Value: `'disabled'` 12996// - Transformed: `true` 12997value => value !== undefined]); 12998 12999/** 13000 * Returns true if value is of the given JSON schema type, or false otherwise. 13001 * 13002 * @see http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.25 13003 * 13004 * @param {*} value Value to test. 13005 * @param {string} type Type to test. 13006 * 13007 * @return {boolean} Whether value is of type. 13008 */ 13009function isOfType(value, type) { 13010 switch (type) { 13011 case 'string': 13012 return typeof value === 'string'; 13013 case 'boolean': 13014 return typeof value === 'boolean'; 13015 case 'object': 13016 return !!value && value.constructor === Object; 13017 case 'null': 13018 return value === null; 13019 case 'array': 13020 return Array.isArray(value); 13021 case 'integer': 13022 case 'number': 13023 return typeof value === 'number'; 13024 } 13025 return true; 13026} 13027 13028/** 13029 * Returns true if value is of an array of given JSON schema types, or false 13030 * otherwise. 13031 * 13032 * @see http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.25 13033 * 13034 * @param {*} value Value to test. 13035 * @param {string[]} types Types to test. 13036 * 13037 * @return {boolean} Whether value is of types. 13038 */ 13039function isOfTypes(value, types) { 13040 return types.some(type => isOfType(value, type)); 13041} 13042 13043/** 13044 * Given an attribute key, an attribute's schema, a block's raw content and the 13045 * commentAttributes returns the attribute value depending on its source 13046 * definition of the given attribute key. 13047 * 13048 * @param {string} attributeKey Attribute key. 13049 * @param {Object} attributeSchema Attribute's schema. 13050 * @param {Node} innerDOM Parsed DOM of block's inner HTML. 13051 * @param {Object} commentAttributes Block's comment attributes. 13052 * @param {string} innerHTML Raw HTML from block node's innerHTML property. 13053 * 13054 * @return {*} Attribute value. 13055 */ 13056function getBlockAttribute(attributeKey, attributeSchema, innerDOM, commentAttributes, innerHTML) { 13057 let value; 13058 switch (attributeSchema.source) { 13059 // An undefined source means that it's an attribute serialized to the 13060 // block's "comment". 13061 case undefined: 13062 value = commentAttributes ? commentAttributes[attributeKey] : undefined; 13063 break; 13064 // raw source means that it's the original raw block content. 13065 case 'raw': 13066 value = innerHTML; 13067 break; 13068 case 'attribute': 13069 case 'property': 13070 case 'html': 13071 case 'text': 13072 case 'children': 13073 case 'node': 13074 case 'query': 13075 case 'tag': 13076 value = parseWithAttributeSchema(innerDOM, attributeSchema); 13077 break; 13078 } 13079 if (!isValidByType(value, attributeSchema.type) || !isValidByEnum(value, attributeSchema.enum)) { 13080 // Reject the value if it is not valid. Reverting to the undefined 13081 // value ensures the default is respected, if applicable. 13082 value = undefined; 13083 } 13084 if (value === undefined) { 13085 value = attributeSchema.default; 13086 } 13087 return value; 13088} 13089 13090/** 13091 * Returns true if value is valid per the given block attribute schema type 13092 * definition, or false otherwise. 13093 * 13094 * @see https://json-schema.org/latest/json-schema-validation.html#rfc.section.6.1.1 13095 * 13096 * @param {*} value Value to test. 13097 * @param {?(Array<string>|string)} type Block attribute schema type. 13098 * 13099 * @return {boolean} Whether value is valid. 13100 */ 13101function isValidByType(value, type) { 13102 return type === undefined || isOfTypes(value, Array.isArray(type) ? type : [type]); 13103} 13104 13105/** 13106 * Returns true if value is valid per the given block attribute schema enum 13107 * definition, or false otherwise. 13108 * 13109 * @see https://json-schema.org/latest/json-schema-validation.html#rfc.section.6.1.2 13110 * 13111 * @param {*} value Value to test. 13112 * @param {?Array} enumSet Block attribute schema enum. 13113 * 13114 * @return {boolean} Whether value is valid. 13115 */ 13116function isValidByEnum(value, enumSet) { 13117 return !Array.isArray(enumSet) || enumSet.includes(value); 13118} 13119 13120/** 13121 * Returns an hpq matcher given a source object. 13122 * 13123 * @param {Object} sourceConfig Attribute Source object. 13124 * 13125 * @return {Function} A hpq Matcher. 13126 */ 13127const matcherFromSource = memize(sourceConfig => { 13128 switch (sourceConfig.source) { 13129 case 'attribute': 13130 let matcher = attr(sourceConfig.selector, sourceConfig.attribute); 13131 if (sourceConfig.type === 'boolean') { 13132 matcher = toBooleanAttributeMatcher(matcher); 13133 } 13134 return matcher; 13135 case 'html': 13136 return matchers_html(sourceConfig.selector, sourceConfig.multiline); 13137 case 'text': 13138 return es_text(sourceConfig.selector); 13139 case 'children': 13140 return children_matcher(sourceConfig.selector); 13141 case 'node': 13142 return node_matcher(sourceConfig.selector); 13143 case 'query': 13144 const subMatchers = Object.fromEntries(Object.entries(sourceConfig.query).map(([key, subSourceConfig]) => [key, matcherFromSource(subSourceConfig)])); 13145 return query(sourceConfig.selector, subMatchers); 13146 case 'tag': 13147 return (0,external_wp_compose_namespaceObject.pipe)([prop(sourceConfig.selector, 'nodeName'), nodeName => nodeName ? nodeName.toLowerCase() : undefined]); 13148 default: 13149 // eslint-disable-next-line no-console 13150 console.error(`Unknown source type "${sourceConfig.source}"`); 13151 } 13152}); 13153 13154/** 13155 * Parse a HTML string into DOM tree. 13156 * 13157 * @param {string|Node} innerHTML HTML string or already parsed DOM node. 13158 * 13159 * @return {Node} Parsed DOM node. 13160 */ 13161function parseHtml(innerHTML) { 13162 return parse(innerHTML, h => h); 13163} 13164 13165/** 13166 * Given a block's raw content and an attribute's schema returns the attribute's 13167 * value depending on its source. 13168 * 13169 * @param {string|Node} innerHTML Block's raw content. 13170 * @param {Object} attributeSchema Attribute's schema. 13171 * 13172 * @return {*} Attribute value. 13173 */ 13174function parseWithAttributeSchema(innerHTML, attributeSchema) { 13175 return matcherFromSource(attributeSchema)(parseHtml(innerHTML)); 13176} 13177 13178/** 13179 * Returns the block attributes of a registered block node given its type. 13180 * 13181 * @param {string|Object} blockTypeOrName Block type or name. 13182 * @param {string|Node} innerHTML Raw block content. 13183 * @param {?Object} attributes Known block attributes (from delimiters). 13184 * 13185 * @return {Object} All block attributes. 13186 */ 13187function getBlockAttributes(blockTypeOrName, innerHTML, attributes = {}) { 13188 var _blockType$attributes; 13189 const doc = parseHtml(innerHTML); 13190 const blockType = normalizeBlockType(blockTypeOrName); 13191 const blockAttributes = Object.fromEntries(Object.entries((_blockType$attributes = blockType.attributes) !== null && _blockType$attributes !== void 0 ? _blockType$attributes : {}).map(([key, schema]) => [key, getBlockAttribute(key, schema, doc, attributes, innerHTML)])); 13192 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getBlockAttributes', blockAttributes, blockType, innerHTML, attributes); 13193} 13194 13195;// CONCATENATED MODULE: ./packages/blocks/build-module/api/parser/fix-custom-classname.js 13196/** 13197 * Internal dependencies 13198 */ 13199 13200 13201 13202const CLASS_ATTR_SCHEMA = { 13203 type: 'string', 13204 source: 'attribute', 13205 selector: '[data-custom-class-name] > *', 13206 attribute: 'class' 13207}; 13208 13209/** 13210 * Given an HTML string, returns an array of class names assigned to the root 13211 * element in the markup. 13212 * 13213 * @param {string} innerHTML Markup string from which to extract classes. 13214 * 13215 * @return {string[]} Array of class names assigned to the root element. 13216 */ 13217function getHTMLRootElementClasses(innerHTML) { 13218 const parsed = parseWithAttributeSchema(`<div data-custom-class-name>${innerHTML}</div>`, CLASS_ATTR_SCHEMA); 13219 return parsed ? parsed.trim().split(/\s+/) : []; 13220} 13221 13222/** 13223 * Given a parsed set of block attributes, if the block supports custom class 13224 * names and an unknown class (per the block's serialization behavior) is
13225 * found, the unknown classes are treated as custom classes. This prevents the 13226 * block from being considered as invalid. 13227 * 13228 * @param {Object} blockAttributes Original block attributes. 13229 * @param {Object} blockType Block type settings. 13230 * @param {string} innerHTML Original block markup. 13231 * 13232 * @return {Object} Filtered block attributes. 13233 */ 13234function fixCustomClassname(blockAttributes, blockType, innerHTML) { 13235 if (hasBlockSupport(blockType, 'customClassName', true)) { 13236 // To determine difference, serialize block given the known set of 13237 // attributes, with the exception of `className`. This will determine 13238 // the default set of classes. From there, any difference in innerHTML 13239 // can be considered as custom classes. 13240 const { 13241 className: omittedClassName, 13242 ...attributesSansClassName 13243 } = blockAttributes; 13244 const serialized = getSaveContent(blockType, attributesSansClassName); 13245 const defaultClasses = getHTMLRootElementClasses(serialized); 13246 const actualClasses = getHTMLRootElementClasses(innerHTML); 13247 const customClasses = actualClasses.filter(className => !defaultClasses.includes(className)); 13248 if (customClasses.length) { 13249 blockAttributes.className = customClasses.join(' '); 13250 } else if (serialized) { 13251 delete blockAttributes.className; 13252 } 13253 } 13254 return blockAttributes; 13255} 13256 13257;// CONCATENATED MODULE: ./packages/blocks/build-module/api/parser/apply-built-in-validation-fixes.js 13258/** 13259 * Internal dependencies 13260 */ 13261 13262 13263/** 13264 * Attempts to fix block invalidation by applying build-in validation fixes 13265 * like moving all extra classNames to the className attribute. 13266 * 13267 * @param {WPBlock} block block object. 13268 * @param {import('../registration').WPBlockType} blockType Block type. This is normalize not necessary and 13269 * can be inferred from the block name, 13270 * but it's here for performance reasons. 13271 * 13272 * @return {WPBlock} Fixed block object 13273 */ 13274function applyBuiltInValidationFixes(block, blockType) { 13275 const updatedBlockAttributes = fixCustomClassname(block.attributes, blockType, block.originalContent); 13276 return { 13277 ...block, 13278 attributes: updatedBlockAttributes 13279 }; 13280} 13281 13282;// CONCATENATED MODULE: ./packages/blocks/build-module/api/parser/apply-block-deprecated-versions.js 13283/** 13284 * Internal dependencies 13285 */ 13286 13287 13288 13289 13290 13291 13292/** 13293 * Function that takes no arguments and always returns false. 13294 * 13295 * @return {boolean} Always returns false. 13296 */ 13297function stubFalse() { 13298 return false; 13299} 13300 13301/** 13302 * Given a block object, returns a new copy of the block with any applicable 13303 * deprecated migrations applied, or the original block if it was both valid 13304 * and no eligible migrations exist. 13305 * 13306 * @param {import(".").WPBlock} block Parsed and invalid block object. 13307 * @param {import(".").WPRawBlock} rawBlock Raw block object. 13308 * @param {import('../registration').WPBlockType} blockType Block type. This is normalize not necessary and 13309 * can be inferred from the block name, 13310 * but it's here for performance reasons. 13311 * 13312 * @return {import(".").WPBlock} Migrated block object. 13313 */ 13314function applyBlockDeprecatedVersions(block, rawBlock, blockType) { 13315 const parsedAttributes = rawBlock.attrs; 13316 const { 13317 deprecated: deprecatedDefinitions 13318 } = blockType; 13319 // Bail early if there are no registered deprecations to be handled. 13320 if (!deprecatedDefinitions || !deprecatedDefinitions.length) { 13321 return block; 13322 } 13323 13324 // By design, blocks lack any sort of version tracking. Instead, to process 13325 // outdated content the system operates a queue out of all the defined 13326 // attribute shapes and tries each definition until the input produces a 13327 // valid result. This mechanism seeks to avoid polluting the user-space with 13328 // machine-specific code. An invalid block is thus a block that could not be 13329 // matched successfully with any of the registered deprecation definitions. 13330 for (let i = 0; i < deprecatedDefinitions.length; i++) { 13331 // A block can opt into a migration even if the block is valid by 13332 // defining `isEligible` on its deprecation. If the block is both valid 13333 // and does not opt to migrate, skip. 13334 const { 13335 isEligible = stubFalse 13336 } = deprecatedDefinitions[i]; 13337 if (block.isValid && !isEligible(parsedAttributes, block.innerBlocks, { 13338 blockNode: rawBlock, 13339 block 13340 })) { 13341 continue; 13342 } 13343 13344 // Block type properties which could impact either serialization or 13345 // parsing are not considered in the deprecated block type by default, 13346 // and must be explicitly provided. 13347 const deprecatedBlockType = Object.assign(omit(blockType, DEPRECATED_ENTRY_KEYS), deprecatedDefinitions[i]); 13348 let migratedBlock = { 13349 ...block, 13350 attributes: getBlockAttributes(deprecatedBlockType, block.originalContent, parsedAttributes) 13351 }; 13352 13353 // Ignore the deprecation if it produces a block which is not val
13353id. 13354 let [isValid] = validateBlock(migratedBlock, deprecatedBlockType); 13355 13356 // If the migrated block is not valid initially, try the built-in fixes. 13357 if (!isValid) { 13358 migratedBlock = applyBuiltInValidationFixes(migratedBlock, deprecatedBlockType); 13359 [isValid] = validateBlock(migratedBlock, deprecatedBlockType); 13360 } 13361 13362 // An invalid block does not imply incorrect HTML but the fact block 13363 // source information could be lost on re-serialization. 13364 if (!isValid) { 13365 continue; 13366 } 13367 let migratedInnerBlocks = migratedBlock.innerBlocks; 13368 let migratedAttributes = migratedBlock.attributes; 13369 13370 // A block may provide custom behavior to assign new attributes and/or 13371 // inner blocks. 13372 const { 13373 migrate 13374 } = deprecatedBlockType; 13375 if (migrate) { 13376 let migrated = migrate(migratedAttributes, block.innerBlocks); 13377 if (!Array.isArray(migrated)) { 13378 migrated = [migrated]; 13379 } 13380 [migratedAttributes = parsedAttributes, migratedInnerBlocks = block.innerBlocks] = migrated; 13381 } 13382 block = { 13383 ...block, 13384 attributes: migratedAttributes, 13385 innerBlocks: migratedInnerBlocks, 13386 isValid: true, 13387 validationIssues: [] 13388 }; 13389 } 13390 return block; 13391} 13392 13393;// CONCATENATED MODULE: ./packages/blocks/build-module/api/parser/index.js 13394/** 13395 * WordPress dependencies 13396 */ 13397 13398 13399 13400/** 13401 * Internal dependencies 13402 */ 13403 13404 13405 13406 13407 13408 13409 13410 13411 13412 13413/** 13414 * The raw structure of a block includes its attributes, inner 13415 * blocks, and inner HTML. It is important to distinguish inner blocks from 13416 * the HTML content of the block as only the latter is relevant for block 13417 * validation and edit operations. 13418 * 13419 * @typedef WPRawBlock 13420 * 13421 * @property {string=} blockName Block name 13422 * @property {Object=} attrs Block raw or comment attributes. 13423 * @property {string} innerHTML HTML content of the block. 13424 * @property {(string|null)[]} innerContent Content without inner blocks. 13425 * @property {WPRawBlock[]} innerBlocks Inner Blocks. 13426 */ 13427 13428/** 13429 * Fully parsed block object. 13430 * 13431 * @typedef WPBlock 13432 * 13433 * @property {string} name Block name 13434 * @property {Object} attributes Block raw or comment attributes. 13435 * @property {WPBlock[]} innerBlocks Inner Blocks. 13436 * @property {string} originalContent Original content of the block before validation fixes. 13437 * @property {boolean} isValid Whether the block is valid. 13438 * @property {Object[]}
13438 validationIssues Validation issues. 13439 * @property {WPRawBlock} [__unstableBlockSource] Un-processed original copy of block if created through parser. 13440 */ 13441 13442/** 13443 * @typedef {Object} ParseOptions 13444 * @property {boolean?} __unstableSkipMigrationLogs If a block is migrated from a deprecated version, skip logging the migration details. 13445 * @property {boolean?} __unstableSkipAutop Whether to skip autop when processing freeform content. 13446 */ 13447 13448/** 13449 * Convert legacy blocks to their canonical form. This function is used 13450 * both in the parser level for previous content and to convert such blocks 13451 * used in Custom Post Types templates. 13452 * 13453 * @param {WPRawBlock} rawBlock 13454 * 13455 * @return {WPRawBlock} The block's name and attributes, changed accordingly if a match was found 13456 */ 13457function convertLegacyBlocks(rawBlock) { 13458 const [correctName, correctedAttributes] = convertLegacyBlockNameAndAttributes(rawBlock.blockName, rawBlock.attrs); 13459 return { 13460 ...rawBlock, 13461 blockName: correctName, 13462 attrs: correctedAttributes 13463 }; 13464} 13465 13466/** 13467 * Normalize the raw block by applying the fallback block name if none given, 13468 * sanitize the parsed HTML... 13469 * 13470 * @param {WPRawBlock} rawBlock The raw block object. 13471 * @param {ParseOptions?} options Extra options for handling block parsing. 13472 * 13473 * @return {WPRawBlock} The normalized block object. 13474 */ 13475function normalizeRawBlock(rawBlock, options) { 13476 const fallbackBlockName = getFreeformContentHandlerName(); 13477 13478 // If the grammar parsing don't produce any block name, use the freeform block. 13479 const rawBlockName = rawBlock.blockName || getFreeformContentHandlerName(); 13480 const rawAttributes = rawBlock.attrs || {}; 13481 const rawInnerBlocks = rawBlock.innerBlocks || []; 13482 let rawInnerHTML = rawBlock.innerHTML.trim(); 13483 13484 // Fallback content may be upgraded from classic content expecting implicit 13485 // automatic paragraphs, so preserve them. Assumes wpautop is idempotent, 13486 // meaning there are no negative consequences to repeated autop calls. 13487 if (rawBlockName === fallbackBlockName && rawBlockName === 'core/freeform' && !options?.__unstableSkipAutop) { 13488 rawInnerHTML = (0,external_wp_autop_namespaceObject.autop)(rawInnerHTML).trim(); 13489 } 13490 return { 13491 ...rawBlock, 13492 blockName: rawBlockName, 13493 attrs: rawAttributes, 13494 innerHTML: rawInnerHTML, 13495 innerBlocks: rawInnerBlocks 13496 }; 13497} 13498 13499/** 13500 * Uses the "unregistered blockType" to create a block object. 13501 * 13502 * @param {WPRawBlock} rawBlock block. 13503 * 13504 * @return {WPRawBlock} The unregistered block object. 13505 */ 13506function createMissingBlockType(rawBlock) { 13507 const unregisteredFallbackBlock = getUnregisteredTypeHandlerName() || getFreeformContentHandlerName(); 13508 13509 // Preserve undelimited content for use by the unregistered type 13510 // handler. A block node's `innerHTML` isn't enough, as that field only 13511 // carries the block's own HTML and not its nested blocks. 13512 const originalUndelimitedContent = serializeRawBlock(rawBlock, { 13513 isCommentDelimited: false 13514 }); 13515 13516 // Preserve full block content for use by the unregistered type 13517 // handler, block boundaries included. 13518 const originalContent = serializeRawBlock(rawBlock, { 13519 isCommentDelimited: true 13520 }); 13521 return { 13522 blockName: unregisteredFallbackBlock, 13523 attrs: { 13524 originalName: rawBlock.blockName, 13525 originalContent, 13526 originalUndelimitedContent 13527 }, 13528 innerHTML: rawBlock.blockName ? originalContent : rawBlock.innerHTML, 13529 innerBlocks: rawBlock.innerBlocks, 13530 innerContent: rawBlock.innerContent 13531 }; 13532} 13533 13534/** 13535 * Validates a block and wraps with validation meta. 13536 * 13537 * The name here is regrettable but `validateBlock` is already taken. 13538 * 13539 * @param {WPBlock} unvalidatedBlock 13540 * @param {import('../registration').WPBlockType} blockType 13541 * @return {WPBlock} validated block, with auto-fixes if initially invalid 13542 */ 13543function applyBlockValidation(unvalidatedBlock, blockType) { 13544 // Attempt to validate the block. 13545 const [isValid] = validateBlock(unvalidatedBlock, blockType); 13546 if (isValid) { 13547 return { 13548 ...unvalidatedBlock,
13549 isValid, 13550 validationIssues: [] 13551 }; 13552 } 13553 13554 // If the block is invalid, attempt some built-in fixes 13555 // like custom classNames handling. 13556 const fixedBlock = applyBuiltInValidationFixes(unvalidatedBlock, blockType); 13557 // Attempt to validate the block once again after the built-in fixes. 13558 const [isFixedValid, validationIssues] = validateBlock(unvalidatedBlock, blockType); 13559 return { 13560 ...fixedBlock, 13561 isValid: isFixedValid, 13562 validationIssues 13563 }; 13564} 13565 13566/** 13567 * Given a raw block returned by grammar parsing, returns a fully parsed block. 13568 * 13569 * @param {WPRawBlock} rawBlock The raw block object. 13570 * @param {ParseOptions} options Extra options for handling block parsing. 13571 * 13572 * @return {WPBlock | undefined} Fully parsed block. 13573 */ 13574function parseRawBlock(rawBlock, options) { 13575 let normalizedBlock = normalizeRawBlock(rawBlock, options); 13576 13577 // During the lifecycle of the project, we renamed some old blocks 13578 // and transformed others to new blocks. To avoid breaking existing content, 13579 // we added this function to properly parse the old content. 13580 normalizedBlock = convertLegacyBlocks(normalizedBlock); 13581 13582 // Try finding the type for known block name. 13583 let blockType = getBlockType(normalizedBlock.blockName); 13584 13585 // If not blockType is found for the specified name, fallback to the "unregistedBlockType". 13586 if (!blockType) { 13587 normalizedBlock = createMissingBlockType(normalizedBlock); 13588 blockType = getBlockType(normalizedBlock.blockName); 13589 } 13590 13591 // If it's an empty freeform block or there's no blockType (no missing block handler) 13592 // Then, just ignore the block. 13593 // It might be a good idea to throw a warning here. 13594 // TODO: I'm unsure about the unregisteredFallbackBlock check, 13595 // it might ignore some dynamic unregistered third party blocks wrongly. 13596 const isFallbackBlock = normalizedBlock.blockName === getFreeformContentHandlerName() || normalizedBlock.blockName === getUnregisteredTypeHandlerName(); 13597 if (!blockType || !normalizedBlock.innerHTML && isFallbackBlock) { 13598 return; 13599 } 13600 13601 // Parse inner blocks recursively. 13602 const parsedInnerBlocks = normalizedBlock.innerBlocks.map(innerBlock => parseRawBlock(innerBlock, options)) 13603 // See https://github.com/WordPress/gutenberg/pull/17164. 13604 .filter(innerBlock => !!innerBlock); 13605 13606 // Get the fully parsed block. 13607 const parsedBlock = createBlock(normalizedBlock.blockName, getBlockAttributes(blockType, normalizedBlock.innerHTML, normalizedBlock.attrs), parsedInnerBlocks); 13608 parsedBlock.originalContent = normalizedBlock.innerHTML; 13609 const validatedBlock = applyBlockValidation(parsedBlock, blockType); 13610 const { 13611 validationIssues 13612 } = validatedBlock; 13613 13614 // Run the block deprecation and migrations. 13615 // This is performed on both invalid and valid blocks because 13616 // migration using the `migrate` functions should run even 13617 // if the output is deemed valid. 13618 const updatedBlock = applyBlockDeprecatedVersions(validatedBlock, normalizedBlock, blockType); 13619 if (!updatedBlock.isValid) { 13620 // Preserve the original unprocessed version of the block 13621 // that we received (no fixes, no deprecations) so that 13622 // we can save it as close to exactly the same way as 13623 // we loaded it. This is important to avoid corruption 13624 // and data loss caused by block implementations trying 13625 // to process data that isn't fully recognized. 13626 updatedBlock.__unstableBlockSource = rawBlock; 13627 } 13628 if (!validatedBlock.isValid && updatedBlock.isValid && !options?.__unstableSkipMigrationLogs) { 13629 /* eslint-disable no-console */ 13630 console.groupCollapsed('Updated Block: %s', blockType.name); 13631 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); 13632 console.groupEnd(); 13633 /* eslint-enable no-console */ 13634 } else if (!validatedBlock.isValid && !updatedBlock.isValid) { 13635 validationIssues.forEach(({ 13636 log, 13637 args 13638 }) => log(...args)); 13639 } 13640 return updatedBlock; 13641} 13642 13643/** 13644 * Utilizes an optimized token-driven parser based on the Gutenberg grammar spec 13645 * defined through a parsing expression grammar to take advantage of the regular 13646 * cadence provided by block delimiters -- composed syntactically through HTML 13647 * comments -- which, given a general HTML document as an input, returns a block 13648 * list array representation. 13649 * 13650 * This is a recursive-descent parser that scans linearly once through the input 13651 * document. Instead of directly recursing it utilizes a trampoline mechanism to 13652 * prevent stack overflow. This initial pass is mainly interested in separating 13653 * and isolating the blocks serialized in the document and manifestly not in the 13654 * content within the blocks. 13655 * 13656 * @see 13657 * https://developer.wordpress.org/block-editor/packages/packages-block-serialization-default-parser/ 13658 * 13659 * @param {string} content The post content. 13660 * @param {ParseOptions} options Extra options for handling block parsing. 13661 * 13662 * @return {Array} Block list. 13663 */ 13664function parser_parse(content, options) { 13665 return (0,external_wp_blockSerializationDefaultParser_namespaceObject.parse)(content).reduce((accumulator, rawBlock) => { 13666 const block = parseRawBlock(rawBlock, options); 13667 if (block) { 13668 accumulator.push(block); 13669 } 13670 return accumulator; 13671 }, []); 13672} 13673 13674;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/get-raw-transforms.js 13675/** 13676 * Internal dependencies 13677 */ 13678 13679function getRawTransforms() { 13680 return getBlockTransforms('from').filter(({ 13681 type 13682 }) => type === 'raw').map(transform => { 13683 return transform.isMatch ? transform : { 13684 ...transform, 13685 isMatch: node => transform.selector && node.matches(transform.selector) 13686 }; 13687 }); 13688} 13689 13690;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/html-to-blocks.js 13691/** 13692 * Internal dependencies 13693 */ 13694 13695 13696 13697 13698/** 13699 * Converts HTML directly to blocks. Looks for a matching transform for each 13700 * top-level tag. The HTML should be filtered to not have any text between 13701 * top-level tags and formatted in a way that blocks can handle the HTML. 13702 * 13703 * @param {string} html HTML to convert. 13704 * @param {Function} handler The handler calling htmlToBlocks: either rawHandler 13705 * or pasteHandler. 13706 * 13707 * @return {Array} An array of blocks. 13708 */ 13709function htmlToBlocks(html, handler) { 13710 const doc = document.implementation.createHTMLDocument(''); 13711 doc.body.innerHTML = html; 13712 return Array.from(doc.body.children).flatMap(node => { 13713 const rawTransform = findTransform(getRawTransforms(), ({ 13714 isMatch 13715 }) => isMatch(node)); 13716 if (!rawTransform) { 13717 return createBlock( 13718 // Should not be hardcoded. 13719 'core/html', getBlockAttributes('core/html', node.outerHTML)); 13720 } 13721 const { 13722 transform, 13723 blockName 13724 } = rawTransform; 13725 if (transform) { 13726 return transform(node, handler); 13727 } 13728 return createBlock(blockName, getBlockAttributes(blockName, node.outerHTML)); 13729 }); 13730} 13731 13732;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/normalise-blocks.js 13733/** 13734 * WordPress dependencies 13735 */ 13736 13737function normaliseBlocks(HTML) { 13738 const decuDoc = document.implementation.createHTMLDocument(''); 13739 const accuDoc = document.implementation.createHTMLDocument(''); 13740 const decu = decuDoc.body; 13741 const accu = accuDoc.body; 13742 decu.innerHTML = HTML; 13743 while (decu.firstChild) { 13744 const node = decu.firstChild; 13745 13746 // Text nodes: wrap in a paragraph, or append to previous. 13747 if (node.nodeType === node.TEXT_NODE) { 13748 if ((0,external_wp_dom_namespaceObject.isEmpty)(node)) { 13749 decu.removeChild(node); 13750 } else {
13751 if (!accu.lastChild || accu.lastChild.nodeName !== 'P') { 13752 accu.appendChild(accuDoc.createElement('P')); 13753 } 13754 accu.lastChild.appendChild(node); 13755 } 13756 // Element nodes. 13757 } else if (node.nodeType === node.ELEMENT_NODE) { 13758 // BR nodes: create a new paragraph on double, or append to previous. 13759 if (node.nodeName === 'BR') { 13760 if (node.nextSibling && node.nextSibling.nodeName === 'BR') { 13761 accu.appendChild(accuDoc.createElement('P')); 13762 decu.removeChild(node.nextSibling); 13763 } 13764 13765 // Don't append to an empty paragraph. 13766 if (accu.lastChild && accu.lastChild.nodeName === 'P' && accu.lastChild.hasChildNodes()) { 13767 accu.lastChild.appendChild(node); 13768 } else { 13769 decu.removeChild(node); 13770 } 13771 } else if (node.nodeName === 'P') { 13772 // Only append non-empty paragraph nodes. 13773 if ((0,external_wp_dom_namespaceObject.isEmpty)(node)) { 13774 decu.removeChild(node); 13775 } else { 13776 accu.appendChild(node); 13777 } 13778 } else if ((0,external_wp_dom_namespaceObject.isPhrasingContent)(node)) { 13779 if (!accu.lastChild || accu.lastChild.nodeName !== 'P') { 13780 accu.appendChild(accuDoc.createElement('P')); 13781 } 13782 accu.lastChild.appendChild(node); 13783 } else { 13784 accu.appendChild(node); 13785 } 13786 } else { 13787 decu.removeChild(node); 13788 } 13789 } 13790 return accu.innerHTML; 13791} 13792 13793;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/special-comment-converter.js 13794/** 13795 * WordPress dependencies 13796 */ 13797 13798 13799/** 13800 * Looks for `<!--nextpage-->` and `<!--more-->` comments and 13801 * replaces them with a custom element representing a future block. 13802 * 13803 * The custom element is a way to bypass the rest of the `raw-handling` 13804 * transforms, which would eliminate other kinds of node with which to carry 13805 * `<!--more-->`'s data: nodes with `data` attributes, empty paragraphs, etc. 13806 * 13807 * The custom element is then expected to be recognized by any registered 13808 * block's `raw` transform. 13809 * 13810 * @param {Node} node The node to be processed. 13811 * @param {Document} doc The document of the node. 13812 * @return {void} 13813 */ 13814function specialCommentConverter(node, doc) { 13815 if (node.nodeType !== node.COMMENT_NODE) { 13816 return; 13817 } 13818 if (node.nodeValue === 'nextpage') { 13819 (0,external_wp_dom_namespaceObject.replace)(node, createNextpage(doc)); 13820 return; 13821 } 13822 if (node.nodeValue.indexOf('more') === 0) { 13823 moreCommentConverter(node, doc); 13824 } 13825} 13826 13827/** 13828 * Convert `<!--more-->` as well as the `<!--more Some text-->` variant 13829 * and its `<!--noteaser-->` companion into the custom element 13830 * described in `specialCommentConverter()`. 13831 * 13832 * @param {Node} node The node to be processed. 13833 * @param {Document} doc The document of the node. 13834 * @return {void} 13835 */ 13836function moreCommentConverter(node, doc) { 13837 // Grab any custom text in the comment. 13838 const customText = node.nodeValue.slice(4).trim(); 13839 13840 /* 13841 * When a `<!--more-->` comment is found, we need to look for any 13842 * `<!--noteaser-->` sibling, but it may not be a direct sibling 13843 * (whitespace typically lies in between) 13844 */ 13845 let sibling = node; 13846 let noTeaser = false; 13847 while (sibling = sibling.nextSibling) { 13848 if (sibling.nodeType === sibling.COMMENT_NODE && sibling.nodeValue === 'noteaser') { 13849 noTeaser = true; 13850 (0,external_wp_dom_namespaceObject.remove)(sibling); 13851 break; 13852 } 13853 } 13854 const moreBlock = createMore(customText, noTeaser, doc); 13855 13856 // If our `<!--more-->` comment is in the middle of a paragraph, we should 13857 // split the paragraph in two and insert the more block in between. If not, 13858 // the more block will eventually end up being inserted after the paragraph. 13859 if (!node.parentNode || node.parentNode.nodeName !== 'P' || node.parentNode.childNodes.length === 1) { 13860 (0,external_wp_dom_namespaceObject.replace)(node, moreBlock); 13861 } else { 13862 const childNodes = Array.from(node.parentNode.childNodes); 13863 const nodeIndex = childNodes.indexOf(node); 13864 const wrapperNode = node.parentNode.parentNode || doc.body; 13865 const paragraphBuilder = (acc, child) => { 13866 if (!acc) { 13867 acc = doc.createElement('p'); 13868 } 13869 acc.appendChild(child); 13870 return acc; 13871 }; 13872 13873 // Split the original parent node and insert our more block 13874 [childNodes.slice(0, nodeIndex).reduce(paragraphBuilder, null), moreBlock, childNodes.slice(nodeIndex + 1).reduce(paragraphBuilder, null)].forEac
13874h(element => element && wrapperNode.insertBefore(element, node.parentNode)); 13875 13876 // Remove the old parent paragraph 13877 (0,external_wp_dom_namespaceObject.remove)(node.parentNode); 13878 } 13879} 13880function createMore(customText, noTeaser, doc) { 13881 const node = doc.createElement('wp-block'); 13882 node.dataset.block = 'core/more'; 13883 if (customText) { 13884 node.dataset.customText = customText; 13885 } 13886 if (noTeaser) { 13887 // "Boolean" data attribute. 13888 node.dataset.noTeaser = ''; 13889 } 13890 return node; 13891} 13892function createNextpage(doc) { 13893 const node = doc.createElement('wp-block'); 13894 node.dataset.block = 'core/nextpage'; 13895 return node; 13896} 13897 13898;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/list-reducer.js 13899/** 13900 * WordPress dependencies 13901 */ 13902 13903function isList(node) { 13904 return node.nodeName === 'OL' || node.nodeName === 'UL'; 13905} 13906function shallowTextContent(element) { 13907 return Array.from(element.childNodes).map(({ 13908 nodeValue = '' 13909 }) => nodeValue).join(''); 13910} 13911function listReducer(node) { 13912 if (!isList(node)) { 13913 return; 13914 } 13915 const list = node; 13916 const prevElement = node.previousElementSibling; 13917 13918 // Merge with previous list if: 13919 // * There is a previous list of the same type. 13920 // * There is only one list item. 13921 if (prevElement && prevElement.nodeName === node.nodeName && list.children.length === 1) { 13922 // Move all child nodes, including any text nodes, if any. 13923 while (list.firstChild) { 13924 prevElement.appendChild(list.firstChild); 13925 } 13926 list.parentNode.removeChild(list); 13927 } 13928 const parentElement = node.parentNode; 13929 13930 // Nested list with empty parent item. 13931 if (parentElement && parentElement.nodeName === 'LI' && parentElement.children.length === 1 && !/\S/.test(shallowTextContent(parentElement))) { 13932 const parentListItem = parentElement; 13933 const prevListItem = parentListItem.previousElementSibling; 13934 const parentList = parentListItem.parentNode; 13935 if (prevListItem) { 13936 prevListItem.appendChild(list); 13937 parentList.removeChild(parentListItem); 13938 } else { 13939 parentList.parentNode.insertBefore(list, parentList); 13940 parentList.parentNode.removeChild(parentList); 13941 } 13942 } 13943 13944 // Invalid: OL/UL > OL/UL. 13945 if (parentElement && isList(parentElement)) { 13946 const prevListItem = node.previousElementSibling; 13947 if (prevListItem) { 13948 prevListItem.appendChild(node); 13949 } else { 13950 (0,external_wp_dom_namespaceObject.unwrap)(node); 13951 } 13952 } 13953} 13954 13955;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/blockquote-normaliser.js 13956/** 13957 * Internal dependencies 13958 */ 13959 13960function blockquoteNormaliser(node) { 13961 if (node.nodeName !== 'BLOCKQUOTE') { 13962 return; 13963 } 13964 node.innerHTML = normaliseBlocks(node.innerHTML); 13965} 13966 13967;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/figure-content-reducer.js 13968/** 13969 * WordPress dependencies 13970 */ 13971 13972 13973/** 13974 * Whether or not the given node is figure content. 13975 * 13976 * @param {Node} node The node to check. 13977 * @param {Object} schema The schema to use. 13978 * 13979 * @return {boolean} True if figure content, false if not. 13980 */ 13981function isFigureContent(node, schema) { 13982 var _schema$figure$childr; 13983 const tag = node.nodeName.toLowerCase(); 13984 13985 // We are looking for tags that can be a child of the figure tag, excluding 13986 // `figcaption` and any phrasing content. 13987 if (tag === 'figcaption' || (0,external_wp_dom_namespaceObject.isTextContent)(node)) { 13988 return false; 13989 } 13990 return tag in ((_schema$figure$childr = schema?.figure?.children) !== null && _schema$figure$childr !== void 0 ? _schema$figure$childr : {}); 13991} 13992 13993/** 13994 * Whether or not the given node can have an anchor. 13995 * 13996 * @param {Node} node The node to check. 13997 * @param {Object} schema The schema to use. 13998 * 13999 * @return {boolean} True if it can, false if not. 14000 */ 14001function canHaveAnchor(node, schema) { 14002 var _schema$figure$childr2; 14003 const tag = node.nodeName.toLowerCase(); 14004 return tag in ((_schema$figure$childr2 = schema?.figure?.children?.a?.children) !== null && _schema$figure$childr2 !== void 0 ? _schema$figure$childr2 : {}); 14005} 14006 14007/** 14008 * Wraps the given element in a figure element. 14009 * 14010 * @param {Element} element The element to wrap. 14011 * @param {Element} beforeElement The element before which to place the figure. 14012 */ 14013function wrapFigureContent(element, beforeElement = element) { 14014 const figure = element.ownerDocument.createElement('figure'); 14015 beforeElement.parentNode.insertBefore(figure, beforeElement); 14016 figure.appendChild(element); 14017} 14018 14019/** 14020 * This filter takes figure content out of paragraphs, wraps it in a figure 14021 * element, and moves any anchors with it if needed. 14022 * 14023 * @param {Node} node The node to filter. 14024 * @param {Document} doc The document of the node. 14025 * @param {Object} schema The schema to use. 14026 * 14027 * @return {void} 14028 */ 14029function figureContentReducer(node, doc, schema) { 14030 if (!isFigureContent(node, schema)) { 14031 return; 14032 } 14033 let nodeToInsert = node; 14034 const parentNode = node.parentNode; 14035 14036 // If the figure content can have an anchor and its parent is an anchor with
14037 // only the figure content, take the anchor out instead of just the content. 14038 if (canHaveAnchor(node, schema) && parentNode.nodeName === 'A' && parentNode.childNodes.length === 1) { 14039 nodeToInsert = node.parentNode; 14040 } 14041 const wrapper = nodeToInsert.closest('p,div'); 14042 14043 // If wrapped in a paragraph or div, only extract if it's aligned or if 14044 // there is no text content. 14045 // Otherwise, if directly at the root, wrap in a figure element. 14046 if (wrapper) { 14047 // In jsdom-jscore, 'node.classList' can be undefined. 14048 // In this case, default to extract as it offers a better UI experience on mobile. 14049 if (!node.classList) { 14050 wrapFigureContent(nodeToInsert, wrapper); 14051 } else if (node.classList.contains('alignright') || node.classList.contains('alignleft') || node.classList.contains('aligncenter') || !wrapper.textContent.trim()) { 14052 wrapFigureContent(nodeToInsert, wrapper); 14053 } 14054 } else if (nodeToInsert.parentNode.nodeName === 'BODY') { 14055 wrapFigureContent(nodeToInsert); 14056 } 14057} 14058 14059;// CONCATENATED MODULE: external ["wp","shortcode"] 14060const external_wp_shortcode_namespaceObject = window["wp"]["shortcode"]; 14061;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/shortcode-converter.js 14062/** 14063 * WordPress dependencies 14064 */ 14065 14066 14067/** 14068 * Internal dependencies 14069 */ 14070 14071 14072 14073 14074const castArray = maybeArray => Array.isArray(maybeArray) ? maybeArray : [maybeArray]; 14075function segmentHTMLToShortcodeBlock(HTML, lastIndex = 0, excludedBlockNames = []) { 14076 // Get all matches. 14077 const transformsFrom = getBlockTransforms('from'); 14078 const transformation = findTransform(transformsFrom, transform => excludedBlockNames.indexOf(transform.blockName) === -1 && transform.type === 'shortcode' && castArray(transform.tag).some(tag => (0,external_wp_shortcode_namespaceObject.regexp)(tag).test(HTML))); 14079 if (!transformation) { 14080 return [HTML]; 14081 } 14082 const transformTags = castArray(transformation.tag); 14083 const transformTag = transformTags.find(tag => (0,external_wp_shortcode_namespaceObject.regexp)(tag).test(HTML)); 14084 let match; 14085 const previousIndex = lastIndex; 14086 if (match = (0,external_wp_shortcode_namespaceObject.next)(transformTag, HTML, lastIndex)) { 14087 lastIndex = match.index + match.content.length; 14088 const beforeHTML = HTML.substr(0, match.index); 14089 const afterHTML = HTML.substr(lastIndex); 14090 14091 // If the shortcode content does not contain HTML and the shortcode is 14092 // not on a new line (or in paragraph from Markdown converter), 14093 // consider the shortcode as inline text, and thus skip conversion for 14094 // this segment. 14095 if (!match.shortcode.content?.includes('<') && !(/(\n|<p>)\s*$/.test(beforeHTML) && /^\s*(\n|<\/p>)/.test(afterHTML))) { 14096 return segmentHTMLToShortcodeBlock(HTML, lastIndex); 14097 } 14098 14099 // If a transformation's `isMatch` predicate fails for the inbound 14100 // shortcode, try again by excluding the current block type. 14101 // 14102 // This is the only call to `segmentHTMLToShortcodeBlock` that should 14103 // ever carry over `excludedBlockNames`. Other calls in the module 14104 // should skip that argument as a way to reset the exclusion state, so 14105 // that one `isMatch` fail in an HTML fragment doesn't prevent any 14106 // valid matches in subsequent fragments. 14107 if (transformation.isMatch && !transformation.isMatch(match.shortcode.attrs)) { 14108 return segmentHTMLToShortcodeBlock(HTML, previousIndex, [...excludedBlockNames, transformation.blockName]); 14109 } 14110 let blocks = []; 14111 if (typeof transformation.transform === 'function') { 14112 // Passing all of `match` as second argument is intentionally broad 14113 // but shouldn't be too relied upon. 14114 // 14115 // See: https://github.com/WordPress/gutenberg/pull/3610#discussion_r152546926 14116 blocks = [].concat(transformation.transform(match.shortcode.attrs, match)); 14117 14118 // Applying the built-in fixes can enhance the attributes with missing content like "className". 14119 blocks = blocks.map(block => { 14120 block.originalContent = match.shortcode.content; 14121 return applyBuiltInValidationFixes(block, getBlockType(block.name)); 14122 }); 14123 } else { 14124 const attributes = Object.fromEntries(Object.entries(transformation.attributes).filter(([, schema]) =>
14124 schema.shortcode) 14125 // Passing all of `match` as second argument is intentionally broad 14126 // but shouldn't be too relied upon. 14127 // 14128 // See: https://github.com/WordPress/gutenberg/pull/3610#discussion_r152546926 14129 .map(([key, schema]) => [key, schema.shortcode(match.shortcode.attrs, match)])); 14130 const blockType = getBlockType(transformation.blockName); 14131 if (!blockType) { 14132 return [HTML]; 14133 } 14134 const transformationBlockType = { 14135 ...blockType, 14136 attributes: transformation.attributes 14137 }; 14138 let block = createBlock(transformation.blockName, getBlockAttributes(transformationBlockType, match.shortcode.content, attributes)); 14139 14140 // Applying the built-in fixes can enhance the attributes with missing content like "className". 14141 block.originalContent = match.shortcode.content; 14142 block = applyBuiltInValidationFixes(block, transformationBlockType); 14143 blocks = [block]; 14144 } 14145 return [...segmentHTMLToShortcodeBlock(beforeHTML), ...blocks, ...segmentHTMLToShortcodeBlock(afterHTML)]; 14146 } 14147 return [HTML]; 14148} 14149/* harmony default export */ const shortcode_converter = (segmentHTMLToShortcodeBlock); 14150 14151// EXTERNAL MODULE: ./node_modules/deepmerge/dist/cjs.js 14152var cjs = __webpack_require__(1919); 14153var cjs_default = /*#__PURE__*/__webpack_require__.n(cjs); 14154;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/utils.js 14155/** 14156 * External dependencies 14157 */ 14158 14159 14160/** 14161 * WordPress dependencies 14162 */ 14163 14164 14165/** 14166 * Internal dependencies 14167 */ 14168 14169 14170const customMerge = key => { 14171 return (srcValue, objValue) => { 14172 switch (key) { 14173 case 'children': 14174 { 14175 if (objValue === '*' || srcValue === '*') { 14176 return '*'; 14177 } 14178 return { 14179 ...objValue, 14180 ...srcValue 14181 }; 14182 } 14183 case 'attributes': 14184 case 'require': 14185 { 14186 return [...(objValue || []), ...(srcValue || [])]; 14187 } 14188 case 'isMatch': 14189 { 14190 // If one of the values being merge is undefined (matches everything), 14191 // the result of the merge will be undefined. 14192 if (!objValue || !srcValue) { 14193 return undefined; 14194 } 14195 // When merging two isMatch functions, the result is a new function 14196 // that returns if one of the source functions returns true. 14197 return (...args) => { 14198 return objValue(...args) || srcValue(...args); 14199 }; 14200 } 14201 } 14202 return cjs_default()(objValue, srcValue, { 14203 customMerge, 14204 clone: false 14205 }); 14206 }; 14207}; 14208function getBlockContentSchemaFromTransforms(transforms, context) { 14209 const phrasingContentSchema = (0,external_wp_dom_namespaceObject.getPhrasingContentSchema)(context); 14210 const schemaArgs = { 14211 phrasingContentSchema, 14212 isPaste: context === 'paste' 14213 }; 14214 const schemas = transforms.map(({ 14215 isMatch, 14216 blockName, 14217 schema 14218 }) => { 14219 const hasAnchorSupport = hasBlockSupport(blockName, 'anchor'); 14220 schema = typeof schema === 'function' ? schema(schemaArgs) : schema; 14221 14222 // If the block does not has anchor support and the transform does not 14223 // provides an isMatch we can return the schema right away. 14224 if (!hasAnchorSupport && !isMatch) { 14225 return schema; 14226 } 14227 if (!schema) { 14228 return {}; 14229 } 14230 return Object.fromEntries(Object.entries(schema).map(([key, value]) => { 14231 let attributes = value.attributes || []; 14232 // If the block supports the "anchor" functionality, it needs to keep its ID attribute. 14233 if (hasAnchorSupport) { 14234 attributes = [...attributes, 'id']; 14235 } 14236 return [key, { 14237 ...value, 14238 attributes,
14239 isMatch: isMatch ? isMatch : undefined 14240 }]; 14241 })); 14242 }); 14243 return cjs_default().all(schemas, { 14244 customMerge, 14245 clone: false 14246 }); 14247} 14248 14249/** 14250 * Gets the block content schema, which is extracted and merged from all 14251 * registered blocks with raw transfroms. 14252 * 14253 * @param {string} context Set to "paste" when in paste context, where the 14254 * schema is more strict. 14255 * 14256 * @return {Object} A complete block content schema. 14257 */ 14258function getBlockContentSchema(context) { 14259 return getBlockContentSchemaFromTransforms(getRawTransforms(), context); 14260} 14261 14262/** 14263 * Checks whether HTML can be considered plain text. That is, it does not contain 14264 * any elements that are not line breaks. 14265 * 14266 * @param {string} HTML The HTML to check. 14267 * 14268 * @return {boolean} Whether the HTML can be considered plain text. 14269 */ 14270function isPlain(HTML) { 14271 return !/<(?!br[ />])/i.test(HTML); 14272} 14273 14274/** 14275 * Given node filters, deeply filters and mutates a NodeList. 14276 * 14277 * @param {NodeList} nodeList The nodeList to filter. 14278 * @param {Array} filters An array of functions that can mutate with the provided node. 14279 * @param {Document} doc The document of the nodeList. 14280 * @param {Object} schema The schema to use. 14281 */ 14282function deepFilterNodeList(nodeList, filters, doc, schema) { 14283 Array.from(nodeList).forEach(node => { 14284 deepFilterNodeList(node.childNodes, filters, doc, schema); 14285 filters.forEach(item => { 14286 // Make sure the node is still attached to the document. 14287 if (!doc.contains(node)) { 14288 return; 14289 } 14290 item(node, doc, schema); 14291 }); 14292 }); 14293} 14294 14295/** 14296 * Given node filters, deeply filters HTML tags. 14297 * Filters from the deepest nodes to the top. 14298 * 14299 * @param {string} HTML The HTML to filter. 14300 * @param {Array} filters An array of functions that can mutate with the provided node. 14301 * @param {Object} schema The schema to use. 14302 * 14303 * @return {string} The filtered HTML. 14304 */ 14305function deepFilterHTML(HTML, filters = [], schema) { 14306 const doc = document.implementation.createHTMLDocument(''); 14307 doc.body.innerHTML = HTML; 14308 deepFilterNodeList(doc.body.childNodes, filters, doc, schema); 14309 return doc.body.innerHTML; 14310} 14311 14312/** 14313 * Gets a sibling within text-level context. 14314 * 14315 * @param {Element} node The subject node. 14316 * @param {string} which "next" or "previous". 14317 */ 14318function getSibling(node, which) { 14319 const sibling = node[`${which}Sibling`]; 14320 if (sibling && (0,external_wp_dom_namespaceObject.isPhrasingContent)(sibling)) { 14321 return sibling; 14322 } 14323 const { 14324 parentNode 14325 } = node; 14326 if (!parentNode || !(0,external_wp_dom_namespaceObject.isPhrasingContent)(parentNode)) { 14327 return; 14328 } 14329 return getSibling(parentNode, which); 14330} 14331 14332;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/index.js 14333/** 14334 * WordPress dependencies 14335 */ 14336 14337 14338 14339/** 14340 * Internal dependencies 14341 */ 14342 14343 14344 14345 14346 14347 14348 14349 14350 14351 14352function deprecatedGetPhrasingContentSchema(context) { 14353 external_wp_deprecated_default()('wp.blocks.getPhrasingContentSchema', { 14354 since: '5.6', 14355 alternative: 'wp.dom.getPhrasingContentSchema' 14356 }); 14357 return (0,external_wp_dom_namespaceObject.getPhrasingContentSchema)(context); 14358} 14359 14360/** 14361 * Converts an HTML string to known blocks. 14362 * 14363 * @param {Object} $1 14364 * @param {string} $1.HTML The HTML to convert. 14365 * 14366 * @return {Array} A list of blocks. 14367 */ 14368function rawHandler({ 14369 HTML = '' 14370}) { 14371 // If we detect block delimiters, parse entirely as blocks. 14372 if (HTML.indexOf('<!-- wp:') !== -1) { 14373 return parser_parse(HTML); 14374 } 14375 14376 // An array of HTML strings and block objects. The blocks replace matched 14377 // shortcodes. 14378 const pieces = shortcode_converter(HTML); 14379 const blockContentSchema = getBlockContentSchema(); 14380 return pieces.map(piece => { 14381 // Already a block from shortcode. 14382 if (typeof piece !== 'string') { 14383 return piece; 14384 } 14385 14386 // These filters are essential for some blocks to be able to transform 14387 // from raw HTML. These filters move around some content or add 14388 // additional tags, they do not remove any content. 14389 const filters = [ 14390 // Needed to adjust invalid lists. 14391 listReducer, 14392 // Needed to create more and nextpage blocks. 14393 specialCommentConverter, 14394 // Needed to create media blocks. 14395 figureContentReducer, 14396 // Needed to create the quote block, which cannot handle text 14397 // without wrapper paragraphs. 14398 blockquoteNormaliser]; 14399 piece = deepFilterHTML(piece, filters, blockContentSchema); 14400 piece = normaliseBlocks(piece); 14401 return htmlToBlocks(piece, rawHandler); 14402 }
14402).flat().filter(Boolean); 14403} 14404 14405;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/comment-remover.js 14406/** 14407 * WordPress dependencies 14408 */ 14409 14410 14411/** 14412 * Looks for comments, and removes them. 14413 * 14414 * @param {Node} node The node to be processed. 14415 * @return {void} 14416 */ 14417function commentRemover(node) { 14418 if (node.nodeType === node.COMMENT_NODE) { 14419 (0,external_wp_dom_namespaceObject.remove)(node); 14420 } 14421} 14422 14423;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/is-inline-content.js 14424/** 14425 * WordPress dependencies 14426 */ 14427 14428 14429/** 14430 * Checks if the given node should be considered inline content, optionally 14431 * depending on a context tag. 14432 * 14433 * @param {Node} node Node name. 14434 * @param {string} contextTag Tag name. 14435 * 14436 * @return {boolean} True if the node is inline content, false if nohe. 14437 */ 14438function isInline(node, contextTag) { 14439 if ((0,external_wp_dom_namespaceObject.isTextContent)(node)) { 14440 return true; 14441 } 14442 if (!contextTag) { 14443 return false; 14444 } 14445 const tag = node.nodeName.toLowerCase(); 14446 const inlineAllowedTagGroups = [['ul', 'li', 'ol'], ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']]; 14447 return inlineAllowedTagGroups.some(tagGroup => [tag, contextTag].filter(t => !tagGroup.includes(t)).length === 0); 14448} 14449function deepCheck(nodes, contextTag) { 14450 return nodes.every(node => isInline(node, contextTag) && deepCheck(Array.from(node.children), contextTag)); 14451} 14452function isDoubleBR(node) { 14453 return node.nodeName === 'BR' && node.previousSibling && node.previousSibling.nodeName === 'BR'; 14454} 14455function isInlineContent(HTML, contextTag) { 14456 const doc = document.implementation.createHTMLDocument(''); 14457 doc.body.innerHTML = HTML; 14458 const nodes = Array.from(doc.body.children); 14459 return !nodes.some(isDoubleBR) && deepCheck(nodes, contextTag); 14460} 14461 14462;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/phrasing-content-reducer.js 14463/** 14464 * WordPress dependencies 14465 */ 14466 14467function phrasingContentReducer(node, doc) { 14468 // In jsdom-jscore, 'node.style' can be null. 14469 // TODO: Explore fixing this by patching jsdom-jscore. 14470 if (node.nodeName === 'SPAN' && node.style) { 14471 const { 14472 fontWeight, 14473 fontStyle, 14474 textDecorationLine, 14475 textDecoration, 14476 verticalAlign 14477 } = node.style; 14478 if (fontWeight === 'bold' || fontWeight === '700') { 14479 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('strong'), node); 14480 } 14481 if (fontStyle === 'italic') { 14482 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('em'), node); 14483 } 14484 14485 // Some DOM implementations (Safari, JSDom) don't support 14486 // style.textDecorationLine, so we check style.textDecoration as a 14487 // fallback. 14488 if (textDecorationLine === 'line-through' || textDecoration.includes('line-through')) { 14489 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('s'), node); 14490 } 14491 if (verticalAlign === 'super') { 14492 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('sup'), node); 14493 } else if (verticalAlign === 'sub') { 14494 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('sub'), node); 14495 } 14496 } else if (node.nodeName === 'B') { 14497 node = (0,external_wp_dom_namespaceObject.replaceTag)(node, 'strong'); 14498 } else if (node.nodeName === 'I') { 14499 node = (0,external_wp_dom_namespaceObject.replaceTag)(node, 'em'); 14500 } else if (node.nodeName === 'A') { 14501 // In jsdom-jscore, 'node.target' can be null. 14502 // TODO: Explore fixing this by patching jsdom-jscore. 14503 if (node.target && node.target.toLowerCase() === '_blank') { 14504 node.rel = 'noreferrer noopener'; 14505 } else { 14506 node.removeAttribute('target'); 14507 node.removeAttribute('rel'); 14508 } 14509 14510 // Saves anchor elements name attribute as id 14511 if (node.name && !node.id) { 14512 node.id = node.name; 14513 } 14514 14515 // Keeps id only if there is an internal link pointing to it 14516 if (node.id && !node.ownerDocument.querySelector(`[href="#${node.id}"]`)) { 14517 node.removeAttribute('id'); 14518 } 14519 } 14520} 14521 14522;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/head-remover.js 14523function headRemover(node) { 14524 if (node.nodeName !== 'SCRIPT' && node.nodeName !== 'NOSCRIPT' && node.nodeName !== 'TEMPLATE' && node.nodeName !== 'STYLE') { 14525 return; 14526 } 14527 node.parentNode.removeChild(node); 14528} 14529 14530;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/ms-list-ignore.js 14531/**
14532 * Looks for comments, and removes them. 14533 * 14534 * @param {Node} node The node to be processed. 14535 * @return {void} 14536 */ 14537function msListIgnore(node) { 14538 if (node.nodeType !== node.ELEMENT_NODE) { 14539 return; 14540 } 14541 const style = node.getAttribute('style'); 14542 if (!style || !style.includes('mso-list')) { 14543 return; 14544 } 14545 const rules = style.split(';').reduce((acc, rule) => { 14546 const [key, value] = rule.split(':'); 14547 acc[key.trim().toLowerCase()] = value.trim().toLowerCase(); 14548 return acc; 14549 }, {}); 14550 if (rules['mso-list'] === 'ignore') { 14551 node.remove(); 14552 } 14553} 14554 14555;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/ms-list-converter.js 14556/** 14557 * Browser dependencies 14558 */ 14559const { 14560 parseInt: ms_list_converter_parseInt 14561} = window; 14562 14563/** 14564 * Internal dependencies 14565 */ 14566 14567 14568function ms_list_converter_isList(node) { 14569 return node.nodeName === 'OL' || node.nodeName === 'UL'; 14570} 14571function msListConverter(node, doc) { 14572 if (node.nodeName !== 'P') { 14573 return; 14574 } 14575 const style = node.getAttribute('style'); 14576 if (!style || !style.includes('mso-list')) { 14577 return; 14578 } 14579 const prevNode = node.previousElementSibling; 14580 14581 // Add new list if no previous. 14582 if (!prevNode || !ms_list_converter_isList(prevNode)) { 14583 // See https://html.spec.whatwg.org/multipage/grouping-content.html#attr-ol-type. 14584 const type = node.textContent.trim().slice(0, 1); 14585 const isNumeric = /[1iIaA]/.test(type); 14586 const newListNode = doc.createElement(isNumeric ? 'ol' : 'ul'); 14587 if (isNumeric) { 14588 newListNode.setAttribute('type', type); 14589 } 14590 node.parentNode.insertBefore(newListNode, node); 14591 } 14592 const listNode = node.previousElementSibling; 14593 const listType = listNode.nodeName; 14594 const listItem = doc.createElement('li'); 14595 let receivingNode = listNode; 14596 14597 // Add content. 14598 listItem.innerHTML = deepFilterHTML(node.innerHTML, [msListIgnore]); 14599 const matches = /mso-list\s*:[^;]+level([0-9]+)/i.exec(style); 14600 let level = matches ? ms_list_converter_parseInt(matches[1], 10) - 1 || 0 : 0; 14601 14602 // Change pointer depending on indentation level. 14603 while (level--) { 14604 receivingNode = receivingNode.lastChild || receivingNode; 14605 14606 // If it's a list, move pointer to the last item. 14607 if (ms_list_converter_isList(receivingNode)) { 14608 receivingNode = receivingNode.lastChild || receivingNode; 14609 } 14610 } 14611 14612 // Make sure we append to a list. 14613 if (!ms_list_converter_isList(receivingNode)) { 14614 receivingNode = receivingNode.appendChild(doc.createElement(listType)); 14615 } 14616 14617 // Append the list item to the list. 14618 receivingNode.appendChild(listItem); 14619 14620 // Remove the wrapper paragraph. 14621 node.parentNode.removeChild(node); 14622} 14623 14624;// CONCATENATED MODULE: external ["wp","blob"] 14625const external_wp_blob_namespaceObject = window["wp"]["blob"]; 14626;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/image-corrector.js 14627/** 14628 * WordPress dependencies 14629 */ 14630 14631 14632/** 14633 * Browser dependencies 14634 */ 14635const { 14636 atob, 14637 File 14638} = window; 14639function imageCorrector(node) { 14640 if (node.nodeName !== 'IMG') { 14641 return; 14642 } 14643 if (node.src.indexOf('file:') === 0) { 14644 node.src = ''; 14645 } 14646 14647 // This piece cannot be tested outside a browser env. 14648 if (node.src.indexOf('data:') === 0) { 14649 const [properties, data] = node.src.split(','); 14650 const [type] = properties.slice(5).split(';'); 14651 if (!data || !type) { 14652 node.src = ''; 14653 return; 14654 } 14655 let decoded; 14656 14657 // Can throw DOMException! 14658 try { 14659 decoded = atob(data); 14660 } catch (e) { 14661 node.src = ''; 14662 return; 14663 } 14664 const uint8Array = new Uint8Array(decoded.length); 14665 for (let i = 0; i < uint8Array.length; i++) { 14666 uint8Array[i] = decoded.charCodeAt(i); 14667 } 14668 const name = type.replace('/', '.'); 14669 const file = new File([uint8Array], name, { 14670 type 14671 }); 14672 node.src = (0,external_wp_blob_namespaceObject.createBlobURL)(file); 14673 } 14674 14675 // Remove trackers and hardly visible images. 14676 if (node.height === 1 || node.width === 1) { 14677 node.parentNode.removeChild(node); 14678 } 14679} 14680 14681;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/div-normaliser.js 14682/** 14683 * Internal dependencies 14684 */ 14685 14686function divNormaliser(node) { 14687 if (node.nodeName !== 'DIV') { 14688 return; 14689 } 14690 node.innerHTML = normaliseBlocks(node.innerHTML); 14691} 14692 14693// EXTERNAL MODULE: ./node_modules/showdown/dist/showdown.js 14694var showdown = __webpack_require__(7308); 14695var showdown_default = /*#__PURE__*/__webpack_require__.n(showdown); 14696;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/markdown-converter.js 14697/** 14698 * External dependencies 14699 */ 14700 14701 14702// Reuse the same showdown converter. 14703const converter = new (showdown_default()).Converter({ 14704 noHeaderId: true, 14705 tables: true, 14706 literalMidWordUnderscores: true, 14707 omitExtraWLInCodeBlocks: true, 14708 simpleLineBreaks: true, 14709 strikethrough: true 14710}); 14711 14712/** 14713 * Corrects the Slack Markdown variant of the code block. 14714 * If uncorrected, it will be converted to inline code. 14715 * 14716 * @see https://get.slack.help/hc/en-us/articles/202288908-how-can-i-add-formatting-to-my-messages-#co
14716de-blocks 14717 * 14718 * @param {string} text The potential Markdown text to correct. 14719 * 14720 * @return {string} The corrected Markdown. 14721 */ 14722function slackMarkdownVariantCorrector(text) { 14723 return text.replace(/((?:^|\n)```)([^\n`]+)(```(?:$|\n))/, (match, p1, p2, p3) => `${p1}\n${p2}\n${p3}`); 14724} 14725function bulletsToAsterisks(text) { 14726 return text.replace(/(^|\n)â¢( +)/g, '$1*$2'); 14727} 14728 14729/** 14730 * Converts a piece of text into HTML based on any Markdown present. 14731 * Also decodes any encoded HTML. 14732 * 14733 * @param {string} text The plain text to convert. 14734 * 14735 * @return {string} HTML. 14736 */ 14737function markdownConverter(text) { 14738 return converter.makeHtml(slackMarkdownVariantCorrector(bulletsToAsterisks(text))); 14739} 14740 14741;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/iframe-remover.js 14742/** 14743 * Removes iframes. 14744 * 14745 * @param {Node} node The node to check. 14746 * 14747 * @return {void} 14748 */ 14749function iframeRemover(node) { 14750 if (node.nodeName === 'IFRAME') { 14751 const text = node.ownerDocument.createTextNode(node.src); 14752 node.parentNode.replaceChild(text, node); 14753 } 14754} 14755 14756;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/google-docs-uid-remover.js 14757/** 14758 * WordPress dependencies 14759 */ 14760 14761function googleDocsUIdRemover(node) { 14762 if (!node.id || node.id.indexOf('docs-internal-guid-') !== 0) { 14763 return; 14764 } 14765 14766 // Google Docs sometimes wraps the content in a B tag. We don't want to keep 14767 // this. 14768 if (node.tagName === 'B') { 14769 (0,external_wp_dom_namespaceObject.unwrap)(node); 14770 } else { 14771 node.removeAttribute('id'); 14772 } 14773} 14774 14775;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/html-formatting-remover.js 14776/** 14777 * Internal dependencies 14778 */ 14779 14780function isFormattingSpace(character) { 14781 return character === ' ' || character === '\r' || character === '\n' || character === '\t'; 14782} 14783 14784/** 14785 * Removes spacing that formats HTML. 14786 * 14787 * @see https://www.w3.org/TR/css-text-3/#white-space-processing 14788 * 14789 * @param {Node} node The node to be processed. 14790 * @return {void} 14791 */ 14792function htmlFormattingRemover(node) { 14793 if (node.nodeType !== node.TEXT_NODE) { 14794 return; 14795 } 14796 14797 // Ignore pre content. Note that this does not use Element#closest due to 14798 // a combination of (a) node may not be Element and (b) node.parentElement 14799 // does not have full support in all browsers (Internet Exporer). 14800 // 14801 // See: https://developer.mozilla.org/en-US/docs/Web/API/Node/parentElement#Browser_compatibility 14802 14803 /** @type {Node?} */ 14804 let parent = node; 14805 while (parent = parent.parentNode) { 14806 if (parent.nodeType === parent.ELEMENT_NODE && parent.nodeName === 'PRE') { 14807 return; 14808 } 14809 } 14810 14811 // First, replace any sequence of HTML formatting space with a single space. 14812 let newData = node.data.replace(/[ \r\n\t]+/g, ' '); 14813 14814 // Remove the leading space if the text element is at the start of a block, 14815 // is preceded by a line break element, or has a space in the previous 14816 // node. 14817 if (newData[0] === ' ') { 14818 const previousSibling = getSibling(node, 'previous'); 14819 if (!previousSibling || previousSibling.nodeName === 'BR' || previousSibling.textContent.slice(-1) === ' ') { 14820 newData = newData.slice(1); 14821 } 14822 } 14823 14824 // Remove the trailing space if the text element is at the end of a block, 14825 // is succeded by a line break element, or has a space in the next text 14826 // node. 14827 if (newData[newData.length - 1] === ' ') { 14828 const nextSibling = getSibling(node, 'next'); 14829 if (!nextSibling || nextSibling.nodeName === 'BR' || nextSibling.nodeType === nextSibling.TEXT_NODE && isFormattingSpace(nextSibling.textContent[0])) { 14830 newData = newData.slice(0, -1); 14831 } 14832 } 14833 14834 // If there's no data left, remove the node, so `previousSibling` stays 14835 // accurate. Otherwise, update the node data. 14836 if (!newData) { 14837 node.parentNode.removeChild(node); 14838 } else { 14839 node.data = newData; 14840 } 14841} 14842 14843;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/br-remover.js 14844/** 14845 * Internal dependencies 14846 */ 14847 14848 14849/** 14850 * Removes trailing br elements from text-level content. 14851 * 14852 * @param {Element} node Node to check. 14853 */ 14854function brRemover(node) { 14855 if (node.nodeName !== 'BR') { 14856 return; 14857 } 14858 if (getSibling(node, 'next')) { 14859 return; 14860 } 14861 node.parentNode.removeChild(node); 14862} 14863 14864;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/empty-paragraph-remover.js 14865/** 14866 * Removes empty paragraph elements. 14867 * 14868 * @param {Element} node Node to check. 14869 */ 14870function emptyParagraphRemover(node) { 14871 if (node.nodeName !== 'P') { 14872 return; 14873 } 14874 if (node.hasChildNodes()) { 14875 return; 14876 } 14877 node.parentNode.removeChild(node); 14878} 14879 14880;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/slack-paragraph-corrector.js 14881/** 14882 * Replaces Slack paragraph markup with a double line break (later converted to 14883 * a proper paragraph). 14884 * 14885 * @param {Element} node Node to check. 14886 */ 14887function slackParagraphCorrector(node) { 14888 if (node.nodeName !== 'SPAN') { 14889 return; 14890 } 14891 if (node.getAttribute('data-stringify-type') !== 'paragraph-break') { 14892 return; 14893 } 14894 const { 14895 parentNode 14896 }
14896 = node; 14897 parentNode.insertBefore(node.ownerDocument.createElement('br'), node); 14898 parentNode.insertBefore(node.ownerDocument.createElement('br'), node); 14899 parentNode.removeChild(node); 14900} 14901 14902;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/paste-handler.js 14903/** 14904 * WordPress dependencies 14905 */ 14906 14907 14908/** 14909 * Internal dependencies 14910 */ 14911 14912 14913 14914 14915 14916 14917 14918 14919 14920 14921 14922 14923 14924 14925 14926 14927 14928 14929 14930 14931 14932 14933 14934 14935 14936 14937 14938/** 14939 * Browser dependencies 14940 */ 14941const { 14942 console: paste_handler_console 14943} = window; 14944 14945/** 14946 * Filters HTML to only contain phrasing content. 14947 * 14948 * @param {string} HTML The HTML to filter. 14949 * @param {boolean} preserveWhiteSpace Whether or not to preserve consequent white space. 14950 * 14951 * @return {string} HTML only containing phrasing content. 14952 */ 14953function filterInlineHTML(HTML, preserveWhiteSpace) { 14954 HTML = deepFilterHTML(HTML, [headRemover, googleDocsUIdRemover, msListIgnore, phrasingContentReducer, commentRemover]); 14955 HTML = (0,external_wp_dom_namespaceObject.removeInvalidHTML)(HTML, (0,external_wp_dom_namespaceObject.getPhrasingContentSchema)('paste'), { 14956 inline: true 14957 }); 14958 if (!preserveWhiteSpace) { 14959 HTML = deepFilterHTML(HTML, [htmlFormattingRemover, brRemover]); 14960 } 14961 14962 // Allows us to ask for this information when we get a report. 14963 paste_handler_console.log('Processed inline HTML:\n\n', HTML); 14964 return HTML; 14965} 14966 14967/** 14968 * Converts an HTML string to known blocks. Strips everything else. 14969 * 14970 * @param {Object} options 14971 * @param {string} [options.HTML] The HTML to convert. 14972 * @param {string} [options.plainText] Plain text version. 14973 * @param {string} [options.mode] Handle content as blocks or inline content. 14974 * * 'AUTO': Decide based on the content passed. 14975 * * 'INLINE': Always handle as inline content, and return string. 14976 * * 'BLOCKS': Always handle as blocks, and return array of blocks. 14977 * @param {Array} [options.tagName] The tag into which content will be inserted. 14978 * @param {boolean} [options.preserveWhiteSpace] Whether or not to preserve consequent white space. 14979 * 14980 * @return {Array|string} A list of blocks or a string, depending on `handlerMode`. 14981 */ 14982function pasteHandler({ 14983 HTML = '', 14984 plainText = '', 14985 mode = 'AUTO', 14986 tagName, 14987 preserveWhiteSpace 14988}) { 14989 // First of all, strip any meta tags. 14990 HTML = HTML.replace(/<meta[^>]+>/g, ''); 14991 // Strip Windows markers. 14992 HTML = HTML.replace(/^\s*<html[^>]*>\s*<body[^>]*>(?:\s*<!--\s*StartFragment\s*-->)?/i, ''); 14993 HTML = HTML.replace(/(?:<!--\s*EndFragment\s*-->\s*)?<\/body>\s*<\/html>\s*$/i, ''); 14994 14995 // If we detect block delimiters in HTML, parse entirely as blocks. 14996 if (mode !== 'INLINE') { 14997 // Check plain text if there is no HTML. 14998 const content = HTML ? HTML : plainText; 14999 if (content.indexOf('<!-- wp:') !== -1) { 15000 return parser_parse(content); 15001 } 15002 } 15003 15004 // Normalize unicode to use composed characters. 15005 // This is unsupported in IE 11 but it's a nice-to-have feature, not mandatory. 15006 // Not normalizing the content will only affect older browsers and won't 15007 // entirely break the app. 15008 // See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize 15009 // See: https://core.trac.wordpress.org/ticket/30130 15010 // See: https://github.com/WordPress/gutenberg/pull/6983#pullrequestreview-125151075 15011 if (String.prototype.normalize) { 15012 HTML = HTML.normalize(); 15013 } 15014 15015 // Parse Markdown (and encoded HTML) if: 15016 // * There is a plain text version. 15017 // * There is no HTML version, or it has no formatting. 15018 if (plainText && (!HTML || isPlain(HTML))) { 15019 HTML = plainText; 15020 15021 // The markdown converter (Showdown) trims whitespace. 15022 if (!/^\s+$/.test(plainText)) { 15023 HTML = markdownConverter(HTML); 15024 } 15025 15026 // Switch to inline mode if: 15027 // * The current mode is AUTO. 15028 // * The original plain text had no line breaks. 15029 // * The original plain text was not an HTML paragraph. 15030 // * The converted text is just a paragraph. 15031 if (mode === 'AUTO' && plainText.indexOf('\n') === -1 && plainText.indexOf('<p>') !== 0 && HTML.indexOf('<p>') === 0) { 15032 mode = 'INLINE'; 15033 } 15034 } 15035 if (mode === 'INLINE') { 15036 return filterInlineHTML(HTML, preserveWhiteSpace); 15037 } 15038 15039 // Must be run before checking if it's inline content. 15040 HTML = deepFilterHTML(HTML, [slackParagraphCorrector]); 15041 15042 // An array of HTML strings and block objects. The blocks replace matched 15043 // shortcodes. 15044 const pieces = shortcode_converter(HTML); 15045 15046 // The call to shortcodeConverter will always return more than one element 15047 // if shortcodes are matched. The reason is when shortcodes are matched 15048 // empty HTML strings are included. 15049 const hasShortcodes = pieces.length > 1; 15050 if (mode === 'AUTO' && !hasShortcodes && isInlineContent(HTML, tagName)) { 15051 return filterInlineHTML(HTML, preserveWhiteSpace); 15052 } 15053 const phrasingContentSchema = (0,external_wp_dom_namespaceObject.getPhrasingContentSchema)('paste'); 15054 const blockContentSchema = getBlockContentSchema('paste'); 15055 const blocks = pieces.map(piece => { 15056 // Already a block from shortcode. 15057 if (typeof piece !== 'string') { 15058 return piece; 15059 } 15060 const filters = [googleDocsUIdRemover, msListConverter, headRemover, listReducer, imageCorrector, phrasingContentReducer, specialCommentConverter, commentRemover, iframeRemover, figureContentReducer, blockquoteNormaliser, divNormaliser]; 15061 const schema = { 15062 ...blockContentSchema, 15063 // Keep top-level phrasing content, normalised by `normaliseBlocks`. 15064 ...phrasingContentSchema 15065 }; 15066 piece = deepFilterHTML(piece, filters, blockContentSchema); 15067 piece = (0,external_wp_dom_namespaceObject.removeInvalidHTML)(piece, schema); 15068 piece = normaliseBlocks(piece); 15069 piece = deepFilterHTML(piece, [htmlFormattingRemover, brRemover, emptyParagraphRemover], blockContentSchema); 15070 15071 // Allows us to ask for this information when we get a report. 15072 paste_handler_console.log('Processed HTML piece:\n\n', piece); 15073 return htmlToBlocks(piece, pasteHandler); 15074 }
15074).flat().filter(Boolean); 15075 15076 // If we're allowed to return inline content, and there is only one 15077 // inlineable block, and the original plain text content does not have any 15078 // line breaks, then treat it as inline paste. 15079 if (mode === 'AUTO' && blocks.length === 1 && hasBlockSupport(blocks[0].name, '__unstablePasteTextInline', false)) { 15080 const trimRegex = /^[\n]+|[\n]+$/g; 15081 // Don't catch line breaks at the start or end. 15082 const trimmedPlainText = plainText.replace(trimRegex, ''); 15083 if (trimmedPlainText !== '' && trimmedPlainText.indexOf('\n') === -1) { 15084 return (0,external_wp_dom_namespaceObject.removeInvalidHTML)(getBlockInnerHTML(blocks[0]), phrasingContentSchema).replace(trimRegex, ''); 15085 } 15086 } 15087 return blocks; 15088} 15089 15090;// CONCATENATED MODULE: ./packages/blocks/build-module/api/categories.js 15091/** 15092 * WordPress dependencies 15093 */ 15094 15095 15096/** 15097 * Internal dependencies 15098 */ 15099 15100 15101/** @typedef {import('../store/reducer').WPBlockCategory} WPBlockCategory */ 15102 15103/** 15104 * Returns all the block categories. 15105 * Ignored from documentation as the recommended usage is via useSelect from @wordpress/data. 15106 * 15107 * @ignore 15108 * 15109 * @return {WPBlockCategory[]} Block categories. 15110 */ 15111function categories_getCategories() { 15112 return (0,external_wp_data_namespaceObject.select)(store).getCategories(); 15113} 15114 15115/** 15116 * Sets the block categories. 15117 * 15118 * @param {WPBlockCategory[]} categories Block categories. 15119 * 15120 * @example 15121 * ```js 15122 * import { __ } from '@wordpress/i18n'; 15123 * import { store as blocksStore, setCategories } from '@wordpress/blocks'; 15124 * import { useSelect } from '@wordpress/data'; 15125 * import { Button } from '@wordpress/components'; 15126 * 15127 * const ExampleComponent = () => { 15128 * // Retrieve the list of current categories. 15129 * const blockCategories = useSelect( 15130 * ( select ) => select( blocksStore ).getCategories(), 15131 * [] 15132 * ); 15133 * 15134 * return ( 15135 * <Button 15136 * onClick={ () => { 15137 * // Add a custom category to the existing list. 15138 * setCategories( [ 15139 * ...blockCategories, 15140 * { title: 'Custom Category', slug: 'custom-category' }, 15141 * ] ); 15142 * } } 15143 * > 15144 * { __( 'Add a new custom block category' ) } 15145 * </Button> 15146 * ); 15147 * }; 15148 * ``` 15149 */ 15150function categories_setCategories(categories) { 15151 (0,external_wp_data_namespaceObject.dispatch)(store).setCategories(categories); 15152} 15153 15154/** 15155 * Updates a category. 15156 * 15157 * @param {string} slug Block category slug. 15158 * @param {WPBlockCategory} category Object containing the category properties 15159 * that should be updated. 15160 * 15161 * @example 15162 * ```js 15163 * import { __ } from '@wordpress/i18n'; 15164 * import { updateCategory } from '@wordpress/blocks'; 15165 * import { Button } from '@wordpress/components'; 15166 * 15167 * const ExampleComponent = () => { 15168 * return ( 15169 * <Button 15170 * onClick={ () => { 15171 * updateCategory( 'text', { title: __( 'Written Word' ) } ); 15172 * } } 15173 * > 15174 * { __( 'Update Text category title' ) } 15175 * </Button> 15176 * ) ; 15177 * }; 15178 * ``` 15179 */ 15180function categories_updateCategory(slug, category) { 15181 (0,external_wp_data_namespaceObject.dispatch)(store).updateCategory(slug, category); 15182} 15183 15184;// CONCATENATED MODULE: ./packages/blocks/build-module/api/templates.js 15185/** 15186 * WordPress dependencies 15187 */ 15188 15189 15190/** 15191 * Internal dependencies 15192 */ 15193 15194 15195 15196 15197/** 15198 * Checks whether a list of blocks matches a template by comparing the block names. 15199 * 15200 * @param {Array} blocks Block list. 15201 * @param {Array} template Block template. 15202 * 15203 * @return {boolean} Whether the list of blocks matches a templates. 15204 */ 15205function doBlocksMatchTemplate(blocks = [], template = []) { 15206 return blocks.length === template.length && template.every(([name,, innerBlocksTemplate], index) => { 15207 const block = blocks[index]; 15208 return name === block.name && doBlocksMatchTemplate(block.innerBlocks, innerBlocksTemplate); 15209 }); 15210} 15211 15212/** 15213 * Synchronize a block list with a block template. 15214 * 15215 * Synchronizing a block list with a block template means that we loop over the blocks 15216 * keep the block as is if it matches the block at the same position in the template 15217 * (If it has the same name) and if doesn't match, we create a new block based on the template. 15218 * Extra blocks not present in the template are removed. 15219 * 15220 * @param {Array} blocks Block list. 15221 * @param {Array} template Block template. 15222 * 15223 * @return {Array} Updated Block list. 15224 */ 15225function synchronizeBlocksWithTemplate(blocks = [], template) { 15226 // If no template is provided, return blocks unmodified. 15227 if (!template) { 15228 return blocks; 15229 } 15230 return template.map(([name, attributes, innerBlocksTemplate], index) => { 15231 var _blockType$attributes; 15232 const block = blocks[index]; 15233 if (block && block.name === name) { 15234 const innerBlocks = synchronizeBlocksWithTemplate(block.innerBlocks, innerBlocksTemplate); 15235 return { 15236 ...block, 15237 innerBlocks 15238 }; 15239 } 15240 15241 // To support old templates that were using the "children" format 15242 // for the attributes using "html" strings now, we normalize the template attributes 15243 // before creating the blocks. 15244 15245 const blockType = getBlockType(name); 15246 const isHTMLAttribute = attributeDefinition => attributeDefinition?.source === 'html'; 15247 const isQueryAttribute = attributeDefinition => attributeDefinition?.source === 'query'; 15248 const normalizeAttributes = (schema, values) => { 15249 if (!values) { 15250 return {}; 15251 } 15252 return Object.fromEntries(Object.entries(values).map(([key, value]) => [key, normalizeAttribute(schema[key], value)])); 15253 }; 15254 const normalizeAttribute = (definition, value) => { 15255 if (isHTMLAttribute(definition) && Array.isArray(value)) { 15256 // Introduce a deprecated call at this point 15257 // When we're confident that "children" format should be removed from the templates. 15258 15259 return (0,external_wp_element_namespaceObject.renderToString)(value); 15260 } 15261 if (isQueryAttribute(definition) && value) { 15262 return value.map(subValues => { 15263 return normalizeAttributes(definition.query, subValues); 15264 }); 15265 } 15266 return value; 15267 }; 15268 const normalizedAttributes = normalizeAttributes((_blockType$attributes = blockType?.attributes) !== null && _blockType$attributes !== void 0 ? _blockType$attributes : {}, attributes); 15269 let [blockName, blockAttributes] = convertLegacyBlockNameAndAttributes(name, normalizedAttributes); 15270 15271 // If a Block is undefined at this point, use the core/missing block as 15272 // a placeholder for a better user experience. 15273 if (undefined === getBlockType(blockName)) { 15274 blockAttributes = { 15275 originalName: name, 15276 originalContent: '', 15277 originalUndelimitedContent: '' 15278 }; 15279 blockName = 'core/missing'; 15280 } 15281 return createBlock(blockName, blockAttributes, synchronizeBlocksWithTemplate([], innerBlocksTemplate)); 15282 }); 15283} 15284 15285;// CONCATENATED MODULE: ./packages/blocks/build-module/api/index.js 15286// The blocktype is the most important concept within the block API. It defines 15287// all aspects of the block configuration and its interfaces, including `edit`
15288// and `save`. The transforms specification allows converting one blocktype to 15289// another through formulas defined by either the source or the destination. 15290// Switching a blocktype is to be considered a one-way operation implying a 15291// transformation in the opposite way has to be handled explicitly. 15292 15293 15294// The block tree is composed of a collection of block nodes. Blocks contained 15295// within other blocks are called inner blocks. An important design 15296// consideration is that inner blocks are -- conceptually -- not part of the 15297// territory established by the parent block that contains them. 15298// 15299// This has multiple practical implications: when parsing, we can safely dispose 15300// of any block boundary found within a block from the innerHTML property when 15301// transfering to state. Not doing so would have a compounding effect on memory 15302// and uncertainty over the source of truth. This can be illustrated in how, 15303// given a tree of `n` nested blocks, the entry node would have to contain the 15304// actual content of each block while each subsequent block node in the state 15305// tree would replicate the entire chain `n-1`, meaning the extreme end node 15306// would have been replicated `n` times as the tree is traversed and would 15307// generate uncertainty as to which one is to hold the current value of the 15308// block. For composition, it also means inner blocks can effectively be child 15309// components whose mechanisms can be shielded from the `edit` implementation 15310// and just passed along. 15311 15312 15313 15314 15315// While block transformations account for a specific surface of the API, there 15316// are also raw transformations which handle arbitrary sources not made out of 15317// blocks but producing block basaed on various heursitics. This includes 15318// pasting rich text or HTML data. 15319 15320 15321// The process of serialization aims to deflate the internal memory of the block 15322// editor and its state representation back into an HTML valid string. This 15323// process restores the document integrity and inserts invisible delimiters 15324// around each block with HTML comment boundaries which can contain any extra 15325// attributes needed to operate with the block later on. 15326 15327 15328// Validation is the process of comparing a block source with its output before 15329// there is any user input or interaction with a block. When this operation 15330// fails -- for whatever reason -- the block is to be considered invali
15330d. As 15331// part of validating a block the system will attempt to run the source against 15332// any provided deprecation definitions. 15333// 15334// Worth emphasizing that validation is not a case of whether the markup is 15335// merely HTML spec-compliant but about how the editor knows to create such 15336// markup and that its inability to create an identical result can be a strong 15337// indicator of potential data loss (the invalidation is then a protective 15338// measure). 15339// 15340// The invalidation process can also be deconstructed in phases: 1) validate the 15341// block exists; 2) validate the source matches the output; 3) validate the 15342// source matches deprecated outputs; 4) work through the significance of 15343// differences. These are stacked in a way that favors performance and optimizes 15344// for the majority of cases. That is to say, the evaluation logic can become 15345// more sophisticated the further down it goes in the process as the cost is 15346// accounted for. The first logic checks have to be extremely efficient since 15347// they will be run for all valid and invalid blocks alike. However, once a 15348// block is detected as invalid -- failing the three first steps -- it is 15349// adequate to spend more time determining validity before throwing a conflict. 15350 15351 15352 15353// Blocks are inherently indifferent about where the data they operate with ends 15354// up being saved. For example, all blocks can have a static and dynamic aspect 15355// to them depending on the needs. The static nature of a block is the `save()` 15356// definition that is meant to be serialized into HTML and which can be left 15357// void. Any block can also register a `render_callback` on the server, which 15358// makes its output dynamic either in part or in its totality. 15359// 15360// Child blocks are defined as a relationship that builds on top of the inner 15361// blocks mechanism. A child block is a block node of a particular type that can 15362// only exist within the inner block boundaries of a specific parent type. This 15363// allows block authors to compose specific blocks that are not meant to be used 15364// outside of a specified parent block context. Thus, child blocks extend the 15365// concept of inner blocks to support a more direct relationship between sets of 15366// blocks. The addition of parentâchild would be a subset of the inner block 15367// functionality under the premise that certain blocks only make sense as 15368// children of another block. 15369 15370 15371 15372// Templates are, in a general sense, a basic collection of block nodes with any 15373// given set of predefined attributes that are supplied as the initial state of 15374// an inner blocks group. These nodes can, in turn, contain any number of nested 15375// blocks within their definition. Templates allow both to specify a default 15376// state for an editor session or a default set of blocks for any inner block 15377// implementation within a specific block. 15378 15379 15380 15381 15382 15383;// CONCATENATED MODULE: ./packages/blocks/build-module/deprecated.js 15384/** 15385 * WordPress dependencies 15386 */ 15387 15388 15389/** 15390 * A Higher Order Component used to inject BlockContent using context to the 15391 * wrapped component. 15392 * 15393 * @deprecated 15394 * 15395 * @param {WPComponent} OriginalComponent The component to enhance. 15396 * @return {WPComponent} The same component. 15397 */ 15398function withBlockContentContext(OriginalComponent) { 15399 external_wp_deprecated_default()('wp.blocks.withBlockContentContext', { 15400 since: '6.1' 15401 }); 15402 return OriginalComponent; 15403} 15404 15405;// CONCATENATED MODULE: ./packages/blocks/build-module/index.js 15406// A "block" is the abstract term used to describe units of markup that, 15407// when composed together, form the content or layout of a page. 15408// The API for blocks is exposed via `wp.blocks`. 15409// 15410// Supported blocks are registered by calling `registerBlockType`. Once registered, 15411// the block is made available as an option to the editor interface. 15412// 15413// Blocks are inferred from the HTML source of a post through a parsing mechanism 15414// and then stored as objects in state, from which it is then rendered for editing. 15415 15416 15417 15418 15419 15420})(); 15421 15422(window.wp = window.wp || {}).blocks = __webpack_exports__; 15423/******/ })() 15424;
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.