[ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 /******/ (() => { // webpackBootstrap 2 /******/ var __webpack_modules__ = ({ 3 4 /***/ 7734: 5 /***/ ((module) => { 6 7 "use strict"; 8 9 10 // do not edit .js files directly - edit src/index.jst 11 12 13 var envHasBigInt64Array = typeof BigInt64Array !== 'undefined'; 14 15 16 module.exports = function equal(a, b) { 17 if (a === b) return true; 18 19 if (a && b && typeof a == 'object' && typeof b == 'object') { 20 if (a.constructor !== b.constructor) return false; 21 22 var length, i, keys; 23 if (Array.isArray(a)) { 24 length = a.length; 25 if (length != b.length) return false; 26 for (i = length; i-- !== 0;) 27 if (!equal(a[i], b[i])) return false; 28 return true; 29 } 30 31 32 if ((a instanceof Map) && (b instanceof Map)) { 33 if (a.size !== b.size) return false; 34 for (i of a.entries()) 35 if (!b.has(i[0])) return false; 36 for (i of a.entries()) 37 if (!equal(i[1], b.get(i[0]))) return false; 38 return true; 39 } 40 41 if ((a instanceof Set) && (b instanceof Set)) { 42 if (a.size !== b.size) return false; 43 for (i of a.entries()) 44 if (!b.has(i[0])) return false; 45 return true; 46 } 47 48 if (ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) { 49 length = a.length; 50 if (length != b.length) return false; 51 for (i = length; i-- !== 0;) 52 if (a[i] !== b[i]) return false; 53 return true; 54 } 55 56 57 if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags; 58 if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf(); 59 if (a.toString !== Object.prototype.toString) return a.toString() === b.toString(); 60 61 keys = Object.keys(a); 62 length = keys.length; 63 if (length !== Object.keys(b).length) return false; 64 65 for (i = length; i-- !== 0;) 66 if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false; 67 68 for (i = length; i-- !== 0;) { 69 var key = keys[i]; 70 71 if (!equal(a[key], b[key])) return false; 72 } 73 74 return true; 75 } 76 77 // true if both NaN, false otherwise 78 return a!==a && b!==b; 79 }; 80 81 82 /***/ }), 83 84 /***/ 5373: 85 /***/ ((__unused_webpack_module, exports) => { 86 87 "use strict"; 88 var __webpack_unused_export__; 89 /** 90 * @license React 91 * react-is.production.min.js 92 * 93 * Copyright (c) Facebook, Inc. and its affiliates. 94 * 95 * This source code is licensed under the MIT license found in the 96 * LICENSE file in the root directory of this source tree. 97 */ 98 var b=Symbol.for("react.element"),c=Symbol.for("react.portal"),d=Symbol.for("react.fragment"),e=Symbol.for("react.strict_mode"),f=Symbol.for("react.profiler"),g=Symbol.for("react.provider"),h=Symbol.for("react.context"),k=Symbol.for("react.server_context"),l=Symbol.for("react.forward_ref"),m=Symbol.for("react.suspense"),n=Symbol.for("react.suspense_list"),p=Symbol.for("react.memo"),q=Symbol.for("react.lazy"),t=Symbol.for("react.offscreen"),u;u=Symbol.for("react.module.reference"); 99 function v(a){if("object"===typeof a&&null!==a){var r=a.$$typeof;switch(r){case b:switch(a=a.type,a){case d:case f:case e:case m:case n:return a;default:switch(a=a&&a.$$typeof,a){case k:case h:case l:case q:case p:case g:return a;default:return r}}case c:return r}}}__webpack_unused_export__=h;__webpack_unused_export__=g;__webpack_unused_export__=b;__webpack_unused_export__=l;__webpack_unused_export__=d;__webpack_unused_export__=q;__webpack_unused_export__=p;__webpack_unused_export__=c;__webpack_unused_export__=f;__webpack_unused_export__=e;__webpack_unused_export__=m; 100 __webpack_unused_export__=n;__webpack_unused_export__=function(){return!1};__webpack_unused_export__=function(){return!1};__webpack_unused_export__=function(a){return v(a)===h};__webpack_unused_export__=function(a){return v(a)===g};__webpack_unused_export__=function(a){return"object"===typeof a&&null!==a&&a.$$typeof===b};__webpack_unused_export__=function(a){return v(a)===l};__webpack_unused_export__=function(a){return v(a)===d};__webpack_unused_export__=function(a){return v(a)===q};__webpack_unused_export__=function(a){return v(a)===p}; 101 __webpack_unused_export__=function(a){return v(a)===c};__webpack_unused_export__=function(a){return v(a)===f};__webpack_unused_export__=function(a){return v(a)===e};__webpack_unused_export__=function(a){return v(a)===m};__webpack_unused_export__=function(a){return v(a)===n}; 102 exports.isValidElementType=function(a){return"string"===typeof a||"function"===typeof a||a===d||a===f||a===e||a===m||a===n||a===t||"object"===typeof a&&null!==a&&(a.$$typeof===q||a.$$typeof===p||a.$$typeof===g||a.$$typeof===h||a.$$typeof===l||a.$$typeof===u||void 0!==a.getModuleId)?!0:!1};__webpack_unused_export__=v; 103 104 105 /***/ }), 106 107 /***/ 8529: 108 /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 109 110 "use strict"; 111 112 113 if (true) { 114 module.exports = __webpack_require__(5373); 115 } else {} 116 117 118 /***/ }), 119 120 /***/ 9681: 121 /***/ ((module) => { 122 123 var characterMap = { 124 "À": "A", 125 "Á": "A", 126 "Â": "A", 127 "Ã": "A", 128 "Ä": "A", 129 "Å": "A", 130 "Ấ": "A", 131 "Ắ": "A", 132 "Ẳ": "A", 133 "Ẵ": "A", 134 "Ặ": "A", 135 "Æ": "AE", 136 "Ầ": "A", 137 "Ằ": "A", 138 "Ȃ": "A", 139 "Ả": "A", 140 "Ạ": "A", 141 "Ẩ": "A", 142 "Ẫ": "A", 143 "Ậ": "A", 144 "Ç": "C", 145 "Ḉ": "C", 146 "È": "E", 147 "É": "E", 148 "Ê": "E", 149 "Ë": "E", 150 "Ế": "E", 151 "Ḗ": "E", 152 "Ề": "E", 153 "Ḕ": "E", 154 "Ḝ": "E", 155 "Ȇ": "E", 156 "Ẻ": "E", 157 "Ẽ": "E", 158 "Ẹ": "E", 159 "Ể": "E", 160 "Ễ": "E", 161 "Ệ": "E", 162 "Ì": "I", 163 "Í": "I", 164 "Î": "I", 165 "Ï": "I", 166 "Ḯ": "I", 167 "Ȋ": "I", 168 "Ỉ": "I", 169 "Ị": "I", 170 "Ð": "D", 171 "Ñ": "N", 172 "Ò": "O", 173 "Ó": "O", 174 "Ô": "O", 175 "Õ": "O", 176 "Ö": "O", 177 "Ø": "O", 178 "Ố": "O", 179 "Ṍ": "O", 180 "Ṓ": "O", 181 "Ȏ": "O", 182 "Ỏ": "O", 183 "Ọ": "O", 184 "Ổ": "O", 185 "Ỗ": "O", 186 "Ộ": "O", 187 "Ờ": "O", 188 "Ở": "O", 189 "Ỡ": "O", 190 "Ớ": "O", 191 "Ợ": "O", 192 "Ù": "U", 193 "Ú": "U", 194 "Û": "U", 195 "Ü": "U", 196 "Ủ": "U", 197 "Ụ": "U", 198 "Ử": "U", 199 "Ữ": "U", 200 "Ự": "U", 201 "Ý": "Y", 202 "à": "a", 203 "á": "a", 204 "â": "a", 205 "ã": "a", 206 "ä": "a", 207 "å": "a", 208 "ấ": "a", 209 "ắ": "a", 210 "ẳ": "a", 211 "ẵ": "a", 212 "ặ": "a", 213 "æ": "ae", 214 "ầ": "a", 215 "ằ": "a", 216 "ȃ": "a", 217 "ả": "a", 218 "ạ": "a", 219 "ẩ": "a", 220 "ẫ": "a", 221 "ậ": "a", 222 "ç": "c", 223 "ḉ": "c", 224 "è": "e", 225 "é": "e", 226 "ê": "e", 227 "ë": "e", 228 "ế": "e", 229 "ḗ": "e", 230 "ề": "e", 231 "ḕ": "e", 232 "ḝ": "e", 233 "ȇ": "e", 234 "ẻ": "e", 235 "ẽ": "e", 236 "ẹ": "e", 237 "ể": "e", 238 "ễ": "e", 239 "ệ": "e", 240 "ì": "i", 241 "í": "i", 242 "î": "i", 243 "ï": "i", 244 "ḯ": "i", 245 "ȋ": "i", 246 "ỉ": "i", 247 "ị": "i", 248 "ð": "d", 249 "ñ": "n", 250 "ò": "o", 251 "ó": "o", 252 "ô": "o", 253 "õ": "o", 254 "ö": "o", 255 "ø": "o", 256 "ố": "o", 257 "ṍ": "o", 258 "ṓ": "o", 259 "ȏ": "o", 260 "ỏ": "o", 261 "ọ": "o", 262 "ổ": "o", 263 "ỗ": "o", 264 "ộ": "o", 265 "ờ": "o", 266 "ở": "o", 267 "ỡ": "o", 268 "ớ": "o", 269 "ợ": "o", 270 "ù": "u", 271 "ú": "u", 272 "û": "u", 273 "ü": "u", 274 "ủ": "u", 275 "ụ": "u", 276 "ử": "u", 277 "ữ": "u", 278 "ự": "u", 279 "ý": "y", 280 "ÿ": "y", 281 "Ā": "A", 282 "ā": "a", 283 "Ă": "A", 284 "ă": "a", 285 "Ą": "A", 286 "ą": "a", 287 "Ć": "C", 288 "ć": "c", 289 "Ĉ": "C", 290 "ĉ": "c", 291 "Ċ": "C", 292 "ċ": "c", 293 "Č": "C", 294 "č": "c", 295 "C̆": "C", 296 "c̆": "c", 297 "Ď": "D", 298 "ď": "d", 299 "Đ": "D", 300 "đ": "d", 301 "Ē": "E", 302 "ē": "e", 303 "Ĕ": "E", 304 "ĕ": "e", 305 "Ė": "E", 306 "ė": "e", 307 "Ę": "E", 308 "ę": "e", 309 "Ě": "E", 310 "ě": "e", 311 "Ĝ": "G", 312 "Ǵ": "G", 313 "ĝ": "g", 314 "ǵ": "g", 315 "Ğ": "G", 316 "ğ": "g", 317 "Ġ": "G", 318 "ġ": "g", 319 "Ģ": "G", 320 "ģ": "g", 321 "Ĥ": "H", 322 "ĥ": "h", 323 "Ħ": "H", 324 "ħ": "h", 325 "Ḫ": "H", 326 "ḫ": "h", 327 "Ĩ": "I", 328 "ĩ": "i", 329 "Ī": "I", 330 "ī": "i", 331 "Ĭ": "I", 332 "ĭ": "i", 333 "Į": "I", 334 "į": "i", 335 "İ": "I", 336 "ı": "i", 337 "IJ": "IJ", 338 "ij": "ij", 339 "Ĵ": "J", 340 "ĵ": "j", 341 "Ķ": "K", 342 "ķ": "k", 343 "Ḱ": "K", 344 "ḱ": "k", 345 "K̆": "K", 346 "k̆": "k", 347 "Ĺ": "L", 348 "ĺ": "l", 349 "Ļ": "L", 350 "ļ": "l", 351 "Ľ": "L", 352 "ľ": "l", 353 "Ŀ": "L", 354 "ŀ": "l", 355 "Ł": "l", 356 "ł": "l", 357 "Ḿ": "M", 358 "ḿ": "m", 359 "M̆": "M", 360 "m̆": "m", 361 "Ń": "N", 362 "ń": "n", 363 "Ņ": "N", 364 "ņ": "n", 365 "Ň": "N", 366 "ň": "n", 367 "ʼn": "n", 368 "N̆": "N", 369 "n̆": "n", 370 "Ō": "O", 371 "ō": "o", 372 "Ŏ": "O", 373 "ŏ": "o", 374 "Ő": "O", 375 "ő": "o", 376 "Œ": "OE", 377 "œ": "oe", 378 "P̆": "P", 379 "p̆": "p", 380 "Ŕ": "R", 381 "ŕ": "r", 382 "Ŗ": "R", 383 "ŗ": "r", 384 "Ř": "R", 385 "ř": "r", 386 "R̆": "R", 387 "r̆": "r", 388 "Ȓ": "R", 389 "ȓ": "r", 390 "Ś": "S", 391 "ś": "s", 392 "Ŝ": "S", 393 "ŝ": "s", 394 "Ş": "S", 395 "Ș": "S", 396 "ș": "s", 397 "ş": "s", 398 "Š": "S", 399 "š": "s", 400 "Ţ": "T", 401 "ţ": "t", 402 "ț": "t", 403 "Ț": "T", 404 "Ť": "T", 405 "ť": "t", 406 "Ŧ": "T", 407 "ŧ": "t", 408 "T̆": "T", 409 "t̆": "t", 410 "Ũ": "U", 411 "ũ": "u", 412 "Ū": "U", 413 "ū": "u", 414 "Ŭ": "U", 415 "ŭ": "u", 416 "Ů": "U", 417 "ů": "u", 418 "Ű": "U", 419 "ű": "u", 420 "Ų": "U", 421 "ų": "u", 422 "Ȗ": "U", 423 "ȗ": "u", 424 "V̆": "V", 425 "v̆": "v", 426 "Ŵ": "W", 427 "ŵ": "w", 428 "Ẃ": "W", 429 "ẃ": "w", 430 "X̆": "X", 431 "x̆": "x", 432 "Ŷ": "Y", 433 "ŷ": "y", 434 "Ÿ": "Y", 435 "Y̆": "Y", 436 "y̆": "y", 437 "Ź": "Z", 438 "ź": "z", 439 "Ż": "Z", 440 "ż": "z", 441 "Ž": "Z", 442 "ž": "z", 443 "ſ": "s", 444 "ƒ": "f", 445 "Ơ": "O", 446 "ơ": "o", 447 "Ư": "U", 448 "ư": "u", 449 "Ǎ": "A", 450 "ǎ": "a", 451 "Ǐ": "I", 452 "ǐ": "i", 453 "Ǒ": "O", 454 "ǒ": "o", 455 "Ǔ": "U", 456 "ǔ": "u", 457 "Ǖ": "U", 458 "ǖ": "u", 459 "Ǘ": "U", 460 "ǘ": "u", 461 "Ǚ": "U", 462 "ǚ": "u", 463 "Ǜ": "U", 464 "ǜ": "u", 465 "Ứ": "U", 466 "ứ": "u", 467 "Ṹ": "U", 468 "ṹ": "u", 469 "Ǻ": "A", 470 "ǻ": "a", 471 "Ǽ": "AE", 472 "ǽ": "ae", 473 "Ǿ": "O", 474 "ǿ": "o", 475 "Þ": "TH", 476 "þ": "th", 477 "Ṕ": "P", 478 "ṕ": "p", 479 "Ṥ": "S", 480 "ṥ": "s", 481 "X́": "X", 482 "x́": "x", 483 "Ѓ": "Г", 484 "ѓ": "г", 485 "Ќ": "К", 486 "ќ": "к", 487 "A̋": "A", 488 "a̋": "a", 489 "E̋": "E", 490 "e̋": "e", 491 "I̋": "I", 492 "i̋": "i", 493 "Ǹ": "N", 494 "ǹ": "n", 495 "Ồ": "O", 496 "ồ": "o", 497 "Ṑ": "O", 498 "ṑ": "o", 499 "Ừ": "U", 500 "ừ": "u", 501 "Ẁ": "W", 502 "ẁ": "w", 503 "Ỳ": "Y", 504 "ỳ": "y", 505 "Ȁ": "A", 506 "ȁ": "a", 507 "Ȅ": "E", 508 "ȅ": "e", 509 "Ȉ": "I", 510 "ȉ": "i", 511 "Ȍ": "O", 512 "ȍ": "o", 513 "Ȑ": "R", 514 "ȑ": "r", 515 "Ȕ": "U", 516 "ȕ": "u", 517 "B̌": "B", 518 "b̌": "b", 519 "Č̣": "C", 520 "č̣": "c", 521 "Ê̌": "E", 522 "ê̌": "e", 523 "F̌": "F", 524 "f̌": "f", 525 "Ǧ": "G", 526 "ǧ": "g", 527 "Ȟ": "H", 528 "ȟ": "h", 529 "J̌": "J", 530 "ǰ": "j", 531 "Ǩ": "K", 532 "ǩ": "k", 533 "M̌": "M", 534 "m̌": "m", 535 "P̌": "P", 536 "p̌": "p", 537 "Q̌": "Q", 538 "q̌": "q", 539 "Ř̩": "R", 540 "ř̩": "r", 541 "Ṧ": "S", 542 "ṧ": "s", 543 "V̌": "V", 544 "v̌": "v", 545 "W̌": "W", 546 "w̌": "w", 547 "X̌": "X", 548 "x̌": "x", 549 "Y̌": "Y", 550 "y̌": "y", 551 "A̧": "A", 552 "a̧": "a", 553 "B̧": "B", 554 "b̧": "b", 555 "Ḑ": "D", 556 "ḑ": "d", 557 "Ȩ": "E", 558 "ȩ": "e", 559 "Ɛ̧": "E", 560 "ɛ̧": "e", 561 "Ḩ": "H", 562 "ḩ": "h", 563 "I̧": "I", 564 "i̧": "i", 565 "Ɨ̧": "I", 566 "ɨ̧": "i", 567 "M̧": "M", 568 "m̧": "m", 569 "O̧": "O", 570 "o̧": "o", 571 "Q̧": "Q", 572 "q̧": "q", 573 "U̧": "U", 574 "u̧": "u", 575 "X̧": "X", 576 "x̧": "x", 577 "Z̧": "Z", 578 "z̧": "z", 579 "й":"и", 580 "Й":"И", 581 "ё":"е", 582 "Ё":"Е", 583 }; 584 585 var chars = Object.keys(characterMap).join('|'); 586 var allAccents = new RegExp(chars, 'g'); 587 var firstAccent = new RegExp(chars, ''); 588 589 function matcher(match) { 590 return characterMap[match]; 591 } 592 593 var removeAccents = function(string) { 594 return string.replace(allAccents, matcher); 595 }; 596 597 var hasAccents = function(string) { 598 return !!string.match(firstAccent); 599 }; 600 601 module.exports = removeAccents; 602 module.exports.has = hasAccents; 603 module.exports.remove = removeAccents; 604 605 606 /***/ }), 607 608 /***/ 1030: 609 /***/ (function(module, exports, __webpack_require__) { 610 611 var __WEBPACK_AMD_DEFINE_RESULT__;;/*! showdown v 1.9.1 - 02-11-2019 */ 612 (function(){ 613 /** 614 * Created by Tivie on 13-07-2015. 615 */ 616 617 function getDefaultOpts (simple) { 618 'use strict'; 619 620 var defaultOptions = { 621 omitExtraWLInCodeBlocks: { 622 defaultValue: false, 623 describe: 'Omit the default extra whiteline added to code blocks', 624 type: 'boolean' 625 }, 626 noHeaderId: { 627 defaultValue: false, 628 describe: 'Turn on/off generated header id', 629 type: 'boolean' 630 }, 631 prefixHeaderId: { 632 defaultValue: false, 633 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', 634 type: 'string' 635 }, 636 rawPrefixHeaderId: { 637 defaultValue: false, 638 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)', 639 type: 'boolean' 640 }, 641 ghCompatibleHeaderId: { 642 defaultValue: false, 643 describe: 'Generate header ids compatible with github style (spaces are replaced with dashes, a bunch of non alphanumeric chars are removed)', 644 type: 'boolean' 645 }, 646 rawHeaderId: { 647 defaultValue: false, 648 describe: 'Remove only spaces, \' and " from generated header ids (including prefixes), replacing them with dashes (-). WARNING: This might result in malformed ids', 649 type: 'boolean' 650 }, 651 headerLevelStart: { 652 defaultValue: false, 653 describe: 'The header blocks level start', 654 type: 'integer' 655 }, 656 parseImgDimensions: { 657 defaultValue: false, 658 describe: 'Turn on/off image dimension parsing', 659 type: 'boolean' 660 }, 661 simplifiedAutoLink: { 662 defaultValue: false, 663 describe: 'Turn on/off GFM autolink style', 664 type: 'boolean' 665 }, 666 excludeTrailingPunctuationFromURLs: { 667 defaultValue: false, 668 describe: 'Excludes trailing punctuation from links generated with autoLinking', 669 type: 'boolean' 670 }, 671 literalMidWordUnderscores: { 672 defaultValue: false, 673 describe: 'Parse midword underscores as literal underscores', 674 type: 'boolean' 675 }, 676 literalMidWordAsterisks: { 677 defaultValue: false, 678 describe: 'Parse midword asterisks as literal asterisks', 679 type: 'boolean' 680 }, 681 strikethrough: { 682 defaultValue: false, 683 describe: 'Turn on/off strikethrough support', 684 type: 'boolean' 685 }, 686 tables: { 687 defaultValue: false, 688 describe: 'Turn on/off tables support', 689 type: 'boolean' 690 }, 691 tablesHeaderId: { 692 defaultValue: false, 693 describe: 'Add an id to table headers', 694 type: 'boolean' 695 }, 696 ghCodeBlocks: { 697 defaultValue: true, 698 describe: 'Turn on/off GFM fenced code blocks support', 699 type: 'boolean' 700 }, 701 tasklists: { 702 defaultValue: false, 703 describe: 'Turn on/off GFM tasklist support', 704 type: 'boolean' 705 }, 706 smoothLivePreview: { 707 defaultValue: false, 708 describe: 'Prevents weird effects in live previews due to incomplete input', 709 type: 'boolean' 710 }, 711 smartIndentationFix: { 712 defaultValue: false, 713 description: 'Tries to smartly fix indentation in es6 strings', 714 type: 'boolean' 715 }, 716 disableForced4SpacesIndentedSublists: { 717 defaultValue: false, 718 description: 'Disables the requirement of indenting nested sublists by 4 spaces', 719 type: 'boolean' 720 }, 721 simpleLineBreaks: { 722 defaultValue: false, 723 description: 'Parses simple line breaks as <br> (GFM Style)', 724 type: 'boolean' 725 }, 726 requireSpaceBeforeHeadingText: { 727 defaultValue: false, 728 description: 'Makes adding a space between `#` and the header text mandatory (GFM Style)', 729 type: 'boolean' 730 }, 731 ghMentions: { 732 defaultValue: false, 733 description: 'Enables github @mentions', 734 type: 'boolean' 735 }, 736 ghMentionsLink: { 737 defaultValue: 'https://github.com/{u}', 738 description: 'Changes the link generated by @mentions. Only applies if ghMentions option is enabled.', 739 type: 'string' 740 }, 741 encodeEmails: { 742 defaultValue: true, 743 description: 'Encode e-mail addresses through the use of Character Entities, transforming ASCII e-mail addresses into its equivalent decimal entities', 744 type: 'boolean' 745 }, 746 openLinksInNewWindow: { 747 defaultValue: false, 748 description: 'Open all links in new windows', 749 type: 'boolean' 750 }, 751 backslashEscapesHTMLTags: { 752 defaultValue: false, 753 description: 'Support for HTML Tag escaping. ex: \<div>foo\</div>', 754 type: 'boolean' 755 }, 756 emoji: { 757 defaultValue: false, 758 description: 'Enable emoji support. Ex: `this is a :smile: emoji`', 759 type: 'boolean' 760 }, 761 underline: { 762 defaultValue: false, 763 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>`', 764 type: 'boolean' 765 }, 766 completeHTMLDocument: { 767 defaultValue: false, 768 description: 'Outputs a complete html document, including `<html>`, `<head>` and `<body>` tags', 769 type: 'boolean' 770 }, 771 metadata: { 772 defaultValue: false, 773 description: 'Enable support for document metadata (defined at the top of the document between `«««` and `»»»` or between `---` and `---`).', 774 type: 'boolean' 775 }, 776 splitAdjacentBlockquotes: { 777 defaultValue: false, 778 description: 'Split adjacent blockquote blocks', 779 type: 'boolean' 780 } 781 }; 782 if (simple === false) { 783 return JSON.parse(JSON.stringify(defaultOptions)); 784 } 785 var ret = {}; 786 for (var opt in defaultOptions) { 787 if (defaultOptions.hasOwnProperty(opt)) { 788 ret[opt] = defaultOptions[opt].defaultValue; 789 } 790 } 791 return ret; 792 } 793 794 function allOptionsOn () { 795 'use strict'; 796 var options = getDefaultOpts(true), 797 ret = {}; 798 for (var opt in options) { 799 if (options.hasOwnProperty(opt)) { 800 ret[opt] = true; 801 } 802 } 803 return ret; 804 } 805 806 /** 807 * Created by Tivie on 06-01-2015. 808 */ 809 810 // Private properties 811 var showdown = {}, 812 parsers = {}, 813 extensions = {}, 814 globalOptions = getDefaultOpts(true), 815 setFlavor = 'vanilla', 816 flavor = { 817 github: { 818 omitExtraWLInCodeBlocks: true, 819 simplifiedAutoLink: true, 820 excludeTrailingPunctuationFromURLs: true, 821 literalMidWordUnderscores: true, 822 strikethrough: true, 823 tables: true, 824 tablesHeaderId: true, 825 ghCodeBlocks: true, 826 tasklists: true, 827 disableForced4SpacesIndentedSublists: true, 828 simpleLineBreaks: true, 829 requireSpaceBeforeHeadingText: true, 830 ghCompatibleHeaderId: true, 831 ghMentions: true, 832 backslashEscapesHTMLTags: true, 833 emoji: true, 834 splitAdjacentBlockquotes: true 835 }, 836 original: { 837 noHeaderId: true, 838 ghCodeBlocks: false 839 }, 840 ghost: { 841 omitExtraWLInCodeBlocks: true, 842 parseImgDimensions: true, 843 simplifiedAutoLink: true, 844 excludeTrailingPunctuationFromURLs: true, 845 literalMidWordUnderscores: true, 846 strikethrough: true, 847 tables: true, 848 tablesHeaderId: true, 849 ghCodeBlocks: true, 850 tasklists: true, 851 smoothLivePreview: true, 852 simpleLineBreaks: true, 853 requireSpaceBeforeHeadingText: true, 854 ghMentions: false, 855 encodeEmails: true 856 }, 857 vanilla: getDefaultOpts(true), 858 allOn: allOptionsOn() 859 }; 860 861 /** 862 * helper namespace 863 * @type {{}} 864 */ 865 showdown.helper = {}; 866 867 /** 868 * TODO LEGACY SUPPORT CODE 869 * @type {{}} 870 */ 871 showdown.extensions = {}; 872 873 /** 874 * Set a global option 875 * @static 876 * @param {string} key 877 * @param {*} value 878 * @returns {showdown} 879 */ 880 showdown.setOption = function (key, value) { 881 'use strict'; 882 globalOptions[key] = value; 883 return this; 884 }; 885 886 /** 887 * Get a global option 888 * @static 889 * @param {string} key 890 * @returns {*} 891 */ 892 showdown.getOption = function (key) { 893 'use strict'; 894 return globalOptions[key]; 895 }; 896 897 /** 898 * Get the global options 899 * @static 900 * @returns {{}} 901 */ 902 showdown.getOptions = function () { 903 'use strict'; 904 return globalOptions; 905 }; 906 907 /** 908 * Reset global options to the default values 909 * @static 910 */ 911 showdown.resetOptions = function () { 912 'use strict'; 913 globalOptions = getDefaultOpts(true); 914 }; 915 916 /** 917 * Set the flavor showdown should use as default 918 * @param {string} name 919 */ 920 showdown.setFlavor = function (name) { 921 'use strict'; 922 if (!flavor.hasOwnProperty(name)) { 923 throw Error(name + ' flavor was not found'); 924 } 925 showdown.resetOptions(); 926 var preset = flavor[name]; 927 setFlavor = name; 928 for (var option in preset) { 929 if (preset.hasOwnProperty(option)) { 930 globalOptions[option] = preset[option]; 931 } 932 } 933 }; 934 935 /** 936 * Get the currently set flavor 937 * @returns {string} 938 */ 939 showdown.getFlavor = function () { 940 'use strict'; 941 return setFlavor; 942 }; 943 944 /** 945 * Get the options of a specified flavor. Returns undefined if the flavor was not found 946 * @param {string} name Name of the flavor 947 * @returns {{}|undefined} 948 */ 949 showdown.getFlavorOptions = function (name) { 950 'use strict'; 951 if (flavor.hasOwnProperty(name)) { 952 return flavor[name]; 953 } 954 }; 955 956 /** 957 * Get the default options 958 * @static 959 * @param {boolean} [simple=true] 960 * @returns {{}} 961 */ 962 showdown.getDefaultOptions = function (simple) { 963 'use strict'; 964 return getDefaultOpts(simple); 965 }; 966 967 /** 968 * Get or set a subParser 969 * 970 * subParser(name) - Get a registered subParser 971 * subParser(name, func) - Register a subParser 972 * @static 973 * @param {string} name 974 * @param {function} [func] 975 * @returns {*} 976 */ 977 showdown.subParser = function (name, func) { 978 'use strict'; 979 if (showdown.helper.isString(name)) { 980 if (typeof func !== 'undefined') { 981 parsers[name] = func; 982 } else { 983 if (parsers.hasOwnProperty(name)) { 984 return parsers[name]; 985 } else { 986 throw Error('SubParser named ' + name + ' not registered!'); 987 } 988 } 989 } 990 }; 991 992 /** 993 * Gets or registers an extension 994 * @static 995 * @param {string} name 996 * @param {object|function=} ext 997 * @returns {*} 998 */ 999 showdown.extension = function (name, ext) { 1000 'use strict'; 1001 1002 if (!showdown.helper.isString(name)) { 1003 throw Error('Extension \'name\' must be a string'); 1004 } 1005 1006 name = showdown.helper.stdExtName(name); 1007 1008 // Getter 1009 if (showdown.helper.isUndefined(ext)) { 1010 if (!extensions.hasOwnProperty(name)) { 1011 throw Error('Extension named ' + name + ' is not registered!'); 1012 } 1013 return extensions[name]; 1014 1015 // Setter 1016 } else { 1017 // Expand extension if it's wrapped in a function 1018 if (typeof ext === 'function') { 1019 ext = ext(); 1020 } 1021 1022 // Ensure extension is an array 1023 if (!showdown.helper.isArray(ext)) { 1024 ext = [ext]; 1025 } 1026 1027 var validExtension = validate(ext, name); 1028 1029 if (validExtension.valid) { 1030 extensions[name] = ext; 1031 } else { 1032 throw Error(validExtension.error); 1033 } 1034 } 1035 }; 1036 1037 /** 1038 * Gets all extensions registered 1039 * @returns {{}} 1040 */ 1041 showdown.getAllExtensions = function () { 1042 'use strict'; 1043 return extensions; 1044 }; 1045 1046 /** 1047 * Remove an extension 1048 * @param {string} name 1049 */ 1050 showdown.removeExtension = function (name) { 1051 'use strict'; 1052 delete extensions[name]; 1053 }; 1054 1055 /** 1056 * Removes all extensions 1057 */ 1058 showdown.resetExtensions = function () { 1059 'use strict'; 1060 extensions = {}; 1061 }; 1062 1063 /** 1064 * Validate extension 1065 * @param {array} extension 1066 * @param {string} name 1067 * @returns {{valid: boolean, error: string}} 1068 */ 1069 function validate (extension, name) { 1070 'use strict'; 1071 1072 var errMsg = (name) ? 'Error in ' + name + ' extension->' : 'Error in unnamed extension', 1073 ret = { 1074 valid: true, 1075 error: '' 1076 }; 1077 1078 if (!showdown.helper.isArray(extension)) { 1079 extension = [extension]; 1080 } 1081 1082 for (var i = 0; i < extension.length; ++i) { 1083 var baseMsg = errMsg + ' sub-extension ' + i + ': ', 1084 ext = extension[i]; 1085 if (typeof ext !== 'object') { 1086 ret.valid = false; 1087 ret.error = baseMsg + 'must be an object, but ' + typeof ext + ' given'; 1088 return ret; 1089 } 1090 1091 if (!showdown.helper.isString(ext.type)) { 1092 ret.valid = false; 1093 ret.error = baseMsg + 'property "type" must be a string, but ' + typeof ext.type + ' given'; 1094 return ret; 1095 } 1096 1097 var type = ext.type = ext.type.toLowerCase(); 1098 1099 // normalize extension type 1100 if (type === 'language') { 1101 type = ext.type = 'lang'; 1102 } 1103 1104 if (type === 'html') { 1105 type = ext.type = 'output'; 1106 } 1107 1108 if (type !== 'lang' && type !== 'output' && type !== 'listener') { 1109 ret.valid = false; 1110 ret.error = baseMsg + 'type ' + type + ' is not recognized. Valid values: "lang/language", "output/html" or "listener"'; 1111 return ret; 1112 } 1113 1114 if (type === 'listener') { 1115 if (showdown.helper.isUndefined(ext.listeners)) { 1116 ret.valid = false; 1117 ret.error = baseMsg + '. Extensions of type "listener" must have a property called "listeners"'; 1118 return ret; 1119 } 1120 } else { 1121 if (showdown.helper.isUndefined(ext.filter) && showdown.helper.isUndefined(ext.regex)) { 1122 ret.valid = false; 1123 ret.error = baseMsg + type + ' extensions must define either a "regex" property or a "filter" method'; 1124 return ret; 1125 } 1126 } 1127 1128 if (ext.listeners) { 1129 if (typeof ext.listeners !== 'object') { 1130 ret.valid = false; 1131 ret.error = baseMsg + '"listeners" property must be an object but ' + typeof ext.listeners + ' given'; 1132 return ret; 1133 } 1134 for (var ln in ext.listeners) { 1135 if (ext.listeners.hasOwnProperty(ln)) { 1136 if (typeof ext.listeners[ln] !== 'function') { 1137 ret.valid = false; 1138 ret.error = baseMsg + '"listeners" property must be an hash of [event name]: [callback]. listeners.' + ln + 1139 ' must be a function but ' + typeof ext.listeners[ln] + ' given'; 1140 return ret; 1141 } 1142 } 1143 } 1144 } 1145 1146 if (ext.filter) { 1147 if (typeof ext.filter !== 'function') { 1148 ret.valid = false; 1149 ret.error = baseMsg + '"filter" must be a function, but ' + typeof ext.filter + ' given'; 1150 return ret; 1151 } 1152 } else if (ext.regex) { 1153 if (showdown.helper.isString(ext.regex)) { 1154 ext.regex = new RegExp(ext.regex, 'g'); 1155 } 1156 if (!(ext.regex instanceof RegExp)) { 1157 ret.valid = false; 1158 ret.error = baseMsg + '"regex" property must either be a string or a RegExp object, but ' + typeof ext.regex + ' given'; 1159 return ret; 1160 } 1161 if (showdown.helper.isUndefined(ext.replace)) { 1162 ret.valid = false; 1163 ret.error = baseMsg + '"regex" extensions must implement a replace string or function'; 1164 return ret; 1165 } 1166 } 1167 } 1168 return ret; 1169 } 1170 1171 /** 1172 * Validate extension 1173 * @param {object} ext 1174 * @returns {boolean} 1175 */ 1176 showdown.validateExtension = function (ext) { 1177 'use strict'; 1178 1179 var validateExtension = validate(ext, null); 1180 if (!validateExtension.valid) { 1181 console.warn(validateExtension.error); 1182 return false; 1183 } 1184 return true; 1185 }; 1186 1187 /** 1188 * showdownjs helper functions 1189 */ 1190 1191 if (!showdown.hasOwnProperty('helper')) { 1192 showdown.helper = {}; 1193 } 1194 1195 /** 1196 * Check if var is string 1197 * @static 1198 * @param {string} a 1199 * @returns {boolean} 1200 */ 1201 showdown.helper.isString = function (a) { 1202 'use strict'; 1203 return (typeof a === 'string' || a instanceof String); 1204 }; 1205 1206 /** 1207 * Check if var is a function 1208 * @static 1209 * @param {*} a 1210 * @returns {boolean} 1211 */ 1212 showdown.helper.isFunction = function (a) { 1213 'use strict'; 1214 var getType = {}; 1215 return a && getType.toString.call(a) === '[object Function]'; 1216 }; 1217 1218 /** 1219 * isArray helper function 1220 * @static 1221 * @param {*} a 1222 * @returns {boolean} 1223 */ 1224 showdown.helper.isArray = function (a) { 1225 'use strict'; 1226 return Array.isArray(a); 1227 }; 1228 1229 /** 1230 * Check if value is undefined 1231 * @static 1232 * @param {*} value The value to check. 1233 * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. 1234 */ 1235 showdown.helper.isUndefined = function (value) { 1236 'use strict'; 1237 return typeof value === 'undefined'; 1238 }; 1239 1240 /** 1241 * ForEach helper function 1242 * Iterates over Arrays and Objects (own properties only) 1243 * @static 1244 * @param {*} obj 1245 * @param {function} callback Accepts 3 params: 1. value, 2. key, 3. the original array/object 1246 */ 1247 showdown.helper.forEach = function (obj, callback) { 1248 'use strict'; 1249 // check if obj is defined 1250 if (showdown.helper.isUndefined(obj)) { 1251 throw new Error('obj param is required'); 1252 } 1253 1254 if (showdown.helper.isUndefined(callback)) { 1255 throw new Error('callback param is required'); 1256 } 1257 1258 if (!showdown.helper.isFunction(callback)) { 1259 throw new Error('callback param must be a function/closure'); 1260 } 1261 1262 if (typeof obj.forEach === 'function') { 1263 obj.forEach(callback); 1264 } else if (showdown.helper.isArray(obj)) { 1265 for (var i = 0; i < obj.length; i++) { 1266 callback(obj[i], i, obj); 1267 } 1268 } else if (typeof (obj) === 'object') { 1269 for (var prop in obj) { 1270 if (obj.hasOwnProperty(prop)) { 1271 callback(obj[prop], prop, obj); 1272 } 1273 } 1274 } else { 1275 throw new Error('obj does not seem to be an array or an iterable object'); 1276 } 1277 }; 1278 1279 /** 1280 * Standardidize extension name 1281 * @static 1282 * @param {string} s extension name 1283 * @returns {string} 1284 */ 1285 showdown.helper.stdExtName = function (s) { 1286 'use strict'; 1287 return s.replace(/[_?*+\/\\.^-]/g, '').replace(/\s/g, '').toLowerCase(); 1288 }; 1289 1290 function escapeCharactersCallback (wholeMatch, m1) { 1291 'use strict'; 1292 var charCodeToEscape = m1.charCodeAt(0); 1293 return '¨E' + charCodeToEscape + 'E'; 1294 } 1295 1296 /** 1297 * Callback used to escape characters when passing through String.replace 1298 * @static 1299 * @param {string} wholeMatch 1300 * @param {string} m1 1301 * @returns {string} 1302 */ 1303 showdown.helper.escapeCharactersCallback = escapeCharactersCallback; 1304 1305 /** 1306 * Escape characters in a string 1307 * @static 1308 * @param {string} text 1309 * @param {string} charsToEscape 1310 * @param {boolean} afterBackslash 1311 * @returns {XML|string|void|*} 1312 */ 1313 showdown.helper.escapeCharacters = function (text, charsToEscape, afterBackslash) { 1314 'use strict'; 1315 // First we have to escape the escape characters so that 1316 // we can build a character class out of them 1317 var regexString = '([' + charsToEscape.replace(/([\[\]\\])/g, '\\$1') + '])'; 1318 1319 if (afterBackslash) { 1320 regexString = '\\\\' + regexString; 1321 } 1322 1323 var regex = new RegExp(regexString, 'g'); 1324 text = text.replace(regex, escapeCharactersCallback); 1325 1326 return text; 1327 }; 1328 1329 /** 1330 * Unescape HTML entities 1331 * @param txt 1332 * @returns {string} 1333 */ 1334 showdown.helper.unescapeHTMLEntities = function (txt) { 1335 'use strict'; 1336 1337 return txt 1338 .replace(/"/g, '"') 1339 .replace(/</g, '<') 1340 .replace(/>/g, '>') 1341 .replace(/&/g, '&'); 1342 }; 1343 1344 var rgxFindMatchPos = function (str, left, right, flags) { 1345 'use strict'; 1346 var f = flags || '', 1347 g = f.indexOf('g') > -1, 1348 x = new RegExp(left + '|' + right, 'g' + f.replace(/g/g, '')), 1349 l = new RegExp(left, f.replace(/g/g, '')), 1350 pos = [], 1351 t, s, m, start, end; 1352 1353 do { 1354 t = 0; 1355 while ((m = x.exec(str))) { 1356 if (l.test(m[0])) { 1357 if (!(t++)) { 1358 s = x.lastIndex; 1359 start = s - m[0].length; 1360 } 1361 } else if (t) { 1362 if (!--t) { 1363 end = m.index + m[0].length; 1364 var obj = { 1365 left: {start: start, end: s}, 1366 match: {start: s, end: m.index}, 1367 right: {start: m.index, end: end}, 1368 wholeMatch: {start: start, end: end} 1369 }; 1370 pos.push(obj); 1371 if (!g) { 1372 return pos; 1373 } 1374 } 1375 } 1376 } 1377 } while (t && (x.lastIndex = s)); 1378 1379 return pos; 1380 }; 1381 1382 /** 1383 * matchRecursiveRegExp 1384 * 1385 * (c) 2007 Steven Levithan <stevenlevithan.com> 1386 * MIT License 1387 * 1388 * Accepts a string to search, a left and right format delimiter 1389 * as regex patterns, and optional regex flags. Returns an array 1390 * of matches, allowing nested instances of left/right delimiters. 1391 * Use the "g" flag to return all matches, otherwise only the 1392 * first is returned. Be careful to ensure that the left and 1393 * right format delimiters produce mutually exclusive matches. 1394 * Backreferences are not supported within the right delimiter 1395 * due to how it is internally combined with the left delimiter. 1396 * When matching strings whose format delimiters are unbalanced 1397 * to the left or right, the output is intentionally as a 1398 * conventional regex library with recursion support would 1399 * produce, e.g. "<<x>" and "<x>>" both produce ["x"] when using 1400 * "<" and ">" as the delimiters (both strings contain a single, 1401 * balanced instance of "<x>"). 1402 * 1403 * examples: 1404 * matchRecursiveRegExp("test", "\\(", "\\)") 1405 * returns: [] 1406 * matchRecursiveRegExp("<t<<e>><s>>t<>", "<", ">", "g") 1407 * returns: ["t<<e>><s>", ""] 1408 * matchRecursiveRegExp("<div id=\"x\">test</div>", "<div\\b[^>]*>", "</div>", "gi") 1409 * returns: ["test"] 1410 */ 1411 showdown.helper.matchRecursiveRegExp = function (str, left, right, flags) { 1412 'use strict'; 1413 1414 var matchPos = rgxFindMatchPos (str, left, right, flags), 1415 results = []; 1416 1417 for (var i = 0; i < matchPos.length; ++i) { 1418 results.push([ 1419 str.slice(matchPos[i].wholeMatch.start, matchPos[i].wholeMatch.end), 1420 str.slice(matchPos[i].match.start, matchPos[i].match.end), 1421 str.slice(matchPos[i].left.start, matchPos[i].left.end), 1422 str.slice(matchPos[i].right.start, matchPos[i].right.end) 1423 ]); 1424 } 1425 return results; 1426 }; 1427 1428 /** 1429 * 1430 * @param {string} str 1431 * @param {string|function} replacement 1432 * @param {string} left 1433 * @param {string} right 1434 * @param {string} flags 1435 * @returns {string} 1436 */ 1437 showdown.helper.replaceRecursiveRegExp = function (str, replacement, left, right, flags) { 1438 'use strict'; 1439 1440 if (!showdown.helper.isFunction(replacement)) { 1441 var repStr = replacement; 1442 replacement = function () { 1443 return repStr; 1444 }; 1445 } 1446 1447 var matchPos = rgxFindMatchPos(str, left, right, flags), 1448 finalStr = str, 1449 lng = matchPos.length; 1450 1451 if (lng > 0) { 1452 var bits = []; 1453 if (matchPos[0].wholeMatch.start !== 0) { 1454 bits.push(str.slice(0, matchPos[0].wholeMatch.start)); 1455 } 1456 for (var i = 0; i < lng; ++i) { 1457 bits.push( 1458 replacement( 1459 str.slice(matchPos[i].wholeMatch.start, matchPos[i].wholeMatch.end), 1460 str.slice(matchPos[i].match.start, matchPos[i].match.end), 1461 str.slice(matchPos[i].left.start, matchPos[i].left.end), 1462 str.slice(matchPos[i].right.start, matchPos[i].right.end) 1463 ) 1464 ); 1465 if (i < lng - 1) { 1466 bits.push(str.slice(matchPos[i].wholeMatch.end, matchPos[i + 1].wholeMatch.start)); 1467 } 1468 } 1469 if (matchPos[lng - 1].wholeMatch.end < str.length) { 1470 bits.push(str.slice(matchPos[lng - 1].wholeMatch.end)); 1471 } 1472 finalStr = bits.join(''); 1473 } 1474 return finalStr; 1475 }; 1476 1477 /** 1478 * Returns the index within the passed String object of the first occurrence of the specified regex, 1479 * starting the search at fromIndex. Returns -1 if the value is not found. 1480 * 1481 * @param {string} str string to search 1482 * @param {RegExp} regex Regular expression to search 1483 * @param {int} [fromIndex = 0] Index to start the search 1484 * @returns {Number} 1485 * @throws InvalidArgumentError 1486 */ 1487 showdown.helper.regexIndexOf = function (str, regex, fromIndex) { 1488 'use strict'; 1489 if (!showdown.helper.isString(str)) { 1490 throw 'InvalidArgumentError: first parameter of showdown.helper.regexIndexOf function must be a string'; 1491 } 1492 if (regex instanceof RegExp === false) { 1493 throw 'InvalidArgumentError: second parameter of showdown.helper.regexIndexOf function must be an instance of RegExp'; 1494 } 1495 var indexOf = str.substring(fromIndex || 0).search(regex); 1496 return (indexOf >= 0) ? (indexOf + (fromIndex || 0)) : indexOf; 1497 }; 1498 1499 /** 1500 * Splits the passed string object at the defined index, and returns an array composed of the two substrings 1501 * @param {string} str string to split 1502 * @param {int} index index to split string at 1503 * @returns {[string,string]} 1504 * @throws InvalidArgumentError 1505 */ 1506 showdown.helper.splitAtIndex = function (str, index) { 1507 'use strict'; 1508 if (!showdown.helper.isString(str)) { 1509 throw 'InvalidArgumentError: first parameter of showdown.helper.regexIndexOf function must be a string'; 1510 } 1511 return [str.substring(0, index), str.substring(index)]; 1512 }; 1513 1514 /** 1515 * Obfuscate an e-mail address through the use of Character Entities, 1516 * transforming ASCII characters into their equivalent decimal or hex entities. 1517 * 1518 * Since it has a random component, subsequent calls to this function produce different results 1519 * 1520 * @param {string} mail 1521 * @returns {string} 1522 */ 1523 showdown.helper.encodeEmailAddress = function (mail) { 1524 'use strict'; 1525 var encode = [ 1526 function (ch) { 1527 return '&#' + ch.charCodeAt(0) + ';'; 1528 }, 1529 function (ch) { 1530 return '&#x' + ch.charCodeAt(0).toString(16) + ';'; 1531 }, 1532 function (ch) { 1533 return ch; 1534 } 1535 ]; 1536 1537 mail = mail.replace(/./g, function (ch) { 1538 if (ch === '@') { 1539 // this *must* be encoded. I insist. 1540 ch = encode[Math.floor(Math.random() * 2)](ch); 1541 } else { 1542 var r = Math.random(); 1543 // roughly 10% raw, 45% hex, 45% dec 1544 ch = ( 1545 r > 0.9 ? encode[2](ch) : r > 0.45 ? encode[1](ch) : encode[0](ch) 1546 ); 1547 } 1548 return ch; 1549 }); 1550 1551 return mail; 1552 }; 1553 1554 /** 1555 * 1556 * @param str 1557 * @param targetLength 1558 * @param padString 1559 * @returns {string} 1560 */ 1561 showdown.helper.padEnd = function padEnd (str, targetLength, padString) { 1562 'use strict'; 1563 /*jshint bitwise: false*/ 1564 // eslint-disable-next-line space-infix-ops 1565 targetLength = targetLength>>0; //floor if number or convert non-number to 0; 1566 /*jshint bitwise: true*/ 1567 padString = String(padString || ' '); 1568 if (str.length > targetLength) { 1569 return String(str); 1570 } else { 1571 targetLength = targetLength - str.length; 1572 if (targetLength > padString.length) { 1573 padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed 1574 } 1575 return String(str) + padString.slice(0,targetLength); 1576 } 1577 }; 1578 1579 /** 1580 * POLYFILLS 1581 */ 1582 // use this instead of builtin is undefined for IE8 compatibility 1583 if (typeof console === 'undefined') { 1584 console = { 1585 warn: function (msg) { 1586 'use strict'; 1587 alert(msg); 1588 }, 1589 log: function (msg) { 1590 'use strict'; 1591 alert(msg); 1592 }, 1593 error: function (msg) { 1594 'use strict'; 1595 throw msg; 1596 } 1597 }; 1598 } 1599 1600 /** 1601 * Common regexes. 1602 * We declare some common regexes to improve performance 1603 */ 1604 showdown.helper.regexes = { 1605 asteriskDashAndColon: /([*_:~])/g 1606 }; 1607 1608 /** 1609 * EMOJIS LIST 1610 */ 1611 showdown.helper.emojis = { 1612 '+1':'\ud83d\udc4d', 1613 '-1':'\ud83d\udc4e', 1614 '100':'\ud83d\udcaf', 1615 '1234':'\ud83d\udd22', 1616 '1st_place_medal':'\ud83e\udd47', 1617 '2nd_place_medal':'\ud83e\udd48', 1618 '3rd_place_medal':'\ud83e\udd49', 1619 '8ball':'\ud83c\udfb1', 1620 'a':'\ud83c\udd70\ufe0f', 1621 'ab':'\ud83c\udd8e', 1622 'abc':'\ud83d\udd24', 1623 'abcd':'\ud83d\udd21', 1624 'accept':'\ud83c\ude51', 1625 'aerial_tramway':'\ud83d\udea1', 1626 'airplane':'\u2708\ufe0f', 1627 'alarm_clock':'\u23f0', 1628 'alembic':'\u2697\ufe0f', 1629 'alien':'\ud83d\udc7d', 1630 'ambulance':'\ud83d\ude91', 1631 'amphora':'\ud83c\udffa', 1632 'anchor':'\u2693\ufe0f', 1633 'angel':'\ud83d\udc7c', 1634 'anger':'\ud83d\udca2', 1635 'angry':'\ud83d\ude20', 1636 'anguished':'\ud83d\ude27', 1637 'ant':'\ud83d\udc1c', 1638 'apple':'\ud83c\udf4e', 1639 'aquarius':'\u2652\ufe0f', 1640 'aries':'\u2648\ufe0f', 1641 'arrow_backward':'\u25c0\ufe0f', 1642 'arrow_double_down':'\u23ec', 1643 'arrow_double_up':'\u23eb', 1644 'arrow_down':'\u2b07\ufe0f', 1645 'arrow_down_small':'\ud83d\udd3d', 1646 'arrow_forward':'\u25b6\ufe0f', 1647 'arrow_heading_down':'\u2935\ufe0f', 1648 'arrow_heading_up':'\u2934\ufe0f', 1649 'arrow_left':'\u2b05\ufe0f', 1650 'arrow_lower_left':'\u2199\ufe0f', 1651 'arrow_lower_right':'\u2198\ufe0f', 1652 'arrow_right':'\u27a1\ufe0f', 1653 'arrow_right_hook':'\u21aa\ufe0f', 1654 'arrow_up':'\u2b06\ufe0f', 1655 'arrow_up_down':'\u2195\ufe0f', 1656 'arrow_up_small':'\ud83d\udd3c', 1657 'arrow_upper_left':'\u2196\ufe0f', 1658 'arrow_upper_right':'\u2197\ufe0f', 1659 'arrows_clockwise':'\ud83d\udd03', 1660 'arrows_counterclockwise':'\ud83d\udd04', 1661 'art':'\ud83c\udfa8', 1662 'articulated_lorry':'\ud83d\ude9b', 1663 'artificial_satellite':'\ud83d\udef0', 1664 'astonished':'\ud83d\ude32', 1665 'athletic_shoe':'\ud83d\udc5f', 1666 'atm':'\ud83c\udfe7', 1667 'atom_symbol':'\u269b\ufe0f', 1668 'avocado':'\ud83e\udd51', 1669 'b':'\ud83c\udd71\ufe0f', 1670 'baby':'\ud83d\udc76', 1671 'baby_bottle':'\ud83c\udf7c', 1672 'baby_chick':'\ud83d\udc24', 1673 'baby_symbol':'\ud83d\udebc', 1674 'back':'\ud83d\udd19', 1675 'bacon':'\ud83e\udd53', 1676 'badminton':'\ud83c\udff8', 1677 'baggage_claim':'\ud83d\udec4', 1678 'baguette_bread':'\ud83e\udd56', 1679 'balance_scale':'\u2696\ufe0f', 1680 'balloon':'\ud83c\udf88', 1681 'ballot_box':'\ud83d\uddf3', 1682 'ballot_box_with_check':'\u2611\ufe0f', 1683 'bamboo':'\ud83c\udf8d', 1684 'banana':'\ud83c\udf4c', 1685 'bangbang':'\u203c\ufe0f', 1686 'bank':'\ud83c\udfe6', 1687 'bar_chart':'\ud83d\udcca', 1688 'barber':'\ud83d\udc88', 1689 'baseball':'\u26be\ufe0f', 1690 'basketball':'\ud83c\udfc0', 1691 'basketball_man':'\u26f9\ufe0f', 1692 'basketball_woman':'\u26f9\ufe0f‍\u2640\ufe0f', 1693 'bat':'\ud83e\udd87', 1694 'bath':'\ud83d\udec0', 1695 'bathtub':'\ud83d\udec1', 1696 'battery':'\ud83d\udd0b', 1697 'beach_umbrella':'\ud83c\udfd6', 1698 'bear':'\ud83d\udc3b', 1699 'bed':'\ud83d\udecf', 1700 'bee':'\ud83d\udc1d', 1701 'beer':'\ud83c\udf7a', 1702 'beers':'\ud83c\udf7b', 1703 'beetle':'\ud83d\udc1e', 1704 'beginner':'\ud83d\udd30', 1705 'bell':'\ud83d\udd14', 1706 'bellhop_bell':'\ud83d\udece', 1707 'bento':'\ud83c\udf71', 1708 'biking_man':'\ud83d\udeb4', 1709 'bike':'\ud83d\udeb2', 1710 'biking_woman':'\ud83d\udeb4‍\u2640\ufe0f', 1711 'bikini':'\ud83d\udc59', 1712 'biohazard':'\u2623\ufe0f', 1713 'bird':'\ud83d\udc26', 1714 'birthday':'\ud83c\udf82', 1715 'black_circle':'\u26ab\ufe0f', 1716 'black_flag':'\ud83c\udff4', 1717 'black_heart':'\ud83d\udda4', 1718 'black_joker':'\ud83c\udccf', 1719 'black_large_square':'\u2b1b\ufe0f', 1720 'black_medium_small_square':'\u25fe\ufe0f', 1721 'black_medium_square':'\u25fc\ufe0f', 1722 'black_nib':'\u2712\ufe0f', 1723 'black_small_square':'\u25aa\ufe0f', 1724 'black_square_button':'\ud83d\udd32', 1725 'blonde_man':'\ud83d\udc71', 1726 'blonde_woman':'\ud83d\udc71‍\u2640\ufe0f', 1727 'blossom':'\ud83c\udf3c', 1728 'blowfish':'\ud83d\udc21', 1729 'blue_book':'\ud83d\udcd8', 1730 'blue_car':'\ud83d\ude99', 1731 'blue_heart':'\ud83d\udc99', 1732 'blush':'\ud83d\ude0a', 1733 'boar':'\ud83d\udc17', 1734 'boat':'\u26f5\ufe0f', 1735 'bomb':'\ud83d\udca3', 1736 'book':'\ud83d\udcd6', 1737 'bookmark':'\ud83d\udd16', 1738 'bookmark_tabs':'\ud83d\udcd1', 1739 'books':'\ud83d\udcda', 1740 'boom':'\ud83d\udca5', 1741 'boot':'\ud83d\udc62', 1742 'bouquet':'\ud83d\udc90', 1743 'bowing_man':'\ud83d\ude47', 1744 'bow_and_arrow':'\ud83c\udff9', 1745 'bowing_woman':'\ud83d\ude47‍\u2640\ufe0f', 1746 'bowling':'\ud83c\udfb3', 1747 'boxing_glove':'\ud83e\udd4a', 1748 'boy':'\ud83d\udc66', 1749 'bread':'\ud83c\udf5e', 1750 'bride_with_veil':'\ud83d\udc70', 1751 'bridge_at_night':'\ud83c\udf09', 1752 'briefcase':'\ud83d\udcbc', 1753 'broken_heart':'\ud83d\udc94', 1754 'bug':'\ud83d\udc1b', 1755 'building_construction':'\ud83c\udfd7', 1756 'bulb':'\ud83d\udca1', 1757 'bullettrain_front':'\ud83d\ude85', 1758 'bullettrain_side':'\ud83d\ude84', 1759 'burrito':'\ud83c\udf2f', 1760 'bus':'\ud83d\ude8c', 1761 'business_suit_levitating':'\ud83d\udd74', 1762 'busstop':'\ud83d\ude8f', 1763 'bust_in_silhouette':'\ud83d\udc64', 1764 'busts_in_silhouette':'\ud83d\udc65', 1765 'butterfly':'\ud83e\udd8b', 1766 'cactus':'\ud83c\udf35', 1767 'cake':'\ud83c\udf70', 1768 'calendar':'\ud83d\udcc6', 1769 'call_me_hand':'\ud83e\udd19', 1770 'calling':'\ud83d\udcf2', 1771 'camel':'\ud83d\udc2b', 1772 'camera':'\ud83d\udcf7', 1773 'camera_flash':'\ud83d\udcf8', 1774 'camping':'\ud83c\udfd5', 1775 'cancer':'\u264b\ufe0f', 1776 'candle':'\ud83d\udd6f', 1777 'candy':'\ud83c\udf6c', 1778 'canoe':'\ud83d\udef6', 1779 'capital_abcd':'\ud83d\udd20', 1780 'capricorn':'\u2651\ufe0f', 1781 'car':'\ud83d\ude97', 1782 'card_file_box':'\ud83d\uddc3', 1783 'card_index':'\ud83d\udcc7', 1784 'card_index_dividers':'\ud83d\uddc2', 1785 'carousel_horse':'\ud83c\udfa0', 1786 'carrot':'\ud83e\udd55', 1787 'cat':'\ud83d\udc31', 1788 'cat2':'\ud83d\udc08', 1789 'cd':'\ud83d\udcbf', 1790 'chains':'\u26d3', 1791 'champagne':'\ud83c\udf7e', 1792 'chart':'\ud83d\udcb9', 1793 'chart_with_downwards_trend':'\ud83d\udcc9', 1794 'chart_with_upwards_trend':'\ud83d\udcc8', 1795 'checkered_flag':'\ud83c\udfc1', 1796 'cheese':'\ud83e\uddc0', 1797 'cherries':'\ud83c\udf52', 1798 'cherry_blossom':'\ud83c\udf38', 1799 'chestnut':'\ud83c\udf30', 1800 'chicken':'\ud83d\udc14', 1801 'children_crossing':'\ud83d\udeb8', 1802 'chipmunk':'\ud83d\udc3f', 1803 'chocolate_bar':'\ud83c\udf6b', 1804 'christmas_tree':'\ud83c\udf84', 1805 'church':'\u26ea\ufe0f', 1806 'cinema':'\ud83c\udfa6', 1807 'circus_tent':'\ud83c\udfaa', 1808 'city_sunrise':'\ud83c\udf07', 1809 'city_sunset':'\ud83c\udf06', 1810 'cityscape':'\ud83c\udfd9', 1811 'cl':'\ud83c\udd91', 1812 'clamp':'\ud83d\udddc', 1813 'clap':'\ud83d\udc4f', 1814 'clapper':'\ud83c\udfac', 1815 'classical_building':'\ud83c\udfdb', 1816 'clinking_glasses':'\ud83e\udd42', 1817 'clipboard':'\ud83d\udccb', 1818 'clock1':'\ud83d\udd50', 1819 'clock10':'\ud83d\udd59', 1820 'clock1030':'\ud83d\udd65', 1821 'clock11':'\ud83d\udd5a', 1822 'clock1130':'\ud83d\udd66', 1823 'clock12':'\ud83d\udd5b', 1824 'clock1230':'\ud83d\udd67', 1825 'clock130':'\ud83d\udd5c', 1826 'clock2':'\ud83d\udd51', 1827 'clock230':'\ud83d\udd5d', 1828 'clock3':'\ud83d\udd52', 1829 'clock330':'\ud83d\udd5e', 1830 'clock4':'\ud83d\udd53', 1831 'clock430':'\ud83d\udd5f', 1832 'clock5':'\ud83d\udd54', 1833 'clock530':'\ud83d\udd60', 1834 'clock6':'\ud83d\udd55', 1835 'clock630':'\ud83d\udd61', 1836 'clock7':'\ud83d\udd56', 1837 'clock730':'\ud83d\udd62', 1838 'clock8':'\ud83d\udd57', 1839 'clock830':'\ud83d\udd63', 1840 'clock9':'\ud83d\udd58', 1841 'clock930':'\ud83d\udd64', 1842 'closed_book':'\ud83d\udcd5', 1843 'closed_lock_with_key':'\ud83d\udd10', 1844 'closed_umbrella':'\ud83c\udf02', 1845 'cloud':'\u2601\ufe0f', 1846 'cloud_with_lightning':'\ud83c\udf29', 1847 'cloud_with_lightning_and_rain':'\u26c8', 1848 'cloud_with_rain':'\ud83c\udf27', 1849 'cloud_with_snow':'\ud83c\udf28', 1850 'clown_face':'\ud83e\udd21', 1851 'clubs':'\u2663\ufe0f', 1852 'cocktail':'\ud83c\udf78', 1853 'coffee':'\u2615\ufe0f', 1854 'coffin':'\u26b0\ufe0f', 1855 'cold_sweat':'\ud83d\ude30', 1856 'comet':'\u2604\ufe0f', 1857 'computer':'\ud83d\udcbb', 1858 'computer_mouse':'\ud83d\uddb1', 1859 'confetti_ball':'\ud83c\udf8a', 1860 'confounded':'\ud83d\ude16', 1861 'confused':'\ud83d\ude15', 1862 'congratulations':'\u3297\ufe0f', 1863 'construction':'\ud83d\udea7', 1864 'construction_worker_man':'\ud83d\udc77', 1865 'construction_worker_woman':'\ud83d\udc77‍\u2640\ufe0f', 1866 'control_knobs':'\ud83c\udf9b', 1867 'convenience_store':'\ud83c\udfea', 1868 'cookie':'\ud83c\udf6a', 1869 'cool':'\ud83c\udd92', 1870 'policeman':'\ud83d\udc6e', 1871 'copyright':'\u00a9\ufe0f', 1872 'corn':'\ud83c\udf3d', 1873 'couch_and_lamp':'\ud83d\udecb', 1874 'couple':'\ud83d\udc6b', 1875 'couple_with_heart_woman_man':'\ud83d\udc91', 1876 'couple_with_heart_man_man':'\ud83d\udc68‍\u2764\ufe0f‍\ud83d\udc68', 1877 'couple_with_heart_woman_woman':'\ud83d\udc69‍\u2764\ufe0f‍\ud83d\udc69', 1878 'couplekiss_man_man':'\ud83d\udc68‍\u2764\ufe0f‍\ud83d\udc8b‍\ud83d\udc68', 1879 'couplekiss_man_woman':'\ud83d\udc8f', 1880 'couplekiss_woman_woman':'\ud83d\udc69‍\u2764\ufe0f‍\ud83d\udc8b‍\ud83d\udc69', 1881 'cow':'\ud83d\udc2e', 1882 'cow2':'\ud83d\udc04', 1883 'cowboy_hat_face':'\ud83e\udd20', 1884 'crab':'\ud83e\udd80', 1885 'crayon':'\ud83d\udd8d', 1886 'credit_card':'\ud83d\udcb3', 1887 'crescent_moon':'\ud83c\udf19', 1888 'cricket':'\ud83c\udfcf', 1889 'crocodile':'\ud83d\udc0a', 1890 'croissant':'\ud83e\udd50', 1891 'crossed_fingers':'\ud83e\udd1e', 1892 'crossed_flags':'\ud83c\udf8c', 1893 'crossed_swords':'\u2694\ufe0f', 1894 'crown':'\ud83d\udc51', 1895 'cry':'\ud83d\ude22', 1896 'crying_cat_face':'\ud83d\ude3f', 1897 'crystal_ball':'\ud83d\udd2e', 1898 'cucumber':'\ud83e\udd52', 1899 'cupid':'\ud83d\udc98', 1900 'curly_loop':'\u27b0', 1901 'currency_exchange':'\ud83d\udcb1', 1902 'curry':'\ud83c\udf5b', 1903 'custard':'\ud83c\udf6e', 1904 'customs':'\ud83d\udec3', 1905 'cyclone':'\ud83c\udf00', 1906 'dagger':'\ud83d\udde1', 1907 'dancer':'\ud83d\udc83', 1908 'dancing_women':'\ud83d\udc6f', 1909 'dancing_men':'\ud83d\udc6f‍\u2642\ufe0f', 1910 'dango':'\ud83c\udf61', 1911 'dark_sunglasses':'\ud83d\udd76', 1912 'dart':'\ud83c\udfaf', 1913 'dash':'\ud83d\udca8', 1914 'date':'\ud83d\udcc5', 1915 'deciduous_tree':'\ud83c\udf33', 1916 'deer':'\ud83e\udd8c', 1917 'department_store':'\ud83c\udfec', 1918 'derelict_house':'\ud83c\udfda', 1919 'desert':'\ud83c\udfdc', 1920 'desert_island':'\ud83c\udfdd', 1921 'desktop_computer':'\ud83d\udda5', 1922 'male_detective':'\ud83d\udd75\ufe0f', 1923 'diamond_shape_with_a_dot_inside':'\ud83d\udca0', 1924 'diamonds':'\u2666\ufe0f', 1925 'disappointed':'\ud83d\ude1e', 1926 'disappointed_relieved':'\ud83d\ude25', 1927 'dizzy':'\ud83d\udcab', 1928 'dizzy_face':'\ud83d\ude35', 1929 'do_not_litter':'\ud83d\udeaf', 1930 'dog':'\ud83d\udc36', 1931 'dog2':'\ud83d\udc15', 1932 'dollar':'\ud83d\udcb5', 1933 'dolls':'\ud83c\udf8e', 1934 'dolphin':'\ud83d\udc2c', 1935 'door':'\ud83d\udeaa', 1936 'doughnut':'\ud83c\udf69', 1937 'dove':'\ud83d\udd4a', 1938 'dragon':'\ud83d\udc09', 1939 'dragon_face':'\ud83d\udc32', 1940 'dress':'\ud83d\udc57', 1941 'dromedary_camel':'\ud83d\udc2a', 1942 'drooling_face':'\ud83e\udd24', 1943 'droplet':'\ud83d\udca7', 1944 'drum':'\ud83e\udd41', 1945 'duck':'\ud83e\udd86', 1946 'dvd':'\ud83d\udcc0', 1947 'e-mail':'\ud83d\udce7', 1948 'eagle':'\ud83e\udd85', 1949 'ear':'\ud83d\udc42', 1950 'ear_of_rice':'\ud83c\udf3e', 1951 'earth_africa':'\ud83c\udf0d', 1952 'earth_americas':'\ud83c\udf0e', 1953 'earth_asia':'\ud83c\udf0f', 1954 'egg':'\ud83e\udd5a', 1955 'eggplant':'\ud83c\udf46', 1956 'eight_pointed_black_star':'\u2734\ufe0f', 1957 'eight_spoked_asterisk':'\u2733\ufe0f', 1958 'electric_plug':'\ud83d\udd0c', 1959 'elephant':'\ud83d\udc18', 1960 'email':'\u2709\ufe0f', 1961 'end':'\ud83d\udd1a', 1962 'envelope_with_arrow':'\ud83d\udce9', 1963 'euro':'\ud83d\udcb6', 1964 'european_castle':'\ud83c\udff0', 1965 'european_post_office':'\ud83c\udfe4', 1966 'evergreen_tree':'\ud83c\udf32', 1967 'exclamation':'\u2757\ufe0f', 1968 'expressionless':'\ud83d\ude11', 1969 'eye':'\ud83d\udc41', 1970 'eye_speech_bubble':'\ud83d\udc41‍\ud83d\udde8', 1971 'eyeglasses':'\ud83d\udc53', 1972 'eyes':'\ud83d\udc40', 1973 'face_with_head_bandage':'\ud83e\udd15', 1974 'face_with_thermometer':'\ud83e\udd12', 1975 'fist_oncoming':'\ud83d\udc4a', 1976 'factory':'\ud83c\udfed', 1977 'fallen_leaf':'\ud83c\udf42', 1978 'family_man_woman_boy':'\ud83d\udc6a', 1979 'family_man_boy':'\ud83d\udc68‍\ud83d\udc66', 1980 'family_man_boy_boy':'\ud83d\udc68‍\ud83d\udc66‍\ud83d\udc66', 1981 'family_man_girl':'\ud83d\udc68‍\ud83d\udc67', 1982 'family_man_girl_boy':'\ud83d\udc68‍\ud83d\udc67‍\ud83d\udc66', 1983 'family_man_girl_girl':'\ud83d\udc68‍\ud83d\udc67‍\ud83d\udc67', 1984 'family_man_man_boy':'\ud83d\udc68‍\ud83d\udc68‍\ud83d\udc66', 1985 'family_man_man_boy_boy':'\ud83d\udc68‍\ud83d\udc68‍\ud83d\udc66‍\ud83d\udc66', 1986 'family_man_man_girl':'\ud83d\udc68‍\ud83d\udc68‍\ud83d\udc67', 1987 'family_man_man_girl_boy':'\ud83d\udc68‍\ud83d\udc68‍\ud83d\udc67‍\ud83d\udc66', 1988 'family_man_man_girl_girl':'\ud83d\udc68‍\ud83d\udc68‍\ud83d\udc67‍\ud83d\udc67', 1989 'family_man_woman_boy_boy':'\ud83d\udc68‍\ud83d\udc69‍\ud83d\udc66‍\ud83d\udc66', 1990 'family_man_woman_girl':'\ud83d\udc68‍\ud83d\udc69‍\ud83d\udc67', 1991 'family_man_woman_girl_boy':'\ud83d\udc68‍\ud83d\udc69‍\ud83d\udc67‍\ud83d\udc66', 1992 'family_man_woman_girl_girl':'\ud83d\udc68‍\ud83d\udc69‍\ud83d\udc67‍\ud83d\udc67', 1993 'family_woman_boy':'\ud83d\udc69‍\ud83d\udc66', 1994 'family_woman_boy_boy':'\ud83d\udc69‍\ud83d\udc66‍\ud83d\udc66', 1995 'family_woman_girl':'\ud83d\udc69‍\ud83d\udc67', 1996 'family_woman_girl_boy':'\ud83d\udc69‍\ud83d\udc67‍\ud83d\udc66', 1997 'family_woman_girl_girl':'\ud83d\udc69‍\ud83d\udc67‍\ud83d\udc67', 1998 'family_woman_woman_boy':'\ud83d\udc69‍\ud83d\udc69‍\ud83d\udc66', 1999 'family_woman_woman_boy_boy':'\ud83d\udc69‍\ud83d\udc69‍\ud83d\udc66‍\ud83d\udc66', 2000 'family_woman_woman_girl':'\ud83d\udc69‍\ud83d\udc69‍\ud83d\udc67', 2001 'family_woman_woman_girl_boy':'\ud83d\udc69‍\ud83d\udc69‍\ud83d\udc67‍\ud83d\udc66', 2002 'family_woman_woman_girl_girl':'\ud83d\udc69‍\ud83d\udc69‍\ud83d\udc67‍\ud83d\udc67', 2003 'fast_forward':'\u23e9', 2004 'fax':'\ud83d\udce0', 2005 'fearful':'\ud83d\ude28', 2006 'feet':'\ud83d\udc3e', 2007 'female_detective':'\ud83d\udd75\ufe0f‍\u2640\ufe0f', 2008 'ferris_wheel':'\ud83c\udfa1', 2009 'ferry':'\u26f4', 2010 'field_hockey':'\ud83c\udfd1', 2011 'file_cabinet':'\ud83d\uddc4', 2012 'file_folder':'\ud83d\udcc1', 2013 'film_projector':'\ud83d\udcfd', 2014 'film_strip':'\ud83c\udf9e', 2015 'fire':'\ud83d\udd25', 2016 'fire_engine':'\ud83d\ude92', 2017 'fireworks':'\ud83c\udf86', 2018 'first_quarter_moon':'\ud83c\udf13', 2019 'first_quarter_moon_with_face':'\ud83c\udf1b', 2020 'fish':'\ud83d\udc1f', 2021 'fish_cake':'\ud83c\udf65', 2022 'fishing_pole_and_fish':'\ud83c\udfa3', 2023 'fist_raised':'\u270a', 2024 'fist_left':'\ud83e\udd1b', 2025 'fist_right':'\ud83e\udd1c', 2026 'flags':'\ud83c\udf8f', 2027 'flashlight':'\ud83d\udd26', 2028 'fleur_de_lis':'\u269c\ufe0f', 2029 'flight_arrival':'\ud83d\udeec', 2030 'flight_departure':'\ud83d\udeeb', 2031 'floppy_disk':'\ud83d\udcbe', 2032 'flower_playing_cards':'\ud83c\udfb4', 2033 'flushed':'\ud83d\ude33', 2034 'fog':'\ud83c\udf2b', 2035 'foggy':'\ud83c\udf01', 2036 'football':'\ud83c\udfc8', 2037 'footprints':'\ud83d\udc63', 2038 'fork_and_knife':'\ud83c\udf74', 2039 'fountain':'\u26f2\ufe0f', 2040 'fountain_pen':'\ud83d\udd8b', 2041 'four_leaf_clover':'\ud83c\udf40', 2042 'fox_face':'\ud83e\udd8a', 2043 'framed_picture':'\ud83d\uddbc', 2044 'free':'\ud83c\udd93', 2045 'fried_egg':'\ud83c\udf73', 2046 'fried_shrimp':'\ud83c\udf64', 2047 'fries':'\ud83c\udf5f', 2048 'frog':'\ud83d\udc38', 2049 'frowning':'\ud83d\ude26', 2050 'frowning_face':'\u2639\ufe0f', 2051 'frowning_man':'\ud83d\ude4d‍\u2642\ufe0f', 2052 'frowning_woman':'\ud83d\ude4d', 2053 'middle_finger':'\ud83d\udd95', 2054 'fuelpump':'\u26fd\ufe0f', 2055 'full_moon':'\ud83c\udf15', 2056 'full_moon_with_face':'\ud83c\udf1d', 2057 'funeral_urn':'\u26b1\ufe0f', 2058 'game_die':'\ud83c\udfb2', 2059 'gear':'\u2699\ufe0f', 2060 'gem':'\ud83d\udc8e', 2061 'gemini':'\u264a\ufe0f', 2062 'ghost':'\ud83d\udc7b', 2063 'gift':'\ud83c\udf81', 2064 'gift_heart':'\ud83d\udc9d', 2065 'girl':'\ud83d\udc67', 2066 'globe_with_meridians':'\ud83c\udf10', 2067 'goal_net':'\ud83e\udd45', 2068 'goat':'\ud83d\udc10', 2069 'golf':'\u26f3\ufe0f', 2070 'golfing_man':'\ud83c\udfcc\ufe0f', 2071 'golfing_woman':'\ud83c\udfcc\ufe0f‍\u2640\ufe0f', 2072 'gorilla':'\ud83e\udd8d', 2073 'grapes':'\ud83c\udf47', 2074 'green_apple':'\ud83c\udf4f', 2075 'green_book':'\ud83d\udcd7', 2076 'green_heart':'\ud83d\udc9a', 2077 'green_salad':'\ud83e\udd57', 2078 'grey_exclamation':'\u2755', 2079 'grey_question':'\u2754', 2080 'grimacing':'\ud83d\ude2c', 2081 'grin':'\ud83d\ude01', 2082 'grinning':'\ud83d\ude00', 2083 'guardsman':'\ud83d\udc82', 2084 'guardswoman':'\ud83d\udc82‍\u2640\ufe0f', 2085 'guitar':'\ud83c\udfb8', 2086 'gun':'\ud83d\udd2b', 2087 'haircut_woman':'\ud83d\udc87', 2088 'haircut_man':'\ud83d\udc87‍\u2642\ufe0f', 2089 'hamburger':'\ud83c\udf54', 2090 'hammer':'\ud83d\udd28', 2091 'hammer_and_pick':'\u2692', 2092 'hammer_and_wrench':'\ud83d\udee0', 2093 'hamster':'\ud83d\udc39', 2094 'hand':'\u270b', 2095 'handbag':'\ud83d\udc5c', 2096 'handshake':'\ud83e\udd1d', 2097 'hankey':'\ud83d\udca9', 2098 'hatched_chick':'\ud83d\udc25', 2099 'hatching_chick':'\ud83d\udc23', 2100 'headphones':'\ud83c\udfa7', 2101 'hear_no_evil':'\ud83d\ude49', 2102 'heart':'\u2764\ufe0f', 2103 'heart_decoration':'\ud83d\udc9f', 2104 'heart_eyes':'\ud83d\ude0d', 2105 'heart_eyes_cat':'\ud83d\ude3b', 2106 'heartbeat':'\ud83d\udc93', 2107 'heartpulse':'\ud83d\udc97', 2108 'hearts':'\u2665\ufe0f', 2109 'heavy_check_mark':'\u2714\ufe0f', 2110 'heavy_division_sign':'\u2797', 2111 'heavy_dollar_sign':'\ud83d\udcb2', 2112 'heavy_heart_exclamation':'\u2763\ufe0f', 2113 'heavy_minus_sign':'\u2796', 2114 'heavy_multiplication_x':'\u2716\ufe0f', 2115 'heavy_plus_sign':'\u2795', 2116 'helicopter':'\ud83d\ude81', 2117 'herb':'\ud83c\udf3f', 2118 'hibiscus':'\ud83c\udf3a', 2119 'high_brightness':'\ud83d\udd06', 2120 'high_heel':'\ud83d\udc60', 2121 'hocho':'\ud83d\udd2a', 2122 'hole':'\ud83d\udd73', 2123 'honey_pot':'\ud83c\udf6f', 2124 'horse':'\ud83d\udc34', 2125 'horse_racing':'\ud83c\udfc7', 2126 'hospital':'\ud83c\udfe5', 2127 'hot_pepper':'\ud83c\udf36', 2128 'hotdog':'\ud83c\udf2d', 2129 'hotel':'\ud83c\udfe8', 2130 'hotsprings':'\u2668\ufe0f', 2131 'hourglass':'\u231b\ufe0f', 2132 'hourglass_flowing_sand':'\u23f3', 2133 'house':'\ud83c\udfe0', 2134 'house_with_garden':'\ud83c\udfe1', 2135 'houses':'\ud83c\udfd8', 2136 'hugs':'\ud83e\udd17', 2137 'hushed':'\ud83d\ude2f', 2138 'ice_cream':'\ud83c\udf68', 2139 'ice_hockey':'\ud83c\udfd2', 2140 'ice_skate':'\u26f8', 2141 'icecream':'\ud83c\udf66', 2142 'id':'\ud83c\udd94', 2143 'ideograph_advantage':'\ud83c\ude50', 2144 'imp':'\ud83d\udc7f', 2145 'inbox_tray':'\ud83d\udce5', 2146 'incoming_envelope':'\ud83d\udce8', 2147 'tipping_hand_woman':'\ud83d\udc81', 2148 'information_source':'\u2139\ufe0f', 2149 'innocent':'\ud83d\ude07', 2150 'interrobang':'\u2049\ufe0f', 2151 'iphone':'\ud83d\udcf1', 2152 'izakaya_lantern':'\ud83c\udfee', 2153 'jack_o_lantern':'\ud83c\udf83', 2154 'japan':'\ud83d\uddfe', 2155 'japanese_castle':'\ud83c\udfef', 2156 'japanese_goblin':'\ud83d\udc7a', 2157 'japanese_ogre':'\ud83d\udc79', 2158 'jeans':'\ud83d\udc56', 2159 'joy':'\ud83d\ude02', 2160 'joy_cat':'\ud83d\ude39', 2161 'joystick':'\ud83d\udd79', 2162 'kaaba':'\ud83d\udd4b', 2163 'key':'\ud83d\udd11', 2164 'keyboard':'\u2328\ufe0f', 2165 'keycap_ten':'\ud83d\udd1f', 2166 'kick_scooter':'\ud83d\udef4', 2167 'kimono':'\ud83d\udc58', 2168 'kiss':'\ud83d\udc8b', 2169 'kissing':'\ud83d\ude17', 2170 'kissing_cat':'\ud83d\ude3d', 2171 'kissing_closed_eyes':'\ud83d\ude1a', 2172 'kissing_heart':'\ud83d\ude18', 2173 'kissing_smiling_eyes':'\ud83d\ude19', 2174 'kiwi_fruit':'\ud83e\udd5d', 2175 'koala':'\ud83d\udc28', 2176 'koko':'\ud83c\ude01', 2177 'label':'\ud83c\udff7', 2178 'large_blue_circle':'\ud83d\udd35', 2179 'large_blue_diamond':'\ud83d\udd37', 2180 'large_orange_diamond':'\ud83d\udd36', 2181 'last_quarter_moon':'\ud83c\udf17', 2182 'last_quarter_moon_with_face':'\ud83c\udf1c', 2183 'latin_cross':'\u271d\ufe0f', 2184 'laughing':'\ud83d\ude06', 2185 'leaves':'\ud83c\udf43', 2186 'ledger':'\ud83d\udcd2', 2187 'left_luggage':'\ud83d\udec5', 2188 'left_right_arrow':'\u2194\ufe0f', 2189 'leftwards_arrow_with_hook':'\u21a9\ufe0f', 2190 'lemon':'\ud83c\udf4b', 2191 'leo':'\u264c\ufe0f', 2192 'leopard':'\ud83d\udc06', 2193 'level_slider':'\ud83c\udf9a', 2194 'libra':'\u264e\ufe0f', 2195 'light_rail':'\ud83d\ude88', 2196 'link':'\ud83d\udd17', 2197 'lion':'\ud83e\udd81', 2198 'lips':'\ud83d\udc44', 2199 'lipstick':'\ud83d\udc84', 2200 'lizard':'\ud83e\udd8e', 2201 'lock':'\ud83d\udd12', 2202 'lock_with_ink_pen':'\ud83d\udd0f', 2203 'lollipop':'\ud83c\udf6d', 2204 'loop':'\u27bf', 2205 'loud_sound':'\ud83d\udd0a', 2206 'loudspeaker':'\ud83d\udce2', 2207 'love_hotel':'\ud83c\udfe9', 2208 'love_letter':'\ud83d\udc8c', 2209 'low_brightness':'\ud83d\udd05', 2210 'lying_face':'\ud83e\udd25', 2211 'm':'\u24c2\ufe0f', 2212 'mag':'\ud83d\udd0d', 2213 'mag_right':'\ud83d\udd0e', 2214 'mahjong':'\ud83c\udc04\ufe0f', 2215 'mailbox':'\ud83d\udceb', 2216 'mailbox_closed':'\ud83d\udcea', 2217 'mailbox_with_mail':'\ud83d\udcec', 2218 'mailbox_with_no_mail':'\ud83d\udced', 2219 'man':'\ud83d\udc68', 2220 'man_artist':'\ud83d\udc68‍\ud83c\udfa8', 2221 'man_astronaut':'\ud83d\udc68‍\ud83d\ude80', 2222 'man_cartwheeling':'\ud83e\udd38‍\u2642\ufe0f', 2223 'man_cook':'\ud83d\udc68‍\ud83c\udf73', 2224 'man_dancing':'\ud83d\udd7a', 2225 'man_facepalming':'\ud83e\udd26‍\u2642\ufe0f', 2226 'man_factory_worker':'\ud83d\udc68‍\ud83c\udfed', 2227 'man_farmer':'\ud83d\udc68‍\ud83c\udf3e', 2228 'man_firefighter':'\ud83d\udc68‍\ud83d\ude92', 2229 'man_health_worker':'\ud83d\udc68‍\u2695\ufe0f', 2230 'man_in_tuxedo':'\ud83e\udd35', 2231 'man_judge':'\ud83d\udc68‍\u2696\ufe0f', 2232 'man_juggling':'\ud83e\udd39‍\u2642\ufe0f', 2233 'man_mechanic':'\ud83d\udc68‍\ud83d\udd27', 2234 'man_office_worker':'\ud83d\udc68‍\ud83d\udcbc', 2235 'man_pilot':'\ud83d\udc68‍\u2708\ufe0f', 2236 'man_playing_handball':'\ud83e\udd3e‍\u2642\ufe0f', 2237 'man_playing_water_polo':'\ud83e\udd3d‍\u2642\ufe0f', 2238 'man_scientist':'\ud83d\udc68‍\ud83d\udd2c', 2239 'man_shrugging':'\ud83e\udd37‍\u2642\ufe0f', 2240 'man_singer':'\ud83d\udc68‍\ud83c\udfa4', 2241 'man_student':'\ud83d\udc68‍\ud83c\udf93', 2242 'man_teacher':'\ud83d\udc68‍\ud83c\udfeb', 2243 'man_technologist':'\ud83d\udc68‍\ud83d\udcbb', 2244 'man_with_gua_pi_mao':'\ud83d\udc72', 2245 'man_with_turban':'\ud83d\udc73', 2246 'tangerine':'\ud83c\udf4a', 2247 'mans_shoe':'\ud83d\udc5e', 2248 'mantelpiece_clock':'\ud83d\udd70', 2249 'maple_leaf':'\ud83c\udf41', 2250 'martial_arts_uniform':'\ud83e\udd4b', 2251 'mask':'\ud83d\ude37', 2252 'massage_woman':'\ud83d\udc86', 2253 'massage_man':'\ud83d\udc86‍\u2642\ufe0f', 2254 'meat_on_bone':'\ud83c\udf56', 2255 'medal_military':'\ud83c\udf96', 2256 'medal_sports':'\ud83c\udfc5', 2257 'mega':'\ud83d\udce3', 2258 'melon':'\ud83c\udf48', 2259 'memo':'\ud83d\udcdd', 2260 'men_wrestling':'\ud83e\udd3c‍\u2642\ufe0f', 2261 'menorah':'\ud83d\udd4e', 2262 'mens':'\ud83d\udeb9', 2263 'metal':'\ud83e\udd18', 2264 'metro':'\ud83d\ude87', 2265 'microphone':'\ud83c\udfa4', 2266 'microscope':'\ud83d\udd2c', 2267 'milk_glass':'\ud83e\udd5b', 2268 'milky_way':'\ud83c\udf0c', 2269 'minibus':'\ud83d\ude90', 2270 'minidisc':'\ud83d\udcbd', 2271 'mobile_phone_off':'\ud83d\udcf4', 2272 'money_mouth_face':'\ud83e\udd11', 2273 'money_with_wings':'\ud83d\udcb8', 2274 'moneybag':'\ud83d\udcb0', 2275 'monkey':'\ud83d\udc12', 2276 'monkey_face':'\ud83d\udc35', 2277 'monorail':'\ud83d\ude9d', 2278 'moon':'\ud83c\udf14', 2279 'mortar_board':'\ud83c\udf93', 2280 'mosque':'\ud83d\udd4c', 2281 'motor_boat':'\ud83d\udee5', 2282 'motor_scooter':'\ud83d\udef5', 2283 'motorcycle':'\ud83c\udfcd', 2284 'motorway':'\ud83d\udee3', 2285 'mount_fuji':'\ud83d\uddfb', 2286 'mountain':'\u26f0', 2287 'mountain_biking_man':'\ud83d\udeb5', 2288 'mountain_biking_woman':'\ud83d\udeb5‍\u2640\ufe0f', 2289 'mountain_cableway':'\ud83d\udea0', 2290 'mountain_railway':'\ud83d\ude9e', 2291 'mountain_snow':'\ud83c\udfd4', 2292 'mouse':'\ud83d\udc2d', 2293 'mouse2':'\ud83d\udc01', 2294 'movie_camera':'\ud83c\udfa5', 2295 'moyai':'\ud83d\uddff', 2296 'mrs_claus':'\ud83e\udd36', 2297 'muscle':'\ud83d\udcaa', 2298 'mushroom':'\ud83c\udf44', 2299 'musical_keyboard':'\ud83c\udfb9', 2300 'musical_note':'\ud83c\udfb5', 2301 'musical_score':'\ud83c\udfbc', 2302 'mute':'\ud83d\udd07', 2303 'nail_care':'\ud83d\udc85', 2304 'name_badge':'\ud83d\udcdb', 2305 'national_park':'\ud83c\udfde', 2306 'nauseated_face':'\ud83e\udd22', 2307 'necktie':'\ud83d\udc54', 2308 'negative_squared_cross_mark':'\u274e', 2309 'nerd_face':'\ud83e\udd13', 2310 'neutral_face':'\ud83d\ude10', 2311 'new':'\ud83c\udd95', 2312 'new_moon':'\ud83c\udf11', 2313 'new_moon_with_face':'\ud83c\udf1a', 2314 'newspaper':'\ud83d\udcf0', 2315 'newspaper_roll':'\ud83d\uddde', 2316 'next_track_button':'\u23ed', 2317 'ng':'\ud83c\udd96', 2318 'no_good_man':'\ud83d\ude45‍\u2642\ufe0f', 2319 'no_good_woman':'\ud83d\ude45', 2320 'night_with_stars':'\ud83c\udf03', 2321 'no_bell':'\ud83d\udd15', 2322 'no_bicycles':'\ud83d\udeb3', 2323 'no_entry':'\u26d4\ufe0f', 2324 'no_entry_sign':'\ud83d\udeab', 2325 'no_mobile_phones':'\ud83d\udcf5', 2326 'no_mouth':'\ud83d\ude36', 2327 'no_pedestrians':'\ud83d\udeb7', 2328 'no_smoking':'\ud83d\udead', 2329 'non-potable_water':'\ud83d\udeb1', 2330 'nose':'\ud83d\udc43', 2331 'notebook':'\ud83d\udcd3', 2332 'notebook_with_decorative_cover':'\ud83d\udcd4', 2333 'notes':'\ud83c\udfb6', 2334 'nut_and_bolt':'\ud83d\udd29', 2335 'o':'\u2b55\ufe0f', 2336 'o2':'\ud83c\udd7e\ufe0f', 2337 'ocean':'\ud83c\udf0a', 2338 'octopus':'\ud83d\udc19', 2339 'oden':'\ud83c\udf62', 2340 'office':'\ud83c\udfe2', 2341 'oil_drum':'\ud83d\udee2', 2342 'ok':'\ud83c\udd97', 2343 'ok_hand':'\ud83d\udc4c', 2344 'ok_man':'\ud83d\ude46‍\u2642\ufe0f', 2345 'ok_woman':'\ud83d\ude46', 2346 'old_key':'\ud83d\udddd', 2347 'older_man':'\ud83d\udc74', 2348 'older_woman':'\ud83d\udc75', 2349 'om':'\ud83d\udd49', 2350 'on':'\ud83d\udd1b', 2351 'oncoming_automobile':'\ud83d\ude98', 2352 'oncoming_bus':'\ud83d\ude8d', 2353 'oncoming_police_car':'\ud83d\ude94', 2354 'oncoming_taxi':'\ud83d\ude96', 2355 'open_file_folder':'\ud83d\udcc2', 2356 'open_hands':'\ud83d\udc50', 2357 'open_mouth':'\ud83d\ude2e', 2358 'open_umbrella':'\u2602\ufe0f', 2359 'ophiuchus':'\u26ce', 2360 'orange_book':'\ud83d\udcd9', 2361 'orthodox_cross':'\u2626\ufe0f', 2362 'outbox_tray':'\ud83d\udce4', 2363 'owl':'\ud83e\udd89', 2364 'ox':'\ud83d\udc02', 2365 'package':'\ud83d\udce6', 2366 'page_facing_up':'\ud83d\udcc4', 2367 'page_with_curl':'\ud83d\udcc3', 2368 'pager':'\ud83d\udcdf', 2369 'paintbrush':'\ud83d\udd8c', 2370 'palm_tree':'\ud83c\udf34', 2371 'pancakes':'\ud83e\udd5e', 2372 'panda_face':'\ud83d\udc3c', 2373 'paperclip':'\ud83d\udcce', 2374 'paperclips':'\ud83d\udd87', 2375 'parasol_on_ground':'\u26f1', 2376 'parking':'\ud83c\udd7f\ufe0f', 2377 'part_alternation_mark':'\u303d\ufe0f', 2378 'partly_sunny':'\u26c5\ufe0f', 2379 'passenger_ship':'\ud83d\udef3', 2380 'passport_control':'\ud83d\udec2', 2381 'pause_button':'\u23f8', 2382 'peace_symbol':'\u262e\ufe0f', 2383 'peach':'\ud83c\udf51', 2384 'peanuts':'\ud83e\udd5c', 2385 'pear':'\ud83c\udf50', 2386 'pen':'\ud83d\udd8a', 2387 'pencil2':'\u270f\ufe0f', 2388 'penguin':'\ud83d\udc27', 2389 'pensive':'\ud83d\ude14', 2390 'performing_arts':'\ud83c\udfad', 2391 'persevere':'\ud83d\ude23', 2392 'person_fencing':'\ud83e\udd3a', 2393 'pouting_woman':'\ud83d\ude4e', 2394 'phone':'\u260e\ufe0f', 2395 'pick':'\u26cf', 2396 'pig':'\ud83d\udc37', 2397 'pig2':'\ud83d\udc16', 2398 'pig_nose':'\ud83d\udc3d', 2399 'pill':'\ud83d\udc8a', 2400 'pineapple':'\ud83c\udf4d', 2401 'ping_pong':'\ud83c\udfd3', 2402 'pisces':'\u2653\ufe0f', 2403 'pizza':'\ud83c\udf55', 2404 'place_of_worship':'\ud83d\uded0', 2405 'plate_with_cutlery':'\ud83c\udf7d', 2406 'play_or_pause_button':'\u23ef', 2407 'point_down':'\ud83d\udc47', 2408 'point_left':'\ud83d\udc48', 2409 'point_right':'\ud83d\udc49', 2410 'point_up':'\u261d\ufe0f', 2411 'point_up_2':'\ud83d\udc46', 2412 'police_car':'\ud83d\ude93', 2413 'policewoman':'\ud83d\udc6e‍\u2640\ufe0f', 2414 'poodle':'\ud83d\udc29', 2415 'popcorn':'\ud83c\udf7f', 2416 'post_office':'\ud83c\udfe3', 2417 'postal_horn':'\ud83d\udcef', 2418 'postbox':'\ud83d\udcee', 2419 'potable_water':'\ud83d\udeb0', 2420 'potato':'\ud83e\udd54', 2421 'pouch':'\ud83d\udc5d', 2422 'poultry_leg':'\ud83c\udf57', 2423 'pound':'\ud83d\udcb7', 2424 'rage':'\ud83d\ude21', 2425 'pouting_cat':'\ud83d\ude3e', 2426 'pouting_man':'\ud83d\ude4e‍\u2642\ufe0f', 2427 'pray':'\ud83d\ude4f', 2428 'prayer_beads':'\ud83d\udcff', 2429 'pregnant_woman':'\ud83e\udd30', 2430 'previous_track_button':'\u23ee', 2431 'prince':'\ud83e\udd34', 2432 'princess':'\ud83d\udc78', 2433 'printer':'\ud83d\udda8', 2434 'purple_heart':'\ud83d\udc9c', 2435 'purse':'\ud83d\udc5b', 2436 'pushpin':'\ud83d\udccc', 2437 'put_litter_in_its_place':'\ud83d\udeae', 2438 'question':'\u2753', 2439 'rabbit':'\ud83d\udc30', 2440 'rabbit2':'\ud83d\udc07', 2441 'racehorse':'\ud83d\udc0e', 2442 'racing_car':'\ud83c\udfce', 2443 'radio':'\ud83d\udcfb', 2444 'radio_button':'\ud83d\udd18', 2445 'radioactive':'\u2622\ufe0f', 2446 'railway_car':'\ud83d\ude83', 2447 'railway_track':'\ud83d\udee4', 2448 'rainbow':'\ud83c\udf08', 2449 'rainbow_flag':'\ud83c\udff3\ufe0f‍\ud83c\udf08', 2450 'raised_back_of_hand':'\ud83e\udd1a', 2451 'raised_hand_with_fingers_splayed':'\ud83d\udd90', 2452 'raised_hands':'\ud83d\ude4c', 2453 'raising_hand_woman':'\ud83d\ude4b', 2454 'raising_hand_man':'\ud83d\ude4b‍\u2642\ufe0f', 2455 'ram':'\ud83d\udc0f', 2456 'ramen':'\ud83c\udf5c', 2457 'rat':'\ud83d\udc00', 2458 'record_button':'\u23fa', 2459 'recycle':'\u267b\ufe0f', 2460 'red_circle':'\ud83d\udd34', 2461 'registered':'\u00ae\ufe0f', 2462 'relaxed':'\u263a\ufe0f', 2463 'relieved':'\ud83d\ude0c', 2464 'reminder_ribbon':'\ud83c\udf97', 2465 'repeat':'\ud83d\udd01', 2466 'repeat_one':'\ud83d\udd02', 2467 'rescue_worker_helmet':'\u26d1', 2468 'restroom':'\ud83d\udebb', 2469 'revolving_hearts':'\ud83d\udc9e', 2470 'rewind':'\u23ea', 2471 'rhinoceros':'\ud83e\udd8f', 2472 'ribbon':'\ud83c\udf80', 2473 'rice':'\ud83c\udf5a', 2474 'rice_ball':'\ud83c\udf59', 2475 'rice_cracker':'\ud83c\udf58', 2476 'rice_scene':'\ud83c\udf91', 2477 'right_anger_bubble':'\ud83d\uddef', 2478 'ring':'\ud83d\udc8d', 2479 'robot':'\ud83e\udd16', 2480 'rocket':'\ud83d\ude80', 2481 'rofl':'\ud83e\udd23', 2482 'roll_eyes':'\ud83d\ude44', 2483 'roller_coaster':'\ud83c\udfa2', 2484 'rooster':'\ud83d\udc13', 2485 'rose':'\ud83c\udf39', 2486 'rosette':'\ud83c\udff5', 2487 'rotating_light':'\ud83d\udea8', 2488 'round_pushpin':'\ud83d\udccd', 2489 'rowing_man':'\ud83d\udea3', 2490 'rowing_woman':'\ud83d\udea3‍\u2640\ufe0f', 2491 'rugby_football':'\ud83c\udfc9', 2492 'running_man':'\ud83c\udfc3', 2493 'running_shirt_with_sash':'\ud83c\udfbd', 2494 'running_woman':'\ud83c\udfc3‍\u2640\ufe0f', 2495 'sa':'\ud83c\ude02\ufe0f', 2496 'sagittarius':'\u2650\ufe0f', 2497 'sake':'\ud83c\udf76', 2498 'sandal':'\ud83d\udc61', 2499 'santa':'\ud83c\udf85', 2500 'satellite':'\ud83d\udce1', 2501 'saxophone':'\ud83c\udfb7', 2502 'school':'\ud83c\udfeb', 2503 'school_satchel':'\ud83c\udf92', 2504 'scissors':'\u2702\ufe0f', 2505 'scorpion':'\ud83e\udd82', 2506 'scorpius':'\u264f\ufe0f', 2507 'scream':'\ud83d\ude31', 2508 'scream_cat':'\ud83d\ude40', 2509 'scroll':'\ud83d\udcdc', 2510 'seat':'\ud83d\udcba', 2511 'secret':'\u3299\ufe0f', 2512 'see_no_evil':'\ud83d\ude48', 2513 'seedling':'\ud83c\udf31', 2514 'selfie':'\ud83e\udd33', 2515 'shallow_pan_of_food':'\ud83e\udd58', 2516 'shamrock':'\u2618\ufe0f', 2517 'shark':'\ud83e\udd88', 2518 'shaved_ice':'\ud83c\udf67', 2519 'sheep':'\ud83d\udc11', 2520 'shell':'\ud83d\udc1a', 2521 'shield':'\ud83d\udee1', 2522 'shinto_shrine':'\u26e9', 2523 'ship':'\ud83d\udea2', 2524 'shirt':'\ud83d\udc55', 2525 'shopping':'\ud83d\udecd', 2526 'shopping_cart':'\ud83d\uded2', 2527 'shower':'\ud83d\udebf', 2528 'shrimp':'\ud83e\udd90', 2529 'signal_strength':'\ud83d\udcf6', 2530 'six_pointed_star':'\ud83d\udd2f', 2531 'ski':'\ud83c\udfbf', 2532 'skier':'\u26f7', 2533 'skull':'\ud83d\udc80', 2534 'skull_and_crossbones':'\u2620\ufe0f', 2535 'sleeping':'\ud83d\ude34', 2536 'sleeping_bed':'\ud83d\udecc', 2537 'sleepy':'\ud83d\ude2a', 2538 'slightly_frowning_face':'\ud83d\ude41', 2539 'slightly_smiling_face':'\ud83d\ude42', 2540 'slot_machine':'\ud83c\udfb0', 2541 'small_airplane':'\ud83d\udee9', 2542 'small_blue_diamond':'\ud83d\udd39', 2543 'small_orange_diamond':'\ud83d\udd38', 2544 'small_red_triangle':'\ud83d\udd3a', 2545 'small_red_triangle_down':'\ud83d\udd3b', 2546 'smile':'\ud83d\ude04', 2547 'smile_cat':'\ud83d\ude38', 2548 'smiley':'\ud83d\ude03', 2549 'smiley_cat':'\ud83d\ude3a', 2550 'smiling_imp':'\ud83d\ude08', 2551 'smirk':'\ud83d\ude0f', 2552 'smirk_cat':'\ud83d\ude3c', 2553 'smoking':'\ud83d\udeac', 2554 'snail':'\ud83d\udc0c', 2555 'snake':'\ud83d\udc0d', 2556 'sneezing_face':'\ud83e\udd27', 2557 'snowboarder':'\ud83c\udfc2', 2558 'snowflake':'\u2744\ufe0f', 2559 'snowman':'\u26c4\ufe0f', 2560 'snowman_with_snow':'\u2603\ufe0f', 2561 'sob':'\ud83d\ude2d', 2562 'soccer':'\u26bd\ufe0f', 2563 'soon':'\ud83d\udd1c', 2564 'sos':'\ud83c\udd98', 2565 'sound':'\ud83d\udd09', 2566 'space_invader':'\ud83d\udc7e', 2567 'spades':'\u2660\ufe0f', 2568 'spaghetti':'\ud83c\udf5d', 2569 'sparkle':'\u2747\ufe0f', 2570 'sparkler':'\ud83c\udf87', 2571 'sparkles':'\u2728', 2572 'sparkling_heart':'\ud83d\udc96', 2573 'speak_no_evil':'\ud83d\ude4a', 2574 'speaker':'\ud83d\udd08', 2575 'speaking_head':'\ud83d\udde3', 2576 'speech_balloon':'\ud83d\udcac', 2577 'speedboat':'\ud83d\udea4', 2578 'spider':'\ud83d\udd77', 2579 'spider_web':'\ud83d\udd78', 2580 'spiral_calendar':'\ud83d\uddd3', 2581 'spiral_notepad':'\ud83d\uddd2', 2582 'spoon':'\ud83e\udd44', 2583 'squid':'\ud83e\udd91', 2584 'stadium':'\ud83c\udfdf', 2585 'star':'\u2b50\ufe0f', 2586 'star2':'\ud83c\udf1f', 2587 'star_and_crescent':'\u262a\ufe0f', 2588 'star_of_david':'\u2721\ufe0f', 2589 'stars':'\ud83c\udf20', 2590 'station':'\ud83d\ude89', 2591 'statue_of_liberty':'\ud83d\uddfd', 2592 'steam_locomotive':'\ud83d\ude82', 2593 'stew':'\ud83c\udf72', 2594 'stop_button':'\u23f9', 2595 'stop_sign':'\ud83d\uded1', 2596 'stopwatch':'\u23f1', 2597 'straight_ruler':'\ud83d\udccf', 2598 'strawberry':'\ud83c\udf53', 2599 'stuck_out_tongue':'\ud83d\ude1b', 2600 'stuck_out_tongue_closed_eyes':'\ud83d\ude1d', 2601 'stuck_out_tongue_winking_eye':'\ud83d\ude1c', 2602 'studio_microphone':'\ud83c\udf99', 2603 'stuffed_flatbread':'\ud83e\udd59', 2604 'sun_behind_large_cloud':'\ud83c\udf25', 2605 'sun_behind_rain_cloud':'\ud83c\udf26', 2606 'sun_behind_small_cloud':'\ud83c\udf24', 2607 'sun_with_face':'\ud83c\udf1e', 2608 'sunflower':'\ud83c\udf3b', 2609 'sunglasses':'\ud83d\ude0e', 2610 'sunny':'\u2600\ufe0f', 2611 'sunrise':'\ud83c\udf05', 2612 'sunrise_over_mountains':'\ud83c\udf04', 2613 'surfing_man':'\ud83c\udfc4', 2614 'surfing_woman':'\ud83c\udfc4‍\u2640\ufe0f', 2615 'sushi':'\ud83c\udf63', 2616 'suspension_railway':'\ud83d\ude9f', 2617 'sweat':'\ud83d\ude13', 2618 'sweat_drops':'\ud83d\udca6', 2619 'sweat_smile':'\ud83d\ude05', 2620 'sweet_potato':'\ud83c\udf60', 2621 'swimming_man':'\ud83c\udfca', 2622 'swimming_woman':'\ud83c\udfca‍\u2640\ufe0f', 2623 'symbols':'\ud83d\udd23', 2624 'synagogue':'\ud83d\udd4d', 2625 'syringe':'\ud83d\udc89', 2626 'taco':'\ud83c\udf2e', 2627 'tada':'\ud83c\udf89', 2628 'tanabata_tree':'\ud83c\udf8b', 2629 'taurus':'\u2649\ufe0f', 2630 'taxi':'\ud83d\ude95', 2631 'tea':'\ud83c\udf75', 2632 'telephone_receiver':'\ud83d\udcde', 2633 'telescope':'\ud83d\udd2d', 2634 'tennis':'\ud83c\udfbe', 2635 'tent':'\u26fa\ufe0f', 2636 'thermometer':'\ud83c\udf21', 2637 'thinking':'\ud83e\udd14', 2638 'thought_balloon':'\ud83d\udcad', 2639 'ticket':'\ud83c\udfab', 2640 'tickets':'\ud83c\udf9f', 2641 'tiger':'\ud83d\udc2f', 2642 'tiger2':'\ud83d\udc05', 2643 'timer_clock':'\u23f2', 2644 'tipping_hand_man':'\ud83d\udc81‍\u2642\ufe0f', 2645 'tired_face':'\ud83d\ude2b', 2646 'tm':'\u2122\ufe0f', 2647 'toilet':'\ud83d\udebd', 2648 'tokyo_tower':'\ud83d\uddfc', 2649 'tomato':'\ud83c\udf45', 2650 'tongue':'\ud83d\udc45', 2651 'top':'\ud83d\udd1d', 2652 'tophat':'\ud83c\udfa9', 2653 'tornado':'\ud83c\udf2a', 2654 'trackball':'\ud83d\uddb2', 2655 'tractor':'\ud83d\ude9c', 2656 'traffic_light':'\ud83d\udea5', 2657 'train':'\ud83d\ude8b', 2658 'train2':'\ud83d\ude86', 2659 'tram':'\ud83d\ude8a', 2660 'triangular_flag_on_post':'\ud83d\udea9', 2661 'triangular_ruler':'\ud83d\udcd0', 2662 'trident':'\ud83d\udd31', 2663 'triumph':'\ud83d\ude24', 2664 'trolleybus':'\ud83d\ude8e', 2665 'trophy':'\ud83c\udfc6', 2666 'tropical_drink':'\ud83c\udf79', 2667 'tropical_fish':'\ud83d\udc20', 2668 'truck':'\ud83d\ude9a', 2669 'trumpet':'\ud83c\udfba', 2670 'tulip':'\ud83c\udf37', 2671 'tumbler_glass':'\ud83e\udd43', 2672 'turkey':'\ud83e\udd83', 2673 'turtle':'\ud83d\udc22', 2674 'tv':'\ud83d\udcfa', 2675 'twisted_rightwards_arrows':'\ud83d\udd00', 2676 'two_hearts':'\ud83d\udc95', 2677 'two_men_holding_hands':'\ud83d\udc6c', 2678 'two_women_holding_hands':'\ud83d\udc6d', 2679 'u5272':'\ud83c\ude39', 2680 'u5408':'\ud83c\ude34', 2681 'u55b6':'\ud83c\ude3a', 2682 'u6307':'\ud83c\ude2f\ufe0f', 2683 'u6708':'\ud83c\ude37\ufe0f', 2684 'u6709':'\ud83c\ude36', 2685 'u6e80':'\ud83c\ude35', 2686 'u7121':'\ud83c\ude1a\ufe0f', 2687 'u7533':'\ud83c\ude38', 2688 'u7981':'\ud83c\ude32', 2689 'u7a7a':'\ud83c\ude33', 2690 'umbrella':'\u2614\ufe0f', 2691 'unamused':'\ud83d\ude12', 2692 'underage':'\ud83d\udd1e', 2693 'unicorn':'\ud83e\udd84', 2694 'unlock':'\ud83d\udd13', 2695 'up':'\ud83c\udd99', 2696 'upside_down_face':'\ud83d\ude43', 2697 'v':'\u270c\ufe0f', 2698 'vertical_traffic_light':'\ud83d\udea6', 2699 'vhs':'\ud83d\udcfc', 2700 'vibration_mode':'\ud83d\udcf3', 2701 'video_camera':'\ud83d\udcf9', 2702 'video_game':'\ud83c\udfae', 2703 'violin':'\ud83c\udfbb', 2704 'virgo':'\u264d\ufe0f', 2705 'volcano':'\ud83c\udf0b', 2706 'volleyball':'\ud83c\udfd0', 2707 'vs':'\ud83c\udd9a', 2708 'vulcan_salute':'\ud83d\udd96', 2709 'walking_man':'\ud83d\udeb6', 2710 'walking_woman':'\ud83d\udeb6‍\u2640\ufe0f', 2711 'waning_crescent_moon':'\ud83c\udf18', 2712 'waning_gibbous_moon':'\ud83c\udf16', 2713 'warning':'\u26a0\ufe0f', 2714 'wastebasket':'\ud83d\uddd1', 2715 'watch':'\u231a\ufe0f', 2716 'water_buffalo':'\ud83d\udc03', 2717 'watermelon':'\ud83c\udf49', 2718 'wave':'\ud83d\udc4b', 2719 'wavy_dash':'\u3030\ufe0f', 2720 'waxing_crescent_moon':'\ud83c\udf12', 2721 'wc':'\ud83d\udebe', 2722 'weary':'\ud83d\ude29', 2723 'wedding':'\ud83d\udc92', 2724 'weight_lifting_man':'\ud83c\udfcb\ufe0f', 2725 'weight_lifting_woman':'\ud83c\udfcb\ufe0f‍\u2640\ufe0f', 2726 'whale':'\ud83d\udc33', 2727 'whale2':'\ud83d\udc0b', 2728 'wheel_of_dharma':'\u2638\ufe0f', 2729 'wheelchair':'\u267f\ufe0f', 2730 'white_check_mark':'\u2705', 2731 'white_circle':'\u26aa\ufe0f', 2732 'white_flag':'\ud83c\udff3\ufe0f', 2733 'white_flower':'\ud83d\udcae', 2734 'white_large_square':'\u2b1c\ufe0f', 2735 'white_medium_small_square':'\u25fd\ufe0f', 2736 'white_medium_square':'\u25fb\ufe0f', 2737 'white_small_square':'\u25ab\ufe0f', 2738 'white_square_button':'\ud83d\udd33', 2739 'wilted_flower':'\ud83e\udd40', 2740 'wind_chime':'\ud83c\udf90', 2741 'wind_face':'\ud83c\udf2c', 2742 'wine_glass':'\ud83c\udf77', 2743 'wink':'\ud83d\ude09', 2744 'wolf':'\ud83d\udc3a', 2745 'woman':'\ud83d\udc69', 2746 'woman_artist':'\ud83d\udc69‍\ud83c\udfa8', 2747 'woman_astronaut':'\ud83d\udc69‍\ud83d\ude80', 2748 'woman_cartwheeling':'\ud83e\udd38‍\u2640\ufe0f', 2749 'woman_cook':'\ud83d\udc69‍\ud83c\udf73', 2750 'woman_facepalming':'\ud83e\udd26‍\u2640\ufe0f', 2751 'woman_factory_worker':'\ud83d\udc69‍\ud83c\udfed', 2752 'woman_farmer':'\ud83d\udc69‍\ud83c\udf3e', 2753 'woman_firefighter':'\ud83d\udc69‍\ud83d\ude92', 2754 'woman_health_worker':'\ud83d\udc69‍\u2695\ufe0f', 2755 'woman_judge':'\ud83d\udc69‍\u2696\ufe0f', 2756 'woman_juggling':'\ud83e\udd39‍\u2640\ufe0f', 2757 'woman_mechanic':'\ud83d\udc69‍\ud83d\udd27', 2758 'woman_office_worker':'\ud83d\udc69‍\ud83d\udcbc', 2759 'woman_pilot':'\ud83d\udc69‍\u2708\ufe0f', 2760 'woman_playing_handball':'\ud83e\udd3e‍\u2640\ufe0f', 2761 'woman_playing_water_polo':'\ud83e\udd3d‍\u2640\ufe0f', 2762 'woman_scientist':'\ud83d\udc69‍\ud83d\udd2c', 2763 'woman_shrugging':'\ud83e\udd37‍\u2640\ufe0f', 2764 'woman_singer':'\ud83d\udc69‍\ud83c\udfa4', 2765 'woman_student':'\ud83d\udc69‍\ud83c\udf93', 2766 'woman_teacher':'\ud83d\udc69‍\ud83c\udfeb', 2767 'woman_technologist':'\ud83d\udc69‍\ud83d\udcbb', 2768 'woman_with_turban':'\ud83d\udc73‍\u2640\ufe0f', 2769 'womans_clothes':'\ud83d\udc5a', 2770 'womans_hat':'\ud83d\udc52', 2771 'women_wrestling':'\ud83e\udd3c‍\u2640\ufe0f', 2772 'womens':'\ud83d\udeba', 2773 'world_map':'\ud83d\uddfa', 2774 'worried':'\ud83d\ude1f', 2775 'wrench':'\ud83d\udd27', 2776 'writing_hand':'\u270d\ufe0f', 2777 'x':'\u274c', 2778 'yellow_heart':'\ud83d\udc9b', 2779 'yen':'\ud83d\udcb4', 2780 'yin_yang':'\u262f\ufe0f', 2781 'yum':'\ud83d\ude0b', 2782 'zap':'\u26a1\ufe0f', 2783 'zipper_mouth_face':'\ud83e\udd10', 2784 'zzz':'\ud83d\udca4', 2785 2786 /* special emojis :P */ 2787 'octocat': '<img alt=":octocat:" height="20" width="20" align="absmiddle" src="https://assets-cdn.github.com/images/icons/emoji/octocat.png">', 2788 '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>' 2789 }; 2790 2791 /** 2792 * Created by Estevao on 31-05-2015. 2793 */ 2794 2795 /** 2796 * Showdown Converter class 2797 * @class 2798 * @param {object} [converterOptions] 2799 * @returns {Converter} 2800 */ 2801 showdown.Converter = function (converterOptions) { 2802 'use strict'; 2803 2804 var 2805 /** 2806 * Options used by this converter 2807 * @private 2808 * @type {{}} 2809 */ 2810 options = {}, 2811 2812 /** 2813 * Language extensions used by this converter 2814 * @private 2815 * @type {Array} 2816 */ 2817 langExtensions = [], 2818 2819 /** 2820 * Output modifiers extensions used by this converter 2821 * @private 2822 * @type {Array} 2823 */ 2824 outputModifiers = [], 2825 2826 /** 2827 * Event listeners 2828 * @private 2829 * @type {{}} 2830 */ 2831 listeners = {}, 2832 2833 /** 2834 * The flavor set in this converter 2835 */ 2836 setConvFlavor = setFlavor, 2837 2838 /** 2839 * Metadata of the document 2840 * @type {{parsed: {}, raw: string, format: string}} 2841 */ 2842 metadata = { 2843 parsed: {}, 2844 raw: '', 2845 format: '' 2846 }; 2847 2848 _constructor(); 2849 2850 /** 2851 * Converter constructor 2852 * @private 2853 */ 2854 function _constructor () { 2855 converterOptions = converterOptions || {}; 2856 2857 for (var gOpt in globalOptions) { 2858 if (globalOptions.hasOwnProperty(gOpt)) { 2859 options[gOpt] = globalOptions[gOpt]; 2860 } 2861 } 2862 2863 // Merge options 2864 if (typeof converterOptions === 'object') { 2865 for (var opt in converterOptions) { 2866 if (converterOptions.hasOwnProperty(opt)) { 2867 options[opt] = converterOptions[opt]; 2868 } 2869 } 2870 } else { 2871 throw Error('Converter expects the passed parameter to be an object, but ' + typeof converterOptions + 2872 ' was passed instead.'); 2873 } 2874 2875 if (options.extensions) { 2876 showdown.helper.forEach(options.extensions, _parseExtension); 2877 } 2878 } 2879 2880 /** 2881 * Parse extension 2882 * @param {*} ext 2883 * @param {string} [name=''] 2884 * @private 2885 */ 2886 function _parseExtension (ext, name) { 2887 2888 name = name || null; 2889 // If it's a string, the extension was previously loaded 2890 if (showdown.helper.isString(ext)) { 2891 ext = showdown.helper.stdExtName(ext); 2892 name = ext; 2893 2894 // LEGACY_SUPPORT CODE 2895 if (showdown.extensions[ext]) { 2896 console.warn('DEPRECATION WARNING: ' + ext + ' is an old extension that uses a deprecated loading method.' + 2897 'Please inform the developer that the extension should be updated!'); 2898 legacyExtensionLoading(showdown.extensions[ext], ext); 2899 return; 2900 // END LEGACY SUPPORT CODE 2901 2902 } else if (!showdown.helper.isUndefined(extensions[ext])) { 2903 ext = extensions[ext]; 2904 2905 } else { 2906 throw Error('Extension "' + ext + '" could not be loaded. It was either not found or is not a valid extension.'); 2907 } 2908 } 2909 2910 if (typeof ext === 'function') { 2911 ext = ext(); 2912 } 2913 2914 if (!showdown.helper.isArray(ext)) { 2915 ext = [ext]; 2916 } 2917 2918 var validExt = validate(ext, name); 2919 if (!validExt.valid) { 2920 throw Error(validExt.error); 2921 } 2922 2923 for (var i = 0; i < ext.length; ++i) { 2924 switch (ext[i].type) { 2925 2926 case 'lang': 2927 langExtensions.push(ext[i]); 2928 break; 2929 2930 case 'output': 2931 outputModifiers.push(ext[i]); 2932 break; 2933 } 2934 if (ext[i].hasOwnProperty('listeners')) { 2935 for (var ln in ext[i].listeners) { 2936 if (ext[i].listeners.hasOwnProperty(ln)) { 2937 listen(ln, ext[i].listeners[ln]); 2938 } 2939 } 2940 } 2941 } 2942 2943 } 2944 2945 /** 2946 * LEGACY_SUPPORT 2947 * @param {*} ext 2948 * @param {string} name 2949 */ 2950 function legacyExtensionLoading (ext, name) { 2951 if (typeof ext === 'function') { 2952 ext = ext(new showdown.Converter()); 2953 } 2954 if (!showdown.helper.isArray(ext)) { 2955 ext = [ext]; 2956 } 2957 var valid = validate(ext, name); 2958 2959 if (!valid.valid) { 2960 throw Error(valid.error); 2961 } 2962 2963 for (var i = 0; i < ext.length; ++i) { 2964 switch (ext[i].type) { 2965 case 'lang': 2966 langExtensions.push(ext[i]); 2967 break; 2968 case 'output': 2969 outputModifiers.push(ext[i]); 2970 break; 2971 default:// should never reach here 2972 throw Error('Extension loader error: Type unrecognized!!!'); 2973 } 2974 } 2975 } 2976 2977 /** 2978 * Listen to an event 2979 * @param {string} name 2980 * @param {function} callback 2981 */ 2982 function listen (name, callback) { 2983 if (!showdown.helper.isString(name)) { 2984 throw Error('Invalid argument in converter.listen() method: name must be a string, but ' + typeof name + ' given'); 2985 } 2986 2987 if (typeof callback !== 'function') { 2988 throw Error('Invalid argument in converter.listen() method: callback must be a function, but ' + typeof callback + ' given'); 2989 } 2990 2991 if (!listeners.hasOwnProperty(name)) { 2992 listeners[name] = []; 2993 } 2994 listeners[name].push(callback); 2995 } 2996 2997 function rTrimInputText (text) { 2998 var rsp = text.match(/^\s*/)[0].length, 2999 rgx = new RegExp('^\\s{0,' + rsp + '}', 'gm'); 3000 return text.replace(rgx, ''); 3001 } 3002 3003 /** 3004 * Dispatch an event 3005 * @private 3006 * @param {string} evtName Event name 3007 * @param {string} text Text 3008 * @param {{}} options Converter Options 3009 * @param {{}} globals 3010 * @returns {string} 3011 */ 3012 this._dispatch = function dispatch (evtName, text, options, globals) { 3013 if (listeners.hasOwnProperty(evtName)) { 3014 for (var ei = 0; ei < listeners[evtName].length; ++ei) { 3015 var nText = listeners[evtName][ei](evtName, text, this, options, globals); 3016 if (nText && typeof nText !== 'undefined') { 3017 text = nText; 3018 } 3019 } 3020 } 3021 return text; 3022 }; 3023 3024 /** 3025 * Listen to an event 3026 * @param {string} name 3027 * @param {function} callback 3028 * @returns {showdown.Converter} 3029 */ 3030 this.listen = function (name, callback) { 3031 listen(name, callback); 3032 return this; 3033 }; 3034 3035 /** 3036 * Converts a markdown string into HTML 3037 * @param {string} text 3038 * @returns {*} 3039 */ 3040 this.makeHtml = function (text) { 3041 //check if text is not falsy 3042 if (!text) { 3043 return text; 3044 } 3045 3046 var globals = { 3047 gHtmlBlocks: [], 3048 gHtmlMdBlocks: [], 3049 gHtmlSpans: [], 3050 gUrls: {}, 3051 gTitles: {}, 3052 gDimensions: {}, 3053 gListLevel: 0, 3054 hashLinkCounts: {}, 3055 langExtensions: langExtensions, 3056 outputModifiers: outputModifiers, 3057 converter: this, 3058 ghCodeBlocks: [], 3059 metadata: { 3060 parsed: {}, 3061 raw: '', 3062 format: '' 3063 } 3064 }; 3065 3066 // This lets us use ¨ trema as an escape char to avoid md5 hashes 3067 // The choice of character is arbitrary; anything that isn't 3068 // magic in Markdown will work. 3069 text = text.replace(/¨/g, '¨T'); 3070 3071 // Replace $ with ¨D 3072 // RegExp interprets $ as a special character 3073 // when it's in a replacement string 3074 text = text.replace(/\$/g, '¨D'); 3075 3076 // Standardize line endings 3077 text = text.replace(/\r\n/g, '\n'); // DOS to Unix 3078 text = text.replace(/\r/g, '\n'); // Mac to Unix 3079 3080 // Stardardize line spaces 3081 text = text.replace(/\u00A0/g, ' '); 3082 3083 if (options.smartIndentationFix) { 3084 text = rTrimInputText(text); 3085 } 3086 3087 // Make sure text begins and ends with a couple of newlines: 3088 text = '\n\n' + text + '\n\n'; 3089 3090 // detab 3091 text = showdown.subParser('detab')(text, options, globals); 3092 3093 /** 3094 * Strip any lines consisting only of spaces and tabs. 3095 * This makes subsequent regexs easier to write, because we can 3096 * match consecutive blank lines with /\n+/ instead of something 3097 * contorted like /[ \t]*\n+/ 3098 */ 3099 text = text.replace(/^[ \t]+$/mg, ''); 3100 3101 //run languageExtensions 3102 showdown.helper.forEach(langExtensions, function (ext) { 3103 text = showdown.subParser('runExtension')(ext, text, options, globals); 3104 }); 3105 3106 // run the sub parsers 3107 text = showdown.subParser('metadata')(text, options, globals); 3108 text = showdown.subParser('hashPreCodeTags')(text, options, globals); 3109 text = showdown.subParser('githubCodeBlocks')(text, options, globals); 3110 text = showdown.subParser('hashHTMLBlocks')(text, options, globals); 3111 text = showdown.subParser('hashCodeTags')(text, options, globals); 3112 text = showdown.subParser('stripLinkDefinitions')(text, options, globals); 3113 text = showdown.subParser('blockGamut')(text, options, globals); 3114 text = showdown.subParser('unhashHTMLSpans')(text, options, globals); 3115 text = showdown.subParser('unescapeSpecialChars')(text, options, globals); 3116 3117 // attacklab: Restore dollar signs 3118 text = text.replace(/¨D/g, '$$'); 3119 3120 // attacklab: Restore tremas 3121 text = text.replace(/¨T/g, '¨'); 3122 3123 // render a complete html document instead of a partial if the option is enabled 3124 text = showdown.subParser('completeHTMLDocument')(text, options, globals); 3125 3126 // Run output modifiers 3127 showdown.helper.forEach(outputModifiers, function (ext) { 3128 text = showdown.subParser('runExtension')(ext, text, options, globals); 3129 }); 3130 3131 // update metadata 3132 metadata = globals.metadata; 3133 return text; 3134 }; 3135 3136 /** 3137 * Converts an HTML string into a markdown string 3138 * @param src 3139 * @param [HTMLParser] A WHATWG DOM and HTML parser, such as JSDOM. If none is supplied, window.document will be used. 3140 * @returns {string} 3141 */ 3142 this.makeMarkdown = this.makeMd = function (src, HTMLParser) { 3143 3144 // replace \r\n with \n 3145 src = src.replace(/\r\n/g, '\n'); 3146 src = src.replace(/\r/g, '\n'); // old macs 3147 3148 // due to an edge case, we need to find this: > < 3149 // to prevent removing of non silent white spaces 3150 // ex: <em>this is</em> <strong>sparta</strong> 3151 src = src.replace(/>[ \t]+</, '>¨NBSP;<'); 3152 3153 if (!HTMLParser) { 3154 if (window && window.document) { 3155 HTMLParser = window.document; 3156 } else { 3157 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'); 3158 } 3159 } 3160 3161 var doc = HTMLParser.createElement('div'); 3162 doc.innerHTML = src; 3163 3164 var globals = { 3165 preList: substitutePreCodeTags(doc) 3166 }; 3167 3168 // remove all newlines and collapse spaces 3169 clean(doc); 3170 3171 // some stuff, like accidental reference links must now be escaped 3172 // TODO 3173 // doc.innerHTML = doc.innerHTML.replace(/\[[\S\t ]]/); 3174 3175 var nodes = doc.childNodes, 3176 mdDoc = ''; 3177 3178 for (var i = 0; i < nodes.length; i++) { 3179 mdDoc += showdown.subParser('makeMarkdown.node')(nodes[i], globals); 3180 } 3181 3182 function clean (node) { 3183 for (var n = 0; n < node.childNodes.length; ++n) { 3184 var child = node.childNodes[n]; 3185 if (child.nodeType === 3) { 3186 if (!/\S/.test(child.nodeValue)) { 3187 node.removeChild(child); 3188 --n; 3189 } else { 3190 child.nodeValue = child.nodeValue.split('\n').join(' '); 3191 child.nodeValue = child.nodeValue.replace(/(\s)+/g, '$1'); 3192 } 3193 } else if (child.nodeType === 1) { 3194 clean(child); 3195 } 3196 } 3197 } 3198 3199 // find all pre tags and replace contents with placeholder 3200 // we need this so that we can remove all indentation from html 3201 // to ease up parsing 3202 function substitutePreCodeTags (doc) { 3203 3204 var pres = doc.querySelectorAll('pre'), 3205 presPH = []; 3206 3207 for (var i = 0; i < pres.length; ++i) { 3208 3209 if (pres[i].childElementCount === 1 && pres[i].firstChild.tagName.toLowerCase() === 'code') { 3210 var content = pres[i].firstChild.innerHTML.trim(), 3211 language = pres[i].firstChild.getAttribute('data-language') || ''; 3212 3213 // if data-language attribute is not defined, then we look for class language-* 3214 if (language === '') { 3215 var classes = pres[i].firstChild.className.split(' '); 3216 for (var c = 0; c < classes.length; ++c) { 3217 var matches = classes[c].match(/^language-(.+)$/); 3218 if (matches !== null) { 3219 language = matches[1]; 3220 break; 3221 } 3222 } 3223 } 3224 3225 // unescape html entities in content 3226 content = showdown.helper.unescapeHTMLEntities(content); 3227 3228 presPH.push(content); 3229 pres[i].outerHTML = '<precode language="' + language + '" precodenum="' + i.toString() + '"></precode>'; 3230 } else { 3231 presPH.push(pres[i].innerHTML); 3232 pres[i].innerHTML = ''; 3233 pres[i].setAttribute('prenum', i.toString()); 3234 } 3235 } 3236 return presPH; 3237 } 3238 3239 return mdDoc; 3240 }; 3241 3242 /** 3243 * Set an option of this Converter instance 3244 * @param {string} key 3245 * @param {*} value 3246 */ 3247 this.setOption = function (key, value) { 3248 options[key] = value; 3249 }; 3250 3251 /** 3252 * Get the option of this Converter instance 3253 * @param {string} key 3254 * @returns {*} 3255 */ 3256 this.getOption = function (key) { 3257 return options[key]; 3258 }; 3259 3260 /** 3261 * Get the options of this Converter instance 3262 * @returns {{}} 3263 */ 3264 this.getOptions = function () { 3265 return options; 3266 }; 3267 3268 /** 3269 * Add extension to THIS converter 3270 * @param {{}} extension 3271 * @param {string} [name=null] 3272 */ 3273 this.addExtension = function (extension, name) { 3274 name = name || null; 3275 _parseExtension(extension, name); 3276 }; 3277 3278 /** 3279 * Use a global registered extension with THIS converter 3280 * @param {string} extensionName Name of the previously registered extension 3281 */ 3282 this.useExtension = function (extensionName) { 3283 _parseExtension(extensionName); 3284 }; 3285 3286 /** 3287 * Set the flavor THIS converter should use 3288 * @param {string} name 3289 */ 3290 this.setFlavor = function (name) { 3291 if (!flavor.hasOwnProperty(name)) { 3292 throw Error(name + ' flavor was not found'); 3293 } 3294 var preset = flavor[name]; 3295 setConvFlavor = name; 3296 for (var option in preset) { 3297 if (preset.hasOwnProperty(option)) { 3298 options[option] = preset[option]; 3299 } 3300 } 3301 }; 3302 3303 /** 3304 * Get the currently set flavor of this converter 3305 * @returns {string} 3306 */ 3307 this.getFlavor = function () { 3308 return setConvFlavor; 3309 }; 3310 3311 /** 3312 * Remove an extension from THIS converter. 3313 * Note: This is a costly operation. It's better to initialize a new converter 3314 * and specify the extensions you wish to use 3315 * @param {Array} extension 3316 */ 3317 this.removeExtension = function (extension) { 3318 if (!showdown.helper.isArray(extension)) { 3319 extension = [extension]; 3320 } 3321 for (var a = 0; a < extension.length; ++a) { 3322 var ext = extension[a]; 3323 for (var i = 0; i < langExtensions.length; ++i) { 3324 if (langExtensions[i] === ext) { 3325 langExtensions[i].splice(i, 1); 3326 } 3327 } 3328 for (var ii = 0; ii < outputModifiers.length; ++i) { 3329 if (outputModifiers[ii] === ext) { 3330 outputModifiers[ii].splice(i, 1); 3331 } 3332 } 3333 } 3334 }; 3335 3336 /** 3337 * Get all extension of THIS converter 3338 * @returns {{language: Array, output: Array}} 3339 */ 3340 this.getAllExtensions = function () { 3341 return { 3342 language: langExtensions, 3343 output: outputModifiers 3344 }; 3345 }; 3346 3347 /** 3348 * Get the metadata of the previously parsed document 3349 * @param raw 3350 * @returns {string|{}} 3351 */ 3352 this.getMetadata = function (raw) { 3353 if (raw) { 3354 return metadata.raw; 3355 } else { 3356 return metadata.parsed; 3357 } 3358 }; 3359 3360 /** 3361 * Get the metadata format of the previously parsed document 3362 * @returns {string} 3363 */ 3364 this.getMetadataFormat = function () { 3365 return metadata.format; 3366 }; 3367 3368 /** 3369 * Private: set a single key, value metadata pair 3370 * @param {string} key 3371 * @param {string} value 3372 */ 3373 this._setMetadataPair = function (key, value) { 3374 metadata.parsed[key] = value; 3375 }; 3376 3377 /** 3378 * Private: set metadata format 3379 * @param {string} format 3380 */ 3381 this._setMetadataFormat = function (format) { 3382 metadata.format = format; 3383 }; 3384 3385 /** 3386 * Private: set metadata raw text 3387 * @param {string} raw 3388 */ 3389 this._setMetadataRaw = function (raw) { 3390 metadata.raw = raw; 3391 }; 3392 }; 3393 3394 /** 3395 * Turn Markdown link shortcuts into XHTML <a> tags. 3396 */ 3397 showdown.subParser('anchors', function (text, options, globals) { 3398 'use strict'; 3399 3400 text = globals.converter._dispatch('anchors.before', text, options, globals); 3401 3402 var writeAnchorTag = function (wholeMatch, linkText, linkId, url, m5, m6, title) { 3403 if (showdown.helper.isUndefined(title)) { 3404 title = ''; 3405 } 3406 linkId = linkId.toLowerCase(); 3407 3408 // Special case for explicit empty url 3409 if (wholeMatch.search(/\(<?\s*>? ?(['"].*['"])?\)$/m) > -1) { 3410 url = ''; 3411 } else if (!url) { 3412 if (!linkId) { 3413 // lower-case and turn embedded newlines into spaces 3414 linkId = linkText.toLowerCase().replace(/ ?\n/g, ' '); 3415 } 3416 url = '#' + linkId; 3417 3418 if (!showdown.helper.isUndefined(globals.gUrls[linkId])) { 3419 url = globals.gUrls[linkId]; 3420 if (!showdown.helper.isUndefined(globals.gTitles[linkId])) { 3421 title = globals.gTitles[linkId]; 3422 } 3423 } else { 3424 return wholeMatch; 3425 } 3426 } 3427 3428 //url = showdown.helper.escapeCharacters(url, '*_', false); // replaced line to improve performance 3429 url = url.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback); 3430 3431 var result = '<a href="' + url + '"'; 3432 3433 if (title !== '' && title !== null) { 3434 title = title.replace(/"/g, '"'); 3435 //title = showdown.helper.escapeCharacters(title, '*_', false); // replaced line to improve performance 3436 title = title.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback); 3437 result += ' title="' + title + '"'; 3438 } 3439 3440 // optionLinksInNewWindow only applies 3441 // to external links. Hash links (#) open in same page 3442 if (options.openLinksInNewWindow && !/^#/.test(url)) { 3443 // escaped _ 3444 result += ' rel="noopener noreferrer" target="¨E95Eblank"'; 3445 } 3446 3447 result += '>' + linkText + '</a>'; 3448 3449 return result; 3450 }; 3451 3452 // First, handle reference-style links: [link text] [id] 3453 text = text.replace(/\[((?:\[[^\]]*]|[^\[\]])*)] ?(?:\n *)?\[(.*?)]()()()()/g, writeAnchorTag); 3454 3455 // Next, inline-style links: [link text](url "optional title") 3456 // cases with crazy urls like ./image/cat1).png 3457 text = text.replace(/\[((?:\[[^\]]*]|[^\[\]])*)]()[ \t]*\([ \t]?<([^>]*)>(?:[ \t]*((["'])([^"]*?)\5))?[ \t]?\)/g, 3458 writeAnchorTag); 3459 3460 // normal cases 3461 text = text.replace(/\[((?:\[[^\]]*]|[^\[\]])*)]()[ \t]*\([ \t]?<?([\S]+?(?:\([\S]*?\)[\S]*?)?)>?(?:[ \t]*((["'])([^"]*?)\5))?[ \t]?\)/g, 3462 writeAnchorTag); 3463 3464 // handle reference-style shortcuts: [link text] 3465 // These must come last in case you've also got [link test][1] 3466 // or [link test](/foo) 3467 text = text.replace(/\[([^\[\]]+)]()()()()()/g, writeAnchorTag); 3468 3469 // Lastly handle GithubMentions if option is enabled 3470 if (options.ghMentions) { 3471 text = text.replace(/(^|\s)(\\)?(@([a-z\d]+(?:[a-z\d.-]+?[a-z\d]+)*))/gmi, function (wm, st, escape, mentions, username) { 3472 if (escape === '\\') { 3473 return st + mentions; 3474 } 3475 3476 //check if options.ghMentionsLink is a string 3477 if (!showdown.helper.isString(options.ghMentionsLink)) { 3478 throw new Error('ghMentionsLink option must be a string'); 3479 } 3480 var lnk = options.ghMentionsLink.replace(/\{u}/g, username), 3481 target = ''; 3482 if (options.openLinksInNewWindow) { 3483 target = ' rel="noopener noreferrer" target="¨E95Eblank"'; 3484 } 3485 return st + '<a href="' + lnk + '"' + target + '>' + mentions + '</a>'; 3486 }); 3487 } 3488 3489 text = globals.converter._dispatch('anchors.after', text, options, globals); 3490 return text; 3491 }); 3492 3493 // url allowed chars [a-z\d_.~:/?#[]@!$&'()*+,;=-] 3494 3495 var simpleURLRegex = /([*~_]+|\b)(((https?|ftp|dict):\/\/|www\.)[^'">\s]+?\.[^'">\s]+?)()(\1)?(?=\s|$)(?!["<>])/gi, 3496 simpleURLRegex2 = /([*~_]+|\b)(((https?|ftp|dict):\/\/|www\.)[^'">\s]+\.[^'">\s]+?)([.!?,()\[\]])?(\1)?(?=\s|$)(?!["<>])/gi, 3497 delimUrlRegex = /()<(((https?|ftp|dict):\/\/|www\.)[^'">\s]+)()>()/gi, 3498 simpleMailRegex = /(^|\s)(?:mailto:)?([A-Za-z0-9!#$%&'*+-/=?^_`{|}~.]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)(?=$|\s)/gmi, 3499 delimMailRegex = /<()(?:mailto:)?([-.\w]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi, 3500 3501 replaceLink = function (options) { 3502 'use strict'; 3503 return function (wm, leadingMagicChars, link, m2, m3, trailingPunctuation, trailingMagicChars) { 3504 link = link.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback); 3505 var lnkTxt = link, 3506 append = '', 3507 target = '', 3508 lmc = leadingMagicChars || '', 3509 tmc = trailingMagicChars || ''; 3510 if (/^www\./i.test(link)) { 3511 link = link.replace(/^www\./i, 'http://www.'); 3512 } 3513 if (options.excludeTrailingPunctuationFromURLs && trailingPunctuation) { 3514 append = trailingPunctuation; 3515 } 3516 if (options.openLinksInNewWindow) { 3517 target = ' rel="noopener noreferrer" target="¨E95Eblank"'; 3518 } 3519 return lmc + '<a href="' + link + '"' + target + '>' + lnkTxt + '</a>' + append + tmc; 3520 }; 3521 }, 3522 3523 replaceMail = function (options, globals) { 3524 'use strict'; 3525 return function (wholeMatch, b, mail) { 3526 var href = 'mailto:'; 3527 b = b || ''; 3528 mail = showdown.subParser('unescapeSpecialChars')(mail, options, globals); 3529 if (options.encodeEmails) { 3530 href = showdown.helper.encodeEmailAddress(href + mail); 3531 mail = showdown.helper.encodeEmailAddress(mail); 3532 } else { 3533 href = href + mail; 3534 } 3535 return b + '<a href="' + href + '">' + mail + '</a>'; 3536 }; 3537 }; 3538 3539 showdown.subParser('autoLinks', function (text, options, globals) { 3540 'use strict'; 3541 3542 text = globals.converter._dispatch('autoLinks.before', text, options, globals); 3543 3544 text = text.replace(delimUrlRegex, replaceLink(options)); 3545 text = text.replace(delimMailRegex, replaceMail(options, globals)); 3546 3547 text = globals.converter._dispatch('autoLinks.after', text, options, globals); 3548 3549 return text; 3550 }); 3551 3552 showdown.subParser('simplifiedAutoLinks', function (text, options, globals) { 3553 'use strict'; 3554 3555 if (!options.simplifiedAutoLink) { 3556 return text; 3557 } 3558 3559 text = globals.converter._dispatch('simplifiedAutoLinks.before', text, options, globals); 3560 3561 if (options.excludeTrailingPunctuationFromURLs) { 3562 text = text.replace(simpleURLRegex2, replaceLink(options)); 3563 } else { 3564 text = text.replace(simpleURLRegex, replaceLink(options)); 3565 } 3566 text = text.replace(simpleMailRegex, replaceMail(options, globals)); 3567 3568 text = globals.converter._dispatch('simplifiedAutoLinks.after', text, options, globals); 3569 3570 return text; 3571 }); 3572 3573 /** 3574 * These are all the transformations that form block-level 3575 * tags like paragraphs, headers, and list items. 3576 */ 3577 showdown.subParser('blockGamut', function (text, options, globals) { 3578 'use strict'; 3579 3580 text = globals.converter._dispatch('blockGamut.before', text, options, globals); 3581 3582 // we parse blockquotes first so that we can have headings and hrs 3583 // inside blockquotes 3584 text = showdown.subParser('blockQuotes')(text, options, globals); 3585 text = showdown.subParser('headers')(text, options, globals); 3586 3587 // Do Horizontal Rules: 3588 text = showdown.subParser('horizontalRule')(text, options, globals); 3589 3590 text = showdown.subParser('lists')(text, options, globals); 3591 text = showdown.subParser('codeBlocks')(text, options, globals); 3592 text = showdown.subParser('tables')(text, options, globals); 3593 3594 // We already ran _HashHTMLBlocks() before, in Markdown(), but that 3595 // was to escape raw HTML in the original Markdown source. This time, 3596 // we're escaping the markup we've just created, so that we don't wrap 3597 // <p> tags around block-level tags. 3598 text = showdown.subParser('hashHTMLBlocks')(text, options, globals); 3599 text = showdown.subParser('paragraphs')(text, options, globals); 3600 3601 text = globals.converter._dispatch('blockGamut.after', text, options, globals); 3602 3603 return text; 3604 }); 3605 3606 showdown.subParser('blockQuotes', function (text, options, globals) { 3607 'use strict'; 3608 3609 text = globals.converter._dispatch('blockQuotes.before', text, options, globals); 3610 3611 // add a couple extra lines after the text and endtext mark 3612 text = text + '\n\n'; 3613 3614 var rgx = /(^ {0,3}>[ \t]?.+\n(.+\n)*\n*)+/gm; 3615 3616 if (options.splitAdjacentBlockquotes) { 3617 rgx = /^ {0,3}>[\s\S]*?(?:\n\n)/gm; 3618 } 3619 3620 text = text.replace(rgx, function (bq) { 3621 // attacklab: hack around Konqueror 3.5.4 bug: 3622 // "----------bug".replace(/^-/g,"") == "bug" 3623 bq = bq.replace(/^[ \t]*>[ \t]?/gm, ''); // trim one level of quoting 3624 3625 // attacklab: clean up hack 3626 bq = bq.replace(/¨0/g, ''); 3627 3628 bq = bq.replace(/^[ \t]+$/gm, ''); // trim whitespace-only lines 3629 bq = showdown.subParser('githubCodeBlocks')(bq, options, globals); 3630 bq = showdown.subParser('blockGamut')(bq, options, globals); // recurse 3631 3632 bq = bq.replace(/(^|\n)/g, '$1 '); 3633 // These leading spaces screw with <pre> content, so we need to fix that: 3634 bq = bq.replace(/(\s*<pre>[^\r]+?<\/pre>)/gm, function (wholeMatch, m1) { 3635 var pre = m1; 3636 // attacklab: hack around Konqueror 3.5.4 bug: 3637 pre = pre.replace(/^ /mg, '¨0'); 3638 pre = pre.replace(/¨0/g, ''); 3639 return pre; 3640 }); 3641 3642 return showdown.subParser('hashBlock')('<blockquote>\n' + bq + '\n</blockquote>', options, globals); 3643 }); 3644 3645 text = globals.converter._dispatch('blockQuotes.after', text, options, globals); 3646 return text; 3647 }); 3648 3649 /** 3650 * Process Markdown `<pre><code>` blocks. 3651 */ 3652 showdown.subParser('codeBlocks', function (text, options, globals) { 3653 'use strict'; 3654 3655 text = globals.converter._dispatch('codeBlocks.before', text, options, globals); 3656 3657 // sentinel workarounds for lack of \A and \Z, safari\khtml bug 3658 text += '¨0'; 3659 3660 var pattern = /(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=¨0))/g; 3661 text = text.replace(pattern, function (wholeMatch, m1, m2) { 3662 var codeblock = m1, 3663 nextChar = m2, 3664 end = '\n'; 3665 3666 codeblock = showdown.subParser('outdent')(codeblock, options, globals); 3667 codeblock = showdown.subParser('encodeCode')(codeblock, options, globals); 3668 codeblock = showdown.subParser('detab')(codeblock, options, globals); 3669 codeblock = codeblock.replace(/^\n+/g, ''); // trim leading newlines 3670 codeblock = codeblock.replace(/\n+$/g, ''); // trim trailing newlines 3671 3672 if (options.omitExtraWLInCodeBlocks) { 3673 end = ''; 3674 } 3675 3676 codeblock = '<pre><code>' + codeblock + end + '</code></pre>'; 3677 3678 return showdown.subParser('hashBlock')(codeblock, options, globals) + nextChar; 3679 }); 3680 3681 // strip sentinel 3682 text = text.replace(/¨0/, ''); 3683 3684 text = globals.converter._dispatch('codeBlocks.after', text, options, globals); 3685 return text; 3686 }); 3687 3688 /** 3689 * 3690 * * Backtick quotes are used for <code></code> spans. 3691 * 3692 * * You can use multiple backticks as the delimiters if you want to 3693 * include literal backticks in the code span. So, this input: 3694 * 3695 * Just type ``foo `bar` baz`` at the prompt. 3696 * 3697 * Will translate to: 3698 * 3699 * <p>Just type <code>foo `bar` baz</code> at the prompt.</p> 3700 * 3701 * There's no arbitrary limit to the number of backticks you 3702 * can use as delimters. If you need three consecutive backticks 3703 * in your code, use four for delimiters, etc. 3704 * 3705 * * You can use spaces to get literal backticks at the edges: 3706 * 3707 * ... type `` `bar` `` ... 3708 * 3709 * Turns to: 3710 * 3711 * ... type <code>`bar`</code> ... 3712 */ 3713 showdown.subParser('codeSpans', function (text, options, globals) { 3714 'use strict'; 3715 3716 text = globals.converter._dispatch('codeSpans.before', text, options, globals); 3717 3718 if (typeof text === 'undefined') { 3719 text = ''; 3720 } 3721 text = text.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm, 3722 function (wholeMatch, m1, m2, m3) { 3723 var c = m3; 3724 c = c.replace(/^([ \t]*)/g, ''); // leading whitespace 3725 c = c.replace(/[ \t]*$/g, ''); // trailing whitespace 3726 c = showdown.subParser('encodeCode')(c, options, globals); 3727 c = m1 + '<code>' + c + '</code>'; 3728 c = showdown.subParser('hashHTMLSpans')(c, options, globals); 3729 return c; 3730 } 3731 ); 3732 3733 text = globals.converter._dispatch('codeSpans.after', text, options, globals); 3734 return text; 3735 }); 3736 3737 /** 3738 * Create a full HTML document from the processed markdown 3739 */ 3740 showdown.subParser('completeHTMLDocument', function (text, options, globals) { 3741 'use strict'; 3742 3743 if (!options.completeHTMLDocument) { 3744 return text; 3745 } 3746 3747 text = globals.converter._dispatch('completeHTMLDocument.before', text, options, globals); 3748 3749 var doctype = 'html', 3750 doctypeParsed = '<!DOCTYPE HTML>\n', 3751 title = '', 3752 charset = '<meta charset="utf-8">\n', 3753 lang = '', 3754 metadata = ''; 3755 3756 if (typeof globals.metadata.parsed.doctype !== 'undefined') { 3757 doctypeParsed = '<!DOCTYPE ' + globals.metadata.parsed.doctype + '>\n'; 3758 doctype = globals.metadata.parsed.doctype.toString().toLowerCase(); 3759 if (doctype === 'html' || doctype === 'html5') { 3760 charset = '<meta charset="utf-8">'; 3761 } 3762 } 3763 3764 for (var meta in globals.metadata.parsed) { 3765 if (globals.metadata.parsed.hasOwnProperty(meta)) { 3766 switch (meta.toLowerCase()) { 3767 case 'doctype': 3768 break; 3769 3770 case 'title': 3771 title = '<title>' + globals.metadata.parsed.title + '</title>\n'; 3772 break; 3773 3774 case 'charset': 3775 if (doctype === 'html' || doctype === 'html5') { 3776 charset = '<meta charset="' + globals.metadata.parsed.charset + '">\n'; 3777 } else { 3778 charset = '<meta name="charset" content="' + globals.metadata.parsed.charset + '">\n'; 3779 } 3780 break; 3781 3782 case 'language': 3783 case 'lang': 3784 lang = ' lang="' + globals.metadata.parsed[meta] + '"'; 3785 metadata += '<meta name="' + meta + '" content="' + globals.metadata.parsed[meta] + '">\n'; 3786 break; 3787 3788 default: 3789 metadata += '<meta name="' + meta + '" content="' + globals.metadata.parsed[meta] + '">\n'; 3790 } 3791 } 3792 } 3793 3794 text = doctypeParsed + '<html' + lang + '>\n<head>\n' + title + charset + metadata + '</head>\n<body>\n' + text.trim() + '\n</body>\n</html>'; 3795 3796 text = globals.converter._dispatch('completeHTMLDocument.after', text, options, globals); 3797 return text; 3798 }); 3799 3800 /** 3801 * Convert all tabs to spaces 3802 */ 3803 showdown.subParser('detab', function (text, options, globals) { 3804 'use strict'; 3805 text = globals.converter._dispatch('detab.before', text, options, globals); 3806 3807 // expand first n-1 tabs 3808 text = text.replace(/\t(?=\t)/g, ' '); // g_tab_width 3809 3810 // replace the nth with two sentinels 3811 text = text.replace(/\t/g, '¨A¨B'); 3812 3813 // use the sentinel to anchor our regex so it doesn't explode 3814 text = text.replace(/¨B(.+?)¨A/g, function (wholeMatch, m1) { 3815 var leadingText = m1, 3816 numSpaces = 4 - leadingText.length % 4; // g_tab_width 3817 3818 // there *must* be a better way to do this: 3819 for (var i = 0; i < numSpaces; i++) { 3820 leadingText += ' '; 3821 } 3822 3823 return leadingText; 3824 }); 3825 3826 // clean up sentinels 3827 text = text.replace(/¨A/g, ' '); // g_tab_width 3828 text = text.replace(/¨B/g, ''); 3829 3830 text = globals.converter._dispatch('detab.after', text, options, globals); 3831 return text; 3832 }); 3833 3834 showdown.subParser('ellipsis', function (text, options, globals) { 3835 'use strict'; 3836 3837 text = globals.converter._dispatch('ellipsis.before', text, options, globals); 3838 3839 text = text.replace(/\.\.\./g, '…'); 3840 3841 text = globals.converter._dispatch('ellipsis.after', text, options, globals); 3842 3843 return text; 3844 }); 3845 3846 /** 3847 * Turn emoji codes into emojis 3848 * 3849 * List of supported emojis: https://github.com/showdownjs/showdown/wiki/Emojis 3850 */ 3851 showdown.subParser('emoji', function (text, options, globals) { 3852 'use strict'; 3853 3854 if (!options.emoji) { 3855 return text; 3856 } 3857 3858 text = globals.converter._dispatch('emoji.before', text, options, globals); 3859 3860 var emojiRgx = /:([\S]+?):/g; 3861 3862 text = text.replace(emojiRgx, function (wm, emojiCode) { 3863 if (showdown.helper.emojis.hasOwnProperty(emojiCode)) { 3864 return showdown.helper.emojis[emojiCode]; 3865 } 3866 return wm; 3867 }); 3868 3869 text = globals.converter._dispatch('emoji.after', text, options, globals); 3870 3871 return text; 3872 }); 3873 3874 /** 3875 * Smart processing for ampersands and angle brackets that need to be encoded. 3876 */ 3877 showdown.subParser('encodeAmpsAndAngles', function (text, options, globals) { 3878 'use strict'; 3879 text = globals.converter._dispatch('encodeAmpsAndAngles.before', text, options, globals); 3880 3881 // Ampersand-encoding based entirely on Nat Irons's Amputator MT plugin: 3882 // http://bumppo.net/projects/amputator/ 3883 text = text.replace(/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/g, '&'); 3884 3885 // Encode naked <'s 3886 text = text.replace(/<(?![a-z\/?$!])/gi, '<'); 3887 3888 // Encode < 3889 text = text.replace(/</g, '<'); 3890 3891 // Encode > 3892 text = text.replace(/>/g, '>'); 3893 3894 text = globals.converter._dispatch('encodeAmpsAndAngles.after', text, options, globals); 3895 return text; 3896 }); 3897 3898 /** 3899 * Returns the string, with after processing the following backslash escape sequences. 3900 * 3901 * attacklab: The polite way to do this is with the new escapeCharacters() function: 3902 * 3903 * text = escapeCharacters(text,"\\",true); 3904 * text = escapeCharacters(text,"`*_{}[]()>#+-.!",true); 3905 * 3906 * ...but we're sidestepping its use of the (slow) RegExp constructor 3907 * as an optimization for Firefox. This function gets called a LOT. 3908 */ 3909 showdown.subParser('encodeBackslashEscapes', function (text, options, globals) { 3910 'use strict'; 3911 text = globals.converter._dispatch('encodeBackslashEscapes.before', text, options, globals); 3912 3913 text = text.replace(/\\(\\)/g, showdown.helper.escapeCharactersCallback); 3914 text = text.replace(/\\([`*_{}\[\]()>#+.!~=|-])/g, showdown.helper.escapeCharactersCallback); 3915 3916 text = globals.converter._dispatch('encodeBackslashEscapes.after', text, options, globals); 3917 return text; 3918 }); 3919 3920 /** 3921 * Encode/escape certain characters inside Markdown code runs. 3922 * The point is that in code, these characters are literals, 3923 * and lose their special Markdown meanings. 3924 */ 3925 showdown.subParser('encodeCode', function (text, options, globals) { 3926 'use strict'; 3927 3928 text = globals.converter._dispatch('encodeCode.before', text, options, globals); 3929 3930 // Encode all ampersands; HTML entities are not 3931 // entities within a Markdown code span. 3932 text = text 3933 .replace(/&/g, '&') 3934 // Do the angle bracket song and dance: 3935 .replace(/</g, '<') 3936 .replace(/>/g, '>') 3937 // Now, escape characters that are magic in Markdown: 3938 .replace(/([*_{}\[\]\\=~-])/g, showdown.helper.escapeCharactersCallback); 3939 3940 text = globals.converter._dispatch('encodeCode.after', text, options, globals); 3941 return text; 3942 }); 3943 3944 /** 3945 * Within tags -- meaning between < and > -- encode [\ ` * _ ~ =] so they 3946 * don't conflict with their use in Markdown for code, italics and strong. 3947 */ 3948 showdown.subParser('escapeSpecialCharsWithinTagAttributes', function (text, options, globals) { 3949 'use strict'; 3950 text = globals.converter._dispatch('escapeSpecialCharsWithinTagAttributes.before', text, options, globals); 3951 3952 // Build a regex to find HTML tags. 3953 var tags = /<\/?[a-z\d_:-]+(?:[\s]+[\s\S]+?)?>/gi, 3954 comments = /<!(--(?:(?:[^>-]|-[^>])(?:[^-]|-[^-])*)--)>/gi; 3955 3956 text = text.replace(tags, function (wholeMatch) { 3957 return wholeMatch 3958 .replace(/(.)<\/?code>(?=.)/g, '$1`') 3959 .replace(/([\\`*_~=|])/g, showdown.helper.escapeCharactersCallback); 3960 }); 3961 3962 text = text.replace(comments, function (wholeMatch) { 3963 return wholeMatch 3964 .replace(/([\\`*_~=|])/g, showdown.helper.escapeCharactersCallback); 3965 }); 3966 3967 text = globals.converter._dispatch('escapeSpecialCharsWithinTagAttributes.after', text, options, globals); 3968 return text; 3969 }); 3970 3971 /** 3972 * Handle github codeblocks prior to running HashHTML so that 3973 * HTML contained within the codeblock gets escaped properly 3974 * Example: 3975 * ```ruby 3976 * def hello_world(x) 3977 * puts "Hello, #{x}" 3978 * end 3979 * ``` 3980 */ 3981 showdown.subParser('githubCodeBlocks', function (text, options, globals) { 3982 'use strict'; 3983 3984 // early exit if option is not enabled 3985 if (!options.ghCodeBlocks) { 3986 return text; 3987 } 3988 3989 text = globals.converter._dispatch('githubCodeBlocks.before', text, options, globals); 3990 3991 text += '¨0'; 3992 3993 text = text.replace(/(?:^|\n)(?: {0,3})(```+|~~~+)(?: *)([^\s`~]*)\n([\s\S]*?)\n(?: {0,3})\1/g, function (wholeMatch, delim, language, codeblock) { 3994 var end = (options.omitExtraWLInCodeBlocks) ? '' : '\n'; 3995 3996 // First parse the github code block 3997 codeblock = showdown.subParser('encodeCode')(codeblock, options, globals); 3998 codeblock = showdown.subParser('detab')(codeblock, options, globals); 3999 codeblock = codeblock.replace(/^\n+/g, ''); // trim leading newlines 4000 codeblock = codeblock.replace(/\n+$/g, ''); // trim trailing whitespace 4001 4002 codeblock = '<pre><code' + (language ? ' class="' + language + ' language-' + language + '"' : '') + '>' + codeblock + end + '</code></pre>'; 4003 4004 codeblock = showdown.subParser('hashBlock')(codeblock, options, globals); 4005 4006 // Since GHCodeblocks can be false positives, we need to 4007 // store the primitive text and the parsed text in a global var, 4008 // and then return a token 4009 return '\n\n¨G' + (globals.ghCodeBlocks.push({text: wholeMatch, codeblock: codeblock}) - 1) + 'G\n\n'; 4010 }); 4011 4012 // attacklab: strip sentinel 4013 text = text.replace(/¨0/, ''); 4014 4015 return globals.converter._dispatch('githubCodeBlocks.after', text, options, globals); 4016 }); 4017 4018 showdown.subParser('hashBlock', function (text, options, globals) { 4019 'use strict'; 4020 text = globals.converter._dispatch('hashBlock.before', text, options, globals); 4021 text = text.replace(/(^\n+|\n+$)/g, ''); 4022 text = '\n\n¨K' + (globals.gHtmlBlocks.push(text) - 1) + 'K\n\n'; 4023 text = globals.converter._dispatch('hashBlock.after', text, options, globals); 4024 return text; 4025 }); 4026 4027 /** 4028 * Hash and escape <code> elements that should not be parsed as markdown 4029 */ 4030 showdown.subParser('hashCodeTags', function (text, options, globals) { 4031 'use strict'; 4032 text = globals.converter._dispatch('hashCodeTags.before', text, options, globals); 4033 4034 var repFunc = function (wholeMatch, match, left, right) { 4035 var codeblock = left + showdown.subParser('encodeCode')(match, options, globals) + right; 4036 return '¨C' + (globals.gHtmlSpans.push(codeblock) - 1) + 'C'; 4037 }; 4038 4039 // Hash naked <code> 4040 text = showdown.helper.replaceRecursiveRegExp(text, repFunc, '<code\\b[^>]*>', '</code>', 'gim'); 4041 4042 text = globals.converter._dispatch('hashCodeTags.after', text, options, globals); 4043 return text; 4044 }); 4045 4046 showdown.subParser('hashElement', function (text, options, globals) { 4047 'use strict'; 4048 4049 return function (wholeMatch, m1) { 4050 var blockText = m1; 4051 4052 // Undo double lines 4053 blockText = blockText.replace(/\n\n/g, '\n'); 4054 blockText = blockText.replace(/^\n/, ''); 4055 4056 // strip trailing blank lines 4057 blockText = blockText.replace(/\n+$/g, ''); 4058 4059 // Replace the element text with a marker ("¨KxK" where x is its key) 4060 blockText = '\n\n¨K' + (globals.gHtmlBlocks.push(blockText) - 1) + 'K\n\n'; 4061 4062 return blockText; 4063 }; 4064 }); 4065 4066 showdown.subParser('hashHTMLBlocks', function (text, options, globals) { 4067 'use strict'; 4068 text = globals.converter._dispatch('hashHTMLBlocks.before', text, options, globals); 4069 4070 var blockTags = [ 4071 'pre', 4072 'div', 4073 'h1', 4074 'h2', 4075 'h3', 4076 'h4', 4077 'h5', 4078 'h6', 4079 'blockquote', 4080 'table', 4081 'dl', 4082 'ol', 4083 'ul', 4084 'script', 4085 'noscript', 4086 'form', 4087 'fieldset', 4088 'iframe', 4089 'math', 4090 'style', 4091 'section', 4092 'header', 4093 'footer', 4094 'nav', 4095 'article', 4096 'aside', 4097 'address', 4098 'audio', 4099 'canvas', 4100 'figure', 4101 'hgroup', 4102 'output', 4103 'video', 4104 'p' 4105 ], 4106 repFunc = function (wholeMatch, match, left, right) { 4107 var txt = wholeMatch; 4108 // check if this html element is marked as markdown 4109 // if so, it's contents should be parsed as markdown 4110 if (left.search(/\bmarkdown\b/) !== -1) { 4111 txt = left + globals.converter.makeHtml(match) + right; 4112 } 4113 return '\n\n¨K' + (globals.gHtmlBlocks.push(txt) - 1) + 'K\n\n'; 4114 }; 4115 4116 if (options.backslashEscapesHTMLTags) { 4117 // encode backslash escaped HTML tags 4118 text = text.replace(/\\<(\/?[^>]+?)>/g, function (wm, inside) { 4119 return '<' + inside + '>'; 4120 }); 4121 } 4122 4123 // hash HTML Blocks 4124 for (var i = 0; i < blockTags.length; ++i) { 4125 4126 var opTagPos, 4127 rgx1 = new RegExp('^ {0,3}(<' + blockTags[i] + '\\b[^>]*>)', 'im'), 4128 patLeft = '<' + blockTags[i] + '\\b[^>]*>', 4129 patRight = '</' + blockTags[i] + '>'; 4130 // 1. Look for the first position of the first opening HTML tag in the text 4131 while ((opTagPos = showdown.helper.regexIndexOf(text, rgx1)) !== -1) { 4132 4133 // if the HTML tag is \ escaped, we need to escape it and break 4134 4135 4136 //2. Split the text in that position 4137 var subTexts = showdown.helper.splitAtIndex(text, opTagPos), 4138 //3. Match recursively 4139 newSubText1 = showdown.helper.replaceRecursiveRegExp(subTexts[1], repFunc, patLeft, patRight, 'im'); 4140 4141 // prevent an infinite loop 4142 if (newSubText1 === subTexts[1]) { 4143 break; 4144 } 4145 text = subTexts[0].concat(newSubText1); 4146 } 4147 } 4148 // HR SPECIAL CASE 4149 text = text.replace(/(\n {0,3}(<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g, 4150 showdown.subParser('hashElement')(text, options, globals)); 4151 4152 // Special case for standalone HTML comments 4153 text = showdown.helper.replaceRecursiveRegExp(text, function (txt) { 4154 return '\n\n¨K' + (globals.gHtmlBlocks.push(txt) - 1) + 'K\n\n'; 4155 }, '^ {0,3}<!--', '-->', 'gm'); 4156 4157 // PHP and ASP-style processor instructions (<?...?> and <%...%>) 4158 text = text.replace(/(?:\n\n)( {0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g, 4159 showdown.subParser('hashElement')(text, options, globals)); 4160 4161 text = globals.converter._dispatch('hashHTMLBlocks.after', text, options, globals); 4162 return text; 4163 }); 4164 4165 /** 4166 * Hash span elements that should not be parsed as markdown 4167 */ 4168 showdown.subParser('hashHTMLSpans', function (text, options, globals) { 4169 'use strict'; 4170 text = globals.converter._dispatch('hashHTMLSpans.before', text, options, globals); 4171 4172 function hashHTMLSpan (html) { 4173 return '¨C' + (globals.gHtmlSpans.push(html) - 1) + 'C'; 4174 } 4175 4176 // Hash Self Closing tags 4177 text = text.replace(/<[^>]+?\/>/gi, function (wm) { 4178 return hashHTMLSpan(wm); 4179 }); 4180 4181 // Hash tags without properties 4182 text = text.replace(/<([^>]+?)>[\s\S]*?<\/\1>/g, function (wm) { 4183 return hashHTMLSpan(wm); 4184 }); 4185 4186 // Hash tags with properties 4187 text = text.replace(/<([^>]+?)\s[^>]+?>[\s\S]*?<\/\1>/g, function (wm) { 4188 return hashHTMLSpan(wm); 4189 }); 4190 4191 // Hash self closing tags without /> 4192 text = text.replace(/<[^>]+?>/gi, function (wm) { 4193 return hashHTMLSpan(wm); 4194 }); 4195 4196 /*showdown.helper.matchRecursiveRegExp(text, '<code\\b[^>]*>', '</code>', 'gi');*/ 4197 4198 text = globals.converter._dispatch('hashHTMLSpans.after', text, options, globals); 4199 return text; 4200 }); 4201 4202 /** 4203 * Unhash HTML spans 4204 */ 4205 showdown.subParser('unhashHTMLSpans', function (text, options, globals) { 4206 'use strict'; 4207 text = globals.converter._dispatch('unhashHTMLSpans.before', text, options, globals); 4208 4209 for (var i = 0; i < globals.gHtmlSpans.length; ++i) { 4210 var repText = globals.gHtmlSpans[i], 4211 // limiter to prevent infinite loop (assume 10 as limit for recurse) 4212 limit = 0; 4213 4214 while (/¨C(\d+)C/.test(repText)) { 4215 var num = RegExp.$1; 4216 repText = repText.replace('¨C' + num + 'C', globals.gHtmlSpans[num]); 4217 if (limit === 10) { 4218 console.error('maximum nesting of 10 spans reached!!!'); 4219 break; 4220 } 4221 ++limit; 4222 } 4223 text = text.replace('¨C' + i + 'C', repText); 4224 } 4225 4226 text = globals.converter._dispatch('unhashHTMLSpans.after', text, options, globals); 4227 return text; 4228 }); 4229 4230 /** 4231 * Hash and escape <pre><code> elements that should not be parsed as markdown 4232 */ 4233 showdown.subParser('hashPreCodeTags', function (text, options, globals) { 4234 'use strict'; 4235 text = globals.converter._dispatch('hashPreCodeTags.before', text, options, globals); 4236 4237 var repFunc = function (wholeMatch, match, left, right) { 4238 // encode html entities 4239 var codeblock = left + showdown.subParser('encodeCode')(match, options, globals) + right; 4240 return '\n\n¨G' + (globals.ghCodeBlocks.push({text: wholeMatch, codeblock: codeblock}) - 1) + 'G\n\n'; 4241 }; 4242 4243 // Hash <pre><code> 4244 text = showdown.helper.replaceRecursiveRegExp(text, repFunc, '^ {0,3}<pre\\b[^>]*>\\s*<code\\b[^>]*>', '^ {0,3}</code>\\s*</pre>', 'gim'); 4245 4246 text = globals.converter._dispatch('hashPreCodeTags.after', text, options, globals); 4247 return text; 4248 }); 4249 4250 showdown.subParser('headers', function (text, options, globals) { 4251 'use strict'; 4252 4253 text = globals.converter._dispatch('headers.before', text, options, globals); 4254 4255 var headerLevelStart = (isNaN(parseInt(options.headerLevelStart))) ? 1 : parseInt(options.headerLevelStart), 4256 4257 // Set text-style headers: 4258 // Header 1 4259 // ======== 4260 // 4261 // Header 2 4262 // -------- 4263 // 4264 setextRegexH1 = (options.smoothLivePreview) ? /^(.+)[ \t]*\n={2,}[ \t]*\n+/gm : /^(.+)[ \t]*\n=+[ \t]*\n+/gm, 4265 setextRegexH2 = (options.smoothLivePreview) ? /^(.+)[ \t]*\n-{2,}[ \t]*\n+/gm : /^(.+)[ \t]*\n-+[ \t]*\n+/gm; 4266 4267 text = text.replace(setextRegexH1, function (wholeMatch, m1) { 4268 4269 var spanGamut = showdown.subParser('spanGamut')(m1, options, globals), 4270 hID = (options.noHeaderId) ? '' : ' id="' + headerId(m1) + '"', 4271 hLevel = headerLevelStart, 4272 hashBlock = '<h' + hLevel + hID + '>' + spanGamut + '</h' + hLevel + '>'; 4273 return showdown.subParser('hashBlock')(hashBlock, options, globals); 4274 }); 4275 4276 text = text.replace(setextRegexH2, function (matchFound, m1) { 4277 var spanGamut = showdown.subParser('spanGamut')(m1, options, globals), 4278 hID = (options.noHeaderId) ? '' : ' id="' + headerId(m1) + '"', 4279 hLevel = headerLevelStart + 1, 4280 hashBlock = '<h' + hLevel + hID + '>' + spanGamut + '</h' + hLevel + '>'; 4281 return showdown.subParser('hashBlock')(hashBlock, options, globals); 4282 }); 4283 4284 // atx-style headers: 4285 // # Header 1 4286 // ## Header 2 4287 // ## Header 2 with closing hashes ## 4288 // ... 4289 // ###### Header 6 4290 // 4291 var atxStyle = (options.requireSpaceBeforeHeadingText) ? /^(#{1,6})[ \t]+(.+?)[ \t]*#*\n+/gm : /^(#{1,6})[ \t]*(.+?)[ \t]*#*\n+/gm; 4292 4293 text = text.replace(atxStyle, function (wholeMatch, m1, m2) { 4294 var hText = m2; 4295 if (options.customizedHeaderId) { 4296 hText = m2.replace(/\s?\{([^{]+?)}\s*$/, ''); 4297 } 4298 4299 var span = showdown.subParser('spanGamut')(hText, options, globals), 4300 hID = (options.noHeaderId) ? '' : ' id="' + headerId(m2) + '"', 4301 hLevel = headerLevelStart - 1 + m1.length, 4302 header = '<h' + hLevel + hID + '>' + span + '</h' + hLevel + '>'; 4303 4304 return showdown.subParser('hashBlock')(header, options, globals); 4305 }); 4306 4307 function headerId (m) { 4308 var title, 4309 prefix; 4310 4311 // It is separate from other options to allow combining prefix and customized 4312 if (options.customizedHeaderId) { 4313 var match = m.match(/\{([^{]+?)}\s*$/); 4314 if (match && match[1]) { 4315 m = match[1]; 4316 } 4317 } 4318 4319 title = m; 4320 4321 // Prefix id to prevent causing inadvertent pre-existing style matches. 4322 if (showdown.helper.isString(options.prefixHeaderId)) { 4323 prefix = options.prefixHeaderId; 4324 } else if (options.prefixHeaderId === true) { 4325 prefix = 'section-'; 4326 } else { 4327 prefix = ''; 4328 } 4329 4330 if (!options.rawPrefixHeaderId) { 4331 title = prefix + title; 4332 } 4333 4334 if (options.ghCompatibleHeaderId) { 4335 title = title 4336 .replace(/ /g, '-') 4337 // replace previously escaped chars (&, ¨ and $) 4338 .replace(/&/g, '') 4339 .replace(/¨T/g, '') 4340 .replace(/¨D/g, '') 4341 // replace rest of the chars (&~$ are repeated as they might have been escaped) 4342 // borrowed from github's redcarpet (some they should produce similar results) 4343 .replace(/[&+$,\/:;=?@"#{}|^¨~\[\]`\\*)(%.!'<>]/g, '') 4344 .toLowerCase(); 4345 } else if (options.rawHeaderId) { 4346 title = title 4347 .replace(/ /g, '-') 4348 // replace previously escaped chars (&, ¨ and $) 4349 .replace(/&/g, '&') 4350 .replace(/¨T/g, '¨') 4351 .replace(/¨D/g, '$') 4352 // replace " and ' 4353 .replace(/["']/g, '-') 4354 .toLowerCase(); 4355 } else { 4356 title = title 4357 .replace(/[^\w]/g, '') 4358 .toLowerCase(); 4359 } 4360 4361 if (options.rawPrefixHeaderId) { 4362 title = prefix + title; 4363 } 4364 4365 if (globals.hashLinkCounts[title]) { 4366 title = title + '-' + (globals.hashLinkCounts[title]++); 4367 } else { 4368 globals.hashLinkCounts[title] = 1; 4369 } 4370 return title; 4371 } 4372 4373 text = globals.converter._dispatch('headers.after', text, options, globals); 4374 return text; 4375 }); 4376 4377 /** 4378 * Turn Markdown link shortcuts into XHTML <a> tags. 4379 */ 4380 showdown.subParser('horizontalRule', function (text, options, globals) { 4381 'use strict'; 4382 text = globals.converter._dispatch('horizontalRule.before', text, options, globals); 4383 4384 var key = showdown.subParser('hashBlock')('<hr />', options, globals); 4385 text = text.replace(/^ {0,2}( ?-){3,}[ \t]*$/gm, key); 4386 text = text.replace(/^ {0,2}( ?\*){3,}[ \t]*$/gm, key); 4387 text = text.replace(/^ {0,2}( ?_){3,}[ \t]*$/gm, key); 4388 4389 text = globals.converter._dispatch('horizontalRule.after', text, options, globals); 4390 return text; 4391 }); 4392 4393 /** 4394 * Turn Markdown image shortcuts into <img> tags. 4395 */ 4396 showdown.subParser('images', function (text, options, globals) { 4397 'use strict'; 4398 4399 text = globals.converter._dispatch('images.before', text, options, globals); 4400 4401 var inlineRegExp = /!\[([^\]]*?)][ \t]*()\([ \t]?<?([\S]+?(?:\([\S]*?\)[\S]*?)?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(["'])([^"]*?)\6)?[ \t]?\)/g, 4402 crazyRegExp = /!\[([^\]]*?)][ \t]*()\([ \t]?<([^>]*)>(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(?:(["'])([^"]*?)\6))?[ \t]?\)/g, 4403 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, 4404 referenceRegExp = /!\[([^\]]*?)] ?(?:\n *)?\[([\s\S]*?)]()()()()()/g, 4405 refShortcutRegExp = /!\[([^\[\]]+)]()()()()()/g; 4406 4407 function writeImageTagBase64 (wholeMatch, altText, linkId, url, width, height, m5, title) { 4408 url = url.replace(/\s/g, ''); 4409 return writeImageTag (wholeMatch, altText, linkId, url, width, height, m5, title); 4410 } 4411 4412 function writeImageTag (wholeMatch, altText, linkId, url, width, height, m5, title) { 4413 4414 var gUrls = globals.gUrls, 4415 gTitles = globals.gTitles, 4416 gDims = globals.gDimensions; 4417 4418 linkId = linkId.toLowerCase(); 4419 4420 if (!title) { 4421 title = ''; 4422 } 4423 // Special case for explicit empty url 4424 if (wholeMatch.search(/\(<?\s*>? ?(['"].*['"])?\)$/m) > -1) { 4425 url = ''; 4426 4427 } else if (url === '' || url === null) { 4428 if (linkId === '' || linkId === null) { 4429 // lower-case and turn embedded newlines into spaces 4430 linkId = altText.toLowerCase().replace(/ ?\n/g, ' '); 4431 } 4432 url = '#' + linkId; 4433 4434 if (!showdown.helper.isUndefined(gUrls[linkId])) { 4435 url = gUrls[linkId]; 4436 if (!showdown.helper.isUndefined(gTitles[linkId])) { 4437 title = gTitles[linkId]; 4438 } 4439 if (!showdown.helper.isUndefined(gDims[linkId])) { 4440 width = gDims[linkId].width; 4441 height = gDims[linkId].height; 4442 } 4443 } else { 4444 return wholeMatch; 4445 } 4446 } 4447 4448 altText = altText 4449 .replace(/"/g, '"') 4450 //altText = showdown.helper.escapeCharacters(altText, '*_', false); 4451 .replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback); 4452 //url = showdown.helper.escapeCharacters(url, '*_', false); 4453 url = url.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback); 4454 var result = '<img src="' + url + '" alt="' + altText + '"'; 4455 4456 if (title && showdown.helper.isString(title)) { 4457 title = title 4458 .replace(/"/g, '"') 4459 //title = showdown.helper.escapeCharacters(title, '*_', false); 4460 .replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback); 4461 result += ' title="' + title + '"'; 4462 } 4463 4464 if (width && height) { 4465 width = (width === '*') ? 'auto' : width; 4466 height = (height === '*') ? 'auto' : height; 4467 4468 result += ' width="' + width + '"'; 4469 result += ' height="' + height + '"'; 4470 } 4471 4472 result += ' />'; 4473 4474 return result; 4475 } 4476 4477 // First, handle reference-style labeled images: ![alt text][id] 4478 text = text.replace(referenceRegExp, writeImageTag); 4479 4480 // Next, handle inline images:  4481 4482 // base64 encoded images 4483 text = text.replace(base64RegExp, writeImageTagBase64); 4484 4485 // cases with crazy urls like ./image/cat1).png 4486 text = text.replace(crazyRegExp, writeImageTag); 4487 4488 // normal cases 4489 text = text.replace(inlineRegExp, writeImageTag); 4490 4491 // handle reference-style shortcuts: ![img text] 4492 text = text.replace(refShortcutRegExp, writeImageTag); 4493 4494 text = globals.converter._dispatch('images.after', text, options, globals); 4495 return text; 4496 }); 4497 4498 showdown.subParser('italicsAndBold', function (text, options, globals) { 4499 'use strict'; 4500 4501 text = globals.converter._dispatch('italicsAndBold.before', text, options, globals); 4502 4503 // it's faster to have 3 separate regexes for each case than have just one 4504 // because of backtracing, in some cases, it could lead to an exponential effect 4505 // called "catastrophic backtrace". Ominous! 4506 4507 function parseInside (txt, left, right) { 4508 /* 4509 if (options.simplifiedAutoLink) { 4510 txt = showdown.subParser('simplifiedAutoLinks')(txt, options, globals); 4511 } 4512 */ 4513 return left + txt + right; 4514 } 4515 4516 // Parse underscores 4517 if (options.literalMidWordUnderscores) { 4518 text = text.replace(/\b___(\S[\s\S]*?)___\b/g, function (wm, txt) { 4519 return parseInside (txt, '<strong><em>', '</em></strong>'); 4520 }); 4521 text = text.replace(/\b__(\S[\s\S]*?)__\b/g, function (wm, txt) { 4522 return parseInside (txt, '<strong>', '</strong>'); 4523 }); 4524 text = text.replace(/\b_(\S[\s\S]*?)_\b/g, function (wm, txt) { 4525 return parseInside (txt, '<em>', '</em>'); 4526 }); 4527 } else { 4528 text = text.replace(/___(\S[\s\S]*?)___/g, function (wm, m) { 4529 return (/\S$/.test(m)) ? parseInside (m, '<strong><em>', '</em></strong>') : wm; 4530 }); 4531 text = text.replace(/__(\S[\s\S]*?)__/g, function (wm, m) { 4532 return (/\S$/.test(m)) ? parseInside (m, '<strong>', '</strong>') : wm; 4533 }); 4534 text = text.replace(/_([^\s_][\s\S]*?)_/g, function (wm, m) { 4535 // !/^_[^_]/.test(m) - test if it doesn't start with __ (since it seems redundant, we removed it) 4536 return (/\S$/.test(m)) ? parseInside (m, '<em>', '</em>') : wm; 4537 }); 4538 } 4539 4540 // Now parse asterisks 4541 if (options.literalMidWordAsterisks) { 4542 text = text.replace(/([^*]|^)\B\*\*\*(\S[\s\S]*?)\*\*\*\B(?!\*)/g, function (wm, lead, txt) { 4543 return parseInside (txt, lead + '<strong><em>', '</em></strong>'); 4544 }); 4545 text = text.replace(/([^*]|^)\B\*\*(\S[\s\S]*?)\*\*\B(?!\*)/g, function (wm, lead, txt) { 4546 return parseInside (txt, lead + '<strong>', '</strong>'); 4547 }); 4548 text = text.replace(/([^*]|^)\B\*(\S[\s\S]*?)\*\B(?!\*)/g, function (wm, lead, txt) { 4549 return parseInside (txt, lead + '<em>', '</em>'); 4550 }); 4551 } else { 4552 text = text.replace(/\*\*\*(\S[\s\S]*?)\*\*\*/g, function (wm, m) { 4553 return (/\S$/.test(m)) ? parseInside (m, '<strong><em>', '</em></strong>') : wm; 4554 }); 4555 text = text.replace(/\*\*(\S[\s\S]*?)\*\*/g, function (wm, m) { 4556 return (/\S$/.test(m)) ? parseInside (m, '<strong>', '</strong>') : wm; 4557 }); 4558 text = text.replace(/\*([^\s*][\s\S]*?)\*/g, function (wm, m) { 4559 // !/^\*[^*]/.test(m) - test if it doesn't start with ** (since it seems redundant, we removed it) 4560 return (/\S$/.test(m)) ? parseInside (m, '<em>', '</em>') : wm; 4561 }); 4562 } 4563 4564 4565 text = globals.converter._dispatch('italicsAndBold.after', text, options, globals); 4566 return text; 4567 }); 4568 4569 /** 4570 * Form HTML ordered (numbered) and unordered (bulleted) lists. 4571 */ 4572 showdown.subParser('lists', function (text, options, globals) { 4573 'use strict'; 4574 4575 /** 4576 * Process the contents of a single ordered or unordered list, splitting it 4577 * into individual list items. 4578 * @param {string} listStr 4579 * @param {boolean} trimTrailing 4580 * @returns {string} 4581 */ 4582 function processListItems (listStr, trimTrailing) { 4583 // The $g_list_level global keeps track of when we're inside a list. 4584 // Each time we enter a list, we increment it; when we leave a list, 4585 // we decrement. If it's zero, we're not in a list anymore. 4586 // 4587 // We do this because when we're not inside a list, we want to treat 4588 // something like this: 4589 // 4590 // I recommend upgrading to version 4591 // 8. Oops, now this line is treated 4592 // as a sub-list. 4593 // 4594 // As a single paragraph, despite the fact that the second line starts 4595 // with a digit-period-space sequence. 4596 // 4597 // Whereas when we're inside a list (or sub-list), that line will be 4598 // treated as the start of a sub-list. What a kludge, huh? This is 4599 // an aspect of Markdown's syntax that's hard to parse perfectly 4600 // without resorting to mind-reading. Perhaps the solution is to 4601 // change the syntax rules such that sub-lists must start with a 4602 // starting cardinal number; e.g. "1." or "a.". 4603 globals.gListLevel++; 4604 4605 // trim trailing blank lines: 4606 listStr = listStr.replace(/\n{2,}$/, '\n'); 4607 4608 // attacklab: add sentinel to emulate \z 4609 listStr += '¨0'; 4610 4611 var rgx = /(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0| {0,3}([*+-]|\d+[.])[ \t]+))/gm, 4612 isParagraphed = (/\n[ \t]*\n(?!¨0)/.test(listStr)); 4613 4614 // Since version 1.5, nesting sublists requires 4 spaces (or 1 tab) indentation, 4615 // which is a syntax breaking change 4616 // activating this option reverts to old behavior 4617 if (options.disableForced4SpacesIndentedSublists) { 4618 rgx = /(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0|\2([*+-]|\d+[.])[ \t]+))/gm; 4619 } 4620 4621 listStr = listStr.replace(rgx, function (wholeMatch, m1, m2, m3, m4, taskbtn, checked) { 4622 checked = (checked && checked.trim() !== ''); 4623 4624 var item = showdown.subParser('outdent')(m4, options, globals), 4625 bulletStyle = ''; 4626 4627 // Support for github tasklists 4628 if (taskbtn && options.tasklists) { 4629 bulletStyle = ' class="task-list-item" style="list-style-type: none;"'; 4630 item = item.replace(/^[ \t]*\[(x|X| )?]/m, function () { 4631 var otp = '<input type="checkbox" disabled style="margin: 0px 0.35em 0.25em -1.6em; vertical-align: middle;"'; 4632 if (checked) { 4633 otp += ' checked'; 4634 } 4635 otp += '>'; 4636 return otp; 4637 }); 4638 } 4639 4640 // ISSUE #312 4641 // This input: - - - a 4642 // causes trouble to the parser, since it interprets it as: 4643 // <ul><li><li><li>a</li></li></li></ul> 4644 // instead of: 4645 // <ul><li>- - a</li></ul> 4646 // So, to prevent it, we will put a marker (¨A)in the beginning of the line 4647 // Kind of hackish/monkey patching, but seems more effective than overcomplicating the list parser 4648 item = item.replace(/^([-*+]|\d\.)[ \t]+[\S\n ]*/g, function (wm2) { 4649 return '¨A' + wm2; 4650 }); 4651 4652 // m1 - Leading line or 4653 // Has a double return (multi paragraph) or 4654 // Has sublist 4655 if (m1 || (item.search(/\n{2,}/) > -1)) { 4656 item = showdown.subParser('githubCodeBlocks')(item, options, globals); 4657 item = showdown.subParser('blockGamut')(item, options, globals); 4658 } else { 4659 // Recursion for sub-lists: 4660 item = showdown.subParser('lists')(item, options, globals); 4661 item = item.replace(/\n$/, ''); // chomp(item) 4662 item = showdown.subParser('hashHTMLBlocks')(item, options, globals); 4663 4664 // Colapse double linebreaks 4665 item = item.replace(/\n\n+/g, '\n\n'); 4666 if (isParagraphed) { 4667 item = showdown.subParser('paragraphs')(item, options, globals); 4668 } else { 4669 item = showdown.subParser('spanGamut')(item, options, globals); 4670 } 4671 } 4672 4673 // now we need to remove the marker (¨A) 4674 item = item.replace('¨A', ''); 4675 // we can finally wrap the line in list item tags 4676 item = '<li' + bulletStyle + '>' + item + '</li>\n'; 4677 4678 return item; 4679 }); 4680 4681 // attacklab: strip sentinel 4682 listStr = listStr.replace(/¨0/g, ''); 4683 4684 globals.gListLevel--; 4685 4686 if (trimTrailing) { 4687 listStr = listStr.replace(/\s+$/, ''); 4688 } 4689 4690 return listStr; 4691 } 4692 4693 function styleStartNumber (list, listType) { 4694 // check if ol and starts by a number different than 1 4695 if (listType === 'ol') { 4696 var res = list.match(/^ *(\d+)\./); 4697 if (res && res[1] !== '1') { 4698 return ' start="' + res[1] + '"'; 4699 } 4700 } 4701 return ''; 4702 } 4703 4704 /** 4705 * Check and parse consecutive lists (better fix for issue #142) 4706 * @param {string} list 4707 * @param {string} listType 4708 * @param {boolean} trimTrailing 4709 * @returns {string} 4710 */ 4711 function parseConsecutiveLists (list, listType, trimTrailing) { 4712 // check if we caught 2 or more consecutive lists by mistake 4713 // we use the counterRgx, meaning if listType is UL we look for OL and vice versa 4714 var olRgx = (options.disableForced4SpacesIndentedSublists) ? /^ ?\d+\.[ \t]/gm : /^ {0,3}\d+\.[ \t]/gm, 4715 ulRgx = (options.disableForced4SpacesIndentedSublists) ? /^ ?[*+-][ \t]/gm : /^ {0,3}[*+-][ \t]/gm, 4716 counterRxg = (listType === 'ul') ? olRgx : ulRgx, 4717 result = ''; 4718 4719 if (list.search(counterRxg) !== -1) { 4720 (function parseCL (txt) { 4721 var pos = txt.search(counterRxg), 4722 style = styleStartNumber(list, listType); 4723 if (pos !== -1) { 4724 // slice 4725 result += '\n\n<' + listType + style + '>\n' + processListItems(txt.slice(0, pos), !!trimTrailing) + '</' + listType + '>\n'; 4726 4727 // invert counterType and listType 4728 listType = (listType === 'ul') ? 'ol' : 'ul'; 4729 counterRxg = (listType === 'ul') ? olRgx : ulRgx; 4730 4731 //recurse 4732 parseCL(txt.slice(pos)); 4733 } else { 4734 result += '\n\n<' + listType + style + '>\n' + processListItems(txt, !!trimTrailing) + '</' + listType + '>\n'; 4735 } 4736 })(list); 4737 } else { 4738 var style = styleStartNumber(list, listType); 4739 result = '\n\n<' + listType + style + '>\n' + processListItems(list, !!trimTrailing) + '</' + listType + '>\n'; 4740 } 4741 4742 return result; 4743 } 4744 4745 /** Start of list parsing **/ 4746 text = globals.converter._dispatch('lists.before', text, options, globals); 4747 // add sentinel to hack around khtml/safari bug: 4748 // http://bugs.webkit.org/show_bug.cgi?id=11231 4749 text += '¨0'; 4750 4751 if (globals.gListLevel) { 4752 text = text.replace(/^(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(¨0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm, 4753 function (wholeMatch, list, m2) { 4754 var listType = (m2.search(/[*+-]/g) > -1) ? 'ul' : 'ol'; 4755 return parseConsecutiveLists(list, listType, true); 4756 } 4757 ); 4758 } else { 4759 text = text.replace(/(\n\n|^\n?)(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(¨0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm, 4760 function (wholeMatch, m1, list, m3) { 4761 var listType = (m3.search(/[*+-]/g) > -1) ? 'ul' : 'ol'; 4762 return parseConsecutiveLists(list, listType, false); 4763 } 4764 ); 4765 } 4766 4767 // strip sentinel 4768 text = text.replace(/¨0/, ''); 4769 text = globals.converter._dispatch('lists.after', text, options, globals); 4770 return text; 4771 }); 4772 4773 /** 4774 * Parse metadata at the top of the document 4775 */ 4776 showdown.subParser('metadata', function (text, options, globals) { 4777 'use strict'; 4778 4779 if (!options.metadata) { 4780 return text; 4781 } 4782 4783 text = globals.converter._dispatch('metadata.before', text, options, globals); 4784 4785 function parseMetadataContents (content) { 4786 // raw is raw so it's not changed in any way 4787 globals.metadata.raw = content; 4788 4789 // escape chars forbidden in html attributes 4790 // double quotes 4791 content = content 4792 // ampersand first 4793 .replace(/&/g, '&') 4794 // double quotes 4795 .replace(/"/g, '"'); 4796 4797 content = content.replace(/\n {4}/g, ' '); 4798 content.replace(/^([\S ]+): +([\s\S]+?)$/gm, function (wm, key, value) { 4799 globals.metadata.parsed[key] = value; 4800 return ''; 4801 }); 4802 } 4803 4804 text = text.replace(/^\s*«««+(\S*?)\n([\s\S]+?)\n»»»+\n/, function (wholematch, format, content) { 4805 parseMetadataContents(content); 4806 return '¨M'; 4807 }); 4808 4809 text = text.replace(/^\s*---+(\S*?)\n([\s\S]+?)\n---+\n/, function (wholematch, format, content) { 4810 if (format) { 4811 globals.metadata.format = format; 4812 } 4813 parseMetadataContents(content); 4814 return '¨M'; 4815 }); 4816 4817 text = text.replace(/¨M/g, ''); 4818 4819 text = globals.converter._dispatch('metadata.after', text, options, globals); 4820 return text; 4821 }); 4822 4823 /** 4824 * Remove one level of line-leading tabs or spaces 4825 */ 4826 showdown.subParser('outdent', function (text, options, globals) { 4827 'use strict'; 4828 text = globals.converter._dispatch('outdent.before', text, options, globals); 4829 4830 // attacklab: hack around Konqueror 3.5.4 bug: 4831 // "----------bug".replace(/^-/g,"") == "bug" 4832 text = text.replace(/^(\t|[ ]{1,4})/gm, '¨0'); // attacklab: g_tab_width 4833 4834 // attacklab: clean up hack 4835 text = text.replace(/¨0/g, ''); 4836 4837 text = globals.converter._dispatch('outdent.after', text, options, globals); 4838 return text; 4839 }); 4840 4841 /** 4842 * 4843 */ 4844 showdown.subParser('paragraphs', function (text, options, globals) { 4845 'use strict'; 4846 4847 text = globals.converter._dispatch('paragraphs.before', text, options, globals); 4848 // Strip leading and trailing lines: 4849 text = text.replace(/^\n+/g, ''); 4850 text = text.replace(/\n+$/g, ''); 4851 4852 var grafs = text.split(/\n{2,}/g), 4853 grafsOut = [], 4854 end = grafs.length; // Wrap <p> tags 4855 4856 for (var i = 0; i < end; i++) { 4857 var str = grafs[i]; 4858 // if this is an HTML marker, copy it 4859 if (str.search(/¨(K|G)(\d+)\1/g) >= 0) { 4860 grafsOut.push(str); 4861 4862 // test for presence of characters to prevent empty lines being parsed 4863 // as paragraphs (resulting in undesired extra empty paragraphs) 4864 } else if (str.search(/\S/) >= 0) { 4865 str = showdown.subParser('spanGamut')(str, options, globals); 4866 str = str.replace(/^([ \t]*)/g, '<p>'); 4867 str += '</p>'; 4868 grafsOut.push(str); 4869 } 4870 } 4871 4872 /** Unhashify HTML blocks */ 4873 end = grafsOut.length; 4874 for (i = 0; i < end; i++) { 4875 var blockText = '', 4876 grafsOutIt = grafsOut[i], 4877 codeFlag = false; 4878 // if this is a marker for an html block... 4879 // use RegExp.test instead of string.search because of QML bug 4880 while (/¨(K|G)(\d+)\1/.test(grafsOutIt)) { 4881 var delim = RegExp.$1, 4882 num = RegExp.$2; 4883 4884 if (delim === 'K') { 4885 blockText = globals.gHtmlBlocks[num]; 4886 } else { 4887 // we need to check if ghBlock is a false positive 4888 if (codeFlag) { 4889 // use encoded version of all text 4890 blockText = showdown.subParser('encodeCode')(globals.ghCodeBlocks[num].text, options, globals); 4891 } else { 4892 blockText = globals.ghCodeBlocks[num].codeblock; 4893 } 4894 } 4895 blockText = blockText.replace(/\$/g, '$$$$'); // Escape any dollar signs 4896 4897 grafsOutIt = grafsOutIt.replace(/(\n\n)?¨(K|G)\d+\2(\n\n)?/, blockText); 4898 // Check if grafsOutIt is a pre->code 4899 if (/^<pre\b[^>]*>\s*<code\b[^>]*>/.test(grafsOutIt)) { 4900 codeFlag = true; 4901 } 4902 } 4903 grafsOut[i] = grafsOutIt; 4904 } 4905 text = grafsOut.join('\n'); 4906 // Strip leading and trailing lines: 4907 text = text.replace(/^\n+/g, ''); 4908 text = text.replace(/\n+$/g, ''); 4909 return globals.converter._dispatch('paragraphs.after', text, options, globals); 4910 }); 4911 4912 /** 4913 * Run extension 4914 */ 4915 showdown.subParser('runExtension', function (ext, text, options, globals) { 4916 'use strict'; 4917 4918 if (ext.filter) { 4919 text = ext.filter(text, globals.converter, options); 4920 4921 } else if (ext.regex) { 4922 // TODO remove this when old extension loading mechanism is deprecated 4923 var re = ext.regex; 4924 if (!(re instanceof RegExp)) { 4925 re = new RegExp(re, 'g'); 4926 } 4927 text = text.replace(re, ext.replace); 4928 } 4929 4930 return text; 4931 }); 4932 4933 /** 4934 * These are all the transformations that occur *within* block-level 4935 * tags like paragraphs, headers, and list items. 4936 */ 4937 showdown.subParser('spanGamut', function (text, options, globals) { 4938 'use strict'; 4939 4940 text = globals.converter._dispatch('spanGamut.before', text, options, globals); 4941 text = showdown.subParser('codeSpans')(text, options, globals); 4942 text = showdown.subParser('escapeSpecialCharsWithinTagAttributes')(text, options, globals); 4943 text = showdown.subParser('encodeBackslashEscapes')(text, options, globals); 4944 4945 // Process anchor and image tags. Images must come first, 4946 // because ![foo][f] looks like an anchor. 4947 text = showdown.subParser('images')(text, options, globals); 4948 text = showdown.subParser('anchors')(text, options, globals); 4949 4950 // Make links out of things like `<http://example.com/>` 4951 // Must come after anchors, because you can use < and > 4952 // delimiters in inline links like [this](<url>). 4953 text = showdown.subParser('autoLinks')(text, options, globals); 4954 text = showdown.subParser('simplifiedAutoLinks')(text, options, globals); 4955 text = showdown.subParser('emoji')(text, options, globals); 4956 text = showdown.subParser('underline')(text, options, globals); 4957 text = showdown.subParser('italicsAndBold')(text, options, globals); 4958 text = showdown.subParser('strikethrough')(text, options, globals); 4959 text = showdown.subParser('ellipsis')(text, options, globals); 4960 4961 // we need to hash HTML tags inside spans 4962 text = showdown.subParser('hashHTMLSpans')(text, options, globals); 4963 4964 // now we encode amps and angles 4965 text = showdown.subParser('encodeAmpsAndAngles')(text, options, globals); 4966 4967 // Do hard breaks 4968 if (options.simpleLineBreaks) { 4969 // GFM style hard breaks 4970 // only add line breaks if the text does not contain a block (special case for lists) 4971 if (!/\n\n¨K/.test(text)) { 4972 text = text.replace(/\n+/g, '<br />\n'); 4973 } 4974 } else { 4975 // Vanilla hard breaks 4976 text = text.replace(/ +\n/g, '<br />\n'); 4977 } 4978 4979 text = globals.converter._dispatch('spanGamut.after', text, options, globals); 4980 return text; 4981 }); 4982 4983 showdown.subParser('strikethrough', function (text, options, globals) { 4984 'use strict'; 4985 4986 function parseInside (txt) { 4987 if (options.simplifiedAutoLink) { 4988 txt = showdown.subParser('simplifiedAutoLinks')(txt, options, globals); 4989 } 4990 return '<del>' + txt + '</del>'; 4991 } 4992 4993 if (options.strikethrough) { 4994 text = globals.converter._dispatch('strikethrough.before', text, options, globals); 4995 text = text.replace(/(?:~){2}([\s\S]+?)(?:~){2}/g, function (wm, txt) { return parseInside(txt); }); 4996 text = globals.converter._dispatch('strikethrough.after', text, options, globals); 4997 } 4998 4999 return text; 5000 }); 5001 5002 /** 5003 * Strips link definitions from text, stores the URLs and titles in 5004 * hash references. 5005 * Link defs are in the form: ^[id]: url "optional title" 5006 */ 5007 showdown.subParser('stripLinkDefinitions', function (text, options, globals) { 5008 'use strict'; 5009 5010 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, 5011 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; 5012 5013 // attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug 5014 text += '¨0'; 5015 5016 var replaceFunc = function (wholeMatch, linkId, url, width, height, blankLines, title) { 5017 linkId = linkId.toLowerCase(); 5018 if (url.match(/^data:.+?\/.+?;base64,/)) { 5019 // remove newlines 5020 globals.gUrls[linkId] = url.replace(/\s/g, ''); 5021 } else { 5022 globals.gUrls[linkId] = showdown.subParser('encodeAmpsAndAngles')(url, options, globals); // Link IDs are case-insensitive 5023 } 5024 5025 if (blankLines) { 5026 // Oops, found blank lines, so it's not a title. 5027 // Put back the parenthetical statement we stole. 5028 return blankLines + title; 5029 5030 } else { 5031 if (title) { 5032 globals.gTitles[linkId] = title.replace(/"|'/g, '"'); 5033 } 5034 if (options.parseImgDimensions && width && height) { 5035 globals.gDimensions[linkId] = { 5036 width: width, 5037 height: height 5038 }; 5039 } 5040 } 5041 // Completely remove the definition from the text 5042 return ''; 5043 }; 5044 5045 // first we try to find base64 link references 5046 text = text.replace(base64Regex, replaceFunc); 5047 5048 text = text.replace(regex, replaceFunc); 5049 5050 // attacklab: strip sentinel 5051 text = text.replace(/¨0/, ''); 5052 5053 return text; 5054 }); 5055 5056 showdown.subParser('tables', function (text, options, globals) { 5057 'use strict'; 5058 5059 if (!options.tables) { 5060 return text; 5061 } 5062 5063 var tableRgx = /^ {0,3}\|?.+\|.+\n {0,3}\|?[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*:?[ \t]*(?:[-=]){2,}[\s\S]+?(?:\n\n|¨0)/gm, 5064 //singeColTblRgx = /^ {0,3}\|.+\|\n {0,3}\|[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*\n(?: {0,3}\|.+\|\n)+(?:\n\n|¨0)/gm; 5065 singeColTblRgx = /^ {0,3}\|.+\|[ \t]*\n {0,3}\|[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*\n( {0,3}\|.+\|[ \t]*\n)*(?:\n|¨0)/gm; 5066 5067 function parseStyles (sLine) { 5068 if (/^:[ \t]*--*$/.test(sLine)) { 5069 return ' style="text-align:left;"'; 5070 } else if (/^--*[ \t]*:[ \t]*$/.test(sLine)) { 5071 return ' style="text-align:right;"'; 5072 } else if (/^:[ \t]*--*[ \t]*:$/.test(sLine)) { 5073 return ' style="text-align:center;"'; 5074 } else { 5075 return ''; 5076 } 5077 } 5078 5079 function parseHeaders (header, style) { 5080 var id = ''; 5081 header = header.trim(); 5082 // support both tablesHeaderId and tableHeaderId due to error in documentation so we don't break backwards compatibility 5083 if (options.tablesHeaderId || options.tableHeaderId) { 5084 id = ' id="' + header.replace(/ /g, '_').toLowerCase() + '"'; 5085 } 5086 header = showdown.subParser('spanGamut')(header, options, globals); 5087 5088 return '<th' + id + style + '>' + header + '</th>\n'; 5089 } 5090 5091 function parseCells (cell, style) { 5092 var subText = showdown.subParser('spanGamut')(cell, options, globals); 5093 return '<td' + style + '>' + subText + '</td>\n'; 5094 } 5095 5096 function buildTable (headers, cells) { 5097 var tb = '<table>\n<thead>\n<tr>\n', 5098 tblLgn = headers.length; 5099 5100 for (var i = 0; i < tblLgn; ++i) { 5101 tb += headers[i]; 5102 } 5103 tb += '</tr>\n</thead>\n<tbody>\n'; 5104 5105 for (i = 0; i < cells.length; ++i) { 5106 tb += '<tr>\n'; 5107 for (var ii = 0; ii < tblLgn; ++ii) { 5108 tb += cells[i][ii]; 5109 } 5110 tb += '</tr>\n'; 5111 } 5112 tb += '</tbody>\n</table>\n'; 5113 return tb; 5114 } 5115 5116 function parseTable (rawTable) { 5117 var i, tableLines = rawTable.split('\n'); 5118 5119 for (i = 0; i < tableLines.length; ++i) { 5120 // strip wrong first and last column if wrapped tables are used 5121 if (/^ {0,3}\|/.test(tableLines[i])) { 5122 tableLines[i] = tableLines[i].replace(/^ {0,3}\|/, ''); 5123 } 5124 if (/\|[ \t]*$/.test(tableLines[i])) { 5125 tableLines[i] = tableLines[i].replace(/\|[ \t]*$/, ''); 5126 } 5127 // parse code spans first, but we only support one line code spans 5128 tableLines[i] = showdown.subParser('codeSpans')(tableLines[i], options, globals); 5129 } 5130 5131 var rawHeaders = tableLines[0].split('|').map(function (s) { return s.trim();}), 5132 rawStyles = tableLines[1].split('|').map(function (s) { return s.trim();}), 5133 rawCells = [], 5134 headers = [], 5135 styles = [], 5136 cells = []; 5137 5138 tableLines.shift(); 5139 tableLines.shift(); 5140 5141 for (i = 0; i < tableLines.length; ++i) { 5142 if (tableLines[i].trim() === '') { 5143 continue; 5144 } 5145 rawCells.push( 5146 tableLines[i] 5147 .split('|') 5148 .map(function (s) { 5149 return s.trim(); 5150 }) 5151 ); 5152 } 5153 5154 if (rawHeaders.length < rawStyles.length) { 5155 return rawTable; 5156 } 5157 5158 for (i = 0; i < rawStyles.length; ++i) { 5159 styles.push(parseStyles(rawStyles[i])); 5160 } 5161 5162 for (i = 0; i < rawHeaders.length; ++i) { 5163 if (showdown.helper.isUndefined(styles[i])) { 5164 styles[i] = ''; 5165 } 5166 headers.push(parseHeaders(rawHeaders[i], styles[i])); 5167 } 5168 5169 for (i = 0; i < rawCells.length; ++i) { 5170 var row = []; 5171 for (var ii = 0; ii < headers.length; ++ii) { 5172 if (showdown.helper.isUndefined(rawCells[i][ii])) { 5173 5174 } 5175 row.push(parseCells(rawCells[i][ii], styles[ii])); 5176 } 5177 cells.push(row); 5178 } 5179 5180 return buildTable(headers, cells); 5181 } 5182 5183 text = globals.converter._dispatch('tables.before', text, options, globals); 5184 5185 // find escaped pipe characters 5186 text = text.replace(/\\(\|)/g, showdown.helper.escapeCharactersCallback); 5187 5188 // parse multi column tables 5189 text = text.replace(tableRgx, parseTable); 5190 5191 // parse one column tables 5192 text = text.replace(singeColTblRgx, parseTable); 5193 5194 text = globals.converter._dispatch('tables.after', text, options, globals); 5195 5196 return text; 5197 }); 5198 5199 showdown.subParser('underline', function (text, options, globals) { 5200 'use strict'; 5201 5202 if (!options.underline) { 5203 return text; 5204 } 5205 5206 text = globals.converter._dispatch('underline.before', text, options, globals); 5207 5208 if (options.literalMidWordUnderscores) { 5209 text = text.replace(/\b___(\S[\s\S]*?)___\b/g, function (wm, txt) { 5210 return '<u>' + txt + '</u>'; 5211 }); 5212 text = text.replace(/\b__(\S[\s\S]*?)__\b/g, function (wm, txt) { 5213 return '<u>' + txt + '</u>'; 5214 }); 5215 } else { 5216 text = text.replace(/___(\S[\s\S]*?)___/g, function (wm, m) { 5217 return (/\S$/.test(m)) ? '<u>' + m + '</u>' : wm; 5218 }); 5219 text = text.replace(/__(\S[\s\S]*?)__/g, function (wm, m) { 5220 return (/\S$/.test(m)) ? '<u>' + m + '</u>' : wm; 5221 }); 5222 } 5223 5224 // escape remaining underscores to prevent them being parsed by italic and bold 5225 text = text.replace(/(_)/g, showdown.helper.escapeCharactersCallback); 5226 5227 text = globals.converter._dispatch('underline.after', text, options, globals); 5228 5229 return text; 5230 }); 5231 5232 /** 5233 * Swap back in all the special characters we've hidden. 5234 */ 5235 showdown.subParser('unescapeSpecialChars', function (text, options, globals) { 5236 'use strict'; 5237 text = globals.converter._dispatch('unescapeSpecialChars.before', text, options, globals); 5238 5239 text = text.replace(/¨E(\d+)E/g, function (wholeMatch, m1) { 5240 var charCodeToReplace = parseInt(m1); 5241 return String.fromCharCode(charCodeToReplace); 5242 }); 5243 5244 text = globals.converter._dispatch('unescapeSpecialChars.after', text, options, globals); 5245 return text; 5246 }); 5247 5248 showdown.subParser('makeMarkdown.blockquote', function (node, globals) { 5249 'use strict'; 5250 5251 var txt = ''; 5252 if (node.hasChildNodes()) { 5253 var children = node.childNodes, 5254 childrenLength = children.length; 5255 5256 for (var i = 0; i < childrenLength; ++i) { 5257 var innerTxt = showdown.subParser('makeMarkdown.node')(children[i], globals); 5258 5259 if (innerTxt === '') { 5260 continue; 5261 } 5262 txt += innerTxt; 5263 } 5264 } 5265 // cleanup 5266 txt = txt.trim(); 5267 txt = '> ' + txt.split('\n').join('\n> '); 5268 return txt; 5269 }); 5270 5271 showdown.subParser('makeMarkdown.codeBlock', function (node, globals) { 5272 'use strict'; 5273 5274 var lang = node.getAttribute('language'), 5275 num = node.getAttribute('precodenum'); 5276 return '```' + lang + '\n' + globals.preList[num] + '\n```'; 5277 }); 5278 5279 showdown.subParser('makeMarkdown.codeSpan', function (node) { 5280 'use strict'; 5281 5282 return '`' + node.innerHTML + '`'; 5283 }); 5284 5285 showdown.subParser('makeMarkdown.emphasis', function (node, globals) { 5286 'use strict'; 5287 5288 var txt = ''; 5289 if (node.hasChildNodes()) { 5290 txt += '*'; 5291 var children = node.childNodes, 5292 childrenLength = children.length; 5293 for (var i = 0; i < childrenLength; ++i) { 5294 txt += showdown.subParser('makeMarkdown.node')(children[i], globals); 5295 } 5296 txt += '*'; 5297 } 5298 return txt; 5299 }); 5300 5301 showdown.subParser('makeMarkdown.header', function (node, globals, headerLevel) { 5302 'use strict'; 5303 5304 var headerMark = new Array(headerLevel + 1).join('#'), 5305 txt = ''; 5306 5307 if (node.hasChildNodes()) { 5308 txt = headerMark + ' '; 5309 var children = node.childNodes, 5310 childrenLength = children.length; 5311 5312 for (var i = 0; i < childrenLength; ++i) { 5313 txt += showdown.subParser('makeMarkdown.node')(children[i], globals); 5314 } 5315 } 5316 return txt; 5317 }); 5318 5319 showdown.subParser('makeMarkdown.hr', function () { 5320 'use strict'; 5321 5322 return '---'; 5323 }); 5324 5325 showdown.subParser('makeMarkdown.image', function (node) { 5326 'use strict'; 5327 5328 var txt = ''; 5329 if (node.hasAttribute('src')) { 5330 txt += ' + '>'; 5332 if (node.hasAttribute('width') && node.hasAttribute('height')) { 5333 txt += ' =' + node.getAttribute('width') + 'x' + node.getAttribute('height'); 5334 } 5335 5336 if (node.hasAttribute('title')) { 5337 txt += ' "' + node.getAttribute('title') + '"'; 5338 } 5339 txt += ')'; 5340 } 5341 return txt; 5342 }); 5343 5344 showdown.subParser('makeMarkdown.links', function (node, globals) { 5345 'use strict'; 5346 5347 var txt = ''; 5348 if (node.hasChildNodes() && node.hasAttribute('href')) { 5349 var children = node.childNodes, 5350 childrenLength = children.length; 5351 txt = '['; 5352 for (var i = 0; i < childrenLength; ++i) { 5353 txt += showdown.subParser('makeMarkdown.node')(children[i], globals); 5354 } 5355 txt += ']('; 5356 txt += '<' + node.getAttribute('href') + '>'; 5357 if (node.hasAttribute('title')) { 5358 txt += ' "' + node.getAttribute('title') + '"'; 5359 } 5360 txt += ')'; 5361 } 5362 return txt; 5363 }); 5364 5365 showdown.subParser('makeMarkdown.list', function (node, globals, type) { 5366 'use strict'; 5367 5368 var txt = ''; 5369 if (!node.hasChildNodes()) { 5370 return ''; 5371 } 5372 var listItems = node.childNodes, 5373 listItemsLenght = listItems.length, 5374 listNum = node.getAttribute('start') || 1; 5375 5376 for (var i = 0; i < listItemsLenght; ++i) { 5377 if (typeof listItems[i].tagName === 'undefined' || listItems[i].tagName.toLowerCase() !== 'li') { 5378 continue; 5379 } 5380 5381 // define the bullet to use in list 5382 var bullet = ''; 5383 if (type === 'ol') { 5384 bullet = listNum.toString() + '. '; 5385 } else { 5386 bullet = '- '; 5387 } 5388 5389 // parse list item 5390 txt += bullet + showdown.subParser('makeMarkdown.listItem')(listItems[i], globals); 5391 ++listNum; 5392 } 5393 5394 // add comment at the end to prevent consecutive lists to be parsed as one 5395 txt += '\n<!-- -->\n'; 5396 return txt.trim(); 5397 }); 5398 5399 showdown.subParser('makeMarkdown.listItem', function (node, globals) { 5400 'use strict'; 5401 5402 var listItemTxt = ''; 5403 5404 var children = node.childNodes, 5405 childrenLenght = children.length; 5406 5407 for (var i = 0; i < childrenLenght; ++i) { 5408 listItemTxt += showdown.subParser('makeMarkdown.node')(children[i], globals); 5409 } 5410 // if it's only one liner, we need to add a newline at the end 5411 if (!/\n$/.test(listItemTxt)) { 5412 listItemTxt += '\n'; 5413 } else { 5414 // it's multiparagraph, so we need to indent 5415 listItemTxt = listItemTxt 5416 .split('\n') 5417 .join('\n ') 5418 .replace(/^ {4}$/gm, '') 5419 .replace(/\n\n+/g, '\n\n'); 5420 } 5421 5422 return listItemTxt; 5423 }); 5424 5425 5426 5427 showdown.subParser('makeMarkdown.node', function (node, globals, spansOnly) { 5428 'use strict'; 5429 5430 spansOnly = spansOnly || false; 5431 5432 var txt = ''; 5433 5434 // edge case of text without wrapper paragraph 5435 if (node.nodeType === 3) { 5436 return showdown.subParser('makeMarkdown.txt')(node, globals); 5437 } 5438 5439 // HTML comment 5440 if (node.nodeType === 8) { 5441 return '<!--' + node.data + '-->\n\n'; 5442 } 5443 5444 // process only node elements 5445 if (node.nodeType !== 1) { 5446 return ''; 5447 } 5448 5449 var tagName = node.tagName.toLowerCase(); 5450 5451 switch (tagName) { 5452 5453 // 5454 // BLOCKS 5455 // 5456 case 'h1': 5457 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 1) + '\n\n'; } 5458 break; 5459 case 'h2': 5460 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 2) + '\n\n'; } 5461 break; 5462 case 'h3': 5463 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 3) + '\n\n'; } 5464 break; 5465 case 'h4': 5466 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 4) + '\n\n'; } 5467 break; 5468 case 'h5': 5469 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 5) + '\n\n'; } 5470 break; 5471 case 'h6': 5472 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 6) + '\n\n'; } 5473 break; 5474 5475 case 'p': 5476 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.paragraph')(node, globals) + '\n\n'; } 5477 break; 5478 5479 case 'blockquote': 5480 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.blockquote')(node, globals) + '\n\n'; } 5481 break; 5482 5483 case 'hr': 5484 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.hr')(node, globals) + '\n\n'; } 5485 break; 5486 5487 case 'ol': 5488 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.list')(node, globals, 'ol') + '\n\n'; } 5489 break; 5490 5491 case 'ul': 5492 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.list')(node, globals, 'ul') + '\n\n'; } 5493 break; 5494 5495 case 'precode': 5496 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.codeBlock')(node, globals) + '\n\n'; } 5497 break; 5498 5499 case 'pre': 5500 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.pre')(node, globals) + '\n\n'; } 5501 break; 5502 5503 case 'table': 5504 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.table')(node, globals) + '\n\n'; } 5505 break; 5506 5507 // 5508 // SPANS 5509 // 5510 case 'code': 5511 txt = showdown.subParser('makeMarkdown.codeSpan')(node, globals); 5512 break; 5513 5514 case 'em': 5515 case 'i': 5516 txt = showdown.subParser('makeMarkdown.emphasis')(node, globals); 5517 break; 5518 5519 case 'strong': 5520 case 'b': 5521 txt = showdown.subParser('makeMarkdown.strong')(node, globals); 5522 break; 5523 5524 case 'del': 5525 txt = showdown.subParser('makeMarkdown.strikethrough')(node, globals); 5526 break; 5527 5528 case 'a': 5529 txt = showdown.subParser('makeMarkdown.links')(node, globals); 5530 break; 5531 5532 case 'img': 5533 txt = showdown.subParser('makeMarkdown.image')(node, globals); 5534 break; 5535 5536 default: 5537 txt = node.outerHTML + '\n\n'; 5538 } 5539 5540 // common normalization 5541 // TODO eventually 5542 5543 return txt; 5544 }); 5545 5546 showdown.subParser('makeMarkdown.paragraph', function (node, globals) { 5547 'use strict'; 5548 5549 var txt = ''; 5550 if (node.hasChildNodes()) { 5551 var children = node.childNodes, 5552 childrenLength = children.length; 5553 for (var i = 0; i < childrenLength; ++i) { 5554 txt += showdown.subParser('makeMarkdown.node')(children[i], globals); 5555 } 5556 } 5557 5558 // some text normalization 5559 txt = txt.trim(); 5560 5561 return txt; 5562 }); 5563 5564 showdown.subParser('makeMarkdown.pre', function (node, globals) { 5565 'use strict'; 5566 5567 var num = node.getAttribute('prenum'); 5568 return '<pre>' + globals.preList[num] + '</pre>'; 5569 }); 5570 5571 showdown.subParser('makeMarkdown.strikethrough', function (node, globals) { 5572 'use strict'; 5573 5574 var txt = ''; 5575 if (node.hasChildNodes()) { 5576 txt += '~~'; 5577 var children = node.childNodes, 5578 childrenLength = children.length; 5579 for (var i = 0; i < childrenLength; ++i) { 5580 txt += showdown.subParser('makeMarkdown.node')(children[i], globals); 5581 } 5582 txt += '~~'; 5583 } 5584 return txt; 5585 }); 5586 5587 showdown.subParser('makeMarkdown.strong', function (node, globals) { 5588 'use strict'; 5589 5590 var txt = ''; 5591 if (node.hasChildNodes()) { 5592 txt += '**'; 5593 var children = node.childNodes, 5594 childrenLength = children.length; 5595 for (var i = 0; i < childrenLength; ++i) { 5596 txt += showdown.subParser('makeMarkdown.node')(children[i], globals); 5597 } 5598 txt += '**'; 5599 } 5600 return txt; 5601 }); 5602 5603 showdown.subParser('makeMarkdown.table', function (node, globals) { 5604 'use strict'; 5605 5606 var txt = '', 5607 tableArray = [[], []], 5608 headings = node.querySelectorAll('thead>tr>th'), 5609 rows = node.querySelectorAll('tbody>tr'), 5610 i, ii; 5611 for (i = 0; i < headings.length; ++i) { 5612 var headContent = showdown.subParser('makeMarkdown.tableCell')(headings[i], globals), 5613 allign = '---'; 5614 5615 if (headings[i].hasAttribute('style')) { 5616 var style = headings[i].getAttribute('style').toLowerCase().replace(/\s/g, ''); 5617 switch (style) { 5618 case 'text-align:left;': 5619 allign = ':---'; 5620 break; 5621 case 'text-align:right;': 5622 allign = '---:'; 5623 break; 5624 case 'text-align:center;': 5625 allign = ':---:'; 5626 break; 5627 } 5628 } 5629 tableArray[0][i] = headContent.trim(); 5630 tableArray[1][i] = allign; 5631 } 5632 5633 for (i = 0; i < rows.length; ++i) { 5634 var r = tableArray.push([]) - 1, 5635 cols = rows[i].getElementsByTagName('td'); 5636 5637 for (ii = 0; ii < headings.length; ++ii) { 5638 var cellContent = ' '; 5639 if (typeof cols[ii] !== 'undefined') { 5640 cellContent = showdown.subParser('makeMarkdown.tableCell')(cols[ii], globals); 5641 } 5642 tableArray[r].push(cellContent); 5643 } 5644 } 5645 5646 var cellSpacesCount = 3; 5647 for (i = 0; i < tableArray.length; ++i) { 5648 for (ii = 0; ii < tableArray[i].length; ++ii) { 5649 var strLen = tableArray[i][ii].length; 5650 if (strLen > cellSpacesCount) { 5651 cellSpacesCount = strLen; 5652 } 5653 } 5654 } 5655 5656 for (i = 0; i < tableArray.length; ++i) { 5657 for (ii = 0; ii < tableArray[i].length; ++ii) { 5658 if (i === 1) { 5659 if (tableArray[i][ii].slice(-1) === ':') { 5660 tableArray[i][ii] = showdown.helper.padEnd(tableArray[i][ii].slice(-1), cellSpacesCount - 1, '-') + ':'; 5661 } else { 5662 tableArray[i][ii] = showdown.helper.padEnd(tableArray[i][ii], cellSpacesCount, '-'); 5663 } 5664 } else { 5665 tableArray[i][ii] = showdown.helper.padEnd(tableArray[i][ii], cellSpacesCount); 5666 } 5667 } 5668 txt += '| ' + tableArray[i].join(' | ') + ' |\n'; 5669 } 5670 5671 return txt.trim(); 5672 }); 5673 5674 showdown.subParser('makeMarkdown.tableCell', function (node, globals) { 5675 'use strict'; 5676 5677 var txt = ''; 5678 if (!node.hasChildNodes()) { 5679 return ''; 5680 } 5681 var children = node.childNodes, 5682 childrenLength = children.length; 5683 5684 for (var i = 0; i < childrenLength; ++i) { 5685 txt += showdown.subParser('makeMarkdown.node')(children[i], globals, true); 5686 } 5687 return txt.trim(); 5688 }); 5689 5690 showdown.subParser('makeMarkdown.txt', function (node) { 5691 'use strict'; 5692 5693 var txt = node.nodeValue; 5694 5695 // multiple spaces are collapsed 5696 txt = txt.replace(/ +/g, ' '); 5697 5698 // replace the custom ¨NBSP; with a space 5699 txt = txt.replace(/¨NBSP;/g, ' '); 5700 5701 // ", <, > and & should replace escaped html entities 5702 txt = showdown.helper.unescapeHTMLEntities(txt); 5703 5704 // escape markdown magic characters 5705 // emphasis, strong and strikethrough - can appear everywhere 5706 // we also escape pipe (|) because of tables 5707 // and escape ` because of code blocks and spans 5708 txt = txt.replace(/([*_~|`])/g, '\\$1'); 5709 5710 // escape > because of blockquotes 5711 txt = txt.replace(/^(\s*)>/g, '\\$1>'); 5712 5713 // hash character, only troublesome at the beginning of a line because of headers 5714 txt = txt.replace(/^#/gm, '\\#'); 5715 5716 // horizontal rules 5717 txt = txt.replace(/^(\s*)([-=]{3,})(\s*)$/, '$1\\$2$3'); 5718 5719 // dot, because of ordered lists, only troublesome at the beginning of a line when preceded by an integer 5720 txt = txt.replace(/^( {0,3}\d+)\./gm, '$1\\.'); 5721 5722 // +, * and -, at the beginning of a line becomes a list, so we need to escape them also (asterisk was already escaped) 5723 txt = txt.replace(/^( {0,3})([+-])/gm, '$1\\$2'); 5724 5725 // images and links, ] followed by ( is problematic, so we escape it 5726 txt = txt.replace(/]([\s]*)\(/g, '\\]$1\\('); 5727 5728 // reference URIs must also be escaped 5729 txt = txt.replace(/^ {0,3}\[([\S \t]*?)]:/gm, '\\[$1]:'); 5730 5731 return txt; 5732 }); 5733 5734 var root = this; 5735 5736 // AMD Loader 5737 if (true) { 5738 !(__WEBPACK_AMD_DEFINE_RESULT__ = (function () { 5739 'use strict'; 5740 return showdown; 5741 }).call(exports, __webpack_require__, exports, module), 5742 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 5743 5744 // CommonJS/nodeJS Loader 5745 } else {} 5746 }).call(this); 5747 5748 5749 5750 5751 /***/ }) 5752 5753 /******/ }); 5754 /************************************************************************/ 5755 /******/ // The module cache 5756 /******/ var __webpack_module_cache__ = {}; 5757 /******/ 5758 /******/ // The require function 5759 /******/ function __webpack_require__(moduleId) { 5760 /******/ // Check if module is in cache 5761 /******/ var cachedModule = __webpack_module_cache__[moduleId]; 5762 /******/ if (cachedModule !== undefined) { 5763 /******/ return cachedModule.exports; 5764 /******/ } 5765 /******/ // Create a new module (and put it into the cache) 5766 /******/ var module = __webpack_module_cache__[moduleId] = { 5767 /******/ // no module.id needed 5768 /******/ // no module.loaded needed 5769 /******/ exports: {} 5770 /******/ }; 5771 /******/ 5772 /******/ // Execute the module function 5773 /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__); 5774 /******/ 5775 /******/ // Return the exports of the module 5776 /******/ return module.exports; 5777 /******/ } 5778 /******/ 5779 /************************************************************************/ 5780 /******/ /* webpack/runtime/compat get default export */ 5781 /******/ (() => { 5782 /******/ // getDefaultExport function for compatibility with non-harmony modules 5783 /******/ __webpack_require__.n = (module) => { 5784 /******/ var getter = module && module.__esModule ? 5785 /******/ () => (module['default']) : 5786 /******/ () => (module); 5787 /******/ __webpack_require__.d(getter, { a: getter }); 5788 /******/ return getter; 5789 /******/ }; 5790 /******/ })(); 5791 /******/ 5792 /******/ /* webpack/runtime/define property getters */ 5793 /******/ (() => { 5794 /******/ // define getter functions for harmony exports 5795 /******/ __webpack_require__.d = (exports, definition) => { 5796 /******/ for(var key in definition) { 5797 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { 5798 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); 5799 /******/ } 5800 /******/ } 5801 /******/ }; 5802 /******/ })(); 5803 /******/ 5804 /******/ /* webpack/runtime/hasOwnProperty shorthand */ 5805 /******/ (() => { 5806 /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) 5807 /******/ })(); 5808 /******/ 5809 /******/ /* webpack/runtime/make namespace object */ 5810 /******/ (() => { 5811 /******/ // define __esModule on exports 5812 /******/ __webpack_require__.r = (exports) => { 5813 /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 5814 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 5815 /******/ } 5816 /******/ Object.defineProperty(exports, '__esModule', { value: true }); 5817 /******/ }; 5818 /******/ })(); 5819 /******/ 5820 /************************************************************************/ 5821 var __webpack_exports__ = {}; 5822 // This entry needs to be wrapped in an IIFE because it needs to be in strict mode. 5823 (() => { 5824 "use strict"; 5825 // ESM COMPAT FLAG 5826 __webpack_require__.r(__webpack_exports__); 5827 5828 // EXPORTS 5829 __webpack_require__.d(__webpack_exports__, { 5830 __EXPERIMENTAL_ELEMENTS: () => (/* reexport */ __EXPERIMENTAL_ELEMENTS), 5831 __EXPERIMENTAL_PATHS_WITH_OVERRIDE: () => (/* reexport */ __EXPERIMENTAL_PATHS_WITH_OVERRIDE), 5832 __EXPERIMENTAL_STYLE_PROPERTY: () => (/* reexport */ __EXPERIMENTAL_STYLE_PROPERTY), 5833 __experimentalCloneSanitizedBlock: () => (/* reexport */ __experimentalCloneSanitizedBlock), 5834 __experimentalGetAccessibleBlockLabel: () => (/* reexport */ getAccessibleBlockLabel), 5835 __experimentalGetBlockAttributesNamesByRole: () => (/* reexport */ __experimentalGetBlockAttributesNamesByRole), 5836 __experimentalGetBlockLabel: () => (/* reexport */ getBlockLabel), 5837 __experimentalSanitizeBlockAttributes: () => (/* reexport */ __experimentalSanitizeBlockAttributes), 5838 __unstableGetBlockProps: () => (/* reexport */ getBlockProps), 5839 __unstableGetInnerBlocksProps: () => (/* reexport */ getInnerBlocksProps), 5840 __unstableSerializeAndClean: () => (/* reexport */ __unstableSerializeAndClean), 5841 children: () => (/* reexport */ children), 5842 cloneBlock: () => (/* reexport */ cloneBlock), 5843 createBlock: () => (/* reexport */ createBlock), 5844 createBlocksFromInnerBlocksTemplate: () => (/* reexport */ createBlocksFromInnerBlocksTemplate), 5845 doBlocksMatchTemplate: () => (/* reexport */ doBlocksMatchTemplate), 5846 findTransform: () => (/* reexport */ findTransform), 5847 getBlockAttributes: () => (/* reexport */ getBlockAttributes), 5848 getBlockAttributesNamesByRole: () => (/* reexport */ getBlockAttributesNamesByRole), 5849 getBlockBindingsSource: () => (/* reexport */ getBlockBindingsSource), 5850 getBlockBindingsSources: () => (/* reexport */ getBlockBindingsSources), 5851 getBlockContent: () => (/* reexport */ getBlockInnerHTML), 5852 getBlockDefaultClassName: () => (/* reexport */ getBlockDefaultClassName), 5853 getBlockFromExample: () => (/* reexport */ getBlockFromExample), 5854 getBlockMenuDefaultClassName: () => (/* reexport */ getBlockMenuDefaultClassName), 5855 getBlockSupport: () => (/* reexport */ getBlockSupport), 5856 getBlockTransforms: () => (/* reexport */ getBlockTransforms), 5857 getBlockType: () => (/* reexport */ getBlockType), 5858 getBlockTypes: () => (/* reexport */ getBlockTypes), 5859 getBlockVariations: () => (/* reexport */ getBlockVariations), 5860 getCategories: () => (/* reexport */ categories_getCategories), 5861 getChildBlockNames: () => (/* reexport */ getChildBlockNames), 5862 getDefaultBlockName: () => (/* reexport */ getDefaultBlockName), 5863 getFreeformContentHandlerName: () => (/* reexport */ getFreeformContentHandlerName), 5864 getGroupingBlockName: () => (/* reexport */ getGroupingBlockName), 5865 getPhrasingContentSchema: () => (/* reexport */ deprecatedGetPhrasingContentSchema), 5866 getPossibleBlockTransformations: () => (/* reexport */ getPossibleBlockTransformations), 5867 getSaveContent: () => (/* reexport */ getSaveContent), 5868 getSaveElement: () => (/* reexport */ getSaveElement), 5869 getUnregisteredTypeHandlerName: () => (/* reexport */ getUnregisteredTypeHandlerName), 5870 hasBlockSupport: () => (/* reexport */ hasBlockSupport), 5871 hasChildBlocks: () => (/* reexport */ hasChildBlocks), 5872 hasChildBlocksWithInserterSupport: () => (/* reexport */ hasChildBlocksWithInserterSupport), 5873 isReusableBlock: () => (/* reexport */ isReusableBlock), 5874 isTemplatePart: () => (/* reexport */ isTemplatePart), 5875 isUnmodifiedBlock: () => (/* reexport */ isUnmodifiedBlock), 5876 isUnmodifiedDefaultBlock: () => (/* reexport */ isUnmodifiedDefaultBlock), 5877 isValidBlockContent: () => (/* reexport */ isValidBlockContent), 5878 isValidIcon: () => (/* reexport */ isValidIcon), 5879 node: () => (/* reexport */ node), 5880 normalizeIconObject: () => (/* reexport */ normalizeIconObject), 5881 parse: () => (/* reexport */ parser_parse), 5882 parseWithAttributeSchema: () => (/* reexport */ parseWithAttributeSchema), 5883 pasteHandler: () => (/* reexport */ pasteHandler), 5884 privateApis: () => (/* reexport */ privateApis), 5885 rawHandler: () => (/* reexport */ rawHandler), 5886 registerBlockBindingsSource: () => (/* reexport */ registerBlockBindingsSource), 5887 registerBlockCollection: () => (/* reexport */ registerBlockCollection), 5888 registerBlockStyle: () => (/* reexport */ registerBlockStyle), 5889 registerBlockType: () => (/* reexport */ registerBlockType), 5890 registerBlockVariation: () => (/* reexport */ registerBlockVariation), 5891 serialize: () => (/* reexport */ serialize), 5892 serializeRawBlock: () => (/* reexport */ serializeRawBlock), 5893 setCategories: () => (/* reexport */ categories_setCategories), 5894 setDefaultBlockName: () => (/* reexport */ setDefaultBlockName), 5895 setFreeformContentHandlerName: () => (/* reexport */ setFreeformContentHandlerName), 5896 setGroupingBlockName: () => (/* reexport */ setGroupingBlockName), 5897 setUnregisteredTypeHandlerName: () => (/* reexport */ setUnregisteredTypeHandlerName), 5898 store: () => (/* reexport */ store), 5899 switchToBlockType: () => (/* reexport */ switchToBlockType), 5900 synchronizeBlocksWithTemplate: () => (/* reexport */ synchronizeBlocksWithTemplate), 5901 unregisterBlockBindingsSource: () => (/* reexport */ unregisterBlockBindingsSource), 5902 unregisterBlockStyle: () => (/* reexport */ unregisterBlockStyle), 5903 unregisterBlockType: () => (/* reexport */ unregisterBlockType), 5904 unregisterBlockVariation: () => (/* reexport */ unregisterBlockVariation), 5905 unstable__bootstrapServerSideBlockDefinitions: () => (/* reexport */ unstable__bootstrapServerSideBlockDefinitions), 5906 updateCategory: () => (/* reexport */ categories_updateCategory), 5907 validateBlock: () => (/* reexport */ validateBlock), 5908 withBlockContentContext: () => (/* reexport */ withBlockContentContext) 5909 }); 5910 5911 // NAMESPACE OBJECT: ./node_modules/@wordpress/blocks/build-module/store/private-selectors.js 5912 var private_selectors_namespaceObject = {}; 5913 __webpack_require__.r(private_selectors_namespaceObject); 5914 __webpack_require__.d(private_selectors_namespaceObject, { 5915 getAllBlockBindingsSources: () => (getAllBlockBindingsSources), 5916 getBlockBindingsSource: () => (private_selectors_getBlockBindingsSource), 5917 getBootstrappedBlockType: () => (getBootstrappedBlockType), 5918 getSupportedStyles: () => (getSupportedStyles), 5919 getUnprocessedBlockTypes: () => (getUnprocessedBlockTypes), 5920 hasContentRoleAttribute: () => (hasContentRoleAttribute) 5921 }); 5922 5923 // NAMESPACE OBJECT: ./node_modules/@wordpress/blocks/build-module/store/selectors.js 5924 var selectors_namespaceObject = {}; 5925 __webpack_require__.r(selectors_namespaceObject); 5926 __webpack_require__.d(selectors_namespaceObject, { 5927 __experimentalHasContentRoleAttribute: () => (__experimentalHasContentRoleAttribute), 5928 getActiveBlockVariation: () => (getActiveBlockVariation), 5929 getBlockStyles: () => (getBlockStyles), 5930 getBlockSupport: () => (selectors_getBlockSupport), 5931 getBlockType: () => (selectors_getBlockType), 5932 getBlockTypes: () => (selectors_getBlockTypes), 5933 getBlockVariations: () => (selectors_getBlockVariations), 5934 getCategories: () => (getCategories), 5935 getChildBlockNames: () => (selectors_getChildBlockNames), 5936 getCollections: () => (getCollections), 5937 getDefaultBlockName: () => (selectors_getDefaultBlockName), 5938 getDefaultBlockVariation: () => (getDefaultBlockVariation), 5939 getFreeformFallbackBlockName: () => (getFreeformFallbackBlockName), 5940 getGroupingBlockName: () => (selectors_getGroupingBlockName), 5941 getUnregisteredFallbackBlockName: () => (getUnregisteredFallbackBlockName), 5942 hasBlockSupport: () => (selectors_hasBlockSupport), 5943 hasChildBlocks: () => (selectors_hasChildBlocks), 5944 hasChildBlocksWithInserterSupport: () => (selectors_hasChildBlocksWithInserterSupport), 5945 isMatchingSearchTerm: () => (isMatchingSearchTerm) 5946 }); 5947 5948 // NAMESPACE OBJECT: ./node_modules/@wordpress/blocks/build-module/store/actions.js 5949 var actions_namespaceObject = {}; 5950 __webpack_require__.r(actions_namespaceObject); 5951 __webpack_require__.d(actions_namespaceObject, { 5952 __experimentalReapplyBlockFilters: () => (__experimentalReapplyBlockFilters), 5953 addBlockCollection: () => (addBlockCollection), 5954 addBlockStyles: () => (addBlockStyles), 5955 addBlockTypes: () => (addBlockTypes), 5956 addBlockVariations: () => (addBlockVariations), 5957 reapplyBlockTypeFilters: () => (reapplyBlockTypeFilters), 5958 removeBlockCollection: () => (removeBlockCollection), 5959 removeBlockStyles: () => (removeBlockStyles), 5960 removeBlockTypes: () => (removeBlockTypes), 5961 removeBlockVariations: () => (removeBlockVariations), 5962 setCategories: () => (setCategories), 5963 setDefaultBlockName: () => (actions_setDefaultBlockName), 5964 setFreeformFallbackBlockName: () => (setFreeformFallbackBlockName), 5965 setGroupingBlockName: () => (actions_setGroupingBlockName), 5966 setUnregisteredFallbackBlockName: () => (setUnregisteredFallbackBlockName), 5967 updateCategory: () => (updateCategory) 5968 }); 5969 5970 // NAMESPACE OBJECT: ./node_modules/@wordpress/blocks/build-module/store/private-actions.js 5971 var private_actions_namespaceObject = {}; 5972 __webpack_require__.r(private_actions_namespaceObject); 5973 __webpack_require__.d(private_actions_namespaceObject, { 5974 addBlockBindingsSource: () => (addBlockBindingsSource), 5975 addBootstrappedBlockType: () => (addBootstrappedBlockType), 5976 addUnprocessedBlockType: () => (addUnprocessedBlockType), 5977 removeBlockBindingsSource: () => (removeBlockBindingsSource) 5978 }); 5979 5980 ;// external ["wp","data"] 5981 const external_wp_data_namespaceObject = window["wp"]["data"]; 5982 ;// ./node_modules/tslib/tslib.es6.mjs 5983 /****************************************************************************** 5984 Copyright (c) Microsoft Corporation. 5985 5986 Permission to use, copy, modify, and/or distribute this software for any 5987 purpose with or without fee is hereby granted. 5988 5989 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 5990 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 5991 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 5992 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 5993 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 5994 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 5995 PERFORMANCE OF THIS SOFTWARE. 5996 ***************************************************************************** */ 5997 /* global Reflect, Promise, SuppressedError, Symbol, Iterator */ 5998 5999 var extendStatics = function(d, b) { 6000 extendStatics = Object.setPrototypeOf || 6001 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || 6002 function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; 6003 return extendStatics(d, b); 6004 }; 6005 6006 function __extends(d, b) { 6007 if (typeof b !== "function" && b !== null) 6008 throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); 6009 extendStatics(d, b); 6010 function __() { this.constructor = d; } 6011 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 6012 } 6013 6014 var __assign = function() { 6015 __assign = Object.assign || function __assign(t) { 6016 for (var s, i = 1, n = arguments.length; i < n; i++) { 6017 s = arguments[i]; 6018 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 6019 } 6020 return t; 6021 } 6022 return __assign.apply(this, arguments); 6023 } 6024 6025 function __rest(s, e) { 6026 var t = {}; 6027 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) 6028 t[p] = s[p]; 6029 if (s != null && typeof Object.getOwnPropertySymbols === "function") 6030 for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { 6031 if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) 6032 t[p[i]] = s[p[i]]; 6033 } 6034 return t; 6035 } 6036 6037 function __decorate(decorators, target, key, desc) { 6038 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 6039 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 6040 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; 6041 return c > 3 && r && Object.defineProperty(target, key, r), r; 6042 } 6043 6044 function __param(paramIndex, decorator) { 6045 return function (target, key) { decorator(target, key, paramIndex); } 6046 } 6047 6048 function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) { 6049 function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; } 6050 var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value"; 6051 var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null; 6052 var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {}); 6053 var _, done = false; 6054 for (var i = decorators.length - 1; i >= 0; i--) { 6055 var context = {}; 6056 for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p]; 6057 for (var p in contextIn.access) context.access[p] = contextIn.access[p]; 6058 context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); }; 6059 var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context); 6060 if (kind === "accessor") { 6061 if (result === void 0) continue; 6062 if (result === null || typeof result !== "object") throw new TypeError("Object expected"); 6063 if (_ = accept(result.get)) descriptor.get = _; 6064 if (_ = accept(result.set)) descriptor.set = _; 6065 if (_ = accept(result.init)) initializers.unshift(_); 6066 } 6067 else if (_ = accept(result)) { 6068 if (kind === "field") initializers.unshift(_); 6069 else descriptor[key] = _; 6070 } 6071 } 6072 if (target) Object.defineProperty(target, contextIn.name, descriptor); 6073 done = true; 6074 }; 6075 6076 function __runInitializers(thisArg, initializers, value) { 6077 var useValue = arguments.length > 2; 6078 for (var i = 0; i < initializers.length; i++) { 6079 value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg); 6080 } 6081 return useValue ? value : void 0; 6082 }; 6083 6084 function __propKey(x) { 6085 return typeof x === "symbol" ? x : "".concat(x); 6086 }; 6087 6088 function __setFunctionName(f, name, prefix) { 6089 if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : ""; 6090 return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name }); 6091 }; 6092 6093 function __metadata(metadataKey, metadataValue) { 6094 if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); 6095 } 6096 6097 function __awaiter(thisArg, _arguments, P, generator) { 6098 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 6099 return new (P || (P = Promise))(function (resolve, reject) { 6100 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 6101 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 6102 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 6103 step((generator = generator.apply(thisArg, _arguments || [])).next()); 6104 }); 6105 } 6106 6107 function __generator(thisArg, body) { 6108 var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype); 6109 return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; 6110 function verb(n) { return function (v) { return step([n, v]); }; } 6111 function step(op) { 6112 if (f) throw new TypeError("Generator is already executing."); 6113 while (g && (g = 0, op[0] && (_ = 0)), _) try { 6114 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; 6115 if (y = 0, t) op = [op[0] & 2, t.value]; 6116 switch (op[0]) { 6117 case 0: case 1: t = op; break; 6118 case 4: _.label++; return { value: op[1], done: false }; 6119 case 5: _.label++; y = op[1]; op = [0]; continue; 6120 case 7: op = _.ops.pop(); _.trys.pop(); continue; 6121 default: 6122 if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } 6123 if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } 6124 if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } 6125 if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } 6126 if (t[2]) _.ops.pop(); 6127 _.trys.pop(); continue; 6128 } 6129 op = body.call(thisArg, _); 6130 } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } 6131 if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; 6132 } 6133 } 6134 6135 var __createBinding = Object.create ? (function(o, m, k, k2) { 6136 if (k2 === undefined) k2 = k; 6137 var desc = Object.getOwnPropertyDescriptor(m, k); 6138 if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6139 desc = { enumerable: true, get: function() { return m[k]; } }; 6140 } 6141 Object.defineProperty(o, k2, desc); 6142 }) : (function(o, m, k, k2) { 6143 if (k2 === undefined) k2 = k; 6144 o[k2] = m[k]; 6145 }); 6146 6147 function __exportStar(m, o) { 6148 for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p); 6149 } 6150 6151 function __values(o) { 6152 var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; 6153 if (m) return m.call(o); 6154 if (o && typeof o.length === "number") return { 6155 next: function () { 6156 if (o && i >= o.length) o = void 0; 6157 return { value: o && o[i++], done: !o }; 6158 } 6159 }; 6160 throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); 6161 } 6162 6163 function __read(o, n) { 6164 var m = typeof Symbol === "function" && o[Symbol.iterator]; 6165 if (!m) return o; 6166 var i = m.call(o), r, ar = [], e; 6167 try { 6168 while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); 6169 } 6170 catch (error) { e = { error: error }; } 6171 finally { 6172 try { 6173 if (r && !r.done && (m = i["return"])) m.call(i); 6174 } 6175 finally { if (e) throw e.error; } 6176 } 6177 return ar; 6178 } 6179 6180 /** @deprecated */ 6181 function __spread() { 6182 for (var ar = [], i = 0; i < arguments.length; i++) 6183 ar = ar.concat(__read(arguments[i])); 6184 return ar; 6185 } 6186 6187 /** @deprecated */ 6188 function __spreadArrays() { 6189 for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; 6190 for (var r = Array(s), k = 0, i = 0; i < il; i++) 6191 for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) 6192 r[k] = a[j]; 6193 return r; 6194 } 6195 6196 function __spreadArray(to, from, pack) { 6197 if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { 6198 if (ar || !(i in from)) { 6199 if (!ar) ar = Array.prototype.slice.call(from, 0, i); 6200 ar[i] = from[i]; 6201 } 6202 } 6203 return to.concat(ar || Array.prototype.slice.call(from)); 6204 } 6205 6206 function __await(v) { 6207 return this instanceof __await ? (this.v = v, this) : new __await(v); 6208 } 6209 6210 function __asyncGenerator(thisArg, _arguments, generator) { 6211 if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); 6212 var g = generator.apply(thisArg, _arguments || []), i, q = []; 6213 return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i; 6214 function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; } 6215 function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } } 6216 function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } 6217 function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } 6218 function fulfill(value) { resume("next", value); } 6219 function reject(value) { resume("throw", value); } 6220 function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } 6221 } 6222 6223 function __asyncDelegator(o) { 6224 var i, p; 6225 return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; 6226 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; } 6227 } 6228 6229 function __asyncValues(o) { 6230 if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); 6231 var m = o[Symbol.asyncIterator], i; 6232 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); 6233 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); }); }; } 6234 function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } 6235 } 6236 6237 function __makeTemplateObject(cooked, raw) { 6238 if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } 6239 return cooked; 6240 }; 6241 6242 var __setModuleDefault = Object.create ? (function(o, v) { 6243 Object.defineProperty(o, "default", { enumerable: true, value: v }); 6244 }) : function(o, v) { 6245 o["default"] = v; 6246 }; 6247 6248 var ownKeys = function(o) { 6249 ownKeys = Object.getOwnPropertyNames || function (o) { 6250 var ar = []; 6251 for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; 6252 return ar; 6253 }; 6254 return ownKeys(o); 6255 }; 6256 6257 function __importStar(mod) { 6258 if (mod && mod.__esModule) return mod; 6259 var result = {}; 6260 if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); 6261 __setModuleDefault(result, mod); 6262 return result; 6263 } 6264 6265 function __importDefault(mod) { 6266 return (mod && mod.__esModule) ? mod : { default: mod }; 6267 } 6268 6269 function __classPrivateFieldGet(receiver, state, kind, f) { 6270 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); 6271 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"); 6272 return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); 6273 } 6274 6275 function __classPrivateFieldSet(receiver, state, value, kind, f) { 6276 if (kind === "m") throw new TypeError("Private method is not writable"); 6277 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); 6278 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"); 6279 return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; 6280 } 6281 6282 function __classPrivateFieldIn(state, receiver) { 6283 if (receiver === null || (typeof receiver !== "object" && typeof receiver !== "function")) throw new TypeError("Cannot use 'in' operator on non-object"); 6284 return typeof state === "function" ? receiver === state : state.has(receiver); 6285 } 6286 6287 function __addDisposableResource(env, value, async) { 6288 if (value !== null && value !== void 0) { 6289 if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected."); 6290 var dispose, inner; 6291 if (async) { 6292 if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined."); 6293 dispose = value[Symbol.asyncDispose]; 6294 } 6295 if (dispose === void 0) { 6296 if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined."); 6297 dispose = value[Symbol.dispose]; 6298 if (async) inner = dispose; 6299 } 6300 if (typeof dispose !== "function") throw new TypeError("Object not disposable."); 6301 if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } }; 6302 env.stack.push({ value: value, dispose: dispose, async: async }); 6303 } 6304 else if (async) { 6305 env.stack.push({ async: true }); 6306 } 6307 return value; 6308 } 6309 6310 var _SuppressedError = typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { 6311 var e = new Error(message); 6312 return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; 6313 }; 6314 6315 function __disposeResources(env) { 6316 function fail(e) { 6317 env.error = env.hasError ? new _SuppressedError(e, env.error, "An error was suppressed during disposal.") : e; 6318 env.hasError = true; 6319 } 6320 var r, s = 0; 6321 function next() { 6322 while (r = env.stack.pop()) { 6323 try { 6324 if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next); 6325 if (r.dispose) { 6326 var result = r.dispose.call(r.value); 6327 if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); }); 6328 } 6329 else s |= 1; 6330 } 6331 catch (e) { 6332 fail(e); 6333 } 6334 } 6335 if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve(); 6336 if (env.hasError) throw env.error; 6337 } 6338 return next(); 6339 } 6340 6341 function __rewriteRelativeImportExtension(path, preserveJsx) { 6342 if (typeof path === "string" && /^\.\.?\//.test(path)) { 6343 return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) { 6344 return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js"); 6345 }); 6346 } 6347 return path; 6348 } 6349 6350 /* harmony default export */ const tslib_es6 = ({ 6351 __extends, 6352 __assign, 6353 __rest, 6354 __decorate, 6355 __param, 6356 __esDecorate, 6357 __runInitializers, 6358 __propKey, 6359 __setFunctionName, 6360 __metadata, 6361 __awaiter, 6362 __generator, 6363 __createBinding, 6364 __exportStar, 6365 __values, 6366 __read, 6367 __spread, 6368 __spreadArrays, 6369 __spreadArray, 6370 __await, 6371 __asyncGenerator, 6372 __asyncDelegator, 6373 __asyncValues, 6374 __makeTemplateObject, 6375 __importStar, 6376 __importDefault, 6377 __classPrivateFieldGet, 6378 __classPrivateFieldSet, 6379 __classPrivateFieldIn, 6380 __addDisposableResource, 6381 __disposeResources, 6382 __rewriteRelativeImportExtension, 6383 }); 6384 6385 ;// ./node_modules/lower-case/dist.es2015/index.js 6386 /** 6387 * Source: ftp://ftp.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt 6388 */ 6389 var SUPPORTED_LOCALE = { 6390 tr: { 6391 regexp: /\u0130|\u0049|\u0049\u0307/g, 6392 map: { 6393 İ: "\u0069", 6394 I: "\u0131", 6395 İ: "\u0069", 6396 }, 6397 }, 6398 az: { 6399 regexp: /\u0130/g, 6400 map: { 6401 İ: "\u0069", 6402 I: "\u0131", 6403 İ: "\u0069", 6404 }, 6405 }, 6406 lt: { 6407 regexp: /\u0049|\u004A|\u012E|\u00CC|\u00CD|\u0128/g, 6408 map: { 6409 I: "\u0069\u0307", 6410 J: "\u006A\u0307", 6411 Į: "\u012F\u0307", 6412 Ì: "\u0069\u0307\u0300", 6413 Í: "\u0069\u0307\u0301", 6414 Ĩ: "\u0069\u0307\u0303", 6415 }, 6416 }, 6417 }; 6418 /** 6419 * Localized lower case. 6420 */ 6421 function localeLowerCase(str, locale) { 6422 var lang = SUPPORTED_LOCALE[locale.toLowerCase()]; 6423 if (lang) 6424 return lowerCase(str.replace(lang.regexp, function (m) { return lang.map[m]; })); 6425 return lowerCase(str); 6426 } 6427 /** 6428 * Lower case as a function. 6429 */ 6430 function lowerCase(str) { 6431 return str.toLowerCase(); 6432 } 6433 6434 ;// ./node_modules/no-case/dist.es2015/index.js 6435 6436 // Support camel case ("camelCase" -> "camel Case" and "CAMELCase" -> "CAMEL Case"). 6437 var DEFAULT_SPLIT_REGEXP = [/([a-z0-9])([A-Z])/g, /([A-Z])([A-Z][a-z])/g]; 6438 // Remove all non-word characters. 6439 var DEFAULT_STRIP_REGEXP = /[^A-Z0-9]+/gi; 6440 /** 6441 * Normalize the string into something other libraries can manipulate easier. 6442 */ 6443 function noCase(input, options) { 6444 if (options === void 0) { options = {}; } 6445 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; 6446 var result = replace(replace(input, splitRegexp, "$1\0$2"), stripRegexp, "\0"); 6447 var start = 0; 6448 var end = result.length; 6449 // Trim the delimiter from around the output string. 6450 while (result.charAt(start) === "\0") 6451 start++; 6452 while (result.charAt(end - 1) === "\0") 6453 end--; 6454 // Transform each token independently. 6455 return result.slice(start, end).split("\0").map(transform).join(delimiter); 6456 } 6457 /** 6458 * Replace `re` in the input string with the replacement value. 6459 */ 6460 function replace(input, re, value) { 6461 if (re instanceof RegExp) 6462 return input.replace(re, value); 6463 return re.reduce(function (input, re) { return input.replace(re, value); }, input); 6464 } 6465 6466 ;// ./node_modules/pascal-case/dist.es2015/index.js 6467 6468 6469 function pascalCaseTransform(input, index) { 6470 var firstChar = input.charAt(0); 6471 var lowerChars = input.substr(1).toLowerCase(); 6472 if (index > 0 && firstChar >= "0" && firstChar <= "9") { 6473 return "_" + firstChar + lowerChars; 6474 } 6475 return "" + firstChar.toUpperCase() + lowerChars; 6476 } 6477 function dist_es2015_pascalCaseTransformMerge(input) { 6478 return input.charAt(0).toUpperCase() + input.slice(1).toLowerCase(); 6479 } 6480 function pascalCase(input, options) { 6481 if (options === void 0) { options = {}; } 6482 return noCase(input, __assign({ delimiter: "", transform: pascalCaseTransform }, options)); 6483 } 6484 6485 ;// ./node_modules/camel-case/dist.es2015/index.js 6486 6487 6488 function camelCaseTransform(input, index) { 6489 if (index === 0) 6490 return input.toLowerCase(); 6491 return pascalCaseTransform(input, index); 6492 } 6493 function camelCaseTransformMerge(input, index) { 6494 if (index === 0) 6495 return input.toLowerCase(); 6496 return pascalCaseTransformMerge(input); 6497 } 6498 function camelCase(input, options) { 6499 if (options === void 0) { options = {}; } 6500 return pascalCase(input, __assign({ transform: camelCaseTransform }, options)); 6501 } 6502 6503 ;// external ["wp","i18n"] 6504 const external_wp_i18n_namespaceObject = window["wp"]["i18n"]; 6505 ;// ./node_modules/colord/index.mjs 6506 var r={grad:.9,turn:360,rad:360/(2*Math.PI)},t=function(r){return"string"==typeof r?r.length>0:"number"==typeof r},n=function(r,t,n){return void 0===t&&(t=0),void 0===n&&(n=Math.pow(10,t)),Math.round(n*r)/n+0},e=function(r,t,n){return void 0===t&&(t=0),void 0===n&&(n=1),r>n?n:r>t?r:t},u=function(r){return(r=isFinite(r)?r%360:0)>0?r:r+360},a=function(r){return{r:e(r.r,0,255),g:e(r.g,0,255),b:e(r.b,0,255),a:e(r.a)}},o=function(r){return{r:n(r.r),g:n(r.g),b:n(r.b),a:n(r.a,3)}},i=/^#([0-9a-f]{3,8})$/i,s=function(r){var t=r.toString(16);return t.length<2?"0"+t:t},h=function(r){var t=r.r,n=r.g,e=r.b,u=r.a,a=Math.max(t,n,e),o=a-Math.min(t,n,e),i=o?a===t?(n-e)/o:a===n?2+(e-t)/o:4+(t-n)/o:0;return{h:60*(i<0?i+6:i),s:a?o/a*100:0,v:a/255*100,a:u}},b=function(r){var t=r.h,n=r.s,e=r.v,u=r.a;t=t/360*6,n/=100,e/=100;var a=Math.floor(t),o=e*(1-n),i=e*(1-(t-a)*n),s=e*(1-(1-t+a)*n),h=a%6;return{r:255*[e,i,o,o,s,e][h],g:255*[s,e,e,i,o,o][h],b:255*[o,o,s,e,e,i][h],a:u}},g=function(r){return{h:u(r.h),s:e(r.s,0,100),l:e(r.l,0,100),a:e(r.a)}},d=function(r){return{h:n(r.h),s:n(r.s),l:n(r.l),a:n(r.a,3)}},f=function(r){return b((n=(t=r).s,{h:t.h,s:(n*=((e=t.l)<50?e:100-e)/100)>0?2*n/(e+n)*100:0,v:e+n,a:t.a}));var t,n,e},c=function(r){return{h:(t=h(r)).h,s:(u=(200-(n=t.s))*(e=t.v)/100)>0&&u<200?n*e/100/(u<=100?u:200-u)*100:0,l:u/2,a:t.a};var t,n,e,u},l=/^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s*,\s*([+-]?\d*\.?\d+)%\s*,\s*([+-]?\d*\.?\d+)%\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,p=/^hsla?\(\s*([+-]?\d*\.?\d+)(deg|rad|grad|turn)?\s+([+-]?\d*\.?\d+)%\s+([+-]?\d*\.?\d+)%\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,v=/^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*,\s*([+-]?\d*\.?\d+)(%)?\s*(?:,\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,m=/^rgba?\(\s*([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s+([+-]?\d*\.?\d+)(%)?\s*(?:\/\s*([+-]?\d*\.?\d+)(%)?\s*)?\)$/i,y={string:[[function(r){var t=i.exec(r);return t?(r=t[1]).length<=4?{r:parseInt(r[0]+r[0],16),g:parseInt(r[1]+r[1],16),b:parseInt(r[2]+r[2],16),a:4===r.length?n(parseInt(r[3]+r[3],16)/255,2):1}:6===r.length||8===r.length?{r:parseInt(r.substr(0,2),16),g:parseInt(r.substr(2,2),16),b:parseInt(r.substr(4,2),16),a:8===r.length?n(parseInt(r.substr(6,2),16)/255,2):1}:null:null},"hex"],[function(r){var t=v.exec(r)||m.exec(r);return t?t[2]!==t[4]||t[4]!==t[6]?null:a({r:Number(t[1])/(t[2]?100/255:1),g:Number(t[3])/(t[4]?100/255:1),b:Number(t[5])/(t[6]?100/255:1),a:void 0===t[7]?1:Number(t[7])/(t[8]?100:1)}):null},"rgb"],[function(t){var n=l.exec(t)||p.exec(t);if(!n)return null;var e,u,a=g({h:(e=n[1],u=n[2],void 0===u&&(u="deg"),Number(e)*(r[u]||1)),s:Number(n[3]),l:Number(n[4]),a:void 0===n[5]?1:Number(n[5])/(n[6]?100:1)});return f(a)},"hsl"]],object:[[function(r){var n=r.r,e=r.g,u=r.b,o=r.a,i=void 0===o?1:o;return t(n)&&t(e)&&t(u)?a({r:Number(n),g:Number(e),b:Number(u),a:Number(i)}):null},"rgb"],[function(r){var n=r.h,e=r.s,u=r.l,a=r.a,o=void 0===a?1:a;if(!t(n)||!t(e)||!t(u))return null;var i=g({h:Number(n),s:Number(e),l:Number(u),a:Number(o)});return f(i)},"hsl"],[function(r){var n=r.h,a=r.s,o=r.v,i=r.a,s=void 0===i?1:i;if(!t(n)||!t(a)||!t(o))return null;var h=function(r){return{h:u(r.h),s:e(r.s,0,100),v:e(r.v,0,100),a:e(r.a)}}({h:Number(n),s:Number(a),v:Number(o),a:Number(s)});return b(h)},"hsv"]]},N=function(r,t){for(var n=0;n<t.length;n++){var e=t[n][0](r);if(e)return[e,t[n][1]]}return[null,void 0]},x=function(r){return"string"==typeof r?N(r.trim(),y.string):"object"==typeof r&&null!==r?N(r,y.object):[null,void 0]},I=function(r){return x(r)[1]},M=function(r,t){var n=c(r);return{h:n.h,s:e(n.s+100*t,0,100),l:n.l,a:n.a}},H=function(r){return(299*r.r+587*r.g+114*r.b)/1e3/255},$=function(r,t){var n=c(r);return{h:n.h,s:n.s,l:e(n.l+100*t,0,100),a:n.a}},j=function(){function r(r){this.parsed=x(r)[0],this.rgba=this.parsed||{r:0,g:0,b:0,a:1}}return r.prototype.isValid=function(){return null!==this.parsed},r.prototype.brightness=function(){return n(H(this.rgba),2)},r.prototype.isDark=function(){return H(this.rgba)<.5},r.prototype.isLight=function(){return H(this.rgba)>=.5},r.prototype.toHex=function(){return r=o(this.rgba),t=r.r,e=r.g,u=r.b,i=(a=r.a)<1?s(n(255*a)):"","#"+s(t)+s(e)+s(u)+i;var r,t,e,u,a,i},r.prototype.toRgb=function(){return o(this.rgba)},r.prototype.toRgbString=function(){return r=o(this.rgba),t=r.r,n=r.g,e=r.b,(u=r.a)<1?"rgba("+t+", "+n+", "+e+", "+u+")":"rgb("+t+", "+n+", "+e+")";var r,t,n,e,u},r.prototype.toHsl=function(){return d(c(this.rgba))},r.prototype.toHslString=function(){return r=d(c(this.rgba)),t=r.h,n=r.s,e=r.l,(u=r.a)<1?"hsla("+t+", "+n+"%, "+e+"%, "+u+")":"hsl("+t+", "+n+"%, "+e+"%)";var r,t,n,e,u},r.prototype.toHsv=function(){return r=h(this.rgba),{h:n(r.h),s:n(r.s),v:n(r.v),a:n(r.a,3)};var r},r.prototype.invert=function(){return w({r:255-(r=this.rgba).r,g:255-r.g,b:255-r.b,a:r.a});var r},r.prototype.saturate=function(r){return void 0===r&&(r=.1),w(M(this.rgba,r))},r.prototype.desaturate=function(r){return void 0===r&&(r=.1),w(M(this.rgba,-r))},r.prototype.grayscale=function(){return w(M(this.rgba,-1))},r.prototype.lighten=function(r){return void 0===r&&(r=.1),w($(this.rgba,r))},r.prototype.darken=function(r){return void 0===r&&(r=.1),w($(this.rgba,-r))},r.prototype.rotate=function(r){return void 0===r&&(r=15),this.hue(this.hue()+r)},r.prototype.alpha=function(r){return"number"==typeof r?w({r:(t=this.rgba).r,g:t.g,b:t.b,a:r}):n(this.rgba.a,3);var t},r.prototype.hue=function(r){var t=c(this.rgba);return"number"==typeof r?w({h:r,s:t.s,l:t.l,a:t.a}):n(t.h)},r.prototype.isEqual=function(r){return this.toHex()===w(r).toHex()},r}(),w=function(r){return r instanceof j?r:new j(r)},S=[],k=function(r){r.forEach(function(r){S.indexOf(r)<0&&(r(j,y),S.push(r))})},E=function(){return new j({r:255*Math.random(),g:255*Math.random(),b:255*Math.random()})}; 6507 6508 ;// ./node_modules/colord/plugins/names.mjs 6509 /* harmony default export */ function names(e,f){var a={white:"#ffffff",bisque:"#ffe4c4",blue:"#0000ff",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",antiquewhite:"#faebd7",aqua:"#00ffff",azure:"#f0ffff",whitesmoke:"#f5f5f5",papayawhip:"#ffefd5",plum:"#dda0dd",blanchedalmond:"#ffebcd",black:"#000000",gold:"#ffd700",goldenrod:"#daa520",gainsboro:"#dcdcdc",cornsilk:"#fff8dc",cornflowerblue:"#6495ed",burlywood:"#deb887",aquamarine:"#7fffd4",beige:"#f5f5dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkkhaki:"#bdb76b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",peachpuff:"#ffdab9",darkmagenta:"#8b008b",darkred:"#8b0000",darkorchid:"#9932cc",darkorange:"#ff8c00",darkslateblue:"#483d8b",gray:"#808080",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",deeppink:"#ff1493",deepskyblue:"#00bfff",wheat:"#f5deb3",firebrick:"#b22222",floralwhite:"#fffaf0",ghostwhite:"#f8f8ff",darkviolet:"#9400d3",magenta:"#ff00ff",green:"#008000",dodgerblue:"#1e90ff",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",blueviolet:"#8a2be2",forestgreen:"#228b22",lawngreen:"#7cfc00",indianred:"#cd5c5c",indigo:"#4b0082",fuchsia:"#ff00ff",brown:"#a52a2a",maroon:"#800000",mediumblue:"#0000cd",lightcoral:"#f08080",darkturquoise:"#00ced1",lightcyan:"#e0ffff",ivory:"#fffff0",lightyellow:"#ffffe0",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",linen:"#faf0e6",mediumaquamarine:"#66cdaa",lemonchiffon:"#fffacd",lime:"#00ff00",khaki:"#f0e68c",mediumseagreen:"#3cb371",limegreen:"#32cd32",mediumspringgreen:"#00fa9a",lightskyblue:"#87cefa",lightblue:"#add8e6",midnightblue:"#191970",lightpink:"#ffb6c1",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",mintcream:"#f5fffa",lightslategray:"#778899",lightslategrey:"#778899",navajowhite:"#ffdead",navy:"#000080",mediumvioletred:"#c71585",powderblue:"#b0e0e6",palegoldenrod:"#eee8aa",oldlace:"#fdf5e6",paleturquoise:"#afeeee",mediumturquoise:"#48d1cc",mediumorchid:"#ba55d3",rebeccapurple:"#663399",lightsteelblue:"#b0c4de",mediumslateblue:"#7b68ee",thistle:"#d8bfd8",tan:"#d2b48c",orchid:"#da70d6",mediumpurple:"#9370db",purple:"#800080",pink:"#ffc0cb",skyblue:"#87ceeb",springgreen:"#00ff7f",palegreen:"#98fb98",red:"#ff0000",yellow:"#ffff00",slateblue:"#6a5acd",lavenderblush:"#fff0f5",peru:"#cd853f",palevioletred:"#db7093",violet:"#ee82ee",teal:"#008080",slategray:"#708090",slategrey:"#708090",aliceblue:"#f0f8ff",darkseagreen:"#8fbc8f",darkolivegreen:"#556b2f",greenyellow:"#adff2f",seagreen:"#2e8b57",seashell:"#fff5ee",tomato:"#ff6347",silver:"#c0c0c0",sienna:"#a0522d",lavender:"#e6e6fa",lightgreen:"#90ee90",orange:"#ffa500",orangered:"#ff4500",steelblue:"#4682b4",royalblue:"#4169e1",turquoise:"#40e0d0",yellowgreen:"#9acd32",salmon:"#fa8072",saddlebrown:"#8b4513",sandybrown:"#f4a460",rosybrown:"#bc8f8f",darksalmon:"#e9967a",lightgoldenrodyellow:"#fafad2",snow:"#fffafa",lightgrey:"#d3d3d3",lightgray:"#d3d3d3",dimgray:"#696969",dimgrey:"#696969",olivedrab:"#6b8e23",olive:"#808000"},r={};for(var d in a)r[a[d]]=d;var l={};e.prototype.toName=function(f){if(!(this.rgba.a||this.rgba.r||this.rgba.g||this.rgba.b))return"transparent";var d,i,n=r[this.toHex()];if(n)return n;if(null==f?void 0:f.closest){var o=this.toRgb(),t=1/0,b="black";if(!l.length)for(var c in a)l[c]=new e(a[c]).toRgb();for(var g in a){var u=(d=o,i=l[g],Math.pow(d.r-i.r,2)+Math.pow(d.g-i.g,2)+Math.pow(d.b-i.b,2));u<t&&(t=u,b=g)}return b}};f.string.push([function(f){var r=f.toLowerCase(),d="transparent"===r?"#0000":a[r];return d?new e(d).toRgb():null},"name"])} 6510 6511 ;// ./node_modules/colord/plugins/a11y.mjs 6512 var a11y_o=function(o){var t=o/255;return t<.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)},a11y_t=function(t){return.2126*a11y_o(t.r)+.7152*a11y_o(t.g)+.0722*a11y_o(t.b)};/* harmony default export */ function a11y(o){o.prototype.luminance=function(){return o=a11y_t(this.rgba),void 0===(r=2)&&(r=0),void 0===n&&(n=Math.pow(10,r)),Math.round(n*o)/n+0;var o,r,n},o.prototype.contrast=function(r){void 0===r&&(r="#FFF");var n,a,i,e,v,u,d,c=r instanceof o?r:new o(r);return e=this.rgba,v=c.toRgb(),u=a11y_t(e),d=a11y_t(v),n=u>d?(u+.05)/(d+.05):(d+.05)/(u+.05),void 0===(a=2)&&(a=0),void 0===i&&(i=Math.pow(10,a)),Math.floor(i*n)/i+0},o.prototype.isReadable=function(o,t){return void 0===o&&(o="#FFF"),void 0===t&&(t={}),this.contrast(o)>=(e=void 0===(i=(r=t).size)?"normal":i,"AAA"===(a=void 0===(n=r.level)?"AA":n)&&"normal"===e?7:"AA"===a&&"large"===e?3:4.5);var r,n,a,i,e}} 6513 6514 ;// external ["wp","element"] 6515 const external_wp_element_namespaceObject = window["wp"]["element"]; 6516 ;// external ["wp","dom"] 6517 const external_wp_dom_namespaceObject = window["wp"]["dom"]; 6518 ;// external ["wp","richText"] 6519 const external_wp_richText_namespaceObject = window["wp"]["richText"]; 6520 ;// external ["wp","deprecated"] 6521 const external_wp_deprecated_namespaceObject = window["wp"]["deprecated"]; 6522 var external_wp_deprecated_default = /*#__PURE__*/__webpack_require__.n(external_wp_deprecated_namespaceObject); 6523 ;// ./node_modules/@wordpress/blocks/build-module/api/constants.js 6524 const BLOCK_ICON_DEFAULT = 'block-default'; 6525 6526 /** 6527 * Array of valid keys in a block type settings deprecation object. 6528 * 6529 * @type {string[]} 6530 */ 6531 const DEPRECATED_ENTRY_KEYS = ['attributes', 'supports', 'save', 'migrate', 'isEligible', 'apiVersion']; 6532 const __EXPERIMENTAL_STYLE_PROPERTY = { 6533 // Kept for back-compatibility purposes. 6534 '--wp--style--color--link': { 6535 value: ['color', 'link'], 6536 support: ['color', 'link'] 6537 }, 6538 aspectRatio: { 6539 value: ['dimensions', 'aspectRatio'], 6540 support: ['dimensions', 'aspectRatio'], 6541 useEngine: true 6542 }, 6543 background: { 6544 value: ['color', 'gradient'], 6545 support: ['color', 'gradients'], 6546 useEngine: true 6547 }, 6548 backgroundColor: { 6549 value: ['color', 'background'], 6550 support: ['color', 'background'], 6551 requiresOptOut: true, 6552 useEngine: true 6553 }, 6554 backgroundImage: { 6555 value: ['background', 'backgroundImage'], 6556 support: ['background', 'backgroundImage'], 6557 useEngine: true 6558 }, 6559 backgroundRepeat: { 6560 value: ['background', 'backgroundRepeat'], 6561 support: ['background', 'backgroundRepeat'], 6562 useEngine: true 6563 }, 6564 backgroundSize: { 6565 value: ['background', 'backgroundSize'], 6566 support: ['background', 'backgroundSize'], 6567 useEngine: true 6568 }, 6569 backgroundPosition: { 6570 value: ['background', 'backgroundPosition'], 6571 support: ['background', 'backgroundPosition'], 6572 useEngine: true 6573 }, 6574 borderColor: { 6575 value: ['border', 'color'], 6576 support: ['__experimentalBorder', 'color'], 6577 useEngine: true 6578 }, 6579 borderRadius: { 6580 value: ['border', 'radius'], 6581 support: ['__experimentalBorder', 'radius'], 6582 properties: { 6583 borderTopLeftRadius: 'topLeft', 6584 borderTopRightRadius: 'topRight', 6585 borderBottomLeftRadius: 'bottomLeft', 6586 borderBottomRightRadius: 'bottomRight' 6587 }, 6588 useEngine: true 6589 }, 6590 borderStyle: { 6591 value: ['border', 'style'], 6592 support: ['__experimentalBorder', 'style'], 6593 useEngine: true 6594 }, 6595 borderWidth: { 6596 value: ['border', 'width'], 6597 support: ['__experimentalBorder', 'width'], 6598 useEngine: true 6599 }, 6600 borderTopColor: { 6601 value: ['border', 'top', 'color'], 6602 support: ['__experimentalBorder', 'color'], 6603 useEngine: true 6604 }, 6605 borderTopStyle: { 6606 value: ['border', 'top', 'style'], 6607 support: ['__experimentalBorder', 'style'], 6608 useEngine: true 6609 }, 6610 borderTopWidth: { 6611 value: ['border', 'top', 'width'], 6612 support: ['__experimentalBorder', 'width'], 6613 useEngine: true 6614 }, 6615 borderRightColor: { 6616 value: ['border', 'right', 'color'], 6617 support: ['__experimentalBorder', 'color'], 6618 useEngine: true 6619 }, 6620 borderRightStyle: { 6621 value: ['border', 'right', 'style'], 6622 support: ['__experimentalBorder', 'style'], 6623 useEngine: true 6624 }, 6625 borderRightWidth: { 6626 value: ['border', 'right', 'width'], 6627 support: ['__experimentalBorder', 'width'], 6628 useEngine: true 6629 }, 6630 borderBottomColor: { 6631 value: ['border', 'bottom', 'color'], 6632 support: ['__experimentalBorder', 'color'], 6633 useEngine: true 6634 }, 6635 borderBottomStyle: { 6636 value: ['border', 'bottom', 'style'], 6637 support: ['__experimentalBorder', 'style'], 6638 useEngine: true 6639 }, 6640 borderBottomWidth: { 6641 value: ['border', 'bottom', 'width'], 6642 support: ['__experimentalBorder', 'width'], 6643 useEngine: true 6644 }, 6645 borderLeftColor: { 6646 value: ['border', 'left', 'color'], 6647 support: ['__experimentalBorder', 'color'], 6648 useEngine: true 6649 }, 6650 borderLeftStyle: { 6651 value: ['border', 'left', 'style'], 6652 support: ['__experimentalBorder', 'style'], 6653 useEngine: true 6654 }, 6655 borderLeftWidth: { 6656 value: ['border', 'left', 'width'], 6657 support: ['__experimentalBorder', 'width'], 6658 useEngine: true 6659 }, 6660 color: { 6661 value: ['color', 'text'], 6662 support: ['color', 'text'], 6663 requiresOptOut: true, 6664 useEngine: true 6665 }, 6666 columnCount: { 6667 value: ['typography', 'textColumns'], 6668 support: ['typography', 'textColumns'], 6669 useEngine: true 6670 }, 6671 filter: { 6672 value: ['filter', 'duotone'], 6673 support: ['filter', 'duotone'] 6674 }, 6675 linkColor: { 6676 value: ['elements', 'link', 'color', 'text'], 6677 support: ['color', 'link'] 6678 }, 6679 captionColor: { 6680 value: ['elements', 'caption', 'color', 'text'], 6681 support: ['color', 'caption'] 6682 }, 6683 buttonColor: { 6684 value: ['elements', 'button', 'color', 'text'], 6685 support: ['color', 'button'] 6686 }, 6687 buttonBackgroundColor: { 6688 value: ['elements', 'button', 'color', 'background'], 6689 support: ['color', 'button'] 6690 }, 6691 headingColor: { 6692 value: ['elements', 'heading', 'color', 'text'], 6693 support: ['color', 'heading'] 6694 }, 6695 headingBackgroundColor: { 6696 value: ['elements', 'heading', 'color', 'background'], 6697 support: ['color', 'heading'] 6698 }, 6699 fontFamily: { 6700 value: ['typography', 'fontFamily'], 6701 support: ['typography', '__experimentalFontFamily'], 6702 useEngine: true 6703 }, 6704 fontSize: { 6705 value: ['typography', 'fontSize'], 6706 support: ['typography', 'fontSize'], 6707 useEngine: true 6708 }, 6709 fontStyle: { 6710 value: ['typography', 'fontStyle'], 6711 support: ['typography', '__experimentalFontStyle'], 6712 useEngine: true 6713 }, 6714 fontWeight: { 6715 value: ['typography', 'fontWeight'], 6716 support: ['typography', '__experimentalFontWeight'], 6717 useEngine: true 6718 }, 6719 lineHeight: { 6720 value: ['typography', 'lineHeight'], 6721 support: ['typography', 'lineHeight'], 6722 useEngine: true 6723 }, 6724 margin: { 6725 value: ['spacing', 'margin'], 6726 support: ['spacing', 'margin'], 6727 properties: { 6728 marginTop: 'top', 6729 marginRight: 'right', 6730 marginBottom: 'bottom', 6731 marginLeft: 'left' 6732 }, 6733 useEngine: true 6734 }, 6735 minHeight: { 6736 value: ['dimensions', 'minHeight'], 6737 support: ['dimensions', 'minHeight'], 6738 useEngine: true 6739 }, 6740 padding: { 6741 value: ['spacing', 'padding'], 6742 support: ['spacing', 'padding'], 6743 properties: { 6744 paddingTop: 'top', 6745 paddingRight: 'right', 6746 paddingBottom: 'bottom', 6747 paddingLeft: 'left' 6748 }, 6749 useEngine: true 6750 }, 6751 textAlign: { 6752 value: ['typography', 'textAlign'], 6753 support: ['typography', 'textAlign'], 6754 useEngine: false 6755 }, 6756 textDecoration: { 6757 value: ['typography', 'textDecoration'], 6758 support: ['typography', '__experimentalTextDecoration'], 6759 useEngine: true 6760 }, 6761 textTransform: { 6762 value: ['typography', 'textTransform'], 6763 support: ['typography', '__experimentalTextTransform'], 6764 useEngine: true 6765 }, 6766 letterSpacing: { 6767 value: ['typography', 'letterSpacing'], 6768 support: ['typography', '__experimentalLetterSpacing'], 6769 useEngine: true 6770 }, 6771 writingMode: { 6772 value: ['typography', 'writingMode'], 6773 support: ['typography', '__experimentalWritingMode'], 6774 useEngine: true 6775 }, 6776 '--wp--style--root--padding': { 6777 value: ['spacing', 'padding'], 6778 support: ['spacing', 'padding'], 6779 properties: { 6780 '--wp--style--root--padding-top': 'top', 6781 '--wp--style--root--padding-right': 'right', 6782 '--wp--style--root--padding-bottom': 'bottom', 6783 '--wp--style--root--padding-left': 'left' 6784 }, 6785 rootOnly: true 6786 } 6787 }; 6788 const __EXPERIMENTAL_ELEMENTS = { 6789 link: 'a:where(:not(.wp-element-button))', 6790 heading: 'h1, h2, h3, h4, h5, h6', 6791 h1: 'h1', 6792 h2: 'h2', 6793 h3: 'h3', 6794 h4: 'h4', 6795 h5: 'h5', 6796 h6: 'h6', 6797 button: '.wp-element-button, .wp-block-button__link', 6798 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', 6799 cite: 'cite' 6800 }; 6801 6802 // These paths may have three origins, custom, theme, and default, 6803 // and are expected to override other origins with custom, theme, 6804 // and default priority. 6805 const __EXPERIMENTAL_PATHS_WITH_OVERRIDE = { 6806 'color.duotone': true, 6807 'color.gradients': true, 6808 'color.palette': true, 6809 'dimensions.aspectRatios': true, 6810 'typography.fontSizes': true, 6811 'spacing.spacingSizes': true 6812 }; 6813 6814 ;// external ["wp","warning"] 6815 const external_wp_warning_namespaceObject = window["wp"]["warning"]; 6816 var external_wp_warning_default = /*#__PURE__*/__webpack_require__.n(external_wp_warning_namespaceObject); 6817 ;// external ["wp","privateApis"] 6818 const external_wp_privateApis_namespaceObject = window["wp"]["privateApis"]; 6819 ;// ./node_modules/@wordpress/blocks/build-module/lock-unlock.js 6820 /** 6821 * WordPress dependencies 6822 */ 6823 6824 const { 6825 lock, 6826 unlock 6827 } = (0,external_wp_privateApis_namespaceObject.__dangerousOptInToUnstableAPIsOnlyForCoreModules)('I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.', '@wordpress/blocks'); 6828 6829 ;// ./node_modules/@wordpress/blocks/build-module/api/registration.js 6830 /* wp:polyfill */ 6831 /** 6832 * WordPress dependencies 6833 */ 6834 6835 6836 6837 6838 /** 6839 * Internal dependencies 6840 */ 6841 const i18nBlockSchema = { 6842 title: "block title", 6843 description: "block description", 6844 keywords: ["block keyword"], 6845 styles: [{ 6846 label: "block style label" 6847 }], 6848 variations: [{ 6849 title: "block variation title", 6850 description: "block variation description", 6851 keywords: ["block variation keyword"] 6852 }] 6853 }; 6854 6855 6856 6857 /** 6858 * An icon type definition. One of a Dashicon slug, an element, 6859 * or a component. 6860 * 6861 * @typedef {(string|Element|Component)} WPIcon 6862 * 6863 * @see https://developer.wordpress.org/resource/dashicons/ 6864 */ 6865 6866 /** 6867 * Render behavior of a block type icon; one of a Dashicon slug, an element, 6868 * or a component. 6869 * 6870 * @typedef {WPIcon} WPBlockTypeIconRender 6871 */ 6872 6873 /** 6874 * An object describing a normalized block type icon. 6875 * 6876 * @typedef {Object} WPBlockTypeIconDescriptor 6877 * 6878 * @property {WPBlockTypeIconRender} src Render behavior of the icon, 6879 * one of a Dashicon slug, an 6880 * element, or a component. 6881 * @property {string} background Optimal background hex string 6882 * color when displaying icon. 6883 * @property {string} foreground Optimal foreground hex string 6884 * color when displaying icon. 6885 * @property {string} shadowColor Optimal shadow hex string 6886 * color when displaying icon. 6887 */ 6888 6889 /** 6890 * Value to use to render the icon for a block type in an editor interface, 6891 * either a Dashicon slug, an element, a component, or an object describing 6892 * the icon. 6893 * 6894 * @typedef {(WPBlockTypeIconDescriptor|WPBlockTypeIconRender)} WPBlockTypeIcon 6895 */ 6896 6897 /** 6898 * Named block variation scopes. 6899 * 6900 * @typedef {'block'|'inserter'|'transform'} WPBlockVariationScope 6901 */ 6902 6903 /** 6904 * An object describing a variation defined for the block type. 6905 * 6906 * @typedef {Object} WPBlockVariation 6907 * 6908 * @property {string} name The unique and machine-readable name. 6909 * @property {string} title A human-readable variation title. 6910 * @property {string} [description] A detailed variation description. 6911 * @property {string} [category] Block type category classification, 6912 * used in search interfaces to arrange 6913 * block types by category. 6914 * @property {WPIcon} [icon] An icon helping to visualize the variation. 6915 * @property {boolean} [isDefault] Indicates whether the current variation is 6916 * the default one. Defaults to `false`. 6917 * @property {Object} [attributes] Values which override block attributes. 6918 * @property {Array[]} [innerBlocks] Initial configuration of nested blocks. 6919 * @property {Object} [example] Example provides structured data for 6920 * the block preview. You can set to 6921 * `undefined` to disable the preview shown 6922 * for the block type. 6923 * @property {WPBlockVariationScope[]} [scope] The list of scopes where the variation 6924 * is applicable. When not provided, it 6925 * assumes all available scopes. 6926 * @property {string[]} [keywords] An array of terms (which can be translated) 6927 * that help users discover the variation 6928 * while searching. 6929 * @property {Function|string[]} [isActive] This can be a function or an array of block attributes. 6930 * Function that accepts a block's attributes and the 6931 * variation's attributes and determines if a variation is active. 6932 * This function doesn't try to find a match dynamically based 6933 * on all block's attributes, as in many cases some attributes are irrelevant. 6934 * An example would be for `embed` block where we only care 6935 * about `providerNameSlug` attribute's value. 6936 * We can also use a `string[]` to tell which attributes 6937 * should be compared as a shorthand. Each attributes will 6938 * be matched and the variation will be active if all of them are matching. 6939 */ 6940 6941 /** 6942 * Defined behavior of a block type. 6943 * 6944 * @typedef {Object} WPBlockType 6945 * 6946 * @property {string} name Block type's namespaced name. 6947 * @property {string} title Human-readable block type label. 6948 * @property {string} [description] A detailed block type description. 6949 * @property {string} [category] Block type category classification, 6950 * used in search interfaces to arrange 6951 * block types by category. 6952 * @property {WPBlockTypeIcon} [icon] Block type icon. 6953 * @property {string[]} [keywords] Additional keywords to produce block 6954 * type as result in search interfaces. 6955 * @property {Object} [attributes] Block type attributes. 6956 * @property {Component} [save] Optional component describing 6957 * serialized markup structure of a 6958 * block type. 6959 * @property {Component} edit Component rendering an element to 6960 * manipulate the attributes of a block 6961 * in the context of an editor. 6962 * @property {WPBlockVariation[]} [variations] The list of block variations. 6963 * @property {Object} [example] Example provides structured data for 6964 * the block preview. When not defined 6965 * then no preview is shown. 6966 */ 6967 6968 function isObject(object) { 6969 return object !== null && typeof object === 'object'; 6970 } 6971 6972 /** 6973 * Sets the server side block definition of blocks. 6974 * 6975 * Ignored from documentation due to being marked as unstable. 6976 * 6977 * @ignore 6978 * 6979 * @param {Object} definitions Server-side block definitions 6980 */ 6981 // eslint-disable-next-line camelcase 6982 function unstable__bootstrapServerSideBlockDefinitions(definitions) { 6983 const { 6984 addBootstrappedBlockType 6985 } = unlock((0,external_wp_data_namespaceObject.dispatch)(store)); 6986 for (const [name, blockType] of Object.entries(definitions)) { 6987 addBootstrappedBlockType(name, blockType); 6988 } 6989 } 6990 6991 /** 6992 * Gets block settings from metadata loaded from `block.json` file 6993 * 6994 * @param {Object} metadata Block metadata loaded from `block.json`. 6995 * @param {string} metadata.textdomain Textdomain to use with translations. 6996 * 6997 * @return {Object} Block settings. 6998 */ 6999 function getBlockSettingsFromMetadata({ 7000 textdomain, 7001 ...metadata 7002 }) { 7003 const allowedFields = ['apiVersion', 'title', 'category', 'parent', 'ancestor', 'icon', 'description', 'keywords', 'attributes', 'providesContext', 'usesContext', 'selectors', 'supports', 'styles', 'example', 'variations', 'blockHooks', 'allowedBlocks']; 7004 const settings = Object.fromEntries(Object.entries(metadata).filter(([key]) => allowedFields.includes(key))); 7005 if (textdomain) { 7006 Object.keys(i18nBlockSchema).forEach(key => { 7007 if (!settings[key]) { 7008 return; 7009 } 7010 settings[key] = translateBlockSettingUsingI18nSchema(i18nBlockSchema[key], settings[key], textdomain); 7011 }); 7012 } 7013 return settings; 7014 } 7015 7016 /** 7017 * Registers a new block provided a unique name and an object defining its 7018 * behavior. Once registered, the block is made available as an option to any 7019 * editor interface where blocks are implemented. 7020 * 7021 * For more in-depth information on registering a custom block see the 7022 * [Create a block tutorial](https://developer.wordpress.org/block-editor/getting-started/create-block/). 7023 * 7024 * @param {string|Object} blockNameOrMetadata Block type name or its metadata. 7025 * @param {Object} settings Block settings. 7026 * 7027 * @example 7028 * ```js 7029 * import { __ } from '@wordpress/i18n'; 7030 * import { registerBlockType } from '@wordpress/blocks' 7031 * 7032 * registerBlockType( 'namespace/block-name', { 7033 * title: __( 'My First Block' ), 7034 * edit: () => <div>{ __( 'Hello from the editor!' ) }</div>, 7035 * save: () => <div>Hello from the saved content!</div>, 7036 * } ); 7037 * ``` 7038 * 7039 * @return {WPBlockType | undefined} The block, if it has been successfully registered; 7040 * otherwise `undefined`. 7041 */ 7042 function registerBlockType(blockNameOrMetadata, settings) { 7043 const name = isObject(blockNameOrMetadata) ? blockNameOrMetadata.name : blockNameOrMetadata; 7044 if (typeof name !== 'string') { 7045 true ? external_wp_warning_default()('Block names must be strings.') : 0; 7046 return; 7047 } 7048 if (!/^[a-z][a-z0-9-]*\/[a-z][a-z0-9-]*$/.test(name)) { 7049 true ? external_wp_warning_default()('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') : 0; 7050 return; 7051 } 7052 if ((0,external_wp_data_namespaceObject.select)(store).getBlockType(name)) { 7053 true ? external_wp_warning_default()('Block "' + name + '" is already registered.') : 0; 7054 return; 7055 } 7056 const { 7057 addBootstrappedBlockType, 7058 addUnprocessedBlockType 7059 } = unlock((0,external_wp_data_namespaceObject.dispatch)(store)); 7060 if (isObject(blockNameOrMetadata)) { 7061 const metadata = getBlockSettingsFromMetadata(blockNameOrMetadata); 7062 addBootstrappedBlockType(name, metadata); 7063 } 7064 addUnprocessedBlockType(name, settings); 7065 return (0,external_wp_data_namespaceObject.select)(store).getBlockType(name); 7066 } 7067 7068 /** 7069 * Translates block settings provided with metadata using the i18n schema. 7070 * 7071 * @param {string|string[]|Object[]} i18nSchema I18n schema for the block setting. 7072 * @param {string|string[]|Object[]} settingValue Value for the block setting. 7073 * @param {string} textdomain Textdomain to use with translations. 7074 * 7075 * @return {string|string[]|Object[]} Translated setting. 7076 */ 7077 function translateBlockSettingUsingI18nSchema(i18nSchema, settingValue, textdomain) { 7078 if (typeof i18nSchema === 'string' && typeof settingValue === 'string') { 7079 // eslint-disable-next-line @wordpress/i18n-no-variables, @wordpress/i18n-text-domain 7080 return (0,external_wp_i18n_namespaceObject._x)(settingValue, i18nSchema, textdomain); 7081 } 7082 if (Array.isArray(i18nSchema) && i18nSchema.length && Array.isArray(settingValue)) { 7083 return settingValue.map(value => translateBlockSettingUsingI18nSchema(i18nSchema[0], value, textdomain)); 7084 } 7085 if (isObject(i18nSchema) && Object.entries(i18nSchema).length && isObject(settingValue)) { 7086 return Object.keys(settingValue).reduce((accumulator, key) => { 7087 if (!i18nSchema[key]) { 7088 accumulator[key] = settingValue[key]; 7089 return accumulator; 7090 } 7091 accumulator[key] = translateBlockSettingUsingI18nSchema(i18nSchema[key], settingValue[key], textdomain); 7092 return accumulator; 7093 }, {}); 7094 } 7095 return settingValue; 7096 } 7097 7098 /** 7099 * Registers a new block collection to group blocks in the same namespace in the inserter. 7100 * 7101 * @param {string} namespace The namespace to group blocks by in the inserter; corresponds to the block namespace. 7102 * @param {Object} settings The block collection settings. 7103 * @param {string} settings.title The title to display in the block inserter. 7104 * @param {Object} [settings.icon] The icon to display in the block inserter. 7105 * 7106 * @example 7107 * ```js 7108 * import { __ } from '@wordpress/i18n'; 7109 * import { registerBlockCollection, registerBlockType } from '@wordpress/blocks'; 7110 * 7111 * // Register the collection. 7112 * registerBlockCollection( 'my-collection', { 7113 * title: __( 'Custom Collection' ), 7114 * } ); 7115 * 7116 * // Register a block in the same namespace to add it to the collection. 7117 * registerBlockType( 'my-collection/block-name', { 7118 * title: __( 'My First Block' ), 7119 * edit: () => <div>{ __( 'Hello from the editor!' ) }</div>, 7120 * save: () => <div>'Hello from the saved content!</div>, 7121 * } ); 7122 * ``` 7123 */ 7124 function registerBlockCollection(namespace, { 7125 title, 7126 icon 7127 }) { 7128 (0,external_wp_data_namespaceObject.dispatch)(store).addBlockCollection(namespace, title, icon); 7129 } 7130 7131 /** 7132 * Unregisters a block collection 7133 * 7134 * @param {string} namespace The namespace to group blocks by in the inserter; corresponds to the block namespace 7135 * 7136 * @example 7137 * ```js 7138 * import { unregisterBlockCollection } from '@wordpress/blocks'; 7139 * 7140 * unregisterBlockCollection( 'my-collection' ); 7141 * ``` 7142 */ 7143 function unregisterBlockCollection(namespace) { 7144 dispatch(blocksStore).removeBlockCollection(namespace); 7145 } 7146 7147 /** 7148 * Unregisters a block. 7149 * 7150 * @param {string} name Block name. 7151 * 7152 * @example 7153 * ```js 7154 * import { __ } from '@wordpress/i18n'; 7155 * import { unregisterBlockType } from '@wordpress/blocks'; 7156 * 7157 * const ExampleComponent = () => { 7158 * return ( 7159 * <Button 7160 * onClick={ () => 7161 * unregisterBlockType( 'my-collection/block-name' ) 7162 * } 7163 * > 7164 * { __( 'Unregister my custom block.' ) } 7165 * </Button> 7166 * ); 7167 * }; 7168 * ``` 7169 * 7170 * @return {WPBlockType | undefined} The previous block value, if it has been successfully 7171 * unregistered; otherwise `undefined`. 7172 */ 7173 function unregisterBlockType(name) { 7174 const oldBlock = (0,external_wp_data_namespaceObject.select)(store).getBlockType(name); 7175 if (!oldBlock) { 7176 true ? external_wp_warning_default()('Block "' + name + '" is not registered.') : 0; 7177 return; 7178 } 7179 (0,external_wp_data_namespaceObject.dispatch)(store).removeBlockTypes(name); 7180 return oldBlock; 7181 } 7182 7183 /** 7184 * Assigns name of block for handling non-block content. 7185 * 7186 * @param {string} blockName Block name. 7187 */ 7188 function setFreeformContentHandlerName(blockName) { 7189 (0,external_wp_data_namespaceObject.dispatch)(store).setFreeformFallbackBlockName(blockName); 7190 } 7191 7192 /** 7193 * Retrieves name of block handling non-block content, or undefined if no 7194 * handler has been defined. 7195 * 7196 * @return {?string} Block name. 7197 */ 7198 function getFreeformContentHandlerName() { 7199 return (0,external_wp_data_namespaceObject.select)(store).getFreeformFallbackBlockName(); 7200 } 7201 7202 /** 7203 * Retrieves name of block used for handling grouping interactions. 7204 * 7205 * @return {?string} Block name. 7206 */ 7207 function getGroupingBlockName() { 7208 return (0,external_wp_data_namespaceObject.select)(store).getGroupingBlockName(); 7209 } 7210 7211 /** 7212 * Assigns name of block handling unregistered block types. 7213 * 7214 * @param {string} blockName Block name. 7215 */ 7216 function setUnregisteredTypeHandlerName(blockName) { 7217 (0,external_wp_data_namespaceObject.dispatch)(store).setUnregisteredFallbackBlockName(blockName); 7218 } 7219 7220 /** 7221 * Retrieves name of block handling unregistered block types, or undefined if no 7222 * handler has been defined. 7223 * 7224 * @return {?string} Block name. 7225 */ 7226 function getUnregisteredTypeHandlerName() { 7227 return (0,external_wp_data_namespaceObject.select)(store).getUnregisteredFallbackBlockName(); 7228 } 7229 7230 /** 7231 * Assigns the default block name. 7232 * 7233 * @param {string} name Block name. 7234 * 7235 * @example 7236 * ```js 7237 * import { setDefaultBlockName } from '@wordpress/blocks'; 7238 * 7239 * const ExampleComponent = () => { 7240 * 7241 * return ( 7242 * <Button onClick={ () => setDefaultBlockName( 'core/heading' ) }> 7243 * { __( 'Set the default block to Heading' ) } 7244 * </Button> 7245 * ); 7246 * }; 7247 * ``` 7248 */ 7249 function setDefaultBlockName(name) { 7250 (0,external_wp_data_namespaceObject.dispatch)(store).setDefaultBlockName(name); 7251 } 7252 7253 /** 7254 * Assigns name of block for handling block grouping interactions. 7255 * 7256 * This function lets you select a different block to group other blocks in instead of the 7257 * default `core/group` block. This function must be used in a component or when the DOM is fully 7258 * loaded. See https://developer.wordpress.org/block-editor/reference-guides/packages/packages-dom-ready/ 7259 * 7260 * @param {string} name Block name. 7261 * 7262 * @example 7263 * ```js 7264 * import { setGroupingBlockName } from '@wordpress/blocks'; 7265 * 7266 * const ExampleComponent = () => { 7267 * 7268 * return ( 7269 * <Button onClick={ () => setGroupingBlockName( 'core/columns' ) }> 7270 * { __( 'Wrap in columns' ) } 7271 * </Button> 7272 * ); 7273 * }; 7274 * ``` 7275 */ 7276 function setGroupingBlockName(name) { 7277 (0,external_wp_data_namespaceObject.dispatch)(store).setGroupingBlockName(name); 7278 } 7279 7280 /** 7281 * Retrieves the default block name. 7282 * 7283 * @return {?string} Block name. 7284 */ 7285 function getDefaultBlockName() { 7286 return (0,external_wp_data_namespaceObject.select)(store).getDefaultBlockName(); 7287 } 7288 7289 /** 7290 * Returns a registered block type. 7291 * 7292 * @param {string} name Block name. 7293 * 7294 * @return {?Object} Block type. 7295 */ 7296 function getBlockType(name) { 7297 return (0,external_wp_data_namespaceObject.select)(store)?.getBlockType(name); 7298 } 7299 7300 /** 7301 * Returns all registered blocks. 7302 * 7303 * @return {Array} Block settings. 7304 */ 7305 function getBlockTypes() { 7306 return (0,external_wp_data_namespaceObject.select)(store).getBlockTypes(); 7307 } 7308 7309 /** 7310 * Returns the block support value for a feature, if defined. 7311 * 7312 * @param {(string|Object)} nameOrType Block name or type object 7313 * @param {string} feature Feature to retrieve 7314 * @param {*} defaultSupports Default value to return if not 7315 * explicitly defined 7316 * 7317 * @return {?*} Block support value 7318 */ 7319 function getBlockSupport(nameOrType, feature, defaultSupports) { 7320 return (0,external_wp_data_namespaceObject.select)(store).getBlockSupport(nameOrType, feature, defaultSupports); 7321 } 7322 7323 /** 7324 * Returns true if the block defines support for a feature, or false otherwise. 7325 * 7326 * @param {(string|Object)} nameOrType Block name or type object. 7327 * @param {string} feature Feature to test. 7328 * @param {boolean} defaultSupports Whether feature is supported by 7329 * default if not explicitly defined. 7330 * 7331 * @return {boolean} Whether block supports feature. 7332 */ 7333 function hasBlockSupport(nameOrType, feature, defaultSupports) { 7334 return (0,external_wp_data_namespaceObject.select)(store).hasBlockSupport(nameOrType, feature, defaultSupports); 7335 } 7336 7337 /** 7338 * Determines whether or not the given block is a reusable block. This is a 7339 * special block type that is used to point to a global block stored via the 7340 * API. 7341 * 7342 * @param {Object} blockOrType Block or Block Type to test. 7343 * 7344 * @return {boolean} Whether the given block is a reusable block. 7345 */ 7346 function isReusableBlock(blockOrType) { 7347 return blockOrType?.name === 'core/block'; 7348 } 7349 7350 /** 7351 * Determines whether or not the given block is a template part. This is a 7352 * special block type that allows composing a page template out of reusable 7353 * design elements. 7354 * 7355 * @param {Object} blockOrType Block or Block Type to test. 7356 * 7357 * @return {boolean} Whether the given block is a template part. 7358 */ 7359 function isTemplatePart(blockOrType) { 7360 return blockOrType?.name === 'core/template-part'; 7361 } 7362 7363 /** 7364 * Returns an array with the child blocks of a given block. 7365 * 7366 * @param {string} blockName Name of block (example: “latest-posts”). 7367 * 7368 * @return {Array} Array of child block names. 7369 */ 7370 const getChildBlockNames = blockName => { 7371 return (0,external_wp_data_namespaceObject.select)(store).getChildBlockNames(blockName); 7372 }; 7373 7374 /** 7375 * Returns a boolean indicating if a block has child blocks or not. 7376 * 7377 * @param {string} blockName Name of block (example: “latest-posts”). 7378 * 7379 * @return {boolean} True if a block contains child blocks and false otherwise. 7380 */ 7381 const hasChildBlocks = blockName => { 7382 return (0,external_wp_data_namespaceObject.select)(store).hasChildBlocks(blockName); 7383 }; 7384 7385 /** 7386 * Returns a boolean indicating if a block has at least one child block with inserter support. 7387 * 7388 * @param {string} blockName Block type name. 7389 * 7390 * @return {boolean} True if a block contains at least one child blocks with inserter support 7391 * and false otherwise. 7392 */ 7393 const hasChildBlocksWithInserterSupport = blockName => { 7394 return (0,external_wp_data_namespaceObject.select)(store).hasChildBlocksWithInserterSupport(blockName); 7395 }; 7396 7397 /** 7398 * Registers a new block style for the given block types. 7399 * 7400 * For more information on connecting the styles with CSS 7401 * [the official documentation](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-styles/#styles). 7402 * 7403 * @param {string|Array} blockNames Name of blocks e.g. “core/latest-posts” or `["core/group", "core/columns"]`. 7404 * @param {Object} styleVariation Object containing `name` which is the class name applied to the block and `label` which identifies the variation to the user. 7405 * 7406 * @example 7407 * ```js 7408 * import { __ } from '@wordpress/i18n'; 7409 * import { registerBlockStyle } from '@wordpress/blocks'; 7410 * import { Button } from '@wordpress/components'; 7411 * 7412 * 7413 * const ExampleComponent = () => { 7414 * return ( 7415 * <Button 7416 * onClick={ () => { 7417 * registerBlockStyle( 'core/quote', { 7418 * name: 'fancy-quote', 7419 * label: __( 'Fancy Quote' ), 7420 * } ); 7421 * } } 7422 * > 7423 * { __( 'Add a new block style for core/quote' ) } 7424 * </Button> 7425 * ); 7426 * }; 7427 * ``` 7428 */ 7429 const registerBlockStyle = (blockNames, styleVariation) => { 7430 (0,external_wp_data_namespaceObject.dispatch)(store).addBlockStyles(blockNames, styleVariation); 7431 }; 7432 7433 /** 7434 * Unregisters a block style for the given block. 7435 * 7436 * @param {string} blockName Name of block (example: “core/latest-posts”). 7437 * @param {string} styleVariationName Name of class applied to the block. 7438 * 7439 * @example 7440 * ```js 7441 * import { __ } from '@wordpress/i18n'; 7442 * import { unregisterBlockStyle } from '@wordpress/blocks'; 7443 * import { Button } from '@wordpress/components'; 7444 * 7445 * const ExampleComponent = () => { 7446 * return ( 7447 * <Button 7448 * onClick={ () => { 7449 * unregisterBlockStyle( 'core/quote', 'plain' ); 7450 * } } 7451 * > 7452 * { __( 'Remove the "Plain" block style for core/quote' ) } 7453 * </Button> 7454 * ); 7455 * }; 7456 * ``` 7457 */ 7458 const unregisterBlockStyle = (blockName, styleVariationName) => { 7459 (0,external_wp_data_namespaceObject.dispatch)(store).removeBlockStyles(blockName, styleVariationName); 7460 }; 7461 7462 /** 7463 * Returns an array with the variations of a given block type. 7464 * Ignored from documentation as the recommended usage is via useSelect from @wordpress/data. 7465 * 7466 * @ignore 7467 * 7468 * @param {string} blockName Name of block (example: “core/columns”). 7469 * @param {WPBlockVariationScope} [scope] Block variation scope name. 7470 * 7471 * @return {(WPBlockVariation[]|void)} Block variations. 7472 */ 7473 const getBlockVariations = (blockName, scope) => { 7474 return (0,external_wp_data_namespaceObject.select)(store).getBlockVariations(blockName, scope); 7475 }; 7476 7477 /** 7478 * Registers a new block variation for the given block type. 7479 * 7480 * For more information on block variations see 7481 * [the official documentation ](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-variations/). 7482 * 7483 * @param {string} blockName Name of the block (example: “core/columns”). 7484 * @param {WPBlockVariation} variation Object describing a block variation. 7485 * 7486 * @example 7487 * ```js 7488 * import { __ } from '@wordpress/i18n'; 7489 * import { registerBlockVariation } from '@wordpress/blocks'; 7490 * import { Button } from '@wordpress/components'; 7491 * 7492 * const ExampleComponent = () => { 7493 * return ( 7494 * <Button 7495 * onClick={ () => { 7496 * registerBlockVariation( 'core/embed', { 7497 * name: 'custom', 7498 * title: __( 'My Custom Embed' ), 7499 * attributes: { providerNameSlug: 'custom' }, 7500 * } ); 7501 * } } 7502 * > 7503 * __( 'Add a custom variation for core/embed' ) } 7504 * </Button> 7505 * ); 7506 * }; 7507 * ``` 7508 */ 7509 const registerBlockVariation = (blockName, variation) => { 7510 if (typeof variation.name !== 'string') { 7511 true ? external_wp_warning_default()('Variation names must be unique strings.') : 0; 7512 } 7513 (0,external_wp_data_namespaceObject.dispatch)(store).addBlockVariations(blockName, variation); 7514 }; 7515 7516 /** 7517 * Unregisters a block variation defined for the given block type. 7518 * 7519 * @param {string} blockName Name of the block (example: “core/columns”). 7520 * @param {string} variationName Name of the variation defined for the block. 7521 * 7522 * @example 7523 * ```js 7524 * import { __ } from '@wordpress/i18n'; 7525 * import { unregisterBlockVariation } from '@wordpress/blocks'; 7526 * import { Button } from '@wordpress/components'; 7527 * 7528 * const ExampleComponent = () => { 7529 * return ( 7530 * <Button 7531 * onClick={ () => { 7532 * unregisterBlockVariation( 'core/embed', 'youtube' ); 7533 * } } 7534 * > 7535 * { __( 'Remove the YouTube variation from core/embed' ) } 7536 * </Button> 7537 * ); 7538 * }; 7539 * ``` 7540 */ 7541 const unregisterBlockVariation = (blockName, variationName) => { 7542 (0,external_wp_data_namespaceObject.dispatch)(store).removeBlockVariations(blockName, variationName); 7543 }; 7544 7545 /** 7546 * Registers a new block bindings source with an object defining its 7547 * behavior. Once registered, the source is available to be connected 7548 * to the supported block attributes. 7549 * 7550 * @since 6.7.0 Introduced in WordPress core. 7551 * 7552 * @param {Object} source Properties of the source to be registered. 7553 * @param {string} source.name The unique and machine-readable name. 7554 * @param {string} [source.label] Human-readable label. Optional when it is defined in the server. 7555 * @param {Array} [source.usesContext] Optional array of context needed by the source only in the editor. 7556 * @param {Function} [source.getValues] Optional function to get the values from the source. 7557 * @param {Function} [source.setValues] Optional function to update multiple values connected to the source. 7558 * @param {Function} [source.canUserEditValue] Optional function to determine if the user can edit the value. 7559 * 7560 * @example 7561 * ```js 7562 * import { _x } from '@wordpress/i18n'; 7563 * import { registerBlockBindingsSource } from '@wordpress/blocks' 7564 * 7565 * registerBlockBindingsSource( { 7566 * name: 'plugin/my-custom-source', 7567 * label: _x( 'My Custom Source', 'block bindings source' ), 7568 * usesContext: [ 'postType' ], 7569 * getValues: getSourceValues, 7570 * setValues: updateMyCustomValuesInBatch, 7571 * canUserEditValue: () => true, 7572 * } ); 7573 * ``` 7574 */ 7575 const registerBlockBindingsSource = source => { 7576 const { 7577 name, 7578 label, 7579 usesContext, 7580 getValues, 7581 setValues, 7582 canUserEditValue, 7583 getFieldsList 7584 } = source; 7585 const existingSource = unlock((0,external_wp_data_namespaceObject.select)(store)).getBlockBindingsSource(name); 7586 7587 /* 7588 * Check if the source has been already registered on the client. 7589 * If any property expected to be "client-only" is defined, return a warning. 7590 */ 7591 const serverProps = ['label', 'usesContext']; 7592 for (const prop in existingSource) { 7593 if (!serverProps.includes(prop) && existingSource[prop]) { 7594 true ? external_wp_warning_default()('Block bindings source "' + name + '" is already registered.') : 0; 7595 return; 7596 } 7597 } 7598 7599 // Check the `name` property is correct. 7600 if (!name) { 7601 true ? external_wp_warning_default()('Block bindings source must contain a name.') : 0; 7602 return; 7603 } 7604 if (typeof name !== 'string') { 7605 true ? external_wp_warning_default()('Block bindings source name must be a string.') : 0; 7606 return; 7607 } 7608 if (/[A-Z]+/.test(name)) { 7609 true ? external_wp_warning_default()('Block bindings source name must not contain uppercase characters.') : 0; 7610 return; 7611 } 7612 if (!/^[a-z0-9/-]+$/.test(name)) { 7613 true ? external_wp_warning_default()('Block bindings source name must contain only valid characters: lowercase characters, hyphens, or digits. Example: my-plugin/my-custom-source.') : 0; 7614 return; 7615 } 7616 if (!/^[a-z0-9-]+\/[a-z0-9-]+$/.test(name)) { 7617 true ? external_wp_warning_default()('Block bindings source name must contain a namespace and valid characters. Example: my-plugin/my-custom-source.') : 0; 7618 return; 7619 } 7620 7621 // Check the `label` property is correct. 7622 7623 if (!label && !existingSource?.label) { 7624 true ? external_wp_warning_default()('Block bindings source must contain a label.') : 0; 7625 return; 7626 } 7627 if (label && typeof label !== 'string') { 7628 true ? external_wp_warning_default()('Block bindings source label must be a string.') : 0; 7629 return; 7630 } 7631 if (label && existingSource?.label && label !== existingSource?.label) { 7632 true ? external_wp_warning_default()('Block bindings "' + name + '" source label was overridden.') : 0; 7633 } 7634 7635 // Check the `usesContext` property is correct. 7636 if (usesContext && !Array.isArray(usesContext)) { 7637 true ? external_wp_warning_default()('Block bindings source usesContext must be an array.') : 0; 7638 return; 7639 } 7640 7641 // Check the `getValues` property is correct. 7642 if (getValues && typeof getValues !== 'function') { 7643 true ? external_wp_warning_default()('Block bindings source getValues must be a function.') : 0; 7644 return; 7645 } 7646 7647 // Check the `setValues` property is correct. 7648 if (setValues && typeof setValues !== 'function') { 7649 true ? external_wp_warning_default()('Block bindings source setValues must be a function.') : 0; 7650 return; 7651 } 7652 7653 // Check the `canUserEditValue` property is correct. 7654 if (canUserEditValue && typeof canUserEditValue !== 'function') { 7655 true ? external_wp_warning_default()('Block bindings source canUserEditValue must be a function.') : 0; 7656 return; 7657 } 7658 7659 // Check the `getFieldsList` property is correct. 7660 if (getFieldsList && typeof getFieldsList !== 'function') { 7661 // eslint-disable-next-line no-console 7662 true ? external_wp_warning_default()('Block bindings source getFieldsList must be a function.') : 0; 7663 return; 7664 } 7665 return unlock((0,external_wp_data_namespaceObject.dispatch)(store)).addBlockBindingsSource(source); 7666 }; 7667 7668 /** 7669 * Unregisters a block bindings source by providing its name. 7670 * 7671 * @since 6.7.0 Introduced in WordPress core. 7672 * 7673 * @param {string} name The name of the block bindings source to unregister. 7674 * 7675 * @example 7676 * ```js 7677 * import { unregisterBlockBindingsSource } from '@wordpress/blocks'; 7678 * 7679 * unregisterBlockBindingsSource( 'plugin/my-custom-source' ); 7680 * ``` 7681 */ 7682 function unregisterBlockBindingsSource(name) { 7683 const oldSource = getBlockBindingsSource(name); 7684 if (!oldSource) { 7685 true ? external_wp_warning_default()('Block bindings source "' + name + '" is not registered.') : 0; 7686 return; 7687 } 7688 unlock((0,external_wp_data_namespaceObject.dispatch)(store)).removeBlockBindingsSource(name); 7689 } 7690 7691 /** 7692 * Returns a registered block bindings source by its name. 7693 * 7694 * @since 6.7.0 Introduced in WordPress core. 7695 * 7696 * @param {string} name Block bindings source name. 7697 * 7698 * @return {?Object} Block bindings source. 7699 */ 7700 function getBlockBindingsSource(name) { 7701 return unlock((0,external_wp_data_namespaceObject.select)(store)).getBlockBindingsSource(name); 7702 } 7703 7704 /** 7705 * Returns all registered block bindings sources. 7706 * 7707 * @since 6.7.0 Introduced in WordPress core. 7708 * 7709 * @return {Array} Block bindings sources. 7710 */ 7711 function getBlockBindingsSources() { 7712 return unlock((0,external_wp_data_namespaceObject.select)(store)).getAllBlockBindingsSources(); 7713 } 7714 7715 ;// ./node_modules/@wordpress/blocks/build-module/api/utils.js 7716 /* wp:polyfill */ 7717 /** 7718 * External dependencies 7719 */ 7720 7721 7722 7723 7724 /** 7725 * WordPress dependencies 7726 */ 7727 7728 7729 7730 7731 7732 7733 /** 7734 * Internal dependencies 7735 */ 7736 7737 7738 k([names, a11y]); 7739 7740 /** 7741 * Array of icon colors containing a color to be used if the icon color 7742 * was not explicitly set but the icon background color was. 7743 * 7744 * @type {Object} 7745 */ 7746 const ICON_COLORS = ['#191e23', '#f8f9f9']; 7747 7748 /** 7749 * Determines whether the block's attributes are equal to the default attributes 7750 * which means the block is unmodified. 7751 * 7752 * @param {WPBlock} block Block Object 7753 * 7754 * @return {boolean} Whether the block is an unmodified block. 7755 */ 7756 function isUnmodifiedBlock(block) { 7757 var _getBlockType$attribu; 7758 return Object.entries((_getBlockType$attribu = getBlockType(block.name)?.attributes) !== null && _getBlockType$attribu !== void 0 ? _getBlockType$attribu : {}).every(([key, definition]) => { 7759 const value = block.attributes[key]; 7760 7761 // Every attribute that has a default must match the default. 7762 if (definition.hasOwnProperty('default')) { 7763 return value === definition.default; 7764 } 7765 7766 // The rich text type is a bit different from the rest because it 7767 // has an implicit default value of an empty RichTextData instance, 7768 // so check the length of the value. 7769 if (definition.type === 'rich-text') { 7770 return !value?.length; 7771 } 7772 7773 // Every attribute that doesn't have a default should be undefined. 7774 return value === undefined; 7775 }); 7776 } 7777 7778 /** 7779 * Determines whether the block is a default block and its attributes are equal 7780 * to the default attributes which means the block is unmodified. 7781 * 7782 * @param {WPBlock} block Block Object 7783 * 7784 * @return {boolean} Whether the block is an unmodified default block. 7785 */ 7786 function isUnmodifiedDefaultBlock(block) { 7787 return block.name === getDefaultBlockName() && isUnmodifiedBlock(block); 7788 } 7789 7790 /** 7791 * Function that checks if the parameter is a valid icon. 7792 * 7793 * @param {*} icon Parameter to be checked. 7794 * 7795 * @return {boolean} True if the parameter is a valid icon and false otherwise. 7796 */ 7797 7798 function isValidIcon(icon) { 7799 return !!icon && (typeof icon === 'string' || (0,external_wp_element_namespaceObject.isValidElement)(icon) || typeof icon === 'function' || icon instanceof external_wp_element_namespaceObject.Component); 7800 } 7801 7802 /** 7803 * Function that receives an icon as set by the blocks during the registration 7804 * and returns a new icon object that is normalized so we can rely on just on possible icon structure 7805 * in the codebase. 7806 * 7807 * @param {WPBlockTypeIconRender} icon Render behavior of a block type icon; 7808 * one of a Dashicon slug, an element, or a 7809 * component. 7810 * 7811 * @return {WPBlockTypeIconDescriptor} Object describing the icon. 7812 */ 7813 function normalizeIconObject(icon) { 7814 icon = icon || BLOCK_ICON_DEFAULT; 7815 if (isValidIcon(icon)) { 7816 return { 7817 src: icon 7818 }; 7819 } 7820 if ('background' in icon) { 7821 const colordBgColor = w(icon.background); 7822 const getColorContrast = iconColor => colordBgColor.contrast(iconColor); 7823 const maxContrast = Math.max(...ICON_COLORS.map(getColorContrast)); 7824 return { 7825 ...icon, 7826 foreground: icon.foreground ? icon.foreground : ICON_COLORS.find(iconColor => getColorContrast(iconColor) === maxContrast), 7827 shadowColor: colordBgColor.alpha(0.3).toRgbString() 7828 }; 7829 } 7830 return icon; 7831 } 7832 7833 /** 7834 * Normalizes block type passed as param. When string is passed then 7835 * it converts it to the matching block type object. 7836 * It passes the original object otherwise. 7837 * 7838 * @param {string|Object} blockTypeOrName Block type or name. 7839 * 7840 * @return {?Object} Block type. 7841 */ 7842 function normalizeBlockType(blockTypeOrName) { 7843 if (typeof blockTypeOrName === 'string') { 7844 return getBlockType(blockTypeOrName); 7845 } 7846 return blockTypeOrName; 7847 } 7848 7849 /** 7850 * Get the label for the block, usually this is either the block title, 7851 * or the value of the block's `label` function when that's specified. 7852 * 7853 * @param {Object} blockType The block type. 7854 * @param {Object} attributes The values of the block's attributes. 7855 * @param {Object} context The intended use for the label. 7856 * 7857 * @return {string} The block label. 7858 */ 7859 function getBlockLabel(blockType, attributes, context = 'visual') { 7860 const { 7861 __experimentalLabel: getLabel, 7862 title 7863 } = blockType; 7864 const label = getLabel && getLabel(attributes, { 7865 context 7866 }); 7867 if (!label) { 7868 return title; 7869 } 7870 if (label.toPlainText) { 7871 return label.toPlainText(); 7872 } 7873 7874 // Strip any HTML (i.e. RichText formatting) before returning. 7875 return (0,external_wp_dom_namespaceObject.__unstableStripHTML)(label); 7876 } 7877 7878 /** 7879 * Get a label for the block for use by screenreaders, this is more descriptive 7880 * than the visual label and includes the block title and the value of the 7881 * `getLabel` function if it's specified. 7882 * 7883 * @param {?Object} blockType The block type. 7884 * @param {Object} attributes The values of the block's attributes. 7885 * @param {?number} position The position of the block in the block list. 7886 * @param {string} [direction='vertical'] The direction of the block layout. 7887 * 7888 * @return {string} The block label. 7889 */ 7890 function getAccessibleBlockLabel(blockType, attributes, position, direction = 'vertical') { 7891 // `title` is already localized, `label` is a user-supplied value. 7892 const title = blockType?.title; 7893 const label = blockType ? getBlockLabel(blockType, attributes, 'accessibility') : ''; 7894 const hasPosition = position !== undefined; 7895 7896 // getBlockLabel returns the block title as a fallback when there's no label, 7897 // if it did return the title, this function needs to avoid adding the 7898 // title twice within the accessible label. Use this `hasLabel` boolean to 7899 // handle that. 7900 const hasLabel = label && label !== title; 7901 if (hasPosition && direction === 'vertical') { 7902 if (hasLabel) { 7903 return (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: accessibility text. 1: The block title. 2: The block row number. 3: The block label.. */ 7904 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. Row %2$d. %3$s'), title, position, label); 7905 } 7906 return (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: accessibility text. 1: The block title. 2: The block row number. */ 7907 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. Row %2$d'), title, position); 7908 } else if (hasPosition && direction === 'horizontal') { 7909 if (hasLabel) { 7910 return (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: accessibility text. 1: The block title. 2: The block column number. 3: The block label.. */ 7911 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. Column %2$d. %3$s'), title, position, label); 7912 } 7913 return (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: accessibility text. 1: The block title. 2: The block column number. */ 7914 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. Column %2$d'), title, position); 7915 } 7916 if (hasLabel) { 7917 return (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: accessibility text. %1: The block title. %2: The block label. */ 7918 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. %2$s'), title, label); 7919 } 7920 return (0,external_wp_i18n_namespaceObject.sprintf)(/* translators: accessibility text. %s: The block title. */ 7921 (0,external_wp_i18n_namespaceObject.__)('%s Block'), title); 7922 } 7923 function getDefault(attributeSchema) { 7924 if (attributeSchema.default !== undefined) { 7925 return attributeSchema.default; 7926 } 7927 if (attributeSchema.type === 'rich-text') { 7928 return new external_wp_richText_namespaceObject.RichTextData(); 7929 } 7930 } 7931 7932 /** 7933 * Check if a block is registered. 7934 * 7935 * @param {string} name The block's name. 7936 * 7937 * @return {boolean} Whether the block is registered. 7938 */ 7939 function isBlockRegistered(name) { 7940 return getBlockType(name) !== undefined; 7941 } 7942 7943 /** 7944 * Ensure attributes contains only values defined by block type, and merge 7945 * default values for missing attributes. 7946 * 7947 * @param {string} name The block's name. 7948 * @param {Object} attributes The block's attributes. 7949 * @return {Object} The sanitized attributes. 7950 */ 7951 function __experimentalSanitizeBlockAttributes(name, attributes) { 7952 // Get the type definition associated with a registered block. 7953 const blockType = getBlockType(name); 7954 if (undefined === blockType) { 7955 throw new Error(`Block type '$name}' is not registered.`); 7956 } 7957 return Object.entries(blockType.attributes).reduce((accumulator, [key, schema]) => { 7958 const value = attributes[key]; 7959 if (undefined !== value) { 7960 if (schema.type === 'rich-text') { 7961 if (value instanceof external_wp_richText_namespaceObject.RichTextData) { 7962 accumulator[key] = value; 7963 } else if (typeof value === 'string') { 7964 accumulator[key] = external_wp_richText_namespaceObject.RichTextData.fromHTMLString(value); 7965 } 7966 } else if (schema.type === 'string' && value instanceof external_wp_richText_namespaceObject.RichTextData) { 7967 accumulator[key] = value.toHTMLString(); 7968 } else { 7969 accumulator[key] = value; 7970 } 7971 } else { 7972 const _default = getDefault(schema); 7973 if (undefined !== _default) { 7974 accumulator[key] = _default; 7975 } 7976 } 7977 if (['node', 'children'].indexOf(schema.source) !== -1) { 7978 // Ensure value passed is always an array, which we're expecting in 7979 // the RichText component to handle the deprecated value. 7980 if (typeof accumulator[key] === 'string') { 7981 accumulator[key] = [accumulator[key]]; 7982 } else if (!Array.isArray(accumulator[key])) { 7983 accumulator[key] = []; 7984 } 7985 } 7986 return accumulator; 7987 }, {}); 7988 } 7989 7990 /** 7991 * Filter block attributes by `role` and return their names. 7992 * 7993 * @param {string} name Block attribute's name. 7994 * @param {string} role The role of a block attribute. 7995 * 7996 * @return {string[]} The attribute names that have the provided role. 7997 */ 7998 function getBlockAttributesNamesByRole(name, role) { 7999 const attributes = getBlockType(name)?.attributes; 8000 if (!attributes) { 8001 return []; 8002 } 8003 const attributesNames = Object.keys(attributes); 8004 if (!role) { 8005 return attributesNames; 8006 } 8007 return attributesNames.filter(attributeName => { 8008 const attribute = attributes[attributeName]; 8009 if (attribute?.role === role) { 8010 return true; 8011 } 8012 if (attribute?.__experimentalRole === role) { 8013 external_wp_deprecated_default()('__experimentalRole attribute', { 8014 since: '6.7', 8015 version: '6.8', 8016 alternative: 'role attribute', 8017 hint: `Check the block.json of the $name} block.` 8018 }); 8019 return true; 8020 } 8021 return false; 8022 }); 8023 } 8024 const __experimentalGetBlockAttributesNamesByRole = (...args) => { 8025 external_wp_deprecated_default()('__experimentalGetBlockAttributesNamesByRole', { 8026 since: '6.7', 8027 version: '6.8', 8028 alternative: 'getBlockAttributesNamesByRole' 8029 }); 8030 return getBlockAttributesNamesByRole(...args); 8031 }; 8032 8033 /** 8034 * Checks if a block is a content block by examining its attributes. 8035 * A block is considered a content block if it has at least one attribute 8036 * with a role of 'content'. 8037 * 8038 * @param {string} name The name of the block to check. 8039 * @return {boolean} Whether the block is a content block. 8040 */ 8041 function isContentBlock(name) { 8042 const attributes = getBlockType(name)?.attributes; 8043 if (!attributes) { 8044 return false; 8045 } 8046 return !!Object.keys(attributes)?.some(attributeKey => { 8047 const attribute = attributes[attributeKey]; 8048 return attribute?.role === 'content' || attribute?.__experimentalRole === 'content'; 8049 }); 8050 } 8051 8052 /** 8053 * Return a new object with the specified keys omitted. 8054 * 8055 * @param {Object} object Original object. 8056 * @param {Array} keys Keys to be omitted. 8057 * 8058 * @return {Object} Object with omitted keys. 8059 */ 8060 function omit(object, keys) { 8061 return Object.fromEntries(Object.entries(object).filter(([key]) => !keys.includes(key))); 8062 } 8063 8064 ;// ./node_modules/@wordpress/blocks/build-module/store/reducer.js 8065 /* wp:polyfill */ 8066 /** 8067 * External dependencies 8068 */ 8069 8070 8071 /** 8072 * WordPress dependencies 8073 */ 8074 8075 8076 8077 /** 8078 * Internal dependencies 8079 */ 8080 8081 8082 /** 8083 * @typedef {Object} WPBlockCategory 8084 * 8085 * @property {string} slug Unique category slug. 8086 * @property {string} title Category label, for display in user interface. 8087 */ 8088 8089 /** 8090 * Default set of categories. 8091 * 8092 * @type {WPBlockCategory[]} 8093 */ 8094 const DEFAULT_CATEGORIES = [{ 8095 slug: 'text', 8096 title: (0,external_wp_i18n_namespaceObject.__)('Text') 8097 }, { 8098 slug: 'media', 8099 title: (0,external_wp_i18n_namespaceObject.__)('Media') 8100 }, { 8101 slug: 'design', 8102 title: (0,external_wp_i18n_namespaceObject.__)('Design') 8103 }, { 8104 slug: 'widgets', 8105 title: (0,external_wp_i18n_namespaceObject.__)('Widgets') 8106 }, { 8107 slug: 'theme', 8108 title: (0,external_wp_i18n_namespaceObject.__)('Theme') 8109 }, { 8110 slug: 'embed', 8111 title: (0,external_wp_i18n_namespaceObject.__)('Embeds') 8112 }, { 8113 slug: 'reusable', 8114 title: (0,external_wp_i18n_namespaceObject.__)('Reusable blocks') 8115 }]; 8116 8117 // Key block types by their name. 8118 function keyBlockTypesByName(types) { 8119 return types.reduce((newBlockTypes, block) => ({ 8120 ...newBlockTypes, 8121 [block.name]: block 8122 }), {}); 8123 } 8124 8125 // Filter items to ensure they're unique by their name. 8126 function getUniqueItemsByName(items) { 8127 return items.reduce((acc, currentItem) => { 8128 if (!acc.some(item => item.name === currentItem.name)) { 8129 acc.push(currentItem); 8130 } 8131 return acc; 8132 }, []); 8133 } 8134 function bootstrappedBlockTypes(state = {}, action) { 8135 switch (action.type) { 8136 case 'ADD_BOOTSTRAPPED_BLOCK_TYPE': 8137 const { 8138 name, 8139 blockType 8140 } = action; 8141 const serverDefinition = state[name]; 8142 let newDefinition; 8143 // Don't overwrite if already set. It covers the case when metadata 8144 // was initialized from the server. 8145 if (serverDefinition) { 8146 // The `blockHooks` prop is not yet included in the server provided 8147 // definitions and needs to be polyfilled. This can be removed when the 8148 // minimum supported WordPress is >= 6.4. 8149 if (serverDefinition.blockHooks === undefined && blockType.blockHooks) { 8150 newDefinition = { 8151 ...serverDefinition, 8152 ...newDefinition, 8153 blockHooks: blockType.blockHooks 8154 }; 8155 } 8156 8157 // The `allowedBlocks` prop is not yet included in the server provided 8158 // definitions and needs to be polyfilled. This can be removed when the 8159 // minimum supported WordPress is >= 6.5. 8160 if (serverDefinition.allowedBlocks === undefined && blockType.allowedBlocks) { 8161 newDefinition = { 8162 ...serverDefinition, 8163 ...newDefinition, 8164 allowedBlocks: blockType.allowedBlocks 8165 }; 8166 } 8167 } else { 8168 newDefinition = Object.fromEntries(Object.entries(blockType).filter(([, value]) => value !== null && value !== undefined).map(([key, value]) => [camelCase(key), value])); 8169 newDefinition.name = name; 8170 } 8171 if (newDefinition) { 8172 return { 8173 ...state, 8174 [name]: newDefinition 8175 }; 8176 } 8177 return state; 8178 case 'REMOVE_BLOCK_TYPES': 8179 return omit(state, action.names); 8180 } 8181 return state; 8182 } 8183 8184 /** 8185 * Reducer managing the unprocessed block types in a form passed when registering the by block. 8186 * It's for internal use only. It allows recomputing the processed block types on-demand after block type filters 8187 * get added or removed. 8188 * 8189 * @param {Object} state Current state. 8190 * @param {Object} action Dispatched action. 8191 * 8192 * @return {Object} Updated state. 8193 */ 8194 function unprocessedBlockTypes(state = {}, action) { 8195 switch (action.type) { 8196 case 'ADD_UNPROCESSED_BLOCK_TYPE': 8197 return { 8198 ...state, 8199 [action.name]: action.blockType 8200 }; 8201 case 'REMOVE_BLOCK_TYPES': 8202 return omit(state, action.names); 8203 } 8204 return state; 8205 } 8206 8207 /** 8208 * Reducer managing the processed block types with all filters applied. 8209 * The state is derived from the `unprocessedBlockTypes` reducer. 8210 * 8211 * @param {Object} state Current state. 8212 * @param {Object} action Dispatched action. 8213 * 8214 * @return {Object} Updated state. 8215 */ 8216 function blockTypes(state = {}, action) { 8217 switch (action.type) { 8218 case 'ADD_BLOCK_TYPES': 8219 return { 8220 ...state, 8221 ...keyBlockTypesByName(action.blockTypes) 8222 }; 8223 case 'REMOVE_BLOCK_TYPES': 8224 return omit(state, action.names); 8225 } 8226 return state; 8227 } 8228 8229 /** 8230 * Reducer managing the block styles. 8231 * 8232 * @param {Object} state Current state. 8233 * @param {Object} action Dispatched action. 8234 * 8235 * @return {Object} Updated state. 8236 */ 8237 function blockStyles(state = {}, action) { 8238 var _state$action$blockNa; 8239 switch (action.type) { 8240 case 'ADD_BLOCK_TYPES': 8241 return { 8242 ...state, 8243 ...Object.fromEntries(Object.entries(keyBlockTypesByName(action.blockTypes)).map(([name, blockType]) => { 8244 var _blockType$styles, _state$blockType$name; 8245 return [name, getUniqueItemsByName([...((_blockType$styles = blockType.styles) !== null && _blockType$styles !== void 0 ? _blockType$styles : []).map(style => ({ 8246 ...style, 8247 source: 'block' 8248 })), ...((_state$blockType$name = state[blockType.name]) !== null && _state$blockType$name !== void 0 ? _state$blockType$name : []).filter(({ 8249 source 8250 }) => 'block' !== source)])]; 8251 })) 8252 }; 8253 case 'ADD_BLOCK_STYLES': 8254 const updatedStyles = {}; 8255 action.blockNames.forEach(blockName => { 8256 var _state$blockName; 8257 updatedStyles[blockName] = getUniqueItemsByName([...((_state$blockName = state[blockName]) !== null && _state$blockName !== void 0 ? _state$blockName : []), ...action.styles]); 8258 }); 8259 return { 8260 ...state, 8261 ...updatedStyles 8262 }; 8263 case 'REMOVE_BLOCK_STYLES': 8264 return { 8265 ...state, 8266 [action.blockName]: ((_state$action$blockNa = state[action.blockName]) !== null && _state$action$blockNa !== void 0 ? _state$action$blockNa : []).filter(style => action.styleNames.indexOf(style.name) === -1) 8267 }; 8268 } 8269 return state; 8270 } 8271 8272 /** 8273 * Reducer managing the block variations. 8274 * 8275 * @param {Object} state Current state. 8276 * @param {Object} action Dispatched action. 8277 * 8278 * @return {Object} Updated state. 8279 */ 8280 function blockVariations(state = {}, action) { 8281 var _state$action$blockNa2, _state$action$blockNa3; 8282 switch (action.type) { 8283 case 'ADD_BLOCK_TYPES': 8284 return { 8285 ...state, 8286 ...Object.fromEntries(Object.entries(keyBlockTypesByName(action.blockTypes)).map(([name, blockType]) => { 8287 var _blockType$variations, _state$blockType$name2; 8288 return [name, getUniqueItemsByName([...((_blockType$variations = blockType.variations) !== null && _blockType$variations !== void 0 ? _blockType$variations : []).map(variation => ({ 8289 ...variation, 8290 source: 'block' 8291 })), ...((_state$blockType$name2 = state[blockType.name]) !== null && _state$blockType$name2 !== void 0 ? _state$blockType$name2 : []).filter(({ 8292 source 8293 }) => 'block' !== source)])]; 8294 })) 8295 }; 8296 case 'ADD_BLOCK_VARIATIONS': 8297 return { 8298 ...state, 8299 [action.blockName]: getUniqueItemsByName([...((_state$action$blockNa2 = state[action.blockName]) !== null && _state$action$blockNa2 !== void 0 ? _state$action$blockNa2 : []), ...action.variations]) 8300 }; 8301 case 'REMOVE_BLOCK_VARIATIONS': 8302 return { 8303 ...state, 8304 [action.blockName]: ((_state$action$blockNa3 = state[action.blockName]) !== null && _state$action$blockNa3 !== void 0 ? _state$action$blockNa3 : []).filter(variation => action.variationNames.indexOf(variation.name) === -1) 8305 }; 8306 } 8307 return state; 8308 } 8309 8310 /** 8311 * Higher-order Reducer creating a reducer keeping track of given block name. 8312 * 8313 * @param {string} setActionType Action type. 8314 * 8315 * @return {Function} Reducer. 8316 */ 8317 function createBlockNameSetterReducer(setActionType) { 8318 return (state = null, action) => { 8319 switch (action.type) { 8320 case 'REMOVE_BLOCK_TYPES': 8321 if (action.names.indexOf(state) !== -1) { 8322 return null; 8323 } 8324 return state; 8325 case setActionType: 8326 return action.name || null; 8327 } 8328 return state; 8329 }; 8330 } 8331 const defaultBlockName = createBlockNameSetterReducer('SET_DEFAULT_BLOCK_NAME'); 8332 const freeformFallbackBlockName = createBlockNameSetterReducer('SET_FREEFORM_FALLBACK_BLOCK_NAME'); 8333 const unregisteredFallbackBlockName = createBlockNameSetterReducer('SET_UNREGISTERED_FALLBACK_BLOCK_NAME'); 8334 const groupingBlockName = createBlockNameSetterReducer('SET_GROUPING_BLOCK_NAME'); 8335 8336 /** 8337 * Reducer managing the categories 8338 * 8339 * @param {WPBlockCategory[]} state Current state. 8340 * @param {Object} action Dispatched action. 8341 * 8342 * @return {WPBlockCategory[]} Updated state. 8343 */ 8344 function categories(state = DEFAULT_CATEGORIES, action) { 8345 switch (action.type) { 8346 case 'SET_CATEGORIES': 8347 // Ensure, that categories are unique by slug. 8348 const uniqueCategories = new Map(); 8349 (action.categories || []).forEach(category => { 8350 uniqueCategories.set(category.slug, category); 8351 }); 8352 return [...uniqueCategories.values()]; 8353 case 'UPDATE_CATEGORY': 8354 { 8355 if (!action.category || !Object.keys(action.category).length) { 8356 return state; 8357 } 8358 const categoryToChange = state.find(({ 8359 slug 8360 }) => slug === action.slug); 8361 if (categoryToChange) { 8362 return state.map(category => { 8363 if (category.slug === action.slug) { 8364 return { 8365 ...category, 8366 ...action.category 8367 }; 8368 } 8369 return category; 8370 }); 8371 } 8372 } 8373 } 8374 return state; 8375 } 8376 function collections(state = {}, action) { 8377 switch (action.type) { 8378 case 'ADD_BLOCK_COLLECTION': 8379 return { 8380 ...state, 8381 [action.namespace]: { 8382 title: action.title, 8383 icon: action.icon 8384 } 8385 }; 8386 case 'REMOVE_BLOCK_COLLECTION': 8387 return omit(state, action.namespace); 8388 } 8389 return state; 8390 } 8391 8392 /** 8393 * Merges usesContext with existing values, potentially defined in the server registration. 8394 * 8395 * @param {string[]} existingUsesContext Existing `usesContext`. 8396 * @param {string[]} newUsesContext Newly added `usesContext`. 8397 * @return {string[]|undefined} Merged `usesContext`. 8398 */ 8399 function getMergedUsesContext(existingUsesContext = [], newUsesContext = []) { 8400 const mergedArrays = Array.from(new Set(existingUsesContext.concat(newUsesContext))); 8401 return mergedArrays.length > 0 ? mergedArrays : undefined; 8402 } 8403 function blockBindingsSources(state = {}, action) { 8404 switch (action.type) { 8405 case 'ADD_BLOCK_BINDINGS_SOURCE': 8406 // Only open this API in Gutenberg and for `core/post-meta` for the moment. 8407 let getFieldsList; 8408 if (false) {} else if (action.name === 'core/post-meta') { 8409 getFieldsList = action.getFieldsList; 8410 } 8411 return { 8412 ...state, 8413 [action.name]: { 8414 label: action.label || state[action.name]?.label, 8415 usesContext: getMergedUsesContext(state[action.name]?.usesContext, action.usesContext), 8416 getValues: action.getValues, 8417 setValues: action.setValues, 8418 // Only set `canUserEditValue` if `setValues` is also defined. 8419 canUserEditValue: action.setValues && action.canUserEditValue, 8420 getFieldsList 8421 } 8422 }; 8423 case 'REMOVE_BLOCK_BINDINGS_SOURCE': 8424 return omit(state, action.name); 8425 } 8426 return state; 8427 } 8428 /* harmony default export */ const reducer = ((0,external_wp_data_namespaceObject.combineReducers)({ 8429 bootstrappedBlockTypes, 8430 unprocessedBlockTypes, 8431 blockTypes, 8432 blockStyles, 8433 blockVariations, 8434 defaultBlockName, 8435 freeformFallbackBlockName, 8436 unregisteredFallbackBlockName, 8437 groupingBlockName, 8438 categories, 8439 collections, 8440 blockBindingsSources 8441 })); 8442 8443 // EXTERNAL MODULE: ./node_modules/remove-accents/index.js 8444 var remove_accents = __webpack_require__(9681); 8445 var remove_accents_default = /*#__PURE__*/__webpack_require__.n(remove_accents); 8446 ;// ./node_modules/@wordpress/blocks/build-module/store/utils.js 8447 /* wp:polyfill */ 8448 /** 8449 * Helper util to return a value from a certain path of the object. 8450 * Path is specified as either: 8451 * - a string of properties, separated by dots, for example: "x.y". 8452 * - an array of properties, for example `[ 'x', 'y' ]`. 8453 * You can also specify a default value in case the result is nullish. 8454 * 8455 * @param {Object} object Input object. 8456 * @param {string|Array} path Path to the object property. 8457 * @param {*} defaultValue Default value if the value at the specified path is nullish. 8458 * @return {*} Value of the object property at the specified path. 8459 */ 8460 const getValueFromObjectPath = (object, path, defaultValue) => { 8461 var _value; 8462 const normalizedPath = Array.isArray(path) ? path : path.split('.'); 8463 let value = object; 8464 normalizedPath.forEach(fieldName => { 8465 value = value?.[fieldName]; 8466 }); 8467 return (_value = value) !== null && _value !== void 0 ? _value : defaultValue; 8468 }; 8469 function utils_isObject(candidate) { 8470 return typeof candidate === 'object' && candidate.constructor === Object && candidate !== null; 8471 } 8472 8473 /** 8474 * Determine whether a set of object properties matches a given object. 8475 * 8476 * Given an object of block attributes and an object of variation attributes, 8477 * this function checks recursively whether all the variation attributes are 8478 * present in the block attributes object. 8479 * 8480 * @param {Object} blockAttributes The object to inspect. 8481 * @param {Object} variationAttributes The object of property values to match. 8482 * @return {boolean} Whether the block attributes match the variation attributes. 8483 */ 8484 function matchesAttributes(blockAttributes, variationAttributes) { 8485 if (utils_isObject(blockAttributes) && utils_isObject(variationAttributes)) { 8486 return Object.entries(variationAttributes).every(([key, value]) => matchesAttributes(blockAttributes?.[key], value)); 8487 } 8488 return blockAttributes === variationAttributes; 8489 } 8490 8491 ;// ./node_modules/@wordpress/blocks/build-module/store/private-selectors.js 8492 /* wp:polyfill */ 8493 /** 8494 * WordPress dependencies 8495 */ 8496 8497 8498 8499 /** 8500 * Internal dependencies 8501 */ 8502 8503 8504 8505 const ROOT_BLOCK_SUPPORTS = ['background', 'backgroundColor', 'color', 'linkColor', 'captionColor', 'buttonColor', 'headingColor', 'fontFamily', 'fontSize', 'fontStyle', 'fontWeight', 'lineHeight', 'padding', 'contentSize', 'wideSize', 'blockGap', 'textDecoration', 'textTransform', 'letterSpacing']; 8506 8507 /** 8508 * Filters the list of supported styles for a given element. 8509 * 8510 * @param {string[]} blockSupports list of supported styles. 8511 * @param {string|undefined} name block name. 8512 * @param {string|undefined} element element name. 8513 * 8514 * @return {string[]} filtered list of supported styles. 8515 */ 8516 function filterElementBlockSupports(blockSupports, name, element) { 8517 return blockSupports.filter(support => { 8518 if (support === 'fontSize' && element === 'heading') { 8519 return false; 8520 } 8521 8522 // This is only available for links 8523 if (support === 'textDecoration' && !name && element !== 'link') { 8524 return false; 8525 } 8526 8527 // This is only available for heading, button, caption and text 8528 if (support === 'textTransform' && !name && !(['heading', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(element) || element === 'button' || element === 'caption' || element === 'text')) { 8529 return false; 8530 } 8531 8532 // This is only available for heading, button, caption and text 8533 if (support === 'letterSpacing' && !name && !(['heading', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(element) || element === 'button' || element === 'caption' || element === 'text')) { 8534 return false; 8535 } 8536 8537 // Text columns is only available for blocks. 8538 if (support === 'textColumns' && !name) { 8539 return false; 8540 } 8541 return true; 8542 }); 8543 } 8544 8545 /** 8546 * Returns the list of supported styles for a given block name and element. 8547 */ 8548 const getSupportedStyles = (0,external_wp_data_namespaceObject.createSelector)((state, name, element) => { 8549 if (!name) { 8550 return filterElementBlockSupports(ROOT_BLOCK_SUPPORTS, name, element); 8551 } 8552 const blockType = selectors_getBlockType(state, name); 8553 if (!blockType) { 8554 return []; 8555 } 8556 const supportKeys = []; 8557 8558 // Check for blockGap support. 8559 // Block spacing support doesn't map directly to a single style property, so needs to be handled separately. 8560 if (blockType?.supports?.spacing?.blockGap) { 8561 supportKeys.push('blockGap'); 8562 } 8563 8564 // check for shadow support 8565 if (blockType?.supports?.shadow) { 8566 supportKeys.push('shadow'); 8567 } 8568 Object.keys(__EXPERIMENTAL_STYLE_PROPERTY).forEach(styleName => { 8569 if (!__EXPERIMENTAL_STYLE_PROPERTY[styleName].support) { 8570 return; 8571 } 8572 8573 // Opting out means that, for certain support keys like background color, 8574 // blocks have to explicitly set the support value false. If the key is 8575 // unset, we still enable it. 8576 if (__EXPERIMENTAL_STYLE_PROPERTY[styleName].requiresOptOut) { 8577 if (__EXPERIMENTAL_STYLE_PROPERTY[styleName].support[0] in blockType.supports && getValueFromObjectPath(blockType.supports, __EXPERIMENTAL_STYLE_PROPERTY[styleName].support) !== false) { 8578 supportKeys.push(styleName); 8579 return; 8580 } 8581 } 8582 if (getValueFromObjectPath(blockType.supports, __EXPERIMENTAL_STYLE_PROPERTY[styleName].support, false)) { 8583 supportKeys.push(styleName); 8584 } 8585 }); 8586 return filterElementBlockSupports(supportKeys, name, element); 8587 }, (state, name) => [state.blockTypes[name]]); 8588 8589 /** 8590 * Returns the bootstrapped block type metadata for a give block name. 8591 * 8592 * @param {Object} state Data state. 8593 * @param {string} name Block name. 8594 * 8595 * @return {Object} Bootstrapped block type metadata for a block. 8596 */ 8597 function getBootstrappedBlockType(state, name) { 8598 return state.bootstrappedBlockTypes[name]; 8599 } 8600 8601 /** 8602 * Returns all the unprocessed (before applying the `registerBlockType` filter) 8603 * block type settings as passed during block registration. 8604 * 8605 * @param {Object} state Data state. 8606 * 8607 * @return {Array} Unprocessed block type settings for all blocks. 8608 */ 8609 function getUnprocessedBlockTypes(state) { 8610 return state.unprocessedBlockTypes; 8611 } 8612 8613 /** 8614 * Returns all the block bindings sources registered. 8615 * 8616 * @param {Object} state Data state. 8617 * 8618 * @return {Object} All the registered sources and their properties. 8619 */ 8620 function getAllBlockBindingsSources(state) { 8621 return state.blockBindingsSources; 8622 } 8623 8624 /** 8625 * Returns a specific block bindings source. 8626 * 8627 * @param {Object} state Data state. 8628 * @param {string} sourceName Name of the source to get. 8629 * 8630 * @return {Object} The specific block binding source and its properties. 8631 */ 8632 function private_selectors_getBlockBindingsSource(state, sourceName) { 8633 return state.blockBindingsSources[sourceName]; 8634 } 8635 8636 /** 8637 * Determines if any of the block type's attributes have 8638 * the content role attribute. 8639 * 8640 * @param {Object} state Data state. 8641 * @param {string} blockTypeName Block type name. 8642 * @return {boolean} Whether block type has content role attribute. 8643 */ 8644 const hasContentRoleAttribute = (state, blockTypeName) => { 8645 const blockType = selectors_getBlockType(state, blockTypeName); 8646 if (!blockType) { 8647 return false; 8648 } 8649 return Object.values(blockType.attributes).some(({ 8650 role, 8651 __experimentalRole 8652 }) => { 8653 if (role === 'content') { 8654 return true; 8655 } 8656 if (__experimentalRole === 'content') { 8657 external_wp_deprecated_default()('__experimentalRole attribute', { 8658 since: '6.7', 8659 version: '6.8', 8660 alternative: 'role attribute', 8661 hint: `Check the block.json of the $blockTypeName} block.` 8662 }); 8663 return true; 8664 } 8665 return false; 8666 }); 8667 }; 8668 8669 ;// ./node_modules/@wordpress/blocks/build-module/store/selectors.js 8670 /* wp:polyfill */ 8671 /** 8672 * External dependencies 8673 */ 8674 8675 8676 /** 8677 * WordPress dependencies 8678 */ 8679 8680 8681 8682 8683 /** 8684 * Internal dependencies 8685 */ 8686 8687 8688 8689 /** @typedef {import('../api/registration').WPBlockVariation} WPBlockVariation */ 8690 /** @typedef {import('../api/registration').WPBlockVariationScope} WPBlockVariationScope */ 8691 /** @typedef {import('./reducer').WPBlockCategory} WPBlockCategory */ 8692 8693 /** 8694 * Given a block name or block type object, returns the corresponding 8695 * normalized block type object. 8696 * 8697 * @param {Object} state Blocks state. 8698 * @param {(string|Object)} nameOrType Block name or type object 8699 * 8700 * @return {Object} Block type object. 8701 */ 8702 const getNormalizedBlockType = (state, nameOrType) => 'string' === typeof nameOrType ? selectors_getBlockType(state, nameOrType) : nameOrType; 8703 8704 /** 8705 * Returns all the available block types. 8706 * 8707 * @param {Object} state Data state. 8708 * 8709 * @example 8710 * ```js 8711 * import { store as blocksStore } from '@wordpress/blocks'; 8712 * import { useSelect } from '@wordpress/data'; 8713 * 8714 * const ExampleComponent = () => { 8715 * const blockTypes = useSelect( 8716 * ( select ) => select( blocksStore ).getBlockTypes(), 8717 * [] 8718 * ); 8719 * 8720 * return ( 8721 * <ul> 8722 * { blockTypes.map( ( block ) => ( 8723 * <li key={ block.name }>{ block.title }</li> 8724 * ) ) } 8725 * </ul> 8726 * ); 8727 * }; 8728 * ``` 8729 * 8730 * @return {Array} Block Types. 8731 */ 8732 const selectors_getBlockTypes = (0,external_wp_data_namespaceObject.createSelector)(state => Object.values(state.blockTypes), state => [state.blockTypes]); 8733 8734 /** 8735 * Returns a block type by name. 8736 * 8737 * @param {Object} state Data state. 8738 * @param {string} name Block type name. 8739 * 8740 * @example 8741 * ```js 8742 * import { store as blocksStore } from '@wordpress/blocks'; 8743 * import { useSelect } from '@wordpress/data'; 8744 * 8745 * const ExampleComponent = () => { 8746 * const paragraphBlock = useSelect( ( select ) => 8747 * ( select ) => select( blocksStore ).getBlockType( 'core/paragraph' ), 8748 * [] 8749 * ); 8750 * 8751 * return ( 8752 * <ul> 8753 * { paragraphBlock && 8754 * Object.entries( paragraphBlock.supports ).map( 8755 * ( blockSupportsEntry ) => { 8756 * const [ propertyName, value ] = blockSupportsEntry; 8757 * return ( 8758 * <li 8759 * key={ propertyName } 8760 * >{ `${ propertyName } : ${ value }` }</li> 8761 * ); 8762 * } 8763 * ) } 8764 * </ul> 8765 * ); 8766 * }; 8767 * ``` 8768 * 8769 * @return {?Object} Block Type. 8770 */ 8771 function selectors_getBlockType(state, name) { 8772 return state.blockTypes[name]; 8773 } 8774 8775 /** 8776 * Returns block styles by block name. 8777 * 8778 * @param {Object} state Data state. 8779 * @param {string} name Block type name. 8780 * 8781 * @example 8782 * ```js 8783 * import { store as blocksStore } from '@wordpress/blocks'; 8784 * import { useSelect } from '@wordpress/data'; 8785 * 8786 * const ExampleComponent = () => { 8787 * const buttonBlockStyles = useSelect( ( select ) => 8788 * select( blocksStore ).getBlockStyles( 'core/button' ), 8789 * [] 8790 * ); 8791 * 8792 * return ( 8793 * <ul> 8794 * { buttonBlockStyles && 8795 * buttonBlockStyles.map( ( style ) => ( 8796 * <li key={ style.name }>{ style.label }</li> 8797 * ) ) } 8798 * </ul> 8799 * ); 8800 * }; 8801 * ``` 8802 * 8803 * @return {Array?} Block Styles. 8804 */ 8805 function getBlockStyles(state, name) { 8806 return state.blockStyles[name]; 8807 } 8808 8809 /** 8810 * Returns block variations by block name. 8811 * 8812 * @param {Object} state Data state. 8813 * @param {string} blockName Block type name. 8814 * @param {WPBlockVariationScope} [scope] Block variation scope name. 8815 * 8816 * @example 8817 * ```js 8818 * import { store as blocksStore } from '@wordpress/blocks'; 8819 * import { useSelect } from '@wordpress/data'; 8820 * 8821 * const ExampleComponent = () => { 8822 * const socialLinkVariations = useSelect( ( select ) => 8823 * select( blocksStore ).getBlockVariations( 'core/social-link' ), 8824 * [] 8825 * ); 8826 * 8827 * return ( 8828 * <ul> 8829 * { socialLinkVariations && 8830 * socialLinkVariations.map( ( variation ) => ( 8831 * <li key={ variation.name }>{ variation.title }</li> 8832 * ) ) } 8833 * </ul> 8834 * ); 8835 * }; 8836 * ``` 8837 * 8838 * @return {(WPBlockVariation[]|void)} Block variations. 8839 */ 8840 const selectors_getBlockVariations = (0,external_wp_data_namespaceObject.createSelector)((state, blockName, scope) => { 8841 const variations = state.blockVariations[blockName]; 8842 if (!variations || !scope) { 8843 return variations; 8844 } 8845 return variations.filter(variation => { 8846 // For backward compatibility reasons, variation's scope defaults to 8847 // `block` and `inserter` when not set. 8848 return (variation.scope || ['block', 'inserter']).includes(scope); 8849 }); 8850 }, (state, blockName) => [state.blockVariations[blockName]]); 8851 8852 /** 8853 * Returns the active block variation for a given block based on its attributes. 8854 * Variations are determined by their `isActive` property. 8855 * Which is either an array of block attribute keys or a function. 8856 * 8857 * In case of an array of block attribute keys, the `attributes` are compared 8858 * to the variation's attributes using strict equality check. 8859 * 8860 * In case of function type, the function should accept a block's attributes 8861 * and the variation's attributes and determines if a variation is active. 8862 * A function that accepts a block's attributes and the variation's attributes and determines if a variation is active. 8863 * 8864 * @param {Object} state Data state. 8865 * @param {string} blockName Name of block (example: “core/columns”). 8866 * @param {Object} attributes Block attributes used to determine active variation. 8867 * @param {WPBlockVariationScope} [scope] Block variation scope name. 8868 * 8869 * @example 8870 * ```js 8871 * import { __ } from '@wordpress/i18n'; 8872 * import { store as blocksStore } from '@wordpress/blocks'; 8873 * import { store as blockEditorStore } from '@wordpress/block-editor'; 8874 * import { useSelect } from '@wordpress/data'; 8875 * 8876 * const ExampleComponent = () => { 8877 * // This example assumes that a core/embed block is the first block in the Block Editor. 8878 * const activeBlockVariation = useSelect( ( select ) => { 8879 * // Retrieve the list of blocks. 8880 * const [ firstBlock ] = select( blockEditorStore ).getBlocks() 8881 * 8882 * // Return the active block variation for the first block. 8883 * return select( blocksStore ).getActiveBlockVariation( 8884 * firstBlock.name, 8885 * firstBlock.attributes 8886 * ); 8887 * }, [] ); 8888 * 8889 * return activeBlockVariation && activeBlockVariation.name === 'spotify' ? ( 8890 * <p>{ __( 'Spotify variation' ) }</p> 8891 * ) : ( 8892 * <p>{ __( 'Other variation' ) }</p> 8893 * ); 8894 * }; 8895 * ``` 8896 * 8897 * @return {(WPBlockVariation|undefined)} Active block variation. 8898 */ 8899 function getActiveBlockVariation(state, blockName, attributes, scope) { 8900 const variations = selectors_getBlockVariations(state, blockName, scope); 8901 if (!variations) { 8902 return variations; 8903 } 8904 const blockType = selectors_getBlockType(state, blockName); 8905 const attributeKeys = Object.keys(blockType?.attributes || {}); 8906 let match; 8907 let maxMatchedAttributes = 0; 8908 for (const variation of variations) { 8909 if (Array.isArray(variation.isActive)) { 8910 const definedAttributes = variation.isActive.filter(attribute => { 8911 // We support nested attribute paths, e.g. `layout.type`. 8912 // In this case, we need to check if the part before the 8913 // first dot is a known attribute. 8914 const topLevelAttribute = attribute.split('.')[0]; 8915 return attributeKeys.includes(topLevelAttribute); 8916 }); 8917 const definedAttributesLength = definedAttributes.length; 8918 if (definedAttributesLength === 0) { 8919 continue; 8920 } 8921 const isMatch = definedAttributes.every(attribute => { 8922 const variationAttributeValue = getValueFromObjectPath(variation.attributes, attribute); 8923 if (variationAttributeValue === undefined) { 8924 return false; 8925 } 8926 let blockAttributeValue = getValueFromObjectPath(attributes, attribute); 8927 if (blockAttributeValue instanceof external_wp_richText_namespaceObject.RichTextData) { 8928 blockAttributeValue = blockAttributeValue.toHTMLString(); 8929 } 8930 return matchesAttributes(blockAttributeValue, variationAttributeValue); 8931 }); 8932 if (isMatch && definedAttributesLength > maxMatchedAttributes) { 8933 match = variation; 8934 maxMatchedAttributes = definedAttributesLength; 8935 } 8936 } else if (variation.isActive?.(attributes, variation.attributes)) { 8937 // If isActive is a function, we cannot know how many attributes it matches. 8938 // This means that we cannot compare the specificity of our matches, 8939 // and simply return the best match we have found. 8940 return match || variation; 8941 } 8942 } 8943 return match; 8944 } 8945 8946 /** 8947 * Returns the default block variation for the given block type. 8948 * When there are multiple variations annotated as the default one, 8949 * the last added item is picked. This simplifies registering overrides. 8950 * When there is no default variation set, it returns the first item. 8951 * 8952 * @param {Object} state Data state. 8953 * @param {string} blockName Block type name. 8954 * @param {WPBlockVariationScope} [scope] Block variation scope name. 8955 * 8956 * @example 8957 * ```js 8958 * import { __, sprintf } from '@wordpress/i18n'; 8959 * import { store as blocksStore } from '@wordpress/blocks'; 8960 * import { useSelect } from '@wordpress/data'; 8961 * 8962 * const ExampleComponent = () => { 8963 * const defaultEmbedBlockVariation = useSelect( ( select ) => 8964 * select( blocksStore ).getDefaultBlockVariation( 'core/embed' ), 8965 * [] 8966 * ); 8967 * 8968 * return ( 8969 * defaultEmbedBlockVariation && ( 8970 * <p> 8971 * { sprintf( 8972 * __( 'core/embed default variation: %s' ), 8973 * defaultEmbedBlockVariation.title 8974 * ) } 8975 * </p> 8976 * ) 8977 * ); 8978 * }; 8979 * ``` 8980 * 8981 * @return {?WPBlockVariation} The default block variation. 8982 */ 8983 function getDefaultBlockVariation(state, blockName, scope) { 8984 const variations = selectors_getBlockVariations(state, blockName, scope); 8985 const defaultVariation = [...variations].reverse().find(({ 8986 isDefault 8987 }) => !!isDefault); 8988 return defaultVariation || variations[0]; 8989 } 8990 8991 /** 8992 * Returns all the available block categories. 8993 * 8994 * @param {Object} state Data state. 8995 * 8996 * @example 8997 * ```js 8998 * import { store as blocksStore } from '@wordpress/blocks'; 8999 * import { useSelect, } from '@wordpress/data'; 9000 * 9001 * const ExampleComponent = () => { 9002 * const blockCategories = useSelect( ( select ) => 9003 * select( blocksStore ).getCategories(), 9004 * [] 9005 * ); 9006 * 9007 * return ( 9008 * <ul> 9009 * { blockCategories.map( ( category ) => ( 9010 * <li key={ category.slug }>{ category.title }</li> 9011 * ) ) } 9012 * </ul> 9013 * ); 9014 * }; 9015 * ``` 9016 * 9017 * @return {WPBlockCategory[]} Categories list. 9018 */ 9019 function getCategories(state) { 9020 return state.categories; 9021 } 9022 9023 /** 9024 * Returns all the available collections. 9025 * 9026 * @param {Object} state Data state. 9027 * 9028 * @example 9029 * ```js 9030 * import { store as blocksStore } from '@wordpress/blocks'; 9031 * import { useSelect } from '@wordpress/data'; 9032 * 9033 * const ExampleComponent = () => { 9034 * const blockCollections = useSelect( ( select ) => 9035 * select( blocksStore ).getCollections(), 9036 * [] 9037 * ); 9038 * 9039 * return ( 9040 * <ul> 9041 * { Object.values( blockCollections ).length > 0 && 9042 * Object.values( blockCollections ).map( ( collection ) => ( 9043 * <li key={ collection.title }>{ collection.title }</li> 9044 * ) ) } 9045 * </ul> 9046 * ); 9047 * }; 9048 * ``` 9049 * 9050 * @return {Object} Collections list. 9051 */ 9052 function getCollections(state) { 9053 return state.collections; 9054 } 9055 9056 /** 9057 * Returns the name of the default block name. 9058 * 9059 * @param {Object} state Data state. 9060 * 9061 * @example 9062 * ```js 9063 * import { __, sprintf } from '@wordpress/i18n'; 9064 * import { store as blocksStore } from '@wordpress/blocks'; 9065 * import { useSelect } from '@wordpress/data'; 9066 * 9067 * const ExampleComponent = () => { 9068 * const defaultBlockName = useSelect( ( select ) => 9069 * select( blocksStore ).getDefaultBlockName(), 9070 * [] 9071 * ); 9072 * 9073 * return ( 9074 * defaultBlockName && ( 9075 * <p> 9076 * { sprintf( __( 'Default block name: %s' ), defaultBlockName ) } 9077 * </p> 9078 * ) 9079 * ); 9080 * }; 9081 * ``` 9082 * 9083 * @return {?string} Default block name. 9084 */ 9085 function selectors_getDefaultBlockName(state) { 9086 return state.defaultBlockName; 9087 } 9088 9089 /** 9090 * Returns the name of the block for handling non-block content. 9091 * 9092 * @param {Object} state Data state. 9093 * 9094 * @example 9095 * ```js 9096 * import { __, sprintf } from '@wordpress/i18n'; 9097 * import { store as blocksStore } from '@wordpress/blocks'; 9098 * import { useSelect } from '@wordpress/data'; 9099 * 9100 * const ExampleComponent = () => { 9101 * const freeformFallbackBlockName = useSelect( ( select ) => 9102 * select( blocksStore ).getFreeformFallbackBlockName(), 9103 * [] 9104 * ); 9105 * 9106 * return ( 9107 * freeformFallbackBlockName && ( 9108 * <p> 9109 * { sprintf( __( 9110 * 'Freeform fallback block name: %s' ), 9111 * freeformFallbackBlockName 9112 * ) } 9113 * </p> 9114 * ) 9115 * ); 9116 * }; 9117 * ``` 9118 * 9119 * @return {?string} Name of the block for handling non-block content. 9120 */ 9121 function getFreeformFallbackBlockName(state) { 9122 return state.freeformFallbackBlockName; 9123 } 9124 9125 /** 9126 * Returns the name of the block for handling unregistered blocks. 9127 * 9128 * @param {Object} state Data state. 9129 * 9130 * @example 9131 * ```js 9132 * import { __, sprintf } from '@wordpress/i18n'; 9133 * import { store as blocksStore } from '@wordpress/blocks'; 9134 * import { useSelect } from '@wordpress/data'; 9135 * 9136 * const ExampleComponent = () => { 9137 * const unregisteredFallbackBlockName = useSelect( ( select ) => 9138 * select( blocksStore ).getUnregisteredFallbackBlockName(), 9139 * [] 9140 * ); 9141 * 9142 * return ( 9143 * unregisteredFallbackBlockName && ( 9144 * <p> 9145 * { sprintf( __( 9146 * 'Unregistered fallback block name: %s' ), 9147 * unregisteredFallbackBlockName 9148 * ) } 9149 * </p> 9150 * ) 9151 * ); 9152 * }; 9153 * ``` 9154 * 9155 * @return {?string} Name of the block for handling unregistered blocks. 9156 */ 9157 function getUnregisteredFallbackBlockName(state) { 9158 return state.unregisteredFallbackBlockName; 9159 } 9160 9161 /** 9162 * Returns the name of the block for handling the grouping of blocks. 9163 * 9164 * @param {Object} state Data state. 9165 * 9166 * @example 9167 * ```js 9168 * import { __, sprintf } from '@wordpress/i18n'; 9169 * import { store as blocksStore } from '@wordpress/blocks'; 9170 * import { useSelect } from '@wordpress/data'; 9171 * 9172 * const ExampleComponent = () => { 9173 * const groupingBlockName = useSelect( ( select ) => 9174 * select( blocksStore ).getGroupingBlockName(), 9175 * [] 9176 * ); 9177 * 9178 * return ( 9179 * groupingBlockName && ( 9180 * <p> 9181 * { sprintf( 9182 * __( 'Default grouping block name: %s' ), 9183 * groupingBlockName 9184 * ) } 9185 * </p> 9186 * ) 9187 * ); 9188 * }; 9189 * ``` 9190 * 9191 * @return {?string} Name of the block for handling the grouping of blocks. 9192 */ 9193 function selectors_getGroupingBlockName(state) { 9194 return state.groupingBlockName; 9195 } 9196 9197 /** 9198 * Returns an array with the child blocks of a given block. 9199 * 9200 * @param {Object} state Data state. 9201 * @param {string} blockName Block type name. 9202 * 9203 * @example 9204 * ```js 9205 * import { store as blocksStore } from '@wordpress/blocks'; 9206 * import { useSelect } from '@wordpress/data'; 9207 * 9208 * const ExampleComponent = () => { 9209 * const childBlockNames = useSelect( ( select ) => 9210 * select( blocksStore ).getChildBlockNames( 'core/navigation' ), 9211 * [] 9212 * ); 9213 * 9214 * return ( 9215 * <ul> 9216 * { childBlockNames && 9217 * childBlockNames.map( ( child ) => ( 9218 * <li key={ child }>{ child }</li> 9219 * ) ) } 9220 * </ul> 9221 * ); 9222 * }; 9223 * ``` 9224 * 9225 * @return {Array} Array of child block names. 9226 */ 9227 const selectors_getChildBlockNames = (0,external_wp_data_namespaceObject.createSelector)((state, blockName) => { 9228 return selectors_getBlockTypes(state).filter(blockType => { 9229 return blockType.parent?.includes(blockName); 9230 }).map(({ 9231 name 9232 }) => name); 9233 }, state => [state.blockTypes]); 9234 9235 /** 9236 * Returns the block support value for a feature, if defined. 9237 * 9238 * @param {Object} state Data state. 9239 * @param {(string|Object)} nameOrType Block name or type object 9240 * @param {Array|string} feature Feature to retrieve 9241 * @param {*} defaultSupports Default value to return if not 9242 * explicitly defined 9243 * 9244 * @example 9245 * ```js 9246 * import { __, sprintf } from '@wordpress/i18n'; 9247 * import { store as blocksStore } from '@wordpress/blocks'; 9248 * import { useSelect } from '@wordpress/data'; 9249 * 9250 * const ExampleComponent = () => { 9251 * const paragraphBlockSupportValue = useSelect( ( select ) => 9252 * select( blocksStore ).getBlockSupport( 'core/paragraph', 'anchor' ), 9253 * [] 9254 * ); 9255 * 9256 * return ( 9257 * <p> 9258 * { sprintf( 9259 * __( 'core/paragraph supports.anchor value: %s' ), 9260 * paragraphBlockSupportValue 9261 * ) } 9262 * </p> 9263 * ); 9264 * }; 9265 * ``` 9266 * 9267 * @return {?*} Block support value 9268 */ 9269 const selectors_getBlockSupport = (state, nameOrType, feature, defaultSupports) => { 9270 const blockType = getNormalizedBlockType(state, nameOrType); 9271 if (!blockType?.supports) { 9272 return defaultSupports; 9273 } 9274 return getValueFromObjectPath(blockType.supports, feature, defaultSupports); 9275 }; 9276 9277 /** 9278 * Returns true if the block defines support for a feature, or false otherwise. 9279 * 9280 * @param {Object} state Data state. 9281 * @param {(string|Object)} nameOrType Block name or type object. 9282 * @param {string} feature Feature to test. 9283 * @param {boolean} defaultSupports Whether feature is supported by 9284 * default if not explicitly defined. 9285 * 9286 * @example 9287 * ```js 9288 * import { __, sprintf } from '@wordpress/i18n'; 9289 * import { store as blocksStore } from '@wordpress/blocks'; 9290 * import { useSelect } from '@wordpress/data'; 9291 * 9292 * const ExampleComponent = () => { 9293 * const paragraphBlockSupportClassName = useSelect( ( select ) => 9294 * select( blocksStore ).hasBlockSupport( 'core/paragraph', 'className' ), 9295 * [] 9296 * ); 9297 * 9298 * return ( 9299 * <p> 9300 * { sprintf( 9301 * __( 'core/paragraph supports custom class name?: %s' ), 9302 * paragraphBlockSupportClassName 9303 * ) } 9304 * /p> 9305 * ); 9306 * }; 9307 * ``` 9308 * 9309 * @return {boolean} Whether block supports feature. 9310 */ 9311 function selectors_hasBlockSupport(state, nameOrType, feature, defaultSupports) { 9312 return !!selectors_getBlockSupport(state, nameOrType, feature, defaultSupports); 9313 } 9314 9315 /** 9316 * Normalizes a search term string: removes accents, converts to lowercase, removes extra whitespace. 9317 * 9318 * @param {string|null|undefined} term Search term to normalize. 9319 * @return {string} Normalized search term. 9320 */ 9321 function getNormalizedSearchTerm(term) { 9322 return remove_accents_default()(term !== null && term !== void 0 ? term : '').toLowerCase().trim(); 9323 } 9324 9325 /** 9326 * Returns true if the block type by the given name or object value matches a 9327 * search term, or false otherwise. 9328 * 9329 * @param {Object} state Blocks state. 9330 * @param {(string|Object)} nameOrType Block name or type object. 9331 * @param {string} searchTerm Search term by which to filter. 9332 * 9333 * @example 9334 * ```js 9335 * import { __, sprintf } from '@wordpress/i18n'; 9336 * import { store as blocksStore } from '@wordpress/blocks'; 9337 * import { useSelect } from '@wordpress/data'; 9338 * 9339 * const ExampleComponent = () => { 9340 * const termFound = useSelect( 9341 * ( select ) => 9342 * select( blocksStore ).isMatchingSearchTerm( 9343 * 'core/navigation', 9344 * 'theme' 9345 * ), 9346 * [] 9347 * ); 9348 * 9349 * return ( 9350 * <p> 9351 * { sprintf( 9352 * __( 9353 * 'Search term was found in the title, keywords, category or description in block.json: %s' 9354 * ), 9355 * termFound 9356 * ) } 9357 * </p> 9358 * ); 9359 * }; 9360 * ``` 9361 * 9362 * @return {Object[]} Whether block type matches search term. 9363 */ 9364 function isMatchingSearchTerm(state, nameOrType, searchTerm = '') { 9365 const blockType = getNormalizedBlockType(state, nameOrType); 9366 const normalizedSearchTerm = getNormalizedSearchTerm(searchTerm); 9367 const isSearchMatch = candidate => getNormalizedSearchTerm(candidate).includes(normalizedSearchTerm); 9368 return isSearchMatch(blockType.title) || blockType.keywords?.some(isSearchMatch) || isSearchMatch(blockType.category) || typeof blockType.description === 'string' && isSearchMatch(blockType.description); 9369 } 9370 9371 /** 9372 * Returns a boolean indicating if a block has child blocks or not. 9373 * 9374 * @param {Object} state Data state. 9375 * @param {string} blockName Block type name. 9376 * 9377 * @example 9378 * ```js 9379 * import { __, sprintf } from '@wordpress/i18n'; 9380 * import { store as blocksStore } from '@wordpress/blocks'; 9381 * import { useSelect } from '@wordpress/data'; 9382 * 9383 * const ExampleComponent = () => { 9384 * const navigationBlockHasChildBlocks = useSelect( ( select ) => 9385 * select( blocksStore ).hasChildBlocks( 'core/navigation' ), 9386 * [] 9387 * ); 9388 * 9389 * return ( 9390 * <p> 9391 * { sprintf( 9392 * __( 'core/navigation has child blocks: %s' ), 9393 * navigationBlockHasChildBlocks 9394 * ) } 9395 * </p> 9396 * ); 9397 * }; 9398 * ``` 9399 * 9400 * @return {boolean} True if a block contains child blocks and false otherwise. 9401 */ 9402 const selectors_hasChildBlocks = (state, blockName) => { 9403 return selectors_getChildBlockNames(state, blockName).length > 0; 9404 }; 9405 9406 /** 9407 * Returns a boolean indicating if a block has at least one child block with inserter support. 9408 * 9409 * @param {Object} state Data state. 9410 * @param {string} blockName Block type name. 9411 * 9412 * @example 9413 * ```js 9414 * import { __, sprintf } from '@wordpress/i18n'; 9415 * import { store as blocksStore } from '@wordpress/blocks'; 9416 * import { useSelect } from '@wordpress/data'; 9417 * 9418 * const ExampleComponent = () => { 9419 * const navigationBlockHasChildBlocksWithInserterSupport = useSelect( ( select ) => 9420 * select( blocksStore ).hasChildBlocksWithInserterSupport( 9421 * 'core/navigation' 9422 * ), 9423 * [] 9424 * ); 9425 * 9426 * return ( 9427 * <p> 9428 * { sprintf( 9429 * __( 'core/navigation has child blocks with inserter support: %s' ), 9430 * navigationBlockHasChildBlocksWithInserterSupport 9431 * ) } 9432 * </p> 9433 * ); 9434 * }; 9435 * ``` 9436 * 9437 * @return {boolean} True if a block contains at least one child blocks with inserter support 9438 * and false otherwise. 9439 */ 9440 const selectors_hasChildBlocksWithInserterSupport = (state, blockName) => { 9441 return selectors_getChildBlockNames(state, blockName).some(childBlockName => { 9442 return selectors_hasBlockSupport(state, childBlockName, 'inserter', true); 9443 }); 9444 }; 9445 const __experimentalHasContentRoleAttribute = (...args) => { 9446 external_wp_deprecated_default()('__experimentalHasContentRoleAttribute', { 9447 since: '6.7', 9448 version: '6.8', 9449 hint: 'This is a private selector.' 9450 }); 9451 return hasContentRoleAttribute(...args); 9452 }; 9453 9454 ;// ./node_modules/is-plain-object/dist/is-plain-object.mjs 9455 /*! 9456 * is-plain-object <https://github.com/jonschlinkert/is-plain-object> 9457 * 9458 * Copyright (c) 2014-2017, Jon Schlinkert. 9459 * Released under the MIT License. 9460 */ 9461 9462 function is_plain_object_isObject(o) { 9463 return Object.prototype.toString.call(o) === '[object Object]'; 9464 } 9465 9466 function isPlainObject(o) { 9467 var ctor,prot; 9468 9469 if (is_plain_object_isObject(o) === false) return false; 9470 9471 // If has modified constructor 9472 ctor = o.constructor; 9473 if (ctor === undefined) return true; 9474 9475 // If has modified prototype 9476 prot = ctor.prototype; 9477 if (is_plain_object_isObject(prot) === false) return false; 9478 9479 // If constructor does not have an Object-specific method 9480 if (prot.hasOwnProperty('isPrototypeOf') === false) { 9481 return false; 9482 } 9483 9484 // Most likely a plain Object 9485 return true; 9486 } 9487 9488 9489 9490 // EXTERNAL MODULE: ./node_modules/react-is/index.js 9491 var react_is = __webpack_require__(8529); 9492 ;// external ["wp","hooks"] 9493 const external_wp_hooks_namespaceObject = window["wp"]["hooks"]; 9494 ;// ./node_modules/@wordpress/blocks/build-module/store/process-block-type.js 9495 /* wp:polyfill */ 9496 /** 9497 * External dependencies 9498 */ 9499 9500 9501 9502 /** 9503 * WordPress dependencies 9504 */ 9505 9506 9507 9508 9509 /** 9510 * Internal dependencies 9511 */ 9512 9513 9514 9515 /** @typedef {import('../api/registration').WPBlockType} WPBlockType */ 9516 9517 /** 9518 * Mapping of legacy category slugs to their latest normal values, used to 9519 * accommodate updates of the default set of block categories. 9520 * 9521 * @type {Record<string,string>} 9522 */ 9523 const LEGACY_CATEGORY_MAPPING = { 9524 common: 'text', 9525 formatting: 'text', 9526 layout: 'design' 9527 }; 9528 9529 /** 9530 * Merge block variations bootstrapped from the server and client. 9531 * 9532 * When a variation is registered in both places, its properties are merged. 9533 * 9534 * @param {Array} bootstrappedVariations - A block type variations from the server. 9535 * @param {Array} clientVariations - A block type variations from the client. 9536 * @return {Array} The merged array of block variations. 9537 */ 9538 function mergeBlockVariations(bootstrappedVariations = [], clientVariations = []) { 9539 const result = [...bootstrappedVariations]; 9540 clientVariations.forEach(clientVariation => { 9541 const index = result.findIndex(bootstrappedVariation => bootstrappedVariation.name === clientVariation.name); 9542 if (index !== -1) { 9543 result[index] = { 9544 ...result[index], 9545 ...clientVariation 9546 }; 9547 } else { 9548 result.push(clientVariation); 9549 } 9550 }); 9551 return result; 9552 } 9553 9554 /** 9555 * Takes the unprocessed block type settings, merges them with block type metadata 9556 * and applies all the existing filters for the registered block type. 9557 * Next, it validates all the settings and performs additional processing to the block type definition. 9558 * 9559 * @param {string} name Block name. 9560 * @param {WPBlockType} blockSettings Unprocessed block type settings. 9561 * 9562 * @return {WPBlockType | undefined} The block, if it has been processed and can be registered; otherwise `undefined`. 9563 */ 9564 const processBlockType = (name, blockSettings) => ({ 9565 select 9566 }) => { 9567 const bootstrappedBlockType = select.getBootstrappedBlockType(name); 9568 const blockType = { 9569 name, 9570 icon: BLOCK_ICON_DEFAULT, 9571 keywords: [], 9572 attributes: {}, 9573 providesContext: {}, 9574 usesContext: [], 9575 selectors: {}, 9576 supports: {}, 9577 styles: [], 9578 blockHooks: {}, 9579 save: () => null, 9580 ...bootstrappedBlockType, 9581 ...blockSettings, 9582 // blockType.variations can be defined as a filePath. 9583 variations: mergeBlockVariations(Array.isArray(bootstrappedBlockType?.variations) ? bootstrappedBlockType.variations : [], Array.isArray(blockSettings?.variations) ? blockSettings.variations : []) 9584 }; 9585 const settings = (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.registerBlockType', blockType, name, null); 9586 if (settings.description && typeof settings.description !== 'string') { 9587 external_wp_deprecated_default()('Declaring non-string block descriptions', { 9588 since: '6.2' 9589 }); 9590 } 9591 if (settings.deprecated) { 9592 settings.deprecated = settings.deprecated.map(deprecation => Object.fromEntries(Object.entries( 9593 // Only keep valid deprecation keys. 9594 (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.registerBlockType', 9595 // Merge deprecation keys with pre-filter settings 9596 // so that filters that depend on specific keys being 9597 // present don't fail. 9598 { 9599 // Omit deprecation keys here so that deprecations 9600 // can opt out of specific keys like "supports". 9601 ...omit(blockType, DEPRECATED_ENTRY_KEYS), 9602 ...deprecation 9603 }, blockType.name, deprecation)).filter(([key]) => DEPRECATED_ENTRY_KEYS.includes(key)))); 9604 } 9605 if (!isPlainObject(settings)) { 9606 true ? external_wp_warning_default()('Block settings must be a valid object.') : 0; 9607 return; 9608 } 9609 if (typeof settings.save !== 'function') { 9610 true ? external_wp_warning_default()('The "save" property must be a valid function.') : 0; 9611 return; 9612 } 9613 if ('edit' in settings && !(0,react_is.isValidElementType)(settings.edit)) { 9614 true ? external_wp_warning_default()('The "edit" property must be a valid component.') : 0; 9615 return; 9616 } 9617 9618 // Canonicalize legacy categories to equivalent fallback. 9619 if (LEGACY_CATEGORY_MAPPING.hasOwnProperty(settings.category)) { 9620 settings.category = LEGACY_CATEGORY_MAPPING[settings.category]; 9621 } 9622 if ('category' in settings && !select.getCategories().some(({ 9623 slug 9624 }) => slug === settings.category)) { 9625 true ? external_wp_warning_default()('The block "' + name + '" is registered with an invalid category "' + settings.category + '".') : 0; 9626 delete settings.category; 9627 } 9628 if (!('title' in settings) || settings.title === '') { 9629 true ? external_wp_warning_default()('The block "' + name + '" must have a title.') : 0; 9630 return; 9631 } 9632 if (typeof settings.title !== 'string') { 9633 true ? external_wp_warning_default()('Block titles must be strings.') : 0; 9634 return; 9635 } 9636 settings.icon = normalizeIconObject(settings.icon); 9637 if (!isValidIcon(settings.icon.src)) { 9638 true ? external_wp_warning_default()('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') : 0; 9639 return; 9640 } 9641 if (typeof settings?.parent === 'string' || settings?.parent instanceof String) { 9642 settings.parent = [settings.parent]; 9643 true ? external_wp_warning_default()('Parent must be undefined or an array of strings (block types), but it is a string.') : 0; 9644 // Intentionally continue: 9645 // 9646 // While string values were never supported, they appeared to work with some unintended side-effects 9647 // that have been fixed by [#66250](https://github.com/WordPress/gutenberg/pull/66250). 9648 // 9649 // To be backwards-compatible, this code that automatically migrates strings to arrays. 9650 } 9651 if (!Array.isArray(settings?.parent) && settings?.parent !== undefined) { 9652 true ? external_wp_warning_default()('Parent must be undefined or an array of block types, but it is ', settings.parent) : 0; 9653 return; 9654 } 9655 if (1 === settings?.parent?.length && name === settings.parent[0]) { 9656 true ? external_wp_warning_default()('Block "' + name + '" cannot be a parent of itself. Please remove the block name from the parent list.') : 0; 9657 return; 9658 } 9659 return settings; 9660 }; 9661 9662 ;// ./node_modules/@wordpress/blocks/build-module/store/actions.js 9663 /** 9664 * WordPress dependencies 9665 */ 9666 9667 9668 /** 9669 * Internal dependencies 9670 */ 9671 9672 9673 /** @typedef {import('../api/registration').WPBlockVariation} WPBlockVariation */ 9674 /** @typedef {import('../api/registration').WPBlockType} WPBlockType */ 9675 /** @typedef {import('./reducer').WPBlockCategory} WPBlockCategory */ 9676 9677 /** 9678 * Returns an action object used in signalling that block types have been added. 9679 * Ignored from documentation as the recommended usage for this action through registerBlockType from @wordpress/blocks. 9680 * 9681 * @ignore 9682 * 9683 * @param {WPBlockType|WPBlockType[]} blockTypes Object or array of objects representing blocks to added. 9684 * 9685 * 9686 * @return {Object} Action object. 9687 */ 9688 function addBlockTypes(blockTypes) { 9689 return { 9690 type: 'ADD_BLOCK_TYPES', 9691 blockTypes: Array.isArray(blockTypes) ? blockTypes : [blockTypes] 9692 }; 9693 } 9694 9695 /** 9696 * Signals that all block types should be computed again. 9697 * It uses stored unprocessed block types and all the most recent list of registered filters. 9698 * 9699 * It addresses the issue where third party block filters get registered after third party blocks. A sample sequence: 9700 * 1. Filter A. 9701 * 2. Block B. 9702 * 3. Block C. 9703 * 4. Filter D. 9704 * 5. Filter E. 9705 * 6. Block F. 9706 * 7. Filter G. 9707 * In this scenario some filters would not get applied for all blocks because they are registered too late. 9708 */ 9709 function reapplyBlockTypeFilters() { 9710 return ({ 9711 dispatch, 9712 select 9713 }) => { 9714 const processedBlockTypes = []; 9715 for (const [name, settings] of Object.entries(select.getUnprocessedBlockTypes())) { 9716 const result = dispatch(processBlockType(name, settings)); 9717 if (result) { 9718 processedBlockTypes.push(result); 9719 } 9720 } 9721 if (!processedBlockTypes.length) { 9722 return; 9723 } 9724 dispatch.addBlockTypes(processedBlockTypes); 9725 }; 9726 } 9727 function __experimentalReapplyBlockFilters() { 9728 external_wp_deprecated_default()('wp.data.dispatch( "core/blocks" ).__experimentalReapplyBlockFilters', { 9729 since: '6.4', 9730 alternative: 'reapplyBlockFilters' 9731 }); 9732 return reapplyBlockTypeFilters(); 9733 } 9734 9735 /** 9736 * Returns an action object used to remove a registered block type. 9737 * Ignored from documentation as the recommended usage for this action through unregisterBlockType from @wordpress/blocks. 9738 * 9739 * @ignore 9740 * 9741 * @param {string|string[]} names Block name or array of block names to be removed. 9742 * 9743 * 9744 * @return {Object} Action object. 9745 */ 9746 function removeBlockTypes(names) { 9747 return { 9748 type: 'REMOVE_BLOCK_TYPES', 9749 names: Array.isArray(names) ? names : [names] 9750 }; 9751 } 9752 9753 /** 9754 * Returns an action object used in signalling that new block styles have been added. 9755 * Ignored from documentation as the recommended usage for this action through registerBlockStyle from @wordpress/blocks. 9756 * 9757 * @param {string|Array} blockNames Block names to register new styles for. 9758 * @param {Array|Object} styles Block style object or array of block style objects. 9759 * 9760 * @ignore 9761 * 9762 * @return {Object} Action object. 9763 */ 9764 function addBlockStyles(blockNames, styles) { 9765 return { 9766 type: 'ADD_BLOCK_STYLES', 9767 styles: Array.isArray(styles) ? styles : [styles], 9768 blockNames: Array.isArray(blockNames) ? blockNames : [blockNames] 9769 }; 9770 } 9771 9772 /** 9773 * Returns an action object used in signalling that block styles have been removed. 9774 * Ignored from documentation as the recommended usage for this action through unregisterBlockStyle from @wordpress/blocks. 9775 * 9776 * @ignore 9777 * 9778 * @param {string} blockName Block name. 9779 * @param {Array|string} styleNames Block style names or array of block style names. 9780 * 9781 * @return {Object} Action object. 9782 */ 9783 function removeBlockStyles(blockName, styleNames) { 9784 return { 9785 type: 'REMOVE_BLOCK_STYLES', 9786 styleNames: Array.isArray(styleNames) ? styleNames : [styleNames], 9787 blockName 9788 }; 9789 } 9790 9791 /** 9792 * Returns an action object used in signalling that new block variations have been added. 9793 * Ignored from documentation as the recommended usage for this action through registerBlockVariation from @wordpress/blocks. 9794 * 9795 * @ignore 9796 * 9797 * @param {string} blockName Block name. 9798 * @param {WPBlockVariation|WPBlockVariation[]} variations Block variations. 9799 * 9800 * @return {Object} Action object. 9801 */ 9802 function addBlockVariations(blockName, variations) { 9803 return { 9804 type: 'ADD_BLOCK_VARIATIONS', 9805 variations: Array.isArray(variations) ? variations : [variations], 9806 blockName 9807 }; 9808 } 9809 9810 /** 9811 * Returns an action object used in signalling that block variations have been removed. 9812 * Ignored from documentation as the recommended usage for this action through unregisterBlockVariation from @wordpress/blocks. 9813 * 9814 * @ignore 9815 * 9816 * @param {string} blockName Block name. 9817 * @param {string|string[]} variationNames Block variation names. 9818 * 9819 * @return {Object} Action object. 9820 */ 9821 function removeBlockVariations(blockName, variationNames) { 9822 return { 9823 type: 'REMOVE_BLOCK_VARIATIONS', 9824 variationNames: Array.isArray(variationNames) ? variationNames : [variationNames], 9825 blockName 9826 }; 9827 } 9828 9829 /** 9830 * Returns an action object used to set the default block name. 9831 * Ignored from documentation as the recommended usage for this action through setDefaultBlockName from @wordpress/blocks. 9832 * 9833 * @ignore 9834 * 9835 * @param {string} name Block name. 9836 * 9837 * @return {Object} Action object. 9838 */ 9839 function actions_setDefaultBlockName(name) { 9840 return { 9841 type: 'SET_DEFAULT_BLOCK_NAME', 9842 name 9843 }; 9844 } 9845 9846 /** 9847 * Returns an action object used to set the name of the block used as a fallback 9848 * for non-block content. 9849 * Ignored from documentation as the recommended usage for this action through setFreeformContentHandlerName from @wordpress/blocks. 9850 * 9851 * @ignore 9852 * 9853 * @param {string} name Block name. 9854 * 9855 * @return {Object} Action object. 9856 */ 9857 function setFreeformFallbackBlockName(name) { 9858 return { 9859 type: 'SET_FREEFORM_FALLBACK_BLOCK_NAME', 9860 name 9861 }; 9862 } 9863 9864 /** 9865 * Returns an action object used to set the name of the block used as a fallback 9866 * for unregistered blocks. 9867 * Ignored from documentation as the recommended usage for this action through setUnregisteredTypeHandlerName from @wordpress/blocks. 9868 * 9869 * @ignore 9870 * 9871 * @param {string} name Block name. 9872 * 9873 * @return {Object} Action object. 9874 */ 9875 function setUnregisteredFallbackBlockName(name) { 9876 return { 9877 type: 'SET_UNREGISTERED_FALLBACK_BLOCK_NAME', 9878 name 9879 }; 9880 } 9881 9882 /** 9883 * Returns an action object used to set the name of the block used 9884 * when grouping other blocks 9885 * eg: in "Group/Ungroup" interactions 9886 * Ignored from documentation as the recommended usage for this action through setGroupingBlockName from @wordpress/blocks. 9887 * 9888 * @ignore 9889 * 9890 * @param {string} name Block name. 9891 * 9892 * @return {Object} Action object. 9893 */ 9894 function actions_setGroupingBlockName(name) { 9895 return { 9896 type: 'SET_GROUPING_BLOCK_NAME', 9897 name 9898 }; 9899 } 9900 9901 /** 9902 * Returns an action object used to set block categories. 9903 * Ignored from documentation as the recommended usage for this action through setCategories from @wordpress/blocks. 9904 * 9905 * @ignore 9906 * 9907 * @param {WPBlockCategory[]} categories Block categories. 9908 * 9909 * @return {Object} Action object. 9910 */ 9911 function setCategories(categories) { 9912 return { 9913 type: 'SET_CATEGORIES', 9914 categories 9915 }; 9916 } 9917 9918 /** 9919 * Returns an action object used to update a category. 9920 * Ignored from documentation as the recommended usage for this action through updateCategory from @wordpress/blocks. 9921 * 9922 * @ignore 9923 * 9924 * @param {string} slug Block category slug. 9925 * @param {Object} category Object containing the category properties that should be updated. 9926 * 9927 * @return {Object} Action object. 9928 */ 9929 function updateCategory(slug, category) { 9930 return { 9931 type: 'UPDATE_CATEGORY', 9932 slug, 9933 category 9934 }; 9935 } 9936 9937 /** 9938 * Returns an action object used to add block collections 9939 * Ignored from documentation as the recommended usage for this action through registerBlockCollection from @wordpress/blocks. 9940 * 9941 * @ignore 9942 * 9943 * @param {string} namespace The namespace of the blocks to put in the collection 9944 * @param {string} title The title to display in the block inserter 9945 * @param {Object} icon (optional) The icon to display in the block inserter 9946 * 9947 * @return {Object} Action object. 9948 */ 9949 function addBlockCollection(namespace, title, icon) { 9950 return { 9951 type: 'ADD_BLOCK_COLLECTION', 9952 namespace, 9953 title, 9954 icon 9955 }; 9956 } 9957 9958 /** 9959 * Returns an action object used to remove block collections 9960 * Ignored from documentation as the recommended usage for this action through unregisterBlockCollection from @wordpress/blocks. 9961 * 9962 * @ignore 9963 * 9964 * @param {string} namespace The namespace of the blocks to put in the collection 9965 * 9966 * @return {Object} Action object. 9967 */ 9968 function removeBlockCollection(namespace) { 9969 return { 9970 type: 'REMOVE_BLOCK_COLLECTION', 9971 namespace 9972 }; 9973 } 9974 9975 ;// ./node_modules/@wordpress/blocks/build-module/store/private-actions.js 9976 /** 9977 * Internal dependencies 9978 */ 9979 9980 9981 /** @typedef {import('../api/registration').WPBlockType} WPBlockType */ 9982 9983 /** 9984 * Add bootstrapped block type metadata to the store. These metadata usually come from 9985 * the `block.json` file and are either statically bootstrapped from the server, or 9986 * passed as the `metadata` parameter to the `registerBlockType` function. 9987 * 9988 * @param {string} name Block name. 9989 * @param {WPBlockType} blockType Block type metadata. 9990 */ 9991 function addBootstrappedBlockType(name, blockType) { 9992 return { 9993 type: 'ADD_BOOTSTRAPPED_BLOCK_TYPE', 9994 name, 9995 blockType 9996 }; 9997 } 9998 9999 /** 10000 * Add unprocessed block type settings to the store. These data are passed as the 10001 * `settings` parameter to the client-side `registerBlockType` function. 10002 * 10003 * @param {string} name Block name. 10004 * @param {WPBlockType} blockType Unprocessed block type settings. 10005 */ 10006 function addUnprocessedBlockType(name, blockType) { 10007 return ({ 10008 dispatch 10009 }) => { 10010 dispatch({ 10011 type: 'ADD_UNPROCESSED_BLOCK_TYPE', 10012 name, 10013 blockType 10014 }); 10015 const processedBlockType = dispatch(processBlockType(name, blockType)); 10016 if (!processedBlockType) { 10017 return; 10018 } 10019 dispatch.addBlockTypes(processedBlockType); 10020 }; 10021 } 10022 10023 /** 10024 * Adds new block bindings source. 10025 * 10026 * @param {string} source Name of the source to register. 10027 */ 10028 function addBlockBindingsSource(source) { 10029 return { 10030 type: 'ADD_BLOCK_BINDINGS_SOURCE', 10031 name: source.name, 10032 label: source.label, 10033 usesContext: source.usesContext, 10034 getValues: source.getValues, 10035 setValues: source.setValues, 10036 canUserEditValue: source.canUserEditValue, 10037 getFieldsList: source.getFieldsList 10038 }; 10039 } 10040 10041 /** 10042 * Removes existing block bindings source. 10043 * 10044 * @param {string} name Name of the source to remove. 10045 */ 10046 function removeBlockBindingsSource(name) { 10047 return { 10048 type: 'REMOVE_BLOCK_BINDINGS_SOURCE', 10049 name 10050 }; 10051 } 10052 10053 ;// ./node_modules/@wordpress/blocks/build-module/store/constants.js 10054 const STORE_NAME = 'core/blocks'; 10055 10056 ;// ./node_modules/@wordpress/blocks/build-module/store/index.js 10057 /** 10058 * WordPress dependencies 10059 */ 10060 10061 10062 /** 10063 * Internal dependencies 10064 */ 10065 10066 10067 10068 10069 10070 10071 10072 10073 /** 10074 * Store definition for the blocks namespace. 10075 * 10076 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#createReduxStore 10077 * 10078 * @type {Object} 10079 */ 10080 const store = (0,external_wp_data_namespaceObject.createReduxStore)(STORE_NAME, { 10081 reducer: reducer, 10082 selectors: selectors_namespaceObject, 10083 actions: actions_namespaceObject 10084 }); 10085 (0,external_wp_data_namespaceObject.register)(store); 10086 unlock(store).registerPrivateSelectors(private_selectors_namespaceObject); 10087 unlock(store).registerPrivateActions(private_actions_namespaceObject); 10088 10089 ;// ./node_modules/@wordpress/blocks/node_modules/uuid/dist/esm-browser/native.js 10090 const randomUUID = typeof crypto !== 'undefined' && crypto.randomUUID && crypto.randomUUID.bind(crypto); 10091 /* harmony default export */ const esm_browser_native = ({ 10092 randomUUID 10093 }); 10094 ;// ./node_modules/@wordpress/blocks/node_modules/uuid/dist/esm-browser/rng.js 10095 // Unique ID creation requires a high quality random # generator. In the browser we therefore 10096 // require the crypto API and do not support built-in fallback to lower quality random number 10097 // generators (like Math.random()). 10098 let getRandomValues; 10099 const rnds8 = new Uint8Array(16); 10100 function rng() { 10101 // lazy load so that environments that need to polyfill have a chance to do so 10102 if (!getRandomValues) { 10103 // getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. 10104 getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto); 10105 10106 if (!getRandomValues) { 10107 throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported'); 10108 } 10109 } 10110 10111 return getRandomValues(rnds8); 10112 } 10113 ;// ./node_modules/@wordpress/blocks/node_modules/uuid/dist/esm-browser/stringify.js 10114 10115 /** 10116 * Convert array of 16 byte values to UUID string format of the form: 10117 * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX 10118 */ 10119 10120 const byteToHex = []; 10121 10122 for (let i = 0; i < 256; ++i) { 10123 byteToHex.push((i + 0x100).toString(16).slice(1)); 10124 } 10125 10126 function unsafeStringify(arr, offset = 0) { 10127 // Note: Be careful editing this code! It's been tuned for performance 10128 // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434 10129 return 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]]; 10130 } 10131 10132 function stringify(arr, offset = 0) { 10133 const uuid = unsafeStringify(arr, offset); // Consistency check for valid UUID. If this throws, it's likely due to one 10134 // of the following: 10135 // - One or more input array values don't map to a hex octet (leading to 10136 // "undefined" in the uuid) 10137 // - Invalid input values for the RFC `version` or `variant` fields 10138 10139 if (!validate(uuid)) { 10140 throw TypeError('Stringified UUID is invalid'); 10141 } 10142 10143 return uuid; 10144 } 10145 10146 /* harmony default export */ const esm_browser_stringify = ((/* unused pure expression or super */ null && (stringify))); 10147 ;// ./node_modules/@wordpress/blocks/node_modules/uuid/dist/esm-browser/v4.js 10148 10149 10150 10151 10152 function v4(options, buf, offset) { 10153 if (esm_browser_native.randomUUID && !buf && !options) { 10154 return esm_browser_native.randomUUID(); 10155 } 10156 10157 options = options || {}; 10158 const rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` 10159 10160 rnds[6] = rnds[6] & 0x0f | 0x40; 10161 rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided 10162 10163 if (buf) { 10164 offset = offset || 0; 10165 10166 for (let i = 0; i < 16; ++i) { 10167 buf[offset + i] = rnds[i]; 10168 } 10169 10170 return buf; 10171 } 10172 10173 return unsafeStringify(rnds); 10174 } 10175 10176 /* harmony default export */ const esm_browser_v4 = (v4); 10177 ;// ./node_modules/@wordpress/blocks/build-module/api/factory.js 10178 /* wp:polyfill */ 10179 /** 10180 * External dependencies 10181 */ 10182 10183 10184 /** 10185 * WordPress dependencies 10186 */ 10187 10188 10189 /** 10190 * Internal dependencies 10191 */ 10192 10193 10194 10195 /** 10196 * Returns a block object given its type and attributes. 10197 * 10198 * @param {string} name Block name. 10199 * @param {Object} attributes Block attributes. 10200 * @param {?Array} innerBlocks Nested blocks. 10201 * 10202 * @return {Object} Block object. 10203 */ 10204 function createBlock(name, attributes = {}, innerBlocks = []) { 10205 if (!isBlockRegistered(name)) { 10206 return createBlock('core/missing', { 10207 originalName: name, 10208 originalContent: '', 10209 originalUndelimitedContent: '' 10210 }); 10211 } 10212 const sanitizedAttributes = __experimentalSanitizeBlockAttributes(name, attributes); 10213 const clientId = esm_browser_v4(); 10214 10215 // Blocks are stored with a unique ID, the assigned type name, the block 10216 // attributes, and their inner blocks. 10217 return { 10218 clientId, 10219 name, 10220 isValid: true, 10221 attributes: sanitizedAttributes, 10222 innerBlocks 10223 }; 10224 } 10225 10226 /** 10227 * Given an array of InnerBlocks templates or Block Objects, 10228 * returns an array of created Blocks from them. 10229 * It handles the case of having InnerBlocks as Blocks by 10230 * converting them to the proper format to continue recursively. 10231 * 10232 * @param {Array} innerBlocksOrTemplate Nested blocks or InnerBlocks templates. 10233 * 10234 * @return {Object[]} Array of Block objects. 10235 */ 10236 function createBlocksFromInnerBlocksTemplate(innerBlocksOrTemplate = []) { 10237 return innerBlocksOrTemplate.map(innerBlock => { 10238 const innerBlockTemplate = Array.isArray(innerBlock) ? innerBlock : [innerBlock.name, innerBlock.attributes, innerBlock.innerBlocks]; 10239 const [name, attributes, innerBlocks = []] = innerBlockTemplate; 10240 return createBlock(name, attributes, createBlocksFromInnerBlocksTemplate(innerBlocks)); 10241 }); 10242 } 10243 10244 /** 10245 * Given a block object, returns a copy of the block object while sanitizing its attributes, 10246 * optionally merging new attributes and/or replacing its inner blocks. 10247 * 10248 * @param {Object} block Block instance. 10249 * @param {Object} mergeAttributes Block attributes. 10250 * @param {?Array} newInnerBlocks Nested blocks. 10251 * 10252 * @return {Object} A cloned block. 10253 */ 10254 function __experimentalCloneSanitizedBlock(block, mergeAttributes = {}, newInnerBlocks) { 10255 const { 10256 name 10257 } = block; 10258 if (!isBlockRegistered(name)) { 10259 return createBlock('core/missing', { 10260 originalName: name, 10261 originalContent: '', 10262 originalUndelimitedContent: '' 10263 }); 10264 } 10265 const clientId = esm_browser_v4(); 10266 const sanitizedAttributes = __experimentalSanitizeBlockAttributes(name, { 10267 ...block.attributes, 10268 ...mergeAttributes 10269 }); 10270 return { 10271 ...block, 10272 clientId, 10273 attributes: sanitizedAttributes, 10274 innerBlocks: newInnerBlocks || block.innerBlocks.map(innerBlock => __experimentalCloneSanitizedBlock(innerBlock)) 10275 }; 10276 } 10277 10278 /** 10279 * Given a block object, returns a copy of the block object, 10280 * optionally merging new attributes and/or replacing its inner blocks. 10281 * 10282 * @param {Object} block Block instance. 10283 * @param {Object} mergeAttributes Block attributes. 10284 * @param {?Array} newInnerBlocks Nested blocks. 10285 * 10286 * @return {Object} A cloned block. 10287 */ 10288 function cloneBlock(block, mergeAttributes = {}, newInnerBlocks) { 10289 const clientId = esm_browser_v4(); 10290 return { 10291 ...block, 10292 clientId, 10293 attributes: { 10294 ...block.attributes, 10295 ...mergeAttributes 10296 }, 10297 innerBlocks: newInnerBlocks || block.innerBlocks.map(innerBlock => cloneBlock(innerBlock)) 10298 }; 10299 } 10300 10301 /** 10302 * Returns a boolean indicating whether a transform is possible based on 10303 * various bits of context. 10304 * 10305 * @param {Object} transform The transform object to validate. 10306 * @param {string} direction Is this a 'from' or 'to' transform. 10307 * @param {Array} blocks The blocks to transform from. 10308 * 10309 * @return {boolean} Is the transform possible? 10310 */ 10311 const isPossibleTransformForSource = (transform, direction, blocks) => { 10312 if (!blocks.length) { 10313 return false; 10314 } 10315 10316 // If multiple blocks are selected, only multi block transforms 10317 // or wildcard transforms are allowed. 10318 const isMultiBlock = blocks.length > 1; 10319 const firstBlockName = blocks[0].name; 10320 const isValidForMultiBlocks = isWildcardBlockTransform(transform) || !isMultiBlock || transform.isMultiBlock; 10321 if (!isValidForMultiBlocks) { 10322 return false; 10323 } 10324 10325 // Check non-wildcard transforms to ensure that transform is valid 10326 // for a block selection of multiple blocks of different types. 10327 if (!isWildcardBlockTransform(transform) && !blocks.every(block => block.name === firstBlockName)) { 10328 return false; 10329 } 10330 10331 // Only consider 'block' type transforms as valid. 10332 const isBlockType = transform.type === 'block'; 10333 if (!isBlockType) { 10334 return false; 10335 } 10336 10337 // Check if the transform's block name matches the source block (or is a wildcard) 10338 // only if this is a transform 'from'. 10339 const sourceBlock = blocks[0]; 10340 const hasMatchingName = direction !== 'from' || transform.blocks.indexOf(sourceBlock.name) !== -1 || isWildcardBlockTransform(transform); 10341 if (!hasMatchingName) { 10342 return false; 10343 } 10344 10345 // Don't allow single Grouping blocks to be transformed into 10346 // a Grouping block. 10347 if (!isMultiBlock && direction === 'from' && isContainerGroupBlock(sourceBlock.name) && isContainerGroupBlock(transform.blockName)) { 10348 return false; 10349 } 10350 10351 // If the transform has a `isMatch` function specified, check that it returns true. 10352 if (!maybeCheckTransformIsMatch(transform, blocks)) { 10353 return false; 10354 } 10355 return true; 10356 }; 10357 10358 /** 10359 * Returns block types that the 'blocks' can be transformed into, based on 10360 * 'from' transforms on other blocks. 10361 * 10362 * @param {Array} blocks The blocks to transform from. 10363 * 10364 * @return {Array} Block types that the blocks can be transformed into. 10365 */ 10366 const getBlockTypesForPossibleFromTransforms = blocks => { 10367 if (!blocks.length) { 10368 return []; 10369 } 10370 const allBlockTypes = getBlockTypes(); 10371 10372 // filter all blocks to find those with a 'from' transform. 10373 const blockTypesWithPossibleFromTransforms = allBlockTypes.filter(blockType => { 10374 const fromTransforms = getBlockTransforms('from', blockType.name); 10375 return !!findTransform(fromTransforms, transform => { 10376 return isPossibleTransformForSource(transform, 'from', blocks); 10377 }); 10378 }); 10379 return blockTypesWithPossibleFromTransforms; 10380 }; 10381 10382 /** 10383 * Returns block types that the 'blocks' can be transformed into, based on 10384 * the source block's own 'to' transforms. 10385 * 10386 * @param {Array} blocks The blocks to transform from. 10387 * 10388 * @return {Array} Block types that the source can be transformed into. 10389 */ 10390 const getBlockTypesForPossibleToTransforms = blocks => { 10391 if (!blocks.length) { 10392 return []; 10393 } 10394 const sourceBlock = blocks[0]; 10395 const blockType = getBlockType(sourceBlock.name); 10396 const transformsTo = blockType ? getBlockTransforms('to', blockType.name) : []; 10397 10398 // filter all 'to' transforms to find those that are possible. 10399 const possibleTransforms = transformsTo.filter(transform => { 10400 return transform && isPossibleTransformForSource(transform, 'to', blocks); 10401 }); 10402 10403 // Build a list of block names using the possible 'to' transforms. 10404 const blockNames = possibleTransforms.map(transformation => transformation.blocks).flat(); 10405 10406 // Map block names to block types. 10407 return blockNames.map(getBlockType); 10408 }; 10409 10410 /** 10411 * Determines whether transform is a "block" type 10412 * and if so whether it is a "wildcard" transform 10413 * ie: targets "any" block type 10414 * 10415 * @param {Object} t the Block transform object 10416 * 10417 * @return {boolean} whether transform is a wildcard transform 10418 */ 10419 const isWildcardBlockTransform = t => t && t.type === 'block' && Array.isArray(t.blocks) && t.blocks.includes('*'); 10420 10421 /** 10422 * Determines whether the given Block is the core Block which 10423 * acts as a container Block for other Blocks as part of the 10424 * Grouping mechanics 10425 * 10426 * @param {string} name the name of the Block to test against 10427 * 10428 * @return {boolean} whether or not the Block is the container Block type 10429 */ 10430 const isContainerGroupBlock = name => name === getGroupingBlockName(); 10431 10432 /** 10433 * Returns an array of block types that the set of blocks received as argument 10434 * can be transformed into. 10435 * 10436 * @param {Array} blocks Blocks array. 10437 * 10438 * @return {Array} Block types that the blocks argument can be transformed to. 10439 */ 10440 function getPossibleBlockTransformations(blocks) { 10441 if (!blocks.length) { 10442 return []; 10443 } 10444 const blockTypesForFromTransforms = getBlockTypesForPossibleFromTransforms(blocks); 10445 const blockTypesForToTransforms = getBlockTypesForPossibleToTransforms(blocks); 10446 return [...new Set([...blockTypesForFromTransforms, ...blockTypesForToTransforms])]; 10447 } 10448 10449 /** 10450 * Given an array of transforms, returns the highest-priority transform where 10451 * the predicate function returns a truthy value. A higher-priority transform 10452 * is one with a lower priority value (i.e. first in priority order). Returns 10453 * null if the transforms set is empty or the predicate function returns a 10454 * falsey value for all entries. 10455 * 10456 * @param {Object[]} transforms Transforms to search. 10457 * @param {Function} predicate Function returning true on matching transform. 10458 * 10459 * @return {?Object} Highest-priority transform candidate. 10460 */ 10461 function findTransform(transforms, predicate) { 10462 // The hooks library already has built-in mechanisms for managing priority 10463 // queue, so leverage via locally-defined instance. 10464 const hooks = (0,external_wp_hooks_namespaceObject.createHooks)(); 10465 for (let i = 0; i < transforms.length; i++) { 10466 const candidate = transforms[i]; 10467 if (predicate(candidate)) { 10468 hooks.addFilter('transform', 'transform/' + i.toString(), result => result ? result : candidate, candidate.priority); 10469 } 10470 } 10471 10472 // Filter name is arbitrarily chosen but consistent with above aggregation. 10473 return hooks.applyFilters('transform', null); 10474 } 10475 10476 /** 10477 * Returns normal block transforms for a given transform direction, optionally 10478 * for a specific block by name, or an empty array if there are no transforms. 10479 * If no block name is provided, returns transforms for all blocks. A normal 10480 * transform object includes `blockName` as a property. 10481 * 10482 * @param {string} direction Transform direction ("to", "from"). 10483 * @param {string|Object} blockTypeOrName Block type or name. 10484 * 10485 * @return {Array} Block transforms for direction. 10486 */ 10487 function getBlockTransforms(direction, blockTypeOrName) { 10488 // When retrieving transforms for all block types, recurse into self. 10489 if (blockTypeOrName === undefined) { 10490 return getBlockTypes().map(({ 10491 name 10492 }) => getBlockTransforms(direction, name)).flat(); 10493 } 10494 10495 // Validate that block type exists and has array of direction. 10496 const blockType = normalizeBlockType(blockTypeOrName); 10497 const { 10498 name: blockName, 10499 transforms 10500 } = blockType || {}; 10501 if (!transforms || !Array.isArray(transforms[direction])) { 10502 return []; 10503 } 10504 const usingMobileTransformations = transforms.supportedMobileTransforms && Array.isArray(transforms.supportedMobileTransforms); 10505 const filteredTransforms = usingMobileTransformations ? transforms[direction].filter(t => { 10506 if (t.type === 'raw') { 10507 return true; 10508 } 10509 if (t.type === 'prefix') { 10510 return true; 10511 } 10512 if (!t.blocks || !t.blocks.length) { 10513 return false; 10514 } 10515 if (isWildcardBlockTransform(t)) { 10516 return true; 10517 } 10518 return t.blocks.every(transformBlockName => transforms.supportedMobileTransforms.includes(transformBlockName)); 10519 }) : transforms[direction]; 10520 10521 // Map transforms to normal form. 10522 return filteredTransforms.map(transform => ({ 10523 ...transform, 10524 blockName, 10525 usingMobileTransformations 10526 })); 10527 } 10528 10529 /** 10530 * Checks that a given transforms isMatch method passes for given source blocks. 10531 * 10532 * @param {Object} transform A transform object. 10533 * @param {Array} blocks Blocks array. 10534 * 10535 * @return {boolean} True if given blocks are a match for the transform. 10536 */ 10537 function maybeCheckTransformIsMatch(transform, blocks) { 10538 if (typeof transform.isMatch !== 'function') { 10539 return true; 10540 } 10541 const sourceBlock = blocks[0]; 10542 const attributes = transform.isMultiBlock ? blocks.map(block => block.attributes) : sourceBlock.attributes; 10543 const block = transform.isMultiBlock ? blocks : sourceBlock; 10544 return transform.isMatch(attributes, block); 10545 } 10546 10547 /** 10548 * Switch one or more blocks into one or more blocks of the new block type. 10549 * 10550 * @param {Array|Object} blocks Blocks array or block object. 10551 * @param {string} name Block name. 10552 * 10553 * @return {?Array} Array of blocks or null. 10554 */ 10555 function switchToBlockType(blocks, name) { 10556 const blocksArray = Array.isArray(blocks) ? blocks : [blocks]; 10557 const isMultiBlock = blocksArray.length > 1; 10558 const firstBlock = blocksArray[0]; 10559 const sourceName = firstBlock.name; 10560 10561 // Find the right transformation by giving priority to the "to" 10562 // transformation. 10563 const transformationsFrom = getBlockTransforms('from', name); 10564 const transformationsTo = getBlockTransforms('to', sourceName); 10565 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)); 10566 10567 // Stop if there is no valid transformation. 10568 if (!transformation) { 10569 return null; 10570 } 10571 let transformationResults; 10572 if (transformation.isMultiBlock) { 10573 if ('__experimentalConvert' in transformation) { 10574 transformationResults = transformation.__experimentalConvert(blocksArray); 10575 } else { 10576 transformationResults = transformation.transform(blocksArray.map(currentBlock => currentBlock.attributes), blocksArray.map(currentBlock => currentBlock.innerBlocks)); 10577 } 10578 } else if ('__experimentalConvert' in transformation) { 10579 transformationResults = transformation.__experimentalConvert(firstBlock); 10580 } else { 10581 transformationResults = transformation.transform(firstBlock.attributes, firstBlock.innerBlocks); 10582 } 10583 10584 // Ensure that the transformation function returned an object or an array 10585 // of objects. 10586 if (transformationResults === null || typeof transformationResults !== 'object') { 10587 return null; 10588 } 10589 10590 // If the transformation function returned a single object, we want to work 10591 // with an array instead. 10592 transformationResults = Array.isArray(transformationResults) ? transformationResults : [transformationResults]; 10593 10594 // Ensure that every block object returned by the transformation has a 10595 // valid block type. 10596 if (transformationResults.some(result => !getBlockType(result.name))) { 10597 return null; 10598 } 10599 const hasSwitchedBlock = transformationResults.some(result => result.name === name); 10600 10601 // Ensure that at least one block object returned by the transformation has 10602 // the expected "destination" block type. 10603 if (!hasSwitchedBlock) { 10604 return null; 10605 } 10606 const ret = transformationResults.map((result, index, results) => { 10607 /** 10608 * Filters an individual transform result from block transformation. 10609 * All of the original blocks are passed, since transformations are 10610 * many-to-many, not one-to-one. 10611 * 10612 * @param {Object} transformedBlock The transformed block. 10613 * @param {Object[]} blocks Original blocks transformed. 10614 * @param {Object[]} index Index of the transformed block on the array of results. 10615 * @param {Object[]} results An array all the blocks that resulted from the transformation. 10616 */ 10617 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.switchToBlockType.transformedBlock', result, blocks, index, results); 10618 }); 10619 return ret; 10620 } 10621 10622 /** 10623 * Create a block object from the example API. 10624 * 10625 * @param {string} name 10626 * @param {Object} example 10627 * 10628 * @return {Object} block. 10629 */ 10630 const getBlockFromExample = (name, example) => { 10631 var _example$innerBlocks; 10632 return createBlock(name, example.attributes, ((_example$innerBlocks = example.innerBlocks) !== null && _example$innerBlocks !== void 0 ? _example$innerBlocks : []).map(innerBlock => getBlockFromExample(innerBlock.name, innerBlock))); 10633 }; 10634 10635 ;// external ["wp","blockSerializationDefaultParser"] 10636 const external_wp_blockSerializationDefaultParser_namespaceObject = window["wp"]["blockSerializationDefaultParser"]; 10637 ;// external ["wp","autop"] 10638 const external_wp_autop_namespaceObject = window["wp"]["autop"]; 10639 ;// external ["wp","isShallowEqual"] 10640 const external_wp_isShallowEqual_namespaceObject = window["wp"]["isShallowEqual"]; 10641 var external_wp_isShallowEqual_default = /*#__PURE__*/__webpack_require__.n(external_wp_isShallowEqual_namespaceObject); 10642 ;// ./node_modules/@wordpress/blocks/build-module/api/parser/serialize-raw-block.js 10643 /* wp:polyfill */ 10644 /** 10645 * Internal dependencies 10646 */ 10647 10648 10649 /** 10650 * @typedef {Object} Options Serialization options. 10651 * @property {boolean} [isCommentDelimited=true] Whether to output HTML comments around blocks. 10652 */ 10653 10654 /** @typedef {import("./").WPRawBlock} WPRawBlock */ 10655 10656 /** 10657 * Serializes a block node into the native HTML-comment-powered block format. 10658 * CAVEAT: This function is intended for re-serializing blocks as parsed by 10659 * valid parsers and skips any validation steps. This is NOT a generic 10660 * serialization function for in-memory blocks. For most purposes, see the 10661 * following functions available in the `@wordpress/blocks` package: 10662 * 10663 * @see serializeBlock 10664 * @see serialize 10665 * 10666 * For more on the format of block nodes as returned by valid parsers: 10667 * 10668 * @see `@wordpress/block-serialization-default-parser` package 10669 * @see `@wordpress/block-serialization-spec-parser` package 10670 * 10671 * @param {WPRawBlock} rawBlock A block node as returned by a valid parser. 10672 * @param {Options} [options={}] Serialization options. 10673 * 10674 * @return {string} An HTML string representing a block. 10675 */ 10676 function serializeRawBlock(rawBlock, options = {}) { 10677 const { 10678 isCommentDelimited = true 10679 } = options; 10680 const { 10681 blockName, 10682 attrs = {}, 10683 innerBlocks = [], 10684 innerContent = [] 10685 } = rawBlock; 10686 let childIndex = 0; 10687 const content = innerContent.map(item => 10688 // `null` denotes a nested block, otherwise we have an HTML fragment. 10689 item !== null ? item : serializeRawBlock(innerBlocks[childIndex++], options)).join('\n').replace(/\n+/g, '\n').trim(); 10690 return isCommentDelimited ? getCommentDelimitedContent(blockName, attrs, content) : content; 10691 } 10692 10693 ;// external "ReactJSXRuntime" 10694 const external_ReactJSXRuntime_namespaceObject = window["ReactJSXRuntime"]; 10695 ;// ./node_modules/@wordpress/blocks/build-module/api/serializer.js 10696 /* wp:polyfill */ 10697 /** 10698 * WordPress dependencies 10699 */ 10700 10701 10702 10703 10704 10705 10706 /** 10707 * Internal dependencies 10708 */ 10709 10710 10711 10712 10713 /** @typedef {import('./parser').WPBlock} WPBlock */ 10714 10715 /** 10716 * @typedef {Object} WPBlockSerializationOptions Serialization Options. 10717 * 10718 * @property {boolean} isInnerBlocks Whether we are serializing inner blocks. 10719 */ 10720 10721 /** 10722 * Returns the block's default classname from its name. 10723 * 10724 * @param {string} blockName The block name. 10725 * 10726 * @return {string} The block's default class. 10727 */ 10728 10729 function getBlockDefaultClassName(blockName) { 10730 // Generated HTML classes for blocks follow the `wp-block-{name}` nomenclature. 10731 // Blocks provided by WordPress drop the prefixes 'core/' or 'core-' (historically used in 'core-embed/'). 10732 const className = 'wp-block-' + blockName.replace(/\//, '-').replace(/^core-/, ''); 10733 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getBlockDefaultClassName', className, blockName); 10734 } 10735 10736 /** 10737 * Returns the block's default menu item classname from its name. 10738 * 10739 * @param {string} blockName The block name. 10740 * 10741 * @return {string} The block's default menu item class. 10742 */ 10743 function getBlockMenuDefaultClassName(blockName) { 10744 // Generated HTML classes for blocks follow the `editor-block-list-item-{name}` nomenclature. 10745 // Blocks provided by WordPress drop the prefixes 'core/' or 'core-' (historically used in 'core-embed/'). 10746 const className = 'editor-block-list-item-' + blockName.replace(/\//, '-').replace(/^core-/, ''); 10747 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getBlockMenuDefaultClassName', className, blockName); 10748 } 10749 const blockPropsProvider = {}; 10750 const innerBlocksPropsProvider = {}; 10751 10752 /** 10753 * Call within a save function to get the props for the block wrapper. 10754 * 10755 * @param {Object} props Optional. Props to pass to the element. 10756 */ 10757 function getBlockProps(props = {}) { 10758 const { 10759 blockType, 10760 attributes 10761 } = blockPropsProvider; 10762 return getBlockProps.skipFilters ? props : (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getSaveContent.extraProps', { 10763 ...props 10764 }, blockType, attributes); 10765 } 10766 10767 /** 10768 * Call within a save function to get the props for the inner blocks wrapper. 10769 * 10770 * @param {Object} props Optional. Props to pass to the element. 10771 */ 10772 function getInnerBlocksProps(props = {}) { 10773 const { 10774 innerBlocks 10775 } = innerBlocksPropsProvider; 10776 // Allow a different component to be passed to getSaveElement to handle 10777 // inner blocks, bypassing the default serialisation. 10778 if (!Array.isArray(innerBlocks)) { 10779 return { 10780 ...props, 10781 children: innerBlocks 10782 }; 10783 } 10784 // Value is an array of blocks, so defer to block serializer. 10785 const html = serialize(innerBlocks, { 10786 isInnerBlocks: true 10787 }); 10788 // Use special-cased raw HTML tag to avoid default escaping. 10789 const children = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_element_namespaceObject.RawHTML, { 10790 children: html 10791 }); 10792 return { 10793 ...props, 10794 children 10795 }; 10796 } 10797 10798 /** 10799 * Given a block type containing a save render implementation and attributes, returns the 10800 * enhanced element to be saved or string when raw HTML expected. 10801 * 10802 * @param {string|Object} blockTypeOrName Block type or name. 10803 * @param {Object} attributes Block attributes. 10804 * @param {?Array} innerBlocks Nested blocks. 10805 * 10806 * @return {Object|string} Save element or raw HTML string. 10807 */ 10808 function getSaveElement(blockTypeOrName, attributes, innerBlocks = []) { 10809 const blockType = normalizeBlockType(blockTypeOrName); 10810 if (!blockType?.save) { 10811 return null; 10812 } 10813 let { 10814 save 10815 } = blockType; 10816 10817 // Component classes are unsupported for save since serialization must 10818 // occur synchronously. For improved interoperability with higher-order 10819 // components which often return component class, emulate basic support. 10820 if (save.prototype instanceof external_wp_element_namespaceObject.Component) { 10821 const instance = new save({ 10822 attributes 10823 }); 10824 save = instance.render.bind(instance); 10825 } 10826 blockPropsProvider.blockType = blockType; 10827 blockPropsProvider.attributes = attributes; 10828 innerBlocksPropsProvider.innerBlocks = innerBlocks; 10829 let element = save({ 10830 attributes, 10831 innerBlocks 10832 }); 10833 if (element !== null && typeof element === 'object' && (0,external_wp_hooks_namespaceObject.hasFilter)('blocks.getSaveContent.extraProps') && !(blockType.apiVersion > 1)) { 10834 /** 10835 * Filters the props applied to the block save result element. 10836 * 10837 * @param {Object} props Props applied to save element. 10838 * @param {WPBlock} blockType Block type definition. 10839 * @param {Object} attributes Block attributes. 10840 */ 10841 const props = (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getSaveContent.extraProps', { 10842 ...element.props 10843 }, blockType, attributes); 10844 if (!external_wp_isShallowEqual_default()(props, element.props)) { 10845 element = (0,external_wp_element_namespaceObject.cloneElement)(element, props); 10846 } 10847 } 10848 10849 /** 10850 * Filters the save result of a block during serialization. 10851 * 10852 * @param {Element} element Block save result. 10853 * @param {WPBlock} blockType Block type definition. 10854 * @param {Object} attributes Block attributes. 10855 */ 10856 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getSaveElement', element, blockType, attributes); 10857 } 10858 10859 /** 10860 * Given a block type containing a save render implementation and attributes, returns the 10861 * static markup to be saved. 10862 * 10863 * @param {string|Object} blockTypeOrName Block type or name. 10864 * @param {Object} attributes Block attributes. 10865 * @param {?Array} innerBlocks Nested blocks. 10866 * 10867 * @return {string} Save content. 10868 */ 10869 function getSaveContent(blockTypeOrName, attributes, innerBlocks) { 10870 const blockType = normalizeBlockType(blockTypeOrName); 10871 return (0,external_wp_element_namespaceObject.renderToString)(getSaveElement(blockType, attributes, innerBlocks)); 10872 } 10873 10874 /** 10875 * Returns attributes which are to be saved and serialized into the block 10876 * comment delimiter. 10877 * 10878 * When a block exists in memory it contains as its attributes both those 10879 * parsed the block comment delimiter _and_ those which matched from the 10880 * contents of the block. 10881 * 10882 * This function returns only those attributes which are needed to persist and 10883 * which cannot be matched from the block content. 10884 * 10885 * @param {Object<string,*>} blockType Block type. 10886 * @param {Object<string,*>} attributes Attributes from in-memory block data. 10887 * 10888 * @return {Object<string,*>} Subset of attributes for comment serialization. 10889 */ 10890 function getCommentAttributes(blockType, attributes) { 10891 var _blockType$attributes; 10892 return Object.entries((_blockType$attributes = blockType.attributes) !== null && _blockType$attributes !== void 0 ? _blockType$attributes : {}).reduce((accumulator, [key, attributeSchema]) => { 10893 const value = attributes[key]; 10894 // Ignore undefined values. 10895 if (undefined === value) { 10896 return accumulator; 10897 } 10898 10899 // Ignore all attributes but the ones with an "undefined" source 10900 // "undefined" source refers to attributes saved in the block comment. 10901 if (attributeSchema.source !== undefined) { 10902 return accumulator; 10903 } 10904 10905 // Ignore all local attributes 10906 if (attributeSchema.role === 'local') { 10907 return accumulator; 10908 } 10909 if (attributeSchema.__experimentalRole === 'local') { 10910 external_wp_deprecated_default()('__experimentalRole attribute', { 10911 since: '6.7', 10912 version: '6.8', 10913 alternative: 'role attribute', 10914 hint: `Check the block.json of the $blockType?.name} block.` 10915 }); 10916 return accumulator; 10917 } 10918 10919 // Ignore default value. 10920 if ('default' in attributeSchema && JSON.stringify(attributeSchema.default) === JSON.stringify(value)) { 10921 return accumulator; 10922 } 10923 10924 // Otherwise, include in comment set. 10925 accumulator[key] = value; 10926 return accumulator; 10927 }, {}); 10928 } 10929 10930 /** 10931 * Given an attributes object, returns a string in the serialized attributes 10932 * format prepared for post content. 10933 * 10934 * @param {Object} attributes Attributes object. 10935 * 10936 * @return {string} Serialized attributes. 10937 */ 10938 function serializeAttributes(attributes) { 10939 return JSON.stringify(attributes) 10940 // Don't break HTML comments. 10941 .replace(/--/g, '\\u002d\\u002d') 10942 10943 // Don't break non-standard-compliant tools. 10944 .replace(/</g, '\\u003c').replace(/>/g, '\\u003e').replace(/&/g, '\\u0026') 10945 10946 // Bypass server stripslashes behavior which would unescape stringify's 10947 // escaping of quotation mark. 10948 // 10949 // See: https://developer.wordpress.org/reference/functions/wp_kses_stripslashes/ 10950 .replace(/\\"/g, '\\u0022'); 10951 } 10952 10953 /** 10954 * Given a block object, returns the Block's Inner HTML markup. 10955 * 10956 * @param {Object} block Block instance. 10957 * 10958 * @return {string} HTML. 10959 */ 10960 function getBlockInnerHTML(block) { 10961 // If block was parsed as invalid or encounters an error while generating 10962 // save content, use original content instead to avoid content loss. If a 10963 // block contains nested content, exempt it from this condition because we 10964 // otherwise have no access to its original content and content loss would 10965 // still occur. 10966 let saveContent = block.originalContent; 10967 if (block.isValid || block.innerBlocks.length) { 10968 try { 10969 saveContent = getSaveContent(block.name, block.attributes, block.innerBlocks); 10970 } catch (error) {} 10971 } 10972 return saveContent; 10973 } 10974 10975 /** 10976 * Returns the content of a block, including comment delimiters. 10977 * 10978 * @param {string} rawBlockName Block name. 10979 * @param {Object} attributes Block attributes. 10980 * @param {string} content Block save content. 10981 * 10982 * @return {string} Comment-delimited block content. 10983 */ 10984 function getCommentDelimitedContent(rawBlockName, attributes, content) { 10985 const serializedAttributes = attributes && Object.entries(attributes).length ? serializeAttributes(attributes) + ' ' : ''; 10986 10987 // Strip core blocks of their namespace prefix. 10988 const blockName = rawBlockName?.startsWith('core/') ? rawBlockName.slice(5) : rawBlockName; 10989 10990 // @todo make the `wp:` prefix potentially configurable. 10991 10992 if (!content) { 10993 return `<!-- wp:$blockName} $serializedAttributes}/-->`; 10994 } 10995 return `<!-- wp:$blockName} $serializedAttributes}-->\n` + content + `\n<!-- /wp:$blockName} -->`; 10996 } 10997 10998 /** 10999 * Returns the content of a block, including comment delimiters, determining 11000 * serialized attributes and content form from the current state of the block. 11001 * 11002 * @param {WPBlock} block Block instance. 11003 * @param {WPBlockSerializationOptions} options Serialization options. 11004 * 11005 * @return {string} Serialized block. 11006 */ 11007 function serializeBlock(block, { 11008 isInnerBlocks = false 11009 } = {}) { 11010 if (!block.isValid && block.__unstableBlockSource) { 11011 return serializeRawBlock(block.__unstableBlockSource); 11012 } 11013 const blockName = block.name; 11014 const saveContent = getBlockInnerHTML(block); 11015 if (blockName === getUnregisteredTypeHandlerName() || !isInnerBlocks && blockName === getFreeformContentHandlerName()) { 11016 return saveContent; 11017 } 11018 const blockType = getBlockType(blockName); 11019 if (!blockType) { 11020 return saveContent; 11021 } 11022 const saveAttributes = getCommentAttributes(blockType, block.attributes); 11023 return getCommentDelimitedContent(blockName, saveAttributes, saveContent); 11024 } 11025 function __unstableSerializeAndClean(blocks) { 11026 // A single unmodified default block is assumed to 11027 // be equivalent to an empty post. 11028 if (blocks.length === 1 && isUnmodifiedDefaultBlock(blocks[0])) { 11029 blocks = []; 11030 } 11031 let content = serialize(blocks); 11032 11033 // For compatibility, treat a post consisting of a 11034 // single freeform block as legacy content and apply 11035 // pre-block-editor removep'd content formatting. 11036 if (blocks.length === 1 && blocks[0].name === getFreeformContentHandlerName() && blocks[0].name === 'core/freeform') { 11037 content = (0,external_wp_autop_namespaceObject.removep)(content); 11038 } 11039 return content; 11040 } 11041 11042 /** 11043 * Takes a block or set of blocks and returns the serialized post content. 11044 * 11045 * @param {Array} blocks Block(s) to serialize. 11046 * @param {WPBlockSerializationOptions} options Serialization options. 11047 * 11048 * @return {string} The post content. 11049 */ 11050 function serialize(blocks, options) { 11051 const blocksArray = Array.isArray(blocks) ? blocks : [blocks]; 11052 return blocksArray.map(block => serializeBlock(block, options)).join('\n\n'); 11053 } 11054 11055 ;// ./node_modules/simple-html-tokenizer/dist/es6/index.js 11056 /** 11057 * generated from https://raw.githubusercontent.com/w3c/html/26b5126f96f736f796b9e29718138919dd513744/entities.json 11058 * do not edit 11059 */ 11060 var namedCharRefs = { 11061 Aacute: "Á", aacute: "á", Abreve: "Ă", abreve: "ă", ac: "∾", acd: "∿", acE: "∾̳", Acirc: "Â", acirc: "â", acute: "´", Acy: "А", acy: "а", AElig: "Æ", aelig: "æ", af: "\u2061", Afr: "𝔄", afr: "𝔞", Agrave: "À", agrave: "à", alefsym: "ℵ", aleph: "ℵ", Alpha: "Α", alpha: "α", Amacr: "Ā", amacr: "ā", amalg: "⨿", amp: "&", AMP: "&", andand: "⩕", And: "⩓", and: "∧", andd: "⩜", andslope: "⩘", andv: "⩚", ang: "∠", ange: "⦤", angle: "∠", angmsdaa: "⦨", angmsdab: "⦩", angmsdac: "⦪", angmsdad: "⦫", angmsdae: "⦬", angmsdaf: "⦭", angmsdag: "⦮", angmsdah: "⦯", angmsd: "∡", angrt: "∟", angrtvb: "⊾", angrtvbd: "⦝", angsph: "∢", angst: "Å", angzarr: "⍼", Aogon: "Ą", aogon: "ą", Aopf: "𝔸", aopf: "𝕒", apacir: "⩯", ap: "≈", apE: "⩰", ape: "≊", apid: "≋", apos: "'", ApplyFunction: "\u2061", approx: "≈", approxeq: "≊", Aring: "Å", aring: "å", Ascr: "𝒜", ascr: "𝒶", Assign: "≔", ast: "*", asymp: "≈", asympeq: "≍", Atilde: "Ã", atilde: "ã", Auml: "Ä", auml: "ä", awconint: "∳", awint: "⨑", backcong: "≌", backepsilon: "϶", backprime: "‵", backsim: "∽", backsimeq: "⋍", Backslash: "∖", Barv: "⫧", barvee: "⊽", barwed: "⌅", Barwed: "⌆", barwedge: "⌅", bbrk: "⎵", bbrktbrk: "⎶", bcong: "≌", Bcy: "Б", bcy: "б", bdquo: "„", becaus: "∵", because: "∵", Because: "∵", bemptyv: "⦰", bepsi: "϶", bernou: "ℬ", Bernoullis: "ℬ", Beta: "Β", beta: "β", beth: "ℶ", between: "≬", Bfr: "𝔅", bfr: "𝔟", bigcap: "⋂", bigcirc: "◯", bigcup: "⋃", bigodot: "⨀", bigoplus: "⨁", bigotimes: "⨂", bigsqcup: "⨆", bigstar: "★", bigtriangledown: "▽", bigtriangleup: "△", biguplus: "⨄", bigvee: "⋁", bigwedge: "⋀", bkarow: "⤍", blacklozenge: "⧫", blacksquare: "▪", blacktriangle: "▴", blacktriangledown: "▾", blacktriangleleft: "◂", blacktriangleright: "▸", blank: "␣", blk12: "▒", blk14: "░", blk34: "▓", block: "█", bne: "=⃥", bnequiv: "≡⃥", bNot: "⫭", bnot: "⌐", Bopf: "𝔹", bopf: "𝕓", bot: "⊥", bottom: "⊥", bowtie: "⋈", boxbox: "⧉", boxdl: "┐", boxdL: "╕", boxDl: "╖", boxDL: "╗", boxdr: "┌", boxdR: "╒", boxDr: "╓", boxDR: "╔", boxh: "─", boxH: "═", boxhd: "┬", boxHd: "╤", boxhD: "╥", boxHD: "╦", boxhu: "┴", boxHu: "╧", boxhU: "╨", boxHU: "╩", boxminus: "⊟", boxplus: "⊞", boxtimes: "⊠", boxul: "┘", boxuL: "╛", boxUl: "╜", boxUL: "╝", boxur: "└", boxuR: "╘", boxUr: "╙", boxUR: "╚", boxv: "│", boxV: "║", boxvh: "┼", boxvH: "╪", boxVh: "╫", boxVH: "╬", boxvl: "┤", boxvL: "╡", boxVl: "╢", boxVL: "╣", boxvr: "├", boxvR: "╞", boxVr: "╟", boxVR: "╠", bprime: "‵", breve: "˘", Breve: "˘", brvbar: "¦", bscr: "𝒷", Bscr: "ℬ", bsemi: "⁏", bsim: "∽", bsime: "⋍", bsolb: "⧅", bsol: "\\", bsolhsub: "⟈", bull: "•", bullet: "•", bump: "≎", bumpE: "⪮", bumpe: "≏", Bumpeq: "≎", bumpeq: "≏", Cacute: "Ć", cacute: "ć", capand: "⩄", capbrcup: "⩉", capcap: "⩋", cap: "∩", Cap: "⋒", capcup: "⩇", capdot: "⩀", CapitalDifferentialD: "ⅅ", caps: "∩︀", caret: "⁁", caron: "ˇ", Cayleys: "ℭ", ccaps: "⩍", Ccaron: "Č", ccaron: "č", Ccedil: "Ç", ccedil: "ç", Ccirc: "Ĉ", ccirc: "ĉ", Cconint: "∰", ccups: "⩌", ccupssm: "⩐", Cdot: "Ċ", cdot: "ċ", cedil: "¸", Cedilla: "¸", cemptyv: "⦲", cent: "¢", centerdot: "·", CenterDot: "·", cfr: "𝔠", Cfr: "ℭ", CHcy: "Ч", chcy: "ч", check: "✓", checkmark: "✓", Chi: "Χ", chi: "χ", circ: "ˆ", circeq: "≗", circlearrowleft: "↺", circlearrowright: "↻", circledast: "⊛", circledcirc: "⊚", circleddash: "⊝", CircleDot: "⊙", circledR: "®", circledS: "Ⓢ", CircleMinus: "⊖", CirclePlus: "⊕", CircleTimes: "⊗", cir: "○", cirE: "⧃", cire: "≗", cirfnint: "⨐", cirmid: "⫯", cirscir: "⧂", ClockwiseContourIntegral: "∲", CloseCurlyDoubleQuote: "”", CloseCurlyQuote: "’", clubs: "♣", clubsuit: "♣", colon: ":", Colon: "∷", Colone: "⩴", colone: "≔", coloneq: "≔", comma: ",", commat: "@", comp: "∁", compfn: "∘", complement: "∁", complexes: "ℂ", cong: "≅", congdot: "⩭", Congruent: "≡", conint: "∮", Conint: "∯", ContourIntegral: "∮", copf: "𝕔", Copf: "ℂ", coprod: "∐", Coproduct: "∐", copy: "©", COPY: "©", copysr: "℗", CounterClockwiseContourIntegral: "∳", crarr: "↵", cross: "✗", Cross: "⨯", Cscr: "𝒞", cscr: "𝒸", csub: "⫏", csube: "⫑", csup: "⫐", csupe: "⫒", ctdot: "⋯", cudarrl: "⤸", cudarrr: "⤵", cuepr: "⋞", cuesc: "⋟", cularr: "↶", cularrp: "⤽", cupbrcap: "⩈", cupcap: "⩆", CupCap: "≍", cup: "∪", Cup: "⋓", cupcup: "⩊", cupdot: "⊍", cupor: "⩅", cups: "∪︀", curarr: "↷", curarrm: "⤼", curlyeqprec: "⋞", curlyeqsucc: "⋟", curlyvee: "⋎", curlywedge: "⋏", curren: "¤", curvearrowleft: "↶", curvearrowright: "↷", cuvee: "⋎", cuwed: "⋏", cwconint: "∲", cwint: "∱", cylcty: "⌭", dagger: "†", Dagger: "‡", daleth: "ℸ", darr: "↓", Darr: "↡", dArr: "⇓", dash: "‐", Dashv: "⫤", dashv: "⊣", dbkarow: "⤏", dblac: "˝", Dcaron: "Ď", dcaron: "ď", Dcy: "Д", dcy: "д", ddagger: "‡", ddarr: "⇊", DD: "ⅅ", dd: "ⅆ", DDotrahd: "⤑", ddotseq: "⩷", deg: "°", Del: "∇", Delta: "Δ", delta: "δ", demptyv: "⦱", dfisht: "⥿", Dfr: "𝔇", dfr: "𝔡", dHar: "⥥", dharl: "⇃", dharr: "⇂", DiacriticalAcute: "´", DiacriticalDot: "˙", DiacriticalDoubleAcute: "˝", DiacriticalGrave: "`", DiacriticalTilde: "˜", diam: "⋄", diamond: "⋄", Diamond: "⋄", diamondsuit: "♦", diams: "♦", die: "¨", DifferentialD: "ⅆ", digamma: "ϝ", disin: "⋲", div: "÷", divide: "÷", divideontimes: "⋇", divonx: "⋇", DJcy: "Ђ", djcy: "ђ", dlcorn: "⌞", dlcrop: "⌍", dollar: "$", Dopf: "𝔻", dopf: "𝕕", Dot: "¨", dot: "˙", DotDot: "⃜", doteq: "≐", doteqdot: "≑", DotEqual: "≐", dotminus: "∸", dotplus: "∔", dotsquare: "⊡", doublebarwedge: "⌆", DoubleContourIntegral: "∯", DoubleDot: "¨", DoubleDownArrow: "⇓", DoubleLeftArrow: "⇐", DoubleLeftRightArrow: "⇔", DoubleLeftTee: "⫤", DoubleLongLeftArrow: "⟸", DoubleLongLeftRightArrow: "⟺", DoubleLongRightArrow: "⟹", DoubleRightArrow: "⇒", DoubleRightTee: "⊨", DoubleUpArrow: "⇑", DoubleUpDownArrow: "⇕", DoubleVerticalBar: "∥", DownArrowBar: "⤓", downarrow: "↓", DownArrow: "↓", Downarrow: "⇓", DownArrowUpArrow: "⇵", DownBreve: "̑", downdownarrows: "⇊", downharpoonleft: "⇃", downharpoonright: "⇂", DownLeftRightVector: "⥐", DownLeftTeeVector: "⥞", DownLeftVectorBar: "⥖", DownLeftVector: "↽", DownRightTeeVector: "⥟", DownRightVectorBar: "⥗", DownRightVector: "⇁", DownTeeArrow: "↧", DownTee: "⊤", drbkarow: "⤐", drcorn: "⌟", drcrop: "⌌", Dscr: "𝒟", dscr: "𝒹", DScy: "Ѕ", dscy: "ѕ", dsol: "⧶", Dstrok: "Đ", dstrok: "đ", dtdot: "⋱", dtri: "▿", dtrif: "▾", duarr: "⇵", duhar: "⥯", dwangle: "⦦", DZcy: "Џ", dzcy: "џ", dzigrarr: "⟿", Eacute: "É", eacute: "é", easter: "⩮", Ecaron: "Ě", ecaron: "ě", Ecirc: "Ê", ecirc: "ê", ecir: "≖", ecolon: "≕", Ecy: "Э", ecy: "э", eDDot: "⩷", Edot: "Ė", edot: "ė", eDot: "≑", ee: "ⅇ", efDot: "≒", Efr: "𝔈", efr: "𝔢", eg: "⪚", Egrave: "È", egrave: "è", egs: "⪖", egsdot: "⪘", el: "⪙", Element: "∈", elinters: "⏧", ell: "ℓ", els: "⪕", elsdot: "⪗", Emacr: "Ē", emacr: "ē", empty: "∅", emptyset: "∅", EmptySmallSquare: "◻", emptyv: "∅", EmptyVerySmallSquare: "▫", emsp13: " ", emsp14: " ", emsp: " ", ENG: "Ŋ", eng: "ŋ", ensp: " ", Eogon: "Ę", eogon: "ę", Eopf: "𝔼", eopf: "𝕖", epar: "⋕", eparsl: "⧣", eplus: "⩱", epsi: "ε", Epsilon: "Ε", epsilon: "ε", epsiv: "ϵ", eqcirc: "≖", eqcolon: "≕", eqsim: "≂", eqslantgtr: "⪖", eqslantless: "⪕", Equal: "⩵", equals: "=", EqualTilde: "≂", equest: "≟", Equilibrium: "⇌", equiv: "≡", equivDD: "⩸", eqvparsl: "⧥", erarr: "⥱", erDot: "≓", escr: "ℯ", Escr: "ℰ", esdot: "≐", Esim: "⩳", esim: "≂", Eta: "Η", eta: "η", ETH: "Ð", eth: "ð", Euml: "Ë", euml: "ë", euro: "€", excl: "!", exist: "∃", Exists: "∃", expectation: "ℰ", exponentiale: "ⅇ", ExponentialE: "ⅇ", fallingdotseq: "≒", Fcy: "Ф", fcy: "ф", female: "♀", ffilig: "ffi", fflig: "ff", ffllig: "ffl", Ffr: "𝔉", ffr: "𝔣", filig: "fi", FilledSmallSquare: "◼", FilledVerySmallSquare: "▪", fjlig: "fj", flat: "♭", fllig: "fl", fltns: "▱", fnof: "ƒ", Fopf: "𝔽", fopf: "𝕗", forall: "∀", ForAll: "∀", fork: "⋔", forkv: "⫙", Fouriertrf: "ℱ", fpartint: "⨍", frac12: "½", frac13: "⅓", frac14: "¼", frac15: "⅕", frac16: "⅙", frac18: "⅛", frac23: "⅔", frac25: "⅖", frac34: "¾", frac35: "⅗", frac38: "⅜", frac45: "⅘", frac56: "⅚", frac58: "⅝", frac78: "⅞", frasl: "⁄", frown: "⌢", fscr: "𝒻", Fscr: "ℱ", gacute: "ǵ", Gamma: "Γ", gamma: "γ", Gammad: "Ϝ", gammad: "ϝ", gap: "⪆", Gbreve: "Ğ", gbreve: "ğ", Gcedil: "Ģ", Gcirc: "Ĝ", gcirc: "ĝ", Gcy: "Г", gcy: "г", Gdot: "Ġ", gdot: "ġ", ge: "≥", gE: "≧", gEl: "⪌", gel: "⋛", geq: "≥", geqq: "≧", geqslant: "⩾", gescc: "⪩", ges: "⩾", gesdot: "⪀", gesdoto: "⪂", gesdotol: "⪄", gesl: "⋛︀", gesles: "⪔", Gfr: "𝔊", gfr: "𝔤", gg: "≫", Gg: "⋙", ggg: "⋙", gimel: "ℷ", GJcy: "Ѓ", gjcy: "ѓ", gla: "⪥", gl: "≷", glE: "⪒", glj: "⪤", gnap: "⪊", gnapprox: "⪊", gne: "⪈", gnE: "≩", gneq: "⪈", gneqq: "≩", gnsim: "⋧", Gopf: "𝔾", gopf: "𝕘", grave: "`", GreaterEqual: "≥", GreaterEqualLess: "⋛", GreaterFullEqual: "≧", GreaterGreater: "⪢", GreaterLess: "≷", GreaterSlantEqual: "⩾", GreaterTilde: "≳", Gscr: "𝒢", gscr: "ℊ", gsim: "≳", gsime: "⪎", gsiml: "⪐", gtcc: "⪧", gtcir: "⩺", gt: ">", GT: ">", Gt: "≫", gtdot: "⋗", gtlPar: "⦕", gtquest: "⩼", gtrapprox: "⪆", gtrarr: "⥸", gtrdot: "⋗", gtreqless: "⋛", gtreqqless: "⪌", gtrless: "≷", gtrsim: "≳", gvertneqq: "≩︀", gvnE: "≩︀", Hacek: "ˇ", hairsp: " ", half: "½", hamilt: "ℋ", HARDcy: "Ъ", hardcy: "ъ", harrcir: "⥈", harr: "↔", hArr: "⇔", harrw: "↭", Hat: "^", hbar: "ℏ", Hcirc: "Ĥ", hcirc: "ĥ", hearts: "♥", heartsuit: "♥", hellip: "…", hercon: "⊹", hfr: "𝔥", Hfr: "ℌ", HilbertSpace: "ℋ", hksearow: "⤥", hkswarow: "⤦", hoarr: "⇿", homtht: "∻", hookleftarrow: "↩", hookrightarrow: "↪", hopf: "𝕙", Hopf: "ℍ", horbar: "―", HorizontalLine: "─", hscr: "𝒽", Hscr: "ℋ", hslash: "ℏ", Hstrok: "Ħ", hstrok: "ħ", HumpDownHump: "≎", HumpEqual: "≏", hybull: "⁃", hyphen: "‐", Iacute: "Í", iacute: "í", ic: "\u2063", Icirc: "Î", icirc: "î", Icy: "И", icy: "и", Idot: "İ", IEcy: "Е", iecy: "е", iexcl: "¡", iff: "⇔", ifr: "𝔦", Ifr: "ℑ", Igrave: "Ì", igrave: "ì", ii: "ⅈ", iiiint: "⨌", iiint: "∭", iinfin: "⧜", iiota: "℩", IJlig: "IJ", ijlig: "ij", Imacr: "Ī", imacr: "ī", image: "ℑ", ImaginaryI: "ⅈ", imagline: "ℐ", imagpart: "ℑ", imath: "ı", Im: "ℑ", imof: "⊷", imped: "Ƶ", Implies: "⇒", incare: "℅", in: "∈", infin: "∞", infintie: "⧝", inodot: "ı", intcal: "⊺", int: "∫", Int: "∬", integers: "ℤ", Integral: "∫", intercal: "⊺", Intersection: "⋂", intlarhk: "⨗", intprod: "⨼", InvisibleComma: "\u2063", InvisibleTimes: "\u2062", IOcy: "Ё", iocy: "ё", Iogon: "Į", iogon: "į", Iopf: "𝕀", iopf: "𝕚", Iota: "Ι", iota: "ι", iprod: "⨼", iquest: "¿", iscr: "𝒾", Iscr: "ℐ", isin: "∈", isindot: "⋵", isinE: "⋹", isins: "⋴", isinsv: "⋳", isinv: "∈", it: "\u2062", Itilde: "Ĩ", itilde: "ĩ", Iukcy: "І", iukcy: "і", Iuml: "Ï", iuml: "ï", Jcirc: "Ĵ", jcirc: "ĵ", Jcy: "Й", jcy: "й", Jfr: "𝔍", jfr: "𝔧", jmath: "ȷ", Jopf: "𝕁", jopf: "𝕛", Jscr: "𝒥", jscr: "𝒿", Jsercy: "Ј", jsercy: "ј", Jukcy: "Є", jukcy: "є", Kappa: "Κ", kappa: "κ", kappav: "ϰ", Kcedil: "Ķ", kcedil: "ķ", Kcy: "К", kcy: "к", Kfr: "𝔎", kfr: "𝔨", kgreen: "ĸ", KHcy: "Х", khcy: "х", KJcy: "Ќ", kjcy: "ќ", Kopf: "𝕂", kopf: "𝕜", Kscr: "𝒦", kscr: "𝓀", lAarr: "⇚", Lacute: "Ĺ", lacute: "ĺ", laemptyv: "⦴", lagran: "ℒ", Lambda: "Λ", lambda: "λ", lang: "⟨", Lang: "⟪", langd: "⦑", langle: "⟨", lap: "⪅", Laplacetrf: "ℒ", laquo: "«", larrb: "⇤", larrbfs: "⤟", larr: "←", Larr: "↞", lArr: "⇐", larrfs: "⤝", larrhk: "↩", larrlp: "↫", larrpl: "⤹", larrsim: "⥳", larrtl: "↢", latail: "⤙", lAtail: "⤛", lat: "⪫", late: "⪭", lates: "⪭︀", lbarr: "⤌", lBarr: "⤎", lbbrk: "❲", lbrace: "{", lbrack: "[", lbrke: "⦋", lbrksld: "⦏", lbrkslu: "⦍", Lcaron: "Ľ", lcaron: "ľ", Lcedil: "Ļ", lcedil: "ļ", lceil: "⌈", lcub: "{", Lcy: "Л", lcy: "л", ldca: "⤶", ldquo: "“", ldquor: "„", ldrdhar: "⥧", ldrushar: "⥋", ldsh: "↲", le: "≤", lE: "≦", LeftAngleBracket: "⟨", LeftArrowBar: "⇤", leftarrow: "←", LeftArrow: "←", Leftarrow: "⇐", LeftArrowRightArrow: "⇆", leftarrowtail: "↢", LeftCeiling: "⌈", LeftDoubleBracket: "⟦", LeftDownTeeVector: "⥡", LeftDownVectorBar: "⥙", LeftDownVector: "⇃", LeftFloor: "⌊", leftharpoondown: "↽", leftharpoonup: "↼", leftleftarrows: "⇇", leftrightarrow: "↔", LeftRightArrow: "↔", Leftrightarrow: "⇔", leftrightarrows: "⇆", leftrightharpoons: "⇋", leftrightsquigarrow: "↭", LeftRightVector: "⥎", LeftTeeArrow: "↤", LeftTee: "⊣", LeftTeeVector: "⥚", leftthreetimes: "⋋", LeftTriangleBar: "⧏", LeftTriangle: "⊲", LeftTriangleEqual: "⊴", LeftUpDownVector: "⥑", LeftUpTeeVector: "⥠", LeftUpVectorBar: "⥘", LeftUpVector: "↿", LeftVectorBar: "⥒", LeftVector: "↼", lEg: "⪋", leg: "⋚", leq: "≤", leqq: "≦", leqslant: "⩽", lescc: "⪨", les: "⩽", lesdot: "⩿", lesdoto: "⪁", lesdotor: "⪃", lesg: "⋚︀", lesges: "⪓", lessapprox: "⪅", lessdot: "⋖", lesseqgtr: "⋚", lesseqqgtr: "⪋", LessEqualGreater: "⋚", LessFullEqual: "≦", LessGreater: "≶", lessgtr: "≶", LessLess: "⪡", lesssim: "≲", LessSlantEqual: "⩽", LessTilde: "≲", lfisht: "⥼", lfloor: "⌊", Lfr: "𝔏", lfr: "𝔩", lg: "≶", lgE: "⪑", lHar: "⥢", lhard: "↽", lharu: "↼", lharul: "⥪", lhblk: "▄", LJcy: "Љ", ljcy: "љ", llarr: "⇇", ll: "≪", Ll: "⋘", llcorner: "⌞", Lleftarrow: "⇚", llhard: "⥫", lltri: "◺", Lmidot: "Ŀ", lmidot: "ŀ", lmoustache: "⎰", lmoust: "⎰", lnap: "⪉", lnapprox: "⪉", lne: "⪇", lnE: "≨", lneq: "⪇", lneqq: "≨", lnsim: "⋦", loang: "⟬", loarr: "⇽", lobrk: "⟦", longleftarrow: "⟵", LongLeftArrow: "⟵", Longleftarrow: "⟸", longleftrightarrow: "⟷", LongLeftRightArrow: "⟷", Longleftrightarrow: "⟺", longmapsto: "⟼", longrightarrow: "⟶", LongRightArrow: "⟶", Longrightarrow: "⟹", looparrowleft: "↫", looparrowright: "↬", lopar: "⦅", Lopf: "𝕃", lopf: "𝕝", loplus: "⨭", lotimes: "⨴", lowast: "∗", lowbar: "_", LowerLeftArrow: "↙", LowerRightArrow: "↘", loz: "◊", lozenge: "◊", lozf: "⧫", lpar: "(", lparlt: "⦓", lrarr: "⇆", lrcorner: "⌟", lrhar: "⇋", lrhard: "⥭", lrm: "\u200e", lrtri: "⊿", lsaquo: "‹", lscr: "𝓁", Lscr: "ℒ", lsh: "↰", Lsh: "↰", lsim: "≲", lsime: "⪍", lsimg: "⪏", lsqb: "[", lsquo: "‘", lsquor: "‚", Lstrok: "Ł", lstrok: "ł", ltcc: "⪦", ltcir: "⩹", lt: "<", LT: "<", Lt: "≪", ltdot: "⋖", lthree: "⋋", ltimes: "⋉", ltlarr: "⥶", ltquest: "⩻", ltri: "◃", ltrie: "⊴", ltrif: "◂", ltrPar: "⦖", lurdshar: "⥊", luruhar: "⥦", lvertneqq: "≨︀", lvnE: "≨︀", macr: "¯", male: "♂", malt: "✠", maltese: "✠", Map: "⤅", map: "↦", mapsto: "↦", mapstodown: "↧", mapstoleft: "↤", mapstoup: "↥", marker: "▮", mcomma: "⨩", Mcy: "М", mcy: "м", mdash: "—", mDDot: "∺", measuredangle: "∡", MediumSpace: " ", Mellintrf: "ℳ", Mfr: "𝔐", mfr: "𝔪", mho: "℧", micro: "µ", midast: "*", midcir: "⫰", mid: "∣", middot: "·", minusb: "⊟", minus: "−", minusd: "∸", minusdu: "⨪", MinusPlus: "∓", mlcp: "⫛", mldr: "…", mnplus: "∓", models: "⊧", Mopf: "𝕄", mopf: "𝕞", mp: "∓", mscr: "𝓂", Mscr: "ℳ", mstpos: "∾", Mu: "Μ", mu: "μ", multimap: "⊸", mumap: "⊸", nabla: "∇", Nacute: "Ń", nacute: "ń", nang: "∠⃒", nap: "≉", napE: "⩰̸", napid: "≋̸", napos: "ʼn", napprox: "≉", natural: "♮", naturals: "ℕ", natur: "♮", nbsp: " ", nbump: "≎̸", nbumpe: "≏̸", ncap: "⩃", Ncaron: "Ň", ncaron: "ň", Ncedil: "Ņ", ncedil: "ņ", ncong: "≇", ncongdot: "⩭̸", ncup: "⩂", Ncy: "Н", ncy: "н", ndash: "–", nearhk: "⤤", nearr: "↗", neArr: "⇗", nearrow: "↗", ne: "≠", nedot: "≐̸", NegativeMediumSpace: "", NegativeThickSpace: "", NegativeThinSpace: "", NegativeVeryThinSpace: "", nequiv: "≢", nesear: "⤨", nesim: "≂̸", NestedGreaterGreater: "≫", NestedLessLess: "≪", NewLine: "\u000a", nexist: "∄", nexists: "∄", Nfr: "𝔑", nfr: "𝔫", ngE: "≧̸", nge: "≱", ngeq: "≱", ngeqq: "≧̸", ngeqslant: "⩾̸", nges: "⩾̸", nGg: "⋙̸", ngsim: "≵", nGt: "≫⃒", ngt: "≯", ngtr: "≯", nGtv: "≫̸", nharr: "↮", nhArr: "⇎", nhpar: "⫲", ni: "∋", nis: "⋼", nisd: "⋺", niv: "∋", NJcy: "Њ", njcy: "њ", nlarr: "↚", nlArr: "⇍", nldr: "‥", nlE: "≦̸", nle: "≰", nleftarrow: "↚", nLeftarrow: "⇍", nleftrightarrow: "↮", nLeftrightarrow: "⇎", nleq: "≰", nleqq: "≦̸", nleqslant: "⩽̸", nles: "⩽̸", nless: "≮", nLl: "⋘̸", nlsim: "≴", nLt: "≪⃒", nlt: "≮", nltri: "⋪", nltrie: "⋬", nLtv: "≪̸", nmid: "∤", NoBreak: "\u2060", NonBreakingSpace: " ", nopf: "𝕟", Nopf: "ℕ", Not: "⫬", not: "¬", NotCongruent: "≢", NotCupCap: "≭", NotDoubleVerticalBar: "∦", NotElement: "∉", NotEqual: "≠", NotEqualTilde: "≂̸", NotExists: "∄", NotGreater: "≯", NotGreaterEqual: "≱", NotGreaterFullEqual: "≧̸", NotGreaterGreater: "≫̸", NotGreaterLess: "≹", NotGreaterSlantEqual: "⩾̸", NotGreaterTilde: "≵", NotHumpDownHump: "≎̸", NotHumpEqual: "≏̸", notin: "∉", notindot: "⋵̸", notinE: "⋹̸", notinva: "∉", notinvb: "⋷", notinvc: "⋶", NotLeftTriangleBar: "⧏̸", NotLeftTriangle: "⋪", NotLeftTriangleEqual: "⋬", NotLess: "≮", NotLessEqual: "≰", NotLessGreater: "≸", NotLessLess: "≪̸", NotLessSlantEqual: "⩽̸", NotLessTilde: "≴", NotNestedGreaterGreater: "⪢̸", NotNestedLessLess: "⪡̸", notni: "∌", notniva: "∌", notnivb: "⋾", notnivc: "⋽", NotPrecedes: "⊀", NotPrecedesEqual: "⪯̸", NotPrecedesSlantEqual: "⋠", NotReverseElement: "∌", NotRightTriangleBar: "⧐̸", NotRightTriangle: "⋫", NotRightTriangleEqual: "⋭", NotSquareSubset: "⊏̸", NotSquareSubsetEqual: "⋢", NotSquareSuperset: "⊐̸", NotSquareSupersetEqual: "⋣", NotSubset: "⊂⃒", NotSubsetEqual: "⊈", NotSucceeds: "⊁", NotSucceedsEqual: "⪰̸", NotSucceedsSlantEqual: "⋡", NotSucceedsTilde: "≿̸", NotSuperset: "⊃⃒", NotSupersetEqual: "⊉", NotTilde: "≁", NotTildeEqual: "≄", NotTildeFullEqual: "≇", NotTildeTilde: "≉", NotVerticalBar: "∤", nparallel: "∦", npar: "∦", nparsl: "⫽⃥", npart: "∂̸", npolint: "⨔", npr: "⊀", nprcue: "⋠", nprec: "⊀", npreceq: "⪯̸", npre: "⪯̸", nrarrc: "⤳̸", nrarr: "↛", nrArr: "⇏", nrarrw: "↝̸", nrightarrow: "↛", nRightarrow: "⇏", nrtri: "⋫", nrtrie: "⋭", nsc: "⊁", nsccue: "⋡", nsce: "⪰̸", Nscr: "𝒩", nscr: "𝓃", nshortmid: "∤", nshortparallel: "∦", nsim: "≁", nsime: "≄", nsimeq: "≄", nsmid: "∤", nspar: "∦", nsqsube: "⋢", nsqsupe: "⋣", nsub: "⊄", nsubE: "⫅̸", nsube: "⊈", nsubset: "⊂⃒", nsubseteq: "⊈", nsubseteqq: "⫅̸", nsucc: "⊁", nsucceq: "⪰̸", nsup: "⊅", nsupE: "⫆̸", nsupe: "⊉", nsupset: "⊃⃒", nsupseteq: "⊉", nsupseteqq: "⫆̸", ntgl: "≹", Ntilde: "Ñ", ntilde: "ñ", ntlg: "≸", ntriangleleft: "⋪", ntrianglelefteq: "⋬", ntriangleright: "⋫", ntrianglerighteq: "⋭", Nu: "Ν", nu: "ν", num: "#", numero: "№", numsp: " ", nvap: "≍⃒", nvdash: "⊬", nvDash: "⊭", nVdash: "⊮", nVDash: "⊯", nvge: "≥⃒", nvgt: ">⃒", nvHarr: "⤄", nvinfin: "⧞", nvlArr: "⤂", nvle: "≤⃒", nvlt: "<⃒", nvltrie: "⊴⃒", nvrArr: "⤃", nvrtrie: "⊵⃒", nvsim: "∼⃒", nwarhk: "⤣", nwarr: "↖", nwArr: "⇖", nwarrow: "↖", nwnear: "⤧", Oacute: "Ó", oacute: "ó", oast: "⊛", Ocirc: "Ô", ocirc: "ô", ocir: "⊚", Ocy: "О", ocy: "о", odash: "⊝", Odblac: "Ő", odblac: "ő", odiv: "⨸", odot: "⊙", odsold: "⦼", OElig: "Œ", oelig: "œ", ofcir: "⦿", Ofr: "𝔒", ofr: "𝔬", ogon: "˛", Ograve: "Ò", ograve: "ò", ogt: "⧁", ohbar: "⦵", ohm: "Ω", oint: "∮", olarr: "↺", olcir: "⦾", olcross: "⦻", oline: "‾", olt: "⧀", Omacr: "Ō", omacr: "ō", Omega: "Ω", omega: "ω", Omicron: "Ο", omicron: "ο", omid: "⦶", ominus: "⊖", Oopf: "𝕆", oopf: "𝕠", opar: "⦷", OpenCurlyDoubleQuote: "“", OpenCurlyQuote: "‘", operp: "⦹", oplus: "⊕", orarr: "↻", Or: "⩔", or: "∨", ord: "⩝", order: "ℴ", orderof: "ℴ", ordf: "ª", ordm: "º", origof: "⊶", oror: "⩖", orslope: "⩗", orv: "⩛", oS: "Ⓢ", Oscr: "𝒪", oscr: "ℴ", Oslash: "Ø", oslash: "ø", osol: "⊘", Otilde: "Õ", otilde: "õ", otimesas: "⨶", Otimes: "⨷", otimes: "⊗", Ouml: "Ö", ouml: "ö", ovbar: "⌽", OverBar: "‾", OverBrace: "⏞", OverBracket: "⎴", OverParenthesis: "⏜", para: "¶", parallel: "∥", par: "∥", parsim: "⫳", parsl: "⫽", part: "∂", PartialD: "∂", Pcy: "П", pcy: "п", percnt: "%", period: ".", permil: "‰", perp: "⊥", pertenk: "‱", Pfr: "𝔓", pfr: "𝔭", Phi: "Φ", phi: "φ", phiv: "ϕ", phmmat: "ℳ", phone: "☎", Pi: "Π", pi: "π", pitchfork: "⋔", piv: "ϖ", planck: "ℏ", planckh: "ℎ", plankv: "ℏ", plusacir: "⨣", plusb: "⊞", pluscir: "⨢", plus: "+", plusdo: "∔", plusdu: "⨥", pluse: "⩲", PlusMinus: "±", plusmn: "±", plussim: "⨦", plustwo: "⨧", pm: "±", Poincareplane: "ℌ", pointint: "⨕", popf: "𝕡", Popf: "ℙ", pound: "£", prap: "⪷", Pr: "⪻", pr: "≺", prcue: "≼", precapprox: "⪷", prec: "≺", preccurlyeq: "≼", Precedes: "≺", PrecedesEqual: "⪯", PrecedesSlantEqual: "≼", PrecedesTilde: "≾", preceq: "⪯", precnapprox: "⪹", precneqq: "⪵", precnsim: "⋨", pre: "⪯", prE: "⪳", precsim: "≾", prime: "′", Prime: "″", primes: "ℙ", prnap: "⪹", prnE: "⪵", prnsim: "⋨", prod: "∏", Product: "∏", profalar: "⌮", profline: "⌒", profsurf: "⌓", prop: "∝", Proportional: "∝", Proportion: "∷", propto: "∝", prsim: "≾", prurel: "⊰", Pscr: "𝒫", pscr: "𝓅", Psi: "Ψ", psi: "ψ", puncsp: " ", Qfr: "𝔔", qfr: "𝔮", qint: "⨌", qopf: "𝕢", Qopf: "ℚ", qprime: "⁗", Qscr: "𝒬", qscr: "𝓆", quaternions: "ℍ", quatint: "⨖", quest: "?", questeq: "≟", quot: "\"", QUOT: "\"", rAarr: "⇛", race: "∽̱", Racute: "Ŕ", racute: "ŕ", radic: "√", raemptyv: "⦳", rang: "⟩", Rang: "⟫", rangd: "⦒", range: "⦥", rangle: "⟩", raquo: "»", rarrap: "⥵", rarrb: "⇥", rarrbfs: "⤠", rarrc: "⤳", rarr: "→", Rarr: "↠", rArr: "⇒", rarrfs: "⤞", rarrhk: "↪", rarrlp: "↬", rarrpl: "⥅", rarrsim: "⥴", Rarrtl: "⤖", rarrtl: "↣", rarrw: "↝", ratail: "⤚", rAtail: "⤜", ratio: "∶", rationals: "ℚ", rbarr: "⤍", rBarr: "⤏", RBarr: "⤐", rbbrk: "❳", rbrace: "}", rbrack: "]", rbrke: "⦌", rbrksld: "⦎", rbrkslu: "⦐", Rcaron: "Ř", rcaron: "ř", Rcedil: "Ŗ", rcedil: "ŗ", rceil: "⌉", rcub: "}", Rcy: "Р", rcy: "р", rdca: "⤷", rdldhar: "⥩", rdquo: "”", rdquor: "”", rdsh: "↳", real: "ℜ", realine: "ℛ", realpart: "ℜ", reals: "ℝ", Re: "ℜ", rect: "▭", reg: "®", REG: "®", ReverseElement: "∋", ReverseEquilibrium: "⇋", ReverseUpEquilibrium: "⥯", rfisht: "⥽", rfloor: "⌋", rfr: "𝔯", Rfr: "ℜ", rHar: "⥤", rhard: "⇁", rharu: "⇀", rharul: "⥬", Rho: "Ρ", rho: "ρ", rhov: "ϱ", RightAngleBracket: "⟩", RightArrowBar: "⇥", rightarrow: "→", RightArrow: "→", Rightarrow: "⇒", RightArrowLeftArrow: "⇄", rightarrowtail: "↣", RightCeiling: "⌉", RightDoubleBracket: "⟧", RightDownTeeVector: "⥝", RightDownVectorBar: "⥕", RightDownVector: "⇂", RightFloor: "⌋", rightharpoondown: "⇁", rightharpoonup: "⇀", rightleftarrows: "⇄", rightleftharpoons: "⇌", rightrightarrows: "⇉", rightsquigarrow: "↝", RightTeeArrow: "↦", RightTee: "⊢", RightTeeVector: "⥛", rightthreetimes: "⋌", RightTriangleBar: "⧐", RightTriangle: "⊳", RightTriangleEqual: "⊵", RightUpDownVector: "⥏", RightUpTeeVector: "⥜", RightUpVectorBar: "⥔", RightUpVector: "↾", RightVectorBar: "⥓", RightVector: "⇀", ring: "˚", risingdotseq: "≓", rlarr: "⇄", rlhar: "⇌", rlm: "\u200f", rmoustache: "⎱", rmoust: "⎱", rnmid: "⫮", roang: "⟭", roarr: "⇾", robrk: "⟧", ropar: "⦆", ropf: "𝕣", Ropf: "ℝ", roplus: "⨮", rotimes: "⨵", RoundImplies: "⥰", rpar: ")", rpargt: "⦔", rppolint: "⨒", rrarr: "⇉", Rrightarrow: "⇛", rsaquo: "›", rscr: "𝓇", Rscr: "ℛ", rsh: "↱", Rsh: "↱", rsqb: "]", rsquo: "’", rsquor: "’", rthree: "⋌", rtimes: "⋊", rtri: "▹", rtrie: "⊵", rtrif: "▸", rtriltri: "⧎", RuleDelayed: "⧴", ruluhar: "⥨", rx: "℞", Sacute: "Ś", sacute: "ś", sbquo: "‚", scap: "⪸", Scaron: "Š", scaron: "š", Sc: "⪼", sc: "≻", sccue: "≽", sce: "⪰", scE: "⪴", Scedil: "Ş", scedil: "ş", Scirc: "Ŝ", scirc: "ŝ", scnap: "⪺", scnE: "⪶", scnsim: "⋩", scpolint: "⨓", scsim: "≿", Scy: "С", scy: "с", sdotb: "⊡", sdot: "⋅", sdote: "⩦", searhk: "⤥", searr: "↘", seArr: "⇘", searrow: "↘", sect: "§", semi: ";", seswar: "⤩", setminus: "∖", setmn: "∖", sext: "✶", Sfr: "𝔖", sfr: "𝔰", sfrown: "⌢", sharp: "♯", SHCHcy: "Щ", shchcy: "щ", SHcy: "Ш", shcy: "ш", ShortDownArrow: "↓", ShortLeftArrow: "←", shortmid: "∣", shortparallel: "∥", ShortRightArrow: "→", ShortUpArrow: "↑", shy: "\u00ad", Sigma: "Σ", sigma: "σ", sigmaf: "ς", sigmav: "ς", sim: "∼", simdot: "⩪", sime: "≃", simeq: "≃", simg: "⪞", simgE: "⪠", siml: "⪝", simlE: "⪟", simne: "≆", simplus: "⨤", simrarr: "⥲", slarr: "←", SmallCircle: "∘", smallsetminus: "∖", smashp: "⨳", smeparsl: "⧤", smid: "∣", smile: "⌣", smt: "⪪", smte: "⪬", smtes: "⪬︀", SOFTcy: "Ь", softcy: "ь", solbar: "⌿", solb: "⧄", sol: "/", Sopf: "𝕊", sopf: "𝕤", spades: "♠", spadesuit: "♠", spar: "∥", sqcap: "⊓", sqcaps: "⊓︀", sqcup: "⊔", sqcups: "⊔︀", Sqrt: "√", sqsub: "⊏", sqsube: "⊑", sqsubset: "⊏", sqsubseteq: "⊑", sqsup: "⊐", sqsupe: "⊒", sqsupset: "⊐", sqsupseteq: "⊒", square: "□", Square: "□", SquareIntersection: "⊓", SquareSubset: "⊏", SquareSubsetEqual: "⊑", SquareSuperset: "⊐", SquareSupersetEqual: "⊒", SquareUnion: "⊔", squarf: "▪", squ: "□", squf: "▪", srarr: "→", Sscr: "𝒮", sscr: "𝓈", ssetmn: "∖", ssmile: "⌣", sstarf: "⋆", Star: "⋆", star: "☆", starf: "★", straightepsilon: "ϵ", straightphi: "ϕ", strns: "¯", sub: "⊂", Sub: "⋐", subdot: "⪽", subE: "⫅", sube: "⊆", subedot: "⫃", submult: "⫁", subnE: "⫋", subne: "⊊", subplus: "⪿", subrarr: "⥹", subset: "⊂", Subset: "⋐", subseteq: "⊆", subseteqq: "⫅", SubsetEqual: "⊆", subsetneq: "⊊", subsetneqq: "⫋", subsim: "⫇", subsub: "⫕", subsup: "⫓", succapprox: "⪸", succ: "≻", succcurlyeq: "≽", Succeeds: "≻", SucceedsEqual: "⪰", SucceedsSlantEqual: "≽", SucceedsTilde: "≿", succeq: "⪰", succnapprox: "⪺", succneqq: "⪶", succnsim: "⋩", succsim: "≿", SuchThat: "∋", sum: "∑", Sum: "∑", sung: "♪", sup1: "¹", sup2: "²", sup3: "³", sup: "⊃", Sup: "⋑", supdot: "⪾", supdsub: "⫘", supE: "⫆", supe: "⊇", supedot: "⫄", Superset: "⊃", SupersetEqual: "⊇", suphsol: "⟉", suphsub: "⫗", suplarr: "⥻", supmult: "⫂", supnE: "⫌", supne: "⊋", supplus: "⫀", supset: "⊃", Supset: "⋑", supseteq: "⊇", supseteqq: "⫆", supsetneq: "⊋", supsetneqq: "⫌", supsim: "⫈", supsub: "⫔", supsup: "⫖", swarhk: "⤦", swarr: "↙", swArr: "⇙", swarrow: "↙", swnwar: "⤪", szlig: "ß", Tab: "\u0009", target: "⌖", Tau: "Τ", tau: "τ", tbrk: "⎴", Tcaron: "Ť", tcaron: "ť", Tcedil: "Ţ", tcedil: "ţ", Tcy: "Т", tcy: "т", tdot: "⃛", telrec: "⌕", Tfr: "𝔗", tfr: "𝔱", there4: "∴", therefore: "∴", Therefore: "∴", Theta: "Θ", theta: "θ", thetasym: "ϑ", thetav: "ϑ", thickapprox: "≈", thicksim: "∼", ThickSpace: " ", ThinSpace: " ", thinsp: " ", thkap: "≈", thksim: "∼", THORN: "Þ", thorn: "þ", tilde: "˜", Tilde: "∼", TildeEqual: "≃", TildeFullEqual: "≅", TildeTilde: "≈", timesbar: "⨱", timesb: "⊠", times: "×", timesd: "⨰", tint: "∭", toea: "⤨", topbot: "⌶", topcir: "⫱", top: "⊤", Topf: "𝕋", topf: "𝕥", topfork: "⫚", tosa: "⤩", tprime: "‴", trade: "™", TRADE: "™", triangle: "▵", triangledown: "▿", triangleleft: "◃", trianglelefteq: "⊴", triangleq: "≜", triangleright: "▹", trianglerighteq: "⊵", tridot: "◬", trie: "≜", triminus: "⨺", TripleDot: "⃛", triplus: "⨹", trisb: "⧍", tritime: "⨻", trpezium: "⏢", Tscr: "𝒯", tscr: "𝓉", TScy: "Ц", tscy: "ц", TSHcy: "Ћ", tshcy: "ћ", Tstrok: "Ŧ", tstrok: "ŧ", twixt: "≬", twoheadleftarrow: "↞", twoheadrightarrow: "↠", Uacute: "Ú", uacute: "ú", uarr: "↑", Uarr: "↟", uArr: "⇑", Uarrocir: "⥉", Ubrcy: "Ў", ubrcy: "ў", Ubreve: "Ŭ", ubreve: "ŭ", Ucirc: "Û", ucirc: "û", Ucy: "У", ucy: "у", udarr: "⇅", Udblac: "Ű", udblac: "ű", udhar: "⥮", ufisht: "⥾", Ufr: "𝔘", ufr: "𝔲", Ugrave: "Ù", ugrave: "ù", uHar: "⥣", uharl: "↿", uharr: "↾", uhblk: "▀", ulcorn: "⌜", ulcorner: "⌜", ulcrop: "⌏", ultri: "◸", Umacr: "Ū", umacr: "ū", uml: "¨", UnderBar: "_", UnderBrace: "⏟", UnderBracket: "⎵", UnderParenthesis: "⏝", Union: "⋃", UnionPlus: "⊎", Uogon: "Ų", uogon: "ų", Uopf: "𝕌", uopf: "𝕦", UpArrowBar: "⤒", uparrow: "↑", UpArrow: "↑", Uparrow: "⇑", UpArrowDownArrow: "⇅", updownarrow: "↕", UpDownArrow: "↕", Updownarrow: "⇕", UpEquilibrium: "⥮", upharpoonleft: "↿", upharpoonright: "↾", uplus: "⊎", UpperLeftArrow: "↖", UpperRightArrow: "↗", upsi: "υ", Upsi: "ϒ", upsih: "ϒ", Upsilon: "Υ", upsilon: "υ", UpTeeArrow: "↥", UpTee: "⊥", upuparrows: "⇈", urcorn: "⌝", urcorner: "⌝", urcrop: "⌎", Uring: "Ů", uring: "ů", urtri: "◹", Uscr: "𝒰", uscr: "𝓊", utdot: "⋰", Utilde: "Ũ", utilde: "ũ", utri: "▵", utrif: "▴", uuarr: "⇈", Uuml: "Ü", uuml: "ü", uwangle: "⦧", vangrt: "⦜", varepsilon: "ϵ", varkappa: "ϰ", varnothing: "∅", varphi: "ϕ", varpi: "ϖ", varpropto: "∝", varr: "↕", vArr: "⇕", varrho: "ϱ", varsigma: "ς", varsubsetneq: "⊊︀", varsubsetneqq: "⫋︀", varsupsetneq: "⊋︀", varsupsetneqq: "⫌︀", vartheta: "ϑ", vartriangleleft: "⊲", vartriangleright: "⊳", vBar: "⫨", Vbar: "⫫", vBarv: "⫩", Vcy: "В", vcy: "в", vdash: "⊢", vDash: "⊨", Vdash: "⊩", VDash: "⊫", Vdashl: "⫦", veebar: "⊻", vee: "∨", Vee: "⋁", veeeq: "≚", vellip: "⋮", verbar: "|", Verbar: "‖", vert: "|", Vert: "‖", VerticalBar: "∣", VerticalLine: "|", VerticalSeparator: "❘", VerticalTilde: "≀", VeryThinSpace: " ", Vfr: "𝔙", vfr: "𝔳", vltri: "⊲", vnsub: "⊂⃒", vnsup: "⊃⃒", Vopf: "𝕍", vopf: "𝕧", vprop: "∝", vrtri: "⊳", Vscr: "𝒱", vscr: "𝓋", vsubnE: "⫋︀", vsubne: "⊊︀", vsupnE: "⫌︀", vsupne: "⊋︀", Vvdash: "⊪", vzigzag: "⦚", Wcirc: "Ŵ", wcirc: "ŵ", wedbar: "⩟", wedge: "∧", Wedge: "⋀", wedgeq: "≙", weierp: "℘", Wfr: "𝔚", wfr: "𝔴", Wopf: "𝕎", wopf: "𝕨", wp: "℘", wr: "≀", wreath: "≀", Wscr: "𝒲", wscr: "𝓌", xcap: "⋂", xcirc: "◯", xcup: "⋃", xdtri: "▽", Xfr: "𝔛", xfr: "𝔵", xharr: "⟷", xhArr: "⟺", Xi: "Ξ", xi: "ξ", xlarr: "⟵", xlArr: "⟸", xmap: "⟼", xnis: "⋻", xodot: "⨀", Xopf: "𝕏", xopf: "𝕩", xoplus: "⨁", xotime: "⨂", xrarr: "⟶", xrArr: "⟹", Xscr: "𝒳", xscr: "𝓍", xsqcup: "⨆", xuplus: "⨄", xutri: "△", xvee: "⋁", xwedge: "⋀", Yacute: "Ý", yacute: "ý", YAcy: "Я", yacy: "я", Ycirc: "Ŷ", ycirc: "ŷ", Ycy: "Ы", ycy: "ы", yen: "¥", Yfr: "𝔜", yfr: "𝔶", YIcy: "Ї", yicy: "ї", Yopf: "𝕐", yopf: "𝕪", Yscr: "𝒴", yscr: "𝓎", YUcy: "Ю", yucy: "ю", yuml: "ÿ", Yuml: "Ÿ", Zacute: "Ź", zacute: "ź", Zcaron: "Ž", zcaron: "ž", Zcy: "З", zcy: "з", Zdot: "Ż", zdot: "ż", zeetrf: "ℨ", ZeroWidthSpace: "", Zeta: "Ζ", zeta: "ζ", zfr: "𝔷", Zfr: "ℨ", ZHcy: "Ж", zhcy: "ж", zigrarr: "⇝", zopf: "𝕫", Zopf: "ℤ", Zscr: "𝒵", zscr: "𝓏", zwj: "\u200d", zwnj: "\u200c" 11062 }; 11063 11064 var HEXCHARCODE = /^#[xX]([A-Fa-f0-9]+)$/; 11065 var CHARCODE = /^#([0-9]+)$/; 11066 var NAMED = /^([A-Za-z0-9]+)$/; 11067 var EntityParser = /** @class */ (function () { 11068 function EntityParser(named) { 11069 this.named = named; 11070 } 11071 EntityParser.prototype.parse = function (entity) { 11072 if (!entity) { 11073 return; 11074 } 11075 var matches = entity.match(HEXCHARCODE); 11076 if (matches) { 11077 return String.fromCharCode(parseInt(matches[1], 16)); 11078 } 11079 matches = entity.match(CHARCODE); 11080 if (matches) { 11081 return String.fromCharCode(parseInt(matches[1], 10)); 11082 } 11083 matches = entity.match(NAMED); 11084 if (matches) { 11085 return this.named[matches[1]]; 11086 } 11087 }; 11088 return EntityParser; 11089 }()); 11090 11091 var WSP = /[\t\n\f ]/; 11092 var ALPHA = /[A-Za-z]/; 11093 var CRLF = /\r\n?/g; 11094 function isSpace(char) { 11095 return WSP.test(char); 11096 } 11097 function isAlpha(char) { 11098 return ALPHA.test(char); 11099 } 11100 function preprocessInput(input) { 11101 return input.replace(CRLF, '\n'); 11102 } 11103 11104 var EventedTokenizer = /** @class */ (function () { 11105 function EventedTokenizer(delegate, entityParser, mode) { 11106 if (mode === void 0) { mode = 'precompile'; } 11107 this.delegate = delegate; 11108 this.entityParser = entityParser; 11109 this.mode = mode; 11110 this.state = "beforeData" /* beforeData */; 11111 this.line = -1; 11112 this.column = -1; 11113 this.input = ''; 11114 this.index = -1; 11115 this.tagNameBuffer = ''; 11116 this.states = { 11117 beforeData: function () { 11118 var char = this.peek(); 11119 if (char === '<' && !this.isIgnoredEndTag()) { 11120 this.transitionTo("tagOpen" /* tagOpen */); 11121 this.markTagStart(); 11122 this.consume(); 11123 } 11124 else { 11125 if (this.mode === 'precompile' && char === '\n') { 11126 var tag = this.tagNameBuffer.toLowerCase(); 11127 if (tag === 'pre' || tag === 'textarea') { 11128 this.consume(); 11129 } 11130 } 11131 this.transitionTo("data" /* data */); 11132 this.delegate.beginData(); 11133 } 11134 }, 11135 data: function () { 11136 var char = this.peek(); 11137 var tag = this.tagNameBuffer; 11138 if (char === '<' && !this.isIgnoredEndTag()) { 11139 this.delegate.finishData(); 11140 this.transitionTo("tagOpen" /* tagOpen */); 11141 this.markTagStart(); 11142 this.consume(); 11143 } 11144 else if (char === '&' && tag !== 'script' && tag !== 'style') { 11145 this.consume(); 11146 this.delegate.appendToData(this.consumeCharRef() || '&'); 11147 } 11148 else { 11149 this.consume(); 11150 this.delegate.appendToData(char); 11151 } 11152 }, 11153 tagOpen: function () { 11154 var char = this.consume(); 11155 if (char === '!') { 11156 this.transitionTo("markupDeclarationOpen" /* markupDeclarationOpen */); 11157 } 11158 else if (char === '/') { 11159 this.transitionTo("endTagOpen" /* endTagOpen */); 11160 } 11161 else if (char === '@' || char === ':' || isAlpha(char)) { 11162 this.transitionTo("tagName" /* tagName */); 11163 this.tagNameBuffer = ''; 11164 this.delegate.beginStartTag(); 11165 this.appendToTagName(char); 11166 } 11167 }, 11168 markupDeclarationOpen: function () { 11169 var char = this.consume(); 11170 if (char === '-' && this.peek() === '-') { 11171 this.consume(); 11172 this.transitionTo("commentStart" /* commentStart */); 11173 this.delegate.beginComment(); 11174 } 11175 else { 11176 var maybeDoctype = char.toUpperCase() + this.input.substring(this.index, this.index + 6).toUpperCase(); 11177 if (maybeDoctype === 'DOCTYPE') { 11178 this.consume(); 11179 this.consume(); 11180 this.consume(); 11181 this.consume(); 11182 this.consume(); 11183 this.consume(); 11184 this.transitionTo("doctype" /* doctype */); 11185 if (this.delegate.beginDoctype) 11186 this.delegate.beginDoctype(); 11187 } 11188 } 11189 }, 11190 doctype: function () { 11191 var char = this.consume(); 11192 if (isSpace(char)) { 11193 this.transitionTo("beforeDoctypeName" /* beforeDoctypeName */); 11194 } 11195 }, 11196 beforeDoctypeName: function () { 11197 var char = this.consume(); 11198 if (isSpace(char)) { 11199 return; 11200 } 11201 else { 11202 this.transitionTo("doctypeName" /* doctypeName */); 11203 if (this.delegate.appendToDoctypeName) 11204 this.delegate.appendToDoctypeName(char.toLowerCase()); 11205 } 11206 }, 11207 doctypeName: function () { 11208 var char = this.consume(); 11209 if (isSpace(char)) { 11210 this.transitionTo("afterDoctypeName" /* afterDoctypeName */); 11211 } 11212 else if (char === '>') { 11213 if (this.delegate.endDoctype) 11214 this.delegate.endDoctype(); 11215 this.transitionTo("beforeData" /* beforeData */); 11216 } 11217 else { 11218 if (this.delegate.appendToDoctypeName) 11219 this.delegate.appendToDoctypeName(char.toLowerCase()); 11220 } 11221 }, 11222 afterDoctypeName: function () { 11223 var char = this.consume(); 11224 if (isSpace(char)) { 11225 return; 11226 } 11227 else if (char === '>') { 11228 if (this.delegate.endDoctype) 11229 this.delegate.endDoctype(); 11230 this.transitionTo("beforeData" /* beforeData */); 11231 } 11232 else { 11233 var nextSixChars = char.toUpperCase() + this.input.substring(this.index, this.index + 5).toUpperCase(); 11234 var isPublic = nextSixChars.toUpperCase() === 'PUBLIC'; 11235 var isSystem = nextSixChars.toUpperCase() === 'SYSTEM'; 11236 if (isPublic || isSystem) { 11237 this.consume(); 11238 this.consume(); 11239 this.consume(); 11240 this.consume(); 11241 this.consume(); 11242 this.consume(); 11243 } 11244 if (isPublic) { 11245 this.transitionTo("afterDoctypePublicKeyword" /* afterDoctypePublicKeyword */); 11246 } 11247 else if (isSystem) { 11248 this.transitionTo("afterDoctypeSystemKeyword" /* afterDoctypeSystemKeyword */); 11249 } 11250 } 11251 }, 11252 afterDoctypePublicKeyword: function () { 11253 var char = this.peek(); 11254 if (isSpace(char)) { 11255 this.transitionTo("beforeDoctypePublicIdentifier" /* beforeDoctypePublicIdentifier */); 11256 this.consume(); 11257 } 11258 else if (char === '"') { 11259 this.transitionTo("doctypePublicIdentifierDoubleQuoted" /* doctypePublicIdentifierDoubleQuoted */); 11260 this.consume(); 11261 } 11262 else if (char === "'") { 11263 this.transitionTo("doctypePublicIdentifierSingleQuoted" /* doctypePublicIdentifierSingleQuoted */); 11264 this.consume(); 11265 } 11266 else if (char === '>') { 11267 this.consume(); 11268 if (this.delegate.endDoctype) 11269 this.delegate.endDoctype(); 11270 this.transitionTo("beforeData" /* beforeData */); 11271 } 11272 }, 11273 doctypePublicIdentifierDoubleQuoted: function () { 11274 var char = this.consume(); 11275 if (char === '"') { 11276 this.transitionTo("afterDoctypePublicIdentifier" /* afterDoctypePublicIdentifier */); 11277 } 11278 else if (char === '>') { 11279 if (this.delegate.endDoctype) 11280 this.delegate.endDoctype(); 11281 this.transitionTo("beforeData" /* beforeData */); 11282 } 11283 else { 11284 if (this.delegate.appendToDoctypePublicIdentifier) 11285 this.delegate.appendToDoctypePublicIdentifier(char); 11286 } 11287 }, 11288 doctypePublicIdentifierSingleQuoted: function () { 11289 var char = this.consume(); 11290 if (char === "'") { 11291 this.transitionTo("afterDoctypePublicIdentifier" /* afterDoctypePublicIdentifier */); 11292 } 11293 else if (char === '>') { 11294 if (this.delegate.endDoctype) 11295 this.delegate.endDoctype(); 11296 this.transitionTo("beforeData" /* beforeData */); 11297 } 11298 else { 11299 if (this.delegate.appendToDoctypePublicIdentifier) 11300 this.delegate.appendToDoctypePublicIdentifier(char); 11301 } 11302 }, 11303 afterDoctypePublicIdentifier: function () { 11304 var char = this.consume(); 11305 if (isSpace(char)) { 11306 this.transitionTo("betweenDoctypePublicAndSystemIdentifiers" /* betweenDoctypePublicAndSystemIdentifiers */); 11307 } 11308 else if (char === '>') { 11309 if (this.delegate.endDoctype) 11310 this.delegate.endDoctype(); 11311 this.transitionTo("beforeData" /* beforeData */); 11312 } 11313 else if (char === '"') { 11314 this.transitionTo("doctypeSystemIdentifierDoubleQuoted" /* doctypeSystemIdentifierDoubleQuoted */); 11315 } 11316 else if (char === "'") { 11317 this.transitionTo("doctypeSystemIdentifierSingleQuoted" /* doctypeSystemIdentifierSingleQuoted */); 11318 } 11319 }, 11320 betweenDoctypePublicAndSystemIdentifiers: function () { 11321 var char = this.consume(); 11322 if (isSpace(char)) { 11323 return; 11324 } 11325 else if (char === '>') { 11326 if (this.delegate.endDoctype) 11327 this.delegate.endDoctype(); 11328 this.transitionTo("beforeData" /* beforeData */); 11329 } 11330 else if (char === '"') { 11331 this.transitionTo("doctypeSystemIdentifierDoubleQuoted" /* doctypeSystemIdentifierDoubleQuoted */); 11332 } 11333 else if (char === "'") { 11334 this.transitionTo("doctypeSystemIdentifierSingleQuoted" /* doctypeSystemIdentifierSingleQuoted */); 11335 } 11336 }, 11337 doctypeSystemIdentifierDoubleQuoted: function () { 11338 var char = this.consume(); 11339 if (char === '"') { 11340 this.transitionTo("afterDoctypeSystemIdentifier" /* afterDoctypeSystemIdentifier */); 11341 } 11342 else if (char === '>') { 11343 if (this.delegate.endDoctype) 11344 this.delegate.endDoctype(); 11345 this.transitionTo("beforeData" /* beforeData */); 11346 } 11347 else { 11348 if (this.delegate.appendToDoctypeSystemIdentifier) 11349 this.delegate.appendToDoctypeSystemIdentifier(char); 11350 } 11351 }, 11352 doctypeSystemIdentifierSingleQuoted: function () { 11353 var char = this.consume(); 11354 if (char === "'") { 11355 this.transitionTo("afterDoctypeSystemIdentifier" /* afterDoctypeSystemIdentifier */); 11356 } 11357 else if (char === '>') { 11358 if (this.delegate.endDoctype) 11359 this.delegate.endDoctype(); 11360 this.transitionTo("beforeData" /* beforeData */); 11361 } 11362 else { 11363 if (this.delegate.appendToDoctypeSystemIdentifier) 11364 this.delegate.appendToDoctypeSystemIdentifier(char); 11365 } 11366 }, 11367 afterDoctypeSystemIdentifier: function () { 11368 var char = this.consume(); 11369 if (isSpace(char)) { 11370 return; 11371 } 11372 else if (char === '>') { 11373 if (this.delegate.endDoctype) 11374 this.delegate.endDoctype(); 11375 this.transitionTo("beforeData" /* beforeData */); 11376 } 11377 }, 11378 commentStart: function () { 11379 var char = this.consume(); 11380 if (char === '-') { 11381 this.transitionTo("commentStartDash" /* commentStartDash */); 11382 } 11383 else if (char === '>') { 11384 this.delegate.finishComment(); 11385 this.transitionTo("beforeData" /* beforeData */); 11386 } 11387 else { 11388 this.delegate.appendToCommentData(char); 11389 this.transitionTo("comment" /* comment */); 11390 } 11391 }, 11392 commentStartDash: function () { 11393 var char = this.consume(); 11394 if (char === '-') { 11395 this.transitionTo("commentEnd" /* commentEnd */); 11396 } 11397 else if (char === '>') { 11398 this.delegate.finishComment(); 11399 this.transitionTo("beforeData" /* beforeData */); 11400 } 11401 else { 11402 this.delegate.appendToCommentData('-'); 11403 this.transitionTo("comment" /* comment */); 11404 } 11405 }, 11406 comment: function () { 11407 var char = this.consume(); 11408 if (char === '-') { 11409 this.transitionTo("commentEndDash" /* commentEndDash */); 11410 } 11411 else { 11412 this.delegate.appendToCommentData(char); 11413 } 11414 }, 11415 commentEndDash: function () { 11416 var char = this.consume(); 11417 if (char === '-') { 11418 this.transitionTo("commentEnd" /* commentEnd */); 11419 } 11420 else { 11421 this.delegate.appendToCommentData('-' + char); 11422 this.transitionTo("comment" /* comment */); 11423 } 11424 }, 11425 commentEnd: function () { 11426 var char = this.consume(); 11427 if (char === '>') { 11428 this.delegate.finishComment(); 11429 this.transitionTo("beforeData" /* beforeData */); 11430 } 11431 else { 11432 this.delegate.appendToCommentData('--' + char); 11433 this.transitionTo("comment" /* comment */); 11434 } 11435 }, 11436 tagName: function () { 11437 var char = this.consume(); 11438 if (isSpace(char)) { 11439 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 11440 } 11441 else if (char === '/') { 11442 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 11443 } 11444 else if (char === '>') { 11445 this.delegate.finishTag(); 11446 this.transitionTo("beforeData" /* beforeData */); 11447 } 11448 else { 11449 this.appendToTagName(char); 11450 } 11451 }, 11452 endTagName: function () { 11453 var char = this.consume(); 11454 if (isSpace(char)) { 11455 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 11456 this.tagNameBuffer = ''; 11457 } 11458 else if (char === '/') { 11459 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 11460 this.tagNameBuffer = ''; 11461 } 11462 else if (char === '>') { 11463 this.delegate.finishTag(); 11464 this.transitionTo("beforeData" /* beforeData */); 11465 this.tagNameBuffer = ''; 11466 } 11467 else { 11468 this.appendToTagName(char); 11469 } 11470 }, 11471 beforeAttributeName: function () { 11472 var char = this.peek(); 11473 if (isSpace(char)) { 11474 this.consume(); 11475 return; 11476 } 11477 else if (char === '/') { 11478 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 11479 this.consume(); 11480 } 11481 else if (char === '>') { 11482 this.consume(); 11483 this.delegate.finishTag(); 11484 this.transitionTo("beforeData" /* beforeData */); 11485 } 11486 else if (char === '=') { 11487 this.delegate.reportSyntaxError('attribute name cannot start with equals sign'); 11488 this.transitionTo("attributeName" /* attributeName */); 11489 this.delegate.beginAttribute(); 11490 this.consume(); 11491 this.delegate.appendToAttributeName(char); 11492 } 11493 else { 11494 this.transitionTo("attributeName" /* attributeName */); 11495 this.delegate.beginAttribute(); 11496 } 11497 }, 11498 attributeName: function () { 11499 var char = this.peek(); 11500 if (isSpace(char)) { 11501 this.transitionTo("afterAttributeName" /* afterAttributeName */); 11502 this.consume(); 11503 } 11504 else if (char === '/') { 11505 this.delegate.beginAttributeValue(false); 11506 this.delegate.finishAttributeValue(); 11507 this.consume(); 11508 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 11509 } 11510 else if (char === '=') { 11511 this.transitionTo("beforeAttributeValue" /* beforeAttributeValue */); 11512 this.consume(); 11513 } 11514 else if (char === '>') { 11515 this.delegate.beginAttributeValue(false); 11516 this.delegate.finishAttributeValue(); 11517 this.consume(); 11518 this.delegate.finishTag(); 11519 this.transitionTo("beforeData" /* beforeData */); 11520 } 11521 else if (char === '"' || char === "'" || char === '<') { 11522 this.delegate.reportSyntaxError(char + ' is not a valid character within attribute names'); 11523 this.consume(); 11524 this.delegate.appendToAttributeName(char); 11525 } 11526 else { 11527 this.consume(); 11528 this.delegate.appendToAttributeName(char); 11529 } 11530 }, 11531 afterAttributeName: function () { 11532 var char = this.peek(); 11533 if (isSpace(char)) { 11534 this.consume(); 11535 return; 11536 } 11537 else if (char === '/') { 11538 this.delegate.beginAttributeValue(false); 11539 this.delegate.finishAttributeValue(); 11540 this.consume(); 11541 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 11542 } 11543 else if (char === '=') { 11544 this.consume(); 11545 this.transitionTo("beforeAttributeValue" /* beforeAttributeValue */); 11546 } 11547 else if (char === '>') { 11548 this.delegate.beginAttributeValue(false); 11549 this.delegate.finishAttributeValue(); 11550 this.consume(); 11551 this.delegate.finishTag(); 11552 this.transitionTo("beforeData" /* beforeData */); 11553 } 11554 else { 11555 this.delegate.beginAttributeValue(false); 11556 this.delegate.finishAttributeValue(); 11557 this.transitionTo("attributeName" /* attributeName */); 11558 this.delegate.beginAttribute(); 11559 this.consume(); 11560 this.delegate.appendToAttributeName(char); 11561 } 11562 }, 11563 beforeAttributeValue: function () { 11564 var char = this.peek(); 11565 if (isSpace(char)) { 11566 this.consume(); 11567 } 11568 else if (char === '"') { 11569 this.transitionTo("attributeValueDoubleQuoted" /* attributeValueDoubleQuoted */); 11570 this.delegate.beginAttributeValue(true); 11571 this.consume(); 11572 } 11573 else if (char === "'") { 11574 this.transitionTo("attributeValueSingleQuoted" /* attributeValueSingleQuoted */); 11575 this.delegate.beginAttributeValue(true); 11576 this.consume(); 11577 } 11578 else if (char === '>') { 11579 this.delegate.beginAttributeValue(false); 11580 this.delegate.finishAttributeValue(); 11581 this.consume(); 11582 this.delegate.finishTag(); 11583 this.transitionTo("beforeData" /* beforeData */); 11584 } 11585 else { 11586 this.transitionTo("attributeValueUnquoted" /* attributeValueUnquoted */); 11587 this.delegate.beginAttributeValue(false); 11588 this.consume(); 11589 this.delegate.appendToAttributeValue(char); 11590 } 11591 }, 11592 attributeValueDoubleQuoted: function () { 11593 var char = this.consume(); 11594 if (char === '"') { 11595 this.delegate.finishAttributeValue(); 11596 this.transitionTo("afterAttributeValueQuoted" /* afterAttributeValueQuoted */); 11597 } 11598 else if (char === '&') { 11599 this.delegate.appendToAttributeValue(this.consumeCharRef() || '&'); 11600 } 11601 else { 11602 this.delegate.appendToAttributeValue(char); 11603 } 11604 }, 11605 attributeValueSingleQuoted: function () { 11606 var char = this.consume(); 11607 if (char === "'") { 11608 this.delegate.finishAttributeValue(); 11609 this.transitionTo("afterAttributeValueQuoted" /* afterAttributeValueQuoted */); 11610 } 11611 else if (char === '&') { 11612 this.delegate.appendToAttributeValue(this.consumeCharRef() || '&'); 11613 } 11614 else { 11615 this.delegate.appendToAttributeValue(char); 11616 } 11617 }, 11618 attributeValueUnquoted: function () { 11619 var char = this.peek(); 11620 if (isSpace(char)) { 11621 this.delegate.finishAttributeValue(); 11622 this.consume(); 11623 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 11624 } 11625 else if (char === '/') { 11626 this.delegate.finishAttributeValue(); 11627 this.consume(); 11628 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 11629 } 11630 else if (char === '&') { 11631 this.consume(); 11632 this.delegate.appendToAttributeValue(this.consumeCharRef() || '&'); 11633 } 11634 else if (char === '>') { 11635 this.delegate.finishAttributeValue(); 11636 this.consume(); 11637 this.delegate.finishTag(); 11638 this.transitionTo("beforeData" /* beforeData */); 11639 } 11640 else { 11641 this.consume(); 11642 this.delegate.appendToAttributeValue(char); 11643 } 11644 }, 11645 afterAttributeValueQuoted: function () { 11646 var char = this.peek(); 11647 if (isSpace(char)) { 11648 this.consume(); 11649 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 11650 } 11651 else if (char === '/') { 11652 this.consume(); 11653 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */); 11654 } 11655 else if (char === '>') { 11656 this.consume(); 11657 this.delegate.finishTag(); 11658 this.transitionTo("beforeData" /* beforeData */); 11659 } 11660 else { 11661 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 11662 } 11663 }, 11664 selfClosingStartTag: function () { 11665 var char = this.peek(); 11666 if (char === '>') { 11667 this.consume(); 11668 this.delegate.markTagAsSelfClosing(); 11669 this.delegate.finishTag(); 11670 this.transitionTo("beforeData" /* beforeData */); 11671 } 11672 else { 11673 this.transitionTo("beforeAttributeName" /* beforeAttributeName */); 11674 } 11675 }, 11676 endTagOpen: function () { 11677 var char = this.consume(); 11678 if (char === '@' || char === ':' || isAlpha(char)) { 11679 this.transitionTo("endTagName" /* endTagName */); 11680 this.tagNameBuffer = ''; 11681 this.delegate.beginEndTag(); 11682 this.appendToTagName(char); 11683 } 11684 } 11685 }; 11686 this.reset(); 11687 } 11688 EventedTokenizer.prototype.reset = function () { 11689 this.transitionTo("beforeData" /* beforeData */); 11690 this.input = ''; 11691 this.tagNameBuffer = ''; 11692 this.index = 0; 11693 this.line = 1; 11694 this.column = 0; 11695 this.delegate.reset(); 11696 }; 11697 EventedTokenizer.prototype.transitionTo = function (state) { 11698 this.state = state; 11699 }; 11700 EventedTokenizer.prototype.tokenize = function (input) { 11701 this.reset(); 11702 this.tokenizePart(input); 11703 this.tokenizeEOF(); 11704 }; 11705 EventedTokenizer.prototype.tokenizePart = function (input) { 11706 this.input += preprocessInput(input); 11707 while (this.index < this.input.length) { 11708 var handler = this.states[this.state]; 11709 if (handler !== undefined) { 11710 handler.call(this); 11711 } 11712 else { 11713 throw new Error("unhandled state " + this.state); 11714 } 11715 } 11716 }; 11717 EventedTokenizer.prototype.tokenizeEOF = function () { 11718 this.flushData(); 11719 }; 11720 EventedTokenizer.prototype.flushData = function () { 11721 if (this.state === 'data') { 11722 this.delegate.finishData(); 11723 this.transitionTo("beforeData" /* beforeData */); 11724 } 11725 }; 11726 EventedTokenizer.prototype.peek = function () { 11727 return this.input.charAt(this.index); 11728 }; 11729 EventedTokenizer.prototype.consume = function () { 11730 var char = this.peek(); 11731 this.index++; 11732 if (char === '\n') { 11733 this.line++; 11734 this.column = 0; 11735 } 11736 else { 11737 this.column++; 11738 } 11739 return char; 11740 }; 11741 EventedTokenizer.prototype.consumeCharRef = function () { 11742 var endIndex = this.input.indexOf(';', this.index); 11743 if (endIndex === -1) { 11744 return; 11745 } 11746 var entity = this.input.slice(this.index, endIndex); 11747 var chars = this.entityParser.parse(entity); 11748 if (chars) { 11749 var count = entity.length; 11750 // consume the entity chars 11751 while (count) { 11752 this.consume(); 11753 count--; 11754 } 11755 // consume the `;` 11756 this.consume(); 11757 return chars; 11758 } 11759 }; 11760 EventedTokenizer.prototype.markTagStart = function () { 11761 this.delegate.tagOpen(); 11762 }; 11763 EventedTokenizer.prototype.appendToTagName = function (char) { 11764 this.tagNameBuffer += char; 11765 this.delegate.appendToTagName(char); 11766 }; 11767 EventedTokenizer.prototype.isIgnoredEndTag = function () { 11768 var tag = this.tagNameBuffer; 11769 return (tag === 'title' && this.input.substring(this.index, this.index + 8) !== '</title>') || 11770 (tag === 'style' && this.input.substring(this.index, this.index + 8) !== '</style>') || 11771 (tag === 'script' && this.input.substring(this.index, this.index + 9) !== '</script>'); 11772 }; 11773 return EventedTokenizer; 11774 }()); 11775 11776 var Tokenizer = /** @class */ (function () { 11777 function Tokenizer(entityParser, options) { 11778 if (options === void 0) { options = {}; } 11779 this.options = options; 11780 this.token = null; 11781 this.startLine = 1; 11782 this.startColumn = 0; 11783 this.tokens = []; 11784 this.tokenizer = new EventedTokenizer(this, entityParser, options.mode); 11785 this._currentAttribute = undefined; 11786 } 11787 Tokenizer.prototype.tokenize = function (input) { 11788 this.tokens = []; 11789 this.tokenizer.tokenize(input); 11790 return this.tokens; 11791 }; 11792 Tokenizer.prototype.tokenizePart = function (input) { 11793 this.tokens = []; 11794 this.tokenizer.tokenizePart(input); 11795 return this.tokens; 11796 }; 11797 Tokenizer.prototype.tokenizeEOF = function () { 11798 this.tokens = []; 11799 this.tokenizer.tokenizeEOF(); 11800 return this.tokens[0]; 11801 }; 11802 Tokenizer.prototype.reset = function () { 11803 this.token = null; 11804 this.startLine = 1; 11805 this.startColumn = 0; 11806 }; 11807 Tokenizer.prototype.current = function () { 11808 var token = this.token; 11809 if (token === null) { 11810 throw new Error('token was unexpectedly null'); 11811 } 11812 if (arguments.length === 0) { 11813 return token; 11814 } 11815 for (var i = 0; i < arguments.length; i++) { 11816 if (token.type === arguments[i]) { 11817 return token; 11818 } 11819 } 11820 throw new Error("token type was unexpectedly " + token.type); 11821 }; 11822 Tokenizer.prototype.push = function (token) { 11823 this.token = token; 11824 this.tokens.push(token); 11825 }; 11826 Tokenizer.prototype.currentAttribute = function () { 11827 return this._currentAttribute; 11828 }; 11829 Tokenizer.prototype.addLocInfo = function () { 11830 if (this.options.loc) { 11831 this.current().loc = { 11832 start: { 11833 line: this.startLine, 11834 column: this.startColumn 11835 }, 11836 end: { 11837 line: this.tokenizer.line, 11838 column: this.tokenizer.column 11839 } 11840 }; 11841 } 11842 this.startLine = this.tokenizer.line; 11843 this.startColumn = this.tokenizer.column; 11844 }; 11845 // Data 11846 Tokenizer.prototype.beginDoctype = function () { 11847 this.push({ 11848 type: "Doctype" /* Doctype */, 11849 name: '', 11850 }); 11851 }; 11852 Tokenizer.prototype.appendToDoctypeName = function (char) { 11853 this.current("Doctype" /* Doctype */).name += char; 11854 }; 11855 Tokenizer.prototype.appendToDoctypePublicIdentifier = function (char) { 11856 var doctype = this.current("Doctype" /* Doctype */); 11857 if (doctype.publicIdentifier === undefined) { 11858 doctype.publicIdentifier = char; 11859 } 11860 else { 11861 doctype.publicIdentifier += char; 11862 } 11863 }; 11864 Tokenizer.prototype.appendToDoctypeSystemIdentifier = function (char) { 11865 var doctype = this.current("Doctype" /* Doctype */); 11866 if (doctype.systemIdentifier === undefined) { 11867 doctype.systemIdentifier = char; 11868 } 11869 else { 11870 doctype.systemIdentifier += char; 11871 } 11872 }; 11873 Tokenizer.prototype.endDoctype = function () { 11874 this.addLocInfo(); 11875 }; 11876 Tokenizer.prototype.beginData = function () { 11877 this.push({ 11878 type: "Chars" /* Chars */, 11879 chars: '' 11880 }); 11881 }; 11882 Tokenizer.prototype.appendToData = function (char) { 11883 this.current("Chars" /* Chars */).chars += char; 11884 }; 11885 Tokenizer.prototype.finishData = function () { 11886 this.addLocInfo(); 11887 }; 11888 // Comment 11889 Tokenizer.prototype.beginComment = function () { 11890 this.push({ 11891 type: "Comment" /* Comment */, 11892 chars: '' 11893 }); 11894 }; 11895 Tokenizer.prototype.appendToCommentData = function (char) { 11896 this.current("Comment" /* Comment */).chars += char; 11897 }; 11898 Tokenizer.prototype.finishComment = function () { 11899 this.addLocInfo(); 11900 }; 11901 // Tags - basic 11902 Tokenizer.prototype.tagOpen = function () { }; 11903 Tokenizer.prototype.beginStartTag = function () { 11904 this.push({ 11905 type: "StartTag" /* StartTag */, 11906 tagName: '', 11907 attributes: [], 11908 selfClosing: false 11909 }); 11910 }; 11911 Tokenizer.prototype.beginEndTag = function () { 11912 this.push({ 11913 type: "EndTag" /* EndTag */, 11914 tagName: '' 11915 }); 11916 }; 11917 Tokenizer.prototype.finishTag = function () { 11918 this.addLocInfo(); 11919 }; 11920 Tokenizer.prototype.markTagAsSelfClosing = function () { 11921 this.current("StartTag" /* StartTag */).selfClosing = true; 11922 }; 11923 // Tags - name 11924 Tokenizer.prototype.appendToTagName = function (char) { 11925 this.current("StartTag" /* StartTag */, "EndTag" /* EndTag */).tagName += char; 11926 }; 11927 // Tags - attributes 11928 Tokenizer.prototype.beginAttribute = function () { 11929 this._currentAttribute = ['', '', false]; 11930 }; 11931 Tokenizer.prototype.appendToAttributeName = function (char) { 11932 this.currentAttribute()[0] += char; 11933 }; 11934 Tokenizer.prototype.beginAttributeValue = function (isQuoted) { 11935 this.currentAttribute()[2] = isQuoted; 11936 }; 11937 Tokenizer.prototype.appendToAttributeValue = function (char) { 11938 this.currentAttribute()[1] += char; 11939 }; 11940 Tokenizer.prototype.finishAttributeValue = function () { 11941 this.current("StartTag" /* StartTag */).attributes.push(this._currentAttribute); 11942 }; 11943 Tokenizer.prototype.reportSyntaxError = function (message) { 11944 this.current().syntaxError = message; 11945 }; 11946 return Tokenizer; 11947 }()); 11948 11949 function tokenize(input, options) { 11950 var tokenizer = new Tokenizer(new EntityParser(namedCharRefs), options); 11951 return tokenizer.tokenize(input); 11952 } 11953 11954 11955 11956 // EXTERNAL MODULE: ./node_modules/fast-deep-equal/es6/index.js 11957 var es6 = __webpack_require__(7734); 11958 var es6_default = /*#__PURE__*/__webpack_require__.n(es6); 11959 ;// external ["wp","htmlEntities"] 11960 const external_wp_htmlEntities_namespaceObject = window["wp"]["htmlEntities"]; 11961 ;// ./node_modules/@wordpress/blocks/build-module/api/validation/logger.js 11962 /** 11963 * @typedef LoggerItem 11964 * @property {Function} log Which logger recorded the message 11965 * @property {Array<any>} args White arguments were supplied to the logger 11966 */ 11967 11968 function createLogger() { 11969 /** 11970 * Creates a log handler with block validation prefix. 11971 * 11972 * @param {Function} logger Original logger function. 11973 * 11974 * @return {Function} Augmented logger function. 11975 */ 11976 function createLogHandler(logger) { 11977 let log = (message, ...args) => logger('Block validation: ' + message, ...args); 11978 11979 // In test environments, pre-process string substitutions to improve 11980 // readability of error messages. We'd prefer to avoid pulling in this 11981 // dependency in runtime environments, and it can be dropped by a combo 11982 // of Webpack env substitution + UglifyJS dead code elimination. 11983 if (false) {} 11984 return log; 11985 } 11986 return { 11987 // eslint-disable-next-line no-console 11988 error: createLogHandler(console.error), 11989 // eslint-disable-next-line no-console 11990 warning: createLogHandler(console.warn), 11991 getItems() { 11992 return []; 11993 } 11994 }; 11995 } 11996 function createQueuedLogger() { 11997 /** 11998 * The list of enqueued log actions to print. 11999 * 12000 * @type {Array<LoggerItem>} 12001 */ 12002 const queue = []; 12003 const logger = createLogger(); 12004 return { 12005 error(...args) { 12006 queue.push({ 12007 log: logger.error, 12008 args 12009 }); 12010 }, 12011 warning(...args) { 12012 queue.push({ 12013 log: logger.warning, 12014 args 12015 }); 12016 }, 12017 getItems() { 12018 return queue; 12019 } 12020 }; 12021 } 12022 12023 ;// ./node_modules/@wordpress/blocks/build-module/api/validation/index.js 12024 /* wp:polyfill */ 12025 /** 12026 * External dependencies 12027 */ 12028 12029 12030 12031 /** 12032 * WordPress dependencies 12033 */ 12034 12035 12036 12037 /** 12038 * Internal dependencies 12039 */ 12040 12041 12042 12043 12044 12045 /** @typedef {import('../parser').WPBlock} WPBlock */ 12046 /** @typedef {import('../registration').WPBlockType} WPBlockType */ 12047 /** @typedef {import('./logger').LoggerItem} LoggerItem */ 12048 12049 const identity = x => x; 12050 12051 /** 12052 * Globally matches any consecutive whitespace 12053 * 12054 * @type {RegExp} 12055 */ 12056 const REGEXP_WHITESPACE = /[\t\n\r\v\f ]+/g; 12057 12058 /** 12059 * Matches a string containing only whitespace 12060 * 12061 * @type {RegExp} 12062 */ 12063 const REGEXP_ONLY_WHITESPACE = /^[\t\n\r\v\f ]*$/; 12064 12065 /** 12066 * Matches a CSS URL type value 12067 * 12068 * @type {RegExp} 12069 */ 12070 const REGEXP_STYLE_URL_TYPE = /^url\s*\(['"\s]*(.*?)['"\s]*\)$/; 12071 12072 /** 12073 * Boolean attributes are attributes whose presence as being assigned is 12074 * meaningful, even if only empty. 12075 * 12076 * See: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#boolean-attributes 12077 * Extracted from: https://html.spec.whatwg.org/multipage/indices.html#attributes-3 12078 * 12079 * Object.keys( Array.from( document.querySelectorAll( '#attributes-1 > tbody > tr' ) ) 12080 * .filter( ( tr ) => tr.lastChild.textContent.indexOf( 'Boolean attribute' ) !== -1 ) 12081 * .reduce( ( result, tr ) => Object.assign( result, { 12082 * [ tr.firstChild.textContent.trim() ]: true 12083 * } ), {} ) ).sort(); 12084 * 12085 * @type {Array} 12086 */ 12087 const BOOLEAN_ATTRIBUTES = ['allowfullscreen', 'allowpaymentrequest', 'allowusermedia', 'async', 'autofocus', 'autoplay', 'checked', 'controls', 'default', 'defer', 'disabled', 'download', 'formnovalidate', 'hidden', 'ismap', 'itemscope', 'loop', 'multiple', 'muted', 'nomodule', 'novalidate', 'open', 'playsinline', 'readonly', 'required', 'reversed', 'selected', 'typemustmatch']; 12088 12089 /** 12090 * Enumerated attributes are attributes which must be of a specific value form. 12091 * Like boolean attributes, these are meaningful if specified, even if not of a 12092 * valid enumerated value. 12093 * 12094 * See: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#enumerated-attribute 12095 * Extracted from: https://html.spec.whatwg.org/multipage/indices.html#attributes-3 12096 * 12097 * Object.keys( Array.from( document.querySelectorAll( '#attributes-1 > tbody > tr' ) ) 12098 * .filter( ( tr ) => /^("(.+?)";?\s*)+/.test( tr.lastChild.textContent.trim() ) ) 12099 * .reduce( ( result, tr ) => Object.assign( result, { 12100 * [ tr.firstChild.textContent.trim() ]: true 12101 * } ), {} ) ).sort(); 12102 * 12103 * @type {Array} 12104 */ 12105 const ENUMERATED_ATTRIBUTES = ['autocapitalize', 'autocomplete', 'charset', 'contenteditable', 'crossorigin', 'decoding', 'dir', 'draggable', 'enctype', 'formenctype', 'formmethod', 'http-equiv', 'inputmode', 'kind', 'method', 'preload', 'scope', 'shape', 'spellcheck', 'translate', 'type', 'wrap']; 12106 12107 /** 12108 * Meaningful attributes are those who cannot be safely ignored when omitted in 12109 * one HTML markup string and not another. 12110 * 12111 * @type {Array} 12112 */ 12113 const MEANINGFUL_ATTRIBUTES = [...BOOLEAN_ATTRIBUTES, ...ENUMERATED_ATTRIBUTES]; 12114 12115 /** 12116 * Array of functions which receive a text string on which to apply normalizing 12117 * behavior for consideration in text token equivalence, carefully ordered from 12118 * least-to-most expensive operations. 12119 * 12120 * @type {Array} 12121 */ 12122 const TEXT_NORMALIZATIONS = [identity, getTextWithCollapsedWhitespace]; 12123 12124 /** 12125 * Regular expression matching a named character reference. In lieu of bundling 12126 * a full set of references, the pattern covers the minimal necessary to test 12127 * positively against the full set. 12128 * 12129 * "The ampersand must be followed by one of the names given in the named 12130 * character references section, using the same case." 12131 * 12132 * Tested against "12.5 Named character references": 12133 * 12134 * ``` 12135 * const references = Array.from( document.querySelectorAll( 12136 * '#named-character-references-table tr[id^=entity-] td:first-child' 12137 * ) ).map( ( code ) => code.textContent ) 12138 * references.every( ( reference ) => /^[\da-z]+$/i.test( reference ) ) 12139 * ``` 12140 * 12141 * @see https://html.spec.whatwg.org/multipage/syntax.html#character-references 12142 * @see https://html.spec.whatwg.org/multipage/named-characters.html#named-character-references 12143 * 12144 * @type {RegExp} 12145 */ 12146 const REGEXP_NAMED_CHARACTER_REFERENCE = /^[\da-z]+$/i; 12147 12148 /** 12149 * Regular expression matching a decimal character reference. 12150 * 12151 * "The ampersand must be followed by a U+0023 NUMBER SIGN character (#), 12152 * followed by one or more ASCII digits, representing a base-ten integer" 12153 * 12154 * @see https://html.spec.whatwg.org/multipage/syntax.html#character-references 12155 * 12156 * @type {RegExp} 12157 */ 12158 const REGEXP_DECIMAL_CHARACTER_REFERENCE = /^#\d+$/; 12159 12160 /** 12161 * Regular expression matching a hexadecimal character reference. 12162 * 12163 * "The ampersand must be followed by a U+0023 NUMBER SIGN character (#), which 12164 * must be followed by either a U+0078 LATIN SMALL LETTER X character (x) or a 12165 * U+0058 LATIN CAPITAL LETTER X character (X), which must then be followed by 12166 * one or more ASCII hex digits, representing a hexadecimal integer" 12167 * 12168 * @see https://html.spec.whatwg.org/multipage/syntax.html#character-references 12169 * 12170 * @type {RegExp} 12171 */ 12172 const REGEXP_HEXADECIMAL_CHARACTER_REFERENCE = /^#x[\da-f]+$/i; 12173 12174 /** 12175 * Returns true if the given string is a valid character reference segment, or 12176 * false otherwise. The text should be stripped of `&` and `;` demarcations. 12177 * 12178 * @param {string} text Text to test. 12179 * 12180 * @return {boolean} Whether text is valid character reference. 12181 */ 12182 function isValidCharacterReference(text) { 12183 return REGEXP_NAMED_CHARACTER_REFERENCE.test(text) || REGEXP_DECIMAL_CHARACTER_REFERENCE.test(text) || REGEXP_HEXADECIMAL_CHARACTER_REFERENCE.test(text); 12184 } 12185 12186 /** 12187 * Substitute EntityParser class for `simple-html-tokenizer` which uses the 12188 * implementation of `decodeEntities` from `html-entities`, in order to avoid 12189 * bundling a massive named character reference. 12190 * 12191 * @see https://github.com/tildeio/simple-html-tokenizer/tree/HEAD/src/entity-parser.ts 12192 */ 12193 class DecodeEntityParser { 12194 /** 12195 * Returns a substitute string for an entity string sequence between `&` 12196 * and `;`, or undefined if no substitution should occur. 12197 * 12198 * @param {string} entity Entity fragment discovered in HTML. 12199 * 12200 * @return {string | undefined} Entity substitute value. 12201 */ 12202 parse(entity) { 12203 if (isValidCharacterReference(entity)) { 12204 return (0,external_wp_htmlEntities_namespaceObject.decodeEntities)('&' + entity + ';'); 12205 } 12206 } 12207 } 12208 12209 /** 12210 * Given a specified string, returns an array of strings split by consecutive 12211 * whitespace, ignoring leading or trailing whitespace. 12212 * 12213 * @param {string} text Original text. 12214 * 12215 * @return {string[]} Text pieces split on whitespace. 12216 */ 12217 function getTextPiecesSplitOnWhitespace(text) { 12218 return text.trim().split(REGEXP_WHITESPACE); 12219 } 12220 12221 /** 12222 * Given a specified string, returns a new trimmed string where all consecutive 12223 * whitespace is collapsed to a single space. 12224 * 12225 * @param {string} text Original text. 12226 * 12227 * @return {string} Trimmed text with consecutive whitespace collapsed. 12228 */ 12229 function getTextWithCollapsedWhitespace(text) { 12230 // This is an overly simplified whitespace comparison. The specification is 12231 // more prescriptive of whitespace behavior in inline and block contexts. 12232 // 12233 // See: https://medium.com/@patrickbrosset/when-does-white-space-matter-in-html-b90e8a7cdd33 12234 return getTextPiecesSplitOnWhitespace(text).join(' '); 12235 } 12236 12237 /** 12238 * Returns attribute pairs of the given StartTag token, including only pairs 12239 * where the value is non-empty or the attribute is a boolean attribute, an 12240 * enumerated attribute, or a custom data- attribute. 12241 * 12242 * @see MEANINGFUL_ATTRIBUTES 12243 * 12244 * @param {Object} token StartTag token. 12245 * 12246 * @return {Array[]} Attribute pairs. 12247 */ 12248 function getMeaningfulAttributePairs(token) { 12249 return token.attributes.filter(pair => { 12250 const [key, value] = pair; 12251 return value || key.indexOf('data-') === 0 || MEANINGFUL_ATTRIBUTES.includes(key); 12252 }); 12253 } 12254 12255 /** 12256 * Returns true if two text tokens (with `chars` property) are equivalent, or 12257 * false otherwise. 12258 * 12259 * @param {Object} actual Actual token. 12260 * @param {Object} expected Expected token. 12261 * @param {Object} logger Validation logger object. 12262 * 12263 * @return {boolean} Whether two text tokens are equivalent. 12264 */ 12265 function isEquivalentTextTokens(actual, expected, logger = createLogger()) { 12266 // This function is intentionally written as syntactically "ugly" as a hot 12267 // path optimization. Text is progressively normalized in order from least- 12268 // to-most operationally expensive, until the earliest point at which text 12269 // can be confidently inferred as being equal. 12270 let actualChars = actual.chars; 12271 let expectedChars = expected.chars; 12272 for (let i = 0; i < TEXT_NORMALIZATIONS.length; i++) { 12273 const normalize = TEXT_NORMALIZATIONS[i]; 12274 actualChars = normalize(actualChars); 12275 expectedChars = normalize(expectedChars); 12276 if (actualChars === expectedChars) { 12277 return true; 12278 } 12279 } 12280 logger.warning('Expected text `%s`, saw `%s`.', expected.chars, actual.chars); 12281 return false; 12282 } 12283 12284 /** 12285 * Given a CSS length value, returns a normalized CSS length value for strict equality 12286 * comparison. 12287 * 12288 * @param {string} value CSS length value. 12289 * 12290 * @return {string} Normalized CSS length value. 12291 */ 12292 function getNormalizedLength(value) { 12293 if (0 === parseFloat(value)) { 12294 return '0'; 12295 } 12296 // Normalize strings with floats to always include a leading zero. 12297 if (value.indexOf('.') === 0) { 12298 return '0' + value; 12299 } 12300 return value; 12301 } 12302 12303 /** 12304 * Given a style value, returns a normalized style value for strict equality 12305 * comparison. 12306 * 12307 * @param {string} value Style value. 12308 * 12309 * @return {string} Normalized style value. 12310 */ 12311 function getNormalizedStyleValue(value) { 12312 const textPieces = getTextPiecesSplitOnWhitespace(value); 12313 const normalizedPieces = textPieces.map(getNormalizedLength); 12314 const result = normalizedPieces.join(' '); 12315 return result 12316 // Normalize URL type to omit whitespace or quotes. 12317 .replace(REGEXP_STYLE_URL_TYPE, 'url($1)'); 12318 } 12319 12320 /** 12321 * Given a style attribute string, returns an object of style properties. 12322 * 12323 * @param {string} text Style attribute. 12324 * 12325 * @return {Object} Style properties. 12326 */ 12327 function getStyleProperties(text) { 12328 const pairs = text 12329 // Trim ending semicolon (avoid including in split) 12330 .replace(/;?\s*$/, '') 12331 // Split on property assignment. 12332 .split(';') 12333 // For each property assignment... 12334 .map(style => { 12335 // ...split further into key-value pairs. 12336 const [key, ...valueParts] = style.split(':'); 12337 const value = valueParts.join(':'); 12338 return [key.trim(), getNormalizedStyleValue(value.trim())]; 12339 }); 12340 return Object.fromEntries(pairs); 12341 } 12342 12343 /** 12344 * Attribute-specific equality handlers 12345 * 12346 * @type {Object} 12347 */ 12348 const isEqualAttributesOfName = { 12349 class: (actual, expected) => { 12350 // Class matches if members are the same, even if out of order or 12351 // superfluous whitespace between. 12352 const [actualPieces, expectedPieces] = [actual, expected].map(getTextPiecesSplitOnWhitespace); 12353 const actualDiff = actualPieces.filter(c => !expectedPieces.includes(c)); 12354 const expectedDiff = expectedPieces.filter(c => !actualPieces.includes(c)); 12355 return actualDiff.length === 0 && expectedDiff.length === 0; 12356 }, 12357 style: (actual, expected) => { 12358 return es6_default()(...[actual, expected].map(getStyleProperties)); 12359 }, 12360 // For each boolean attribute, mere presence of attribute in both is enough 12361 // to assume equivalence. 12362 ...Object.fromEntries(BOOLEAN_ATTRIBUTES.map(attribute => [attribute, () => true])) 12363 }; 12364 12365 /** 12366 * Given two sets of attribute tuples, returns true if the attribute sets are 12367 * equivalent. 12368 * 12369 * @param {Array[]} actual Actual attributes tuples. 12370 * @param {Array[]} expected Expected attributes tuples. 12371 * @param {Object} logger Validation logger object. 12372 * 12373 * @return {boolean} Whether attributes are equivalent. 12374 */ 12375 function isEqualTagAttributePairs(actual, expected, logger = createLogger()) { 12376 // Attributes is tokenized as tuples. Their lengths should match. This also 12377 // avoids us needing to check both attributes sets, since if A has any keys 12378 // which do not exist in B, we know the sets to be different. 12379 if (actual.length !== expected.length) { 12380 logger.warning('Expected attributes %o, instead saw %o.', expected, actual); 12381 return false; 12382 } 12383 12384 // Attributes are not guaranteed to occur in the same order. For validating 12385 // actual attributes, first convert the set of expected attribute values to 12386 // an object, for lookup by key. 12387 const expectedAttributes = {}; 12388 for (let i = 0; i < expected.length; i++) { 12389 expectedAttributes[expected[i][0].toLowerCase()] = expected[i][1]; 12390 } 12391 for (let i = 0; i < actual.length; i++) { 12392 const [name, actualValue] = actual[i]; 12393 const nameLower = name.toLowerCase(); 12394 12395 // As noted above, if missing member in B, assume different. 12396 if (!expectedAttributes.hasOwnProperty(nameLower)) { 12397 logger.warning('Encountered unexpected attribute `%s`.', name); 12398 return false; 12399 } 12400 const expectedValue = expectedAttributes[nameLower]; 12401 const isEqualAttributes = isEqualAttributesOfName[nameLower]; 12402 if (isEqualAttributes) { 12403 // Defer custom attribute equality handling. 12404 if (!isEqualAttributes(actualValue, expectedValue)) { 12405 logger.warning('Expected attribute `%s` of value `%s`, saw `%s`.', name, expectedValue, actualValue); 12406 return false; 12407 } 12408 } else if (actualValue !== expectedValue) { 12409 // Otherwise strict inequality should bail. 12410 logger.warning('Expected attribute `%s` of value `%s`, saw `%s`.', name, expectedValue, actualValue); 12411 return false; 12412 } 12413 } 12414 return true; 12415 } 12416 12417 /** 12418 * Token-type-specific equality handlers 12419 * 12420 * @type {Object} 12421 */ 12422 const isEqualTokensOfType = { 12423 StartTag: (actual, expected, logger = createLogger()) => { 12424 if (actual.tagName !== expected.tagName && 12425 // Optimization: Use short-circuit evaluation to defer case- 12426 // insensitive check on the assumption that the majority case will 12427 // have exactly equal tag names. 12428 actual.tagName.toLowerCase() !== expected.tagName.toLowerCase()) { 12429 logger.warning('Expected tag name `%s`, instead saw `%s`.', expected.tagName, actual.tagName); 12430 return false; 12431 } 12432 return isEqualTagAttributePairs(...[actual, expected].map(getMeaningfulAttributePairs), logger); 12433 }, 12434 Chars: isEquivalentTextTokens, 12435 Comment: isEquivalentTextTokens 12436 }; 12437 12438 /** 12439 * Given an array of tokens, returns the first token which is not purely 12440 * whitespace. 12441 * 12442 * Mutates the tokens array. 12443 * 12444 * @param {Object[]} tokens Set of tokens to search. 12445 * 12446 * @return {Object | undefined} Next non-whitespace token. 12447 */ 12448 function getNextNonWhitespaceToken(tokens) { 12449 let token; 12450 while (token = tokens.shift()) { 12451 if (token.type !== 'Chars') { 12452 return token; 12453 } 12454 if (!REGEXP_ONLY_WHITESPACE.test(token.chars)) { 12455 return token; 12456 } 12457 } 12458 } 12459 12460 /** 12461 * Tokenize an HTML string, gracefully handling any errors thrown during 12462 * underlying tokenization. 12463 * 12464 * @param {string} html HTML string to tokenize. 12465 * @param {Object} logger Validation logger object. 12466 * 12467 * @return {Object[]|null} Array of valid tokenized HTML elements, or null on error 12468 */ 12469 function getHTMLTokens(html, logger = createLogger()) { 12470 try { 12471 return new Tokenizer(new DecodeEntityParser()).tokenize(html); 12472 } catch (e) { 12473 logger.warning('Malformed HTML detected: %s', html); 12474 } 12475 return null; 12476 } 12477 12478 /** 12479 * Returns true if the next HTML token closes the current token. 12480 * 12481 * @param {Object} currentToken Current token to compare with. 12482 * @param {Object|undefined} nextToken Next token to compare against. 12483 * 12484 * @return {boolean} true if `nextToken` closes `currentToken`, false otherwise 12485 */ 12486 function isClosedByToken(currentToken, nextToken) { 12487 // Ensure this is a self closed token. 12488 if (!currentToken.selfClosing) { 12489 return false; 12490 } 12491 12492 // Check token names and determine if nextToken is the closing tag for currentToken. 12493 if (nextToken && nextToken.tagName === currentToken.tagName && nextToken.type === 'EndTag') { 12494 return true; 12495 } 12496 return false; 12497 } 12498 12499 /** 12500 * Returns true if the given HTML strings are effectively equivalent, or 12501 * false otherwise. Invalid HTML is not considered equivalent, even if the 12502 * strings directly match. 12503 * 12504 * @param {string} actual Actual HTML string. 12505 * @param {string} expected Expected HTML string. 12506 * @param {Object} logger Validation logger object. 12507 * 12508 * @return {boolean} Whether HTML strings are equivalent. 12509 */ 12510 function isEquivalentHTML(actual, expected, logger = createLogger()) { 12511 // Short-circuit if markup is identical. 12512 if (actual === expected) { 12513 return true; 12514 } 12515 12516 // Tokenize input content and reserialized save content. 12517 const [actualTokens, expectedTokens] = [actual, expected].map(html => getHTMLTokens(html, logger)); 12518 12519 // If either is malformed then stop comparing - the strings are not equivalent. 12520 if (!actualTokens || !expectedTokens) { 12521 return false; 12522 } 12523 let actualToken, expectedToken; 12524 while (actualToken = getNextNonWhitespaceToken(actualTokens)) { 12525 expectedToken = getNextNonWhitespaceToken(expectedTokens); 12526 12527 // Inequal if exhausted all expected tokens. 12528 if (!expectedToken) { 12529 logger.warning('Expected end of content, instead saw %o.', actualToken); 12530 return false; 12531 } 12532 12533 // Inequal if next non-whitespace token of each set are not same type. 12534 if (actualToken.type !== expectedToken.type) { 12535 logger.warning('Expected token of type `%s` (%o), instead saw `%s` (%o).', expectedToken.type, expectedToken, actualToken.type, actualToken); 12536 return false; 12537 } 12538 12539 // Defer custom token type equality handling, otherwise continue and 12540 // assume as equal. 12541 const isEqualTokens = isEqualTokensOfType[actualToken.type]; 12542 if (isEqualTokens && !isEqualTokens(actualToken, expectedToken, logger)) { 12543 return false; 12544 } 12545 12546 // Peek at the next tokens (actual and expected) to see if they close 12547 // a self-closing tag. 12548 if (isClosedByToken(actualToken, expectedTokens[0])) { 12549 // Consume the next expected token that closes the current actual 12550 // self-closing token. 12551 getNextNonWhitespaceToken(expectedTokens); 12552 } else if (isClosedByToken(expectedToken, actualTokens[0])) { 12553 // Consume the next actual token that closes the current expected 12554 // self-closing token. 12555 getNextNonWhitespaceToken(actualTokens); 12556 } 12557 } 12558 if (expectedToken = getNextNonWhitespaceToken(expectedTokens)) { 12559 // If any non-whitespace tokens remain in expected token set, this 12560 // indicates inequality. 12561 logger.warning('Expected %o, instead saw end of content.', expectedToken); 12562 return false; 12563 } 12564 return true; 12565 } 12566 12567 /** 12568 * Returns an object with `isValid` property set to `true` if the parsed block 12569 * is valid given the input content. A block is considered valid if, when serialized 12570 * with assumed attributes, the content matches the original value. If block is 12571 * invalid, this function returns all validations issues as well. 12572 * 12573 * @param {string|Object} blockTypeOrName Block type. 12574 * @param {Object} attributes Parsed block attributes. 12575 * @param {string} originalBlockContent Original block content. 12576 * @param {Object} logger Validation logger object. 12577 * 12578 * @return {Object} Whether block is valid and contains validation messages. 12579 */ 12580 12581 /** 12582 * Returns an object with `isValid` property set to `true` if the parsed block 12583 * is valid given the input content. A block is considered valid if, when serialized 12584 * with assumed attributes, the content matches the original value. If block is 12585 * invalid, this function returns all validations issues as well. 12586 * 12587 * @param {WPBlock} block block object. 12588 * @param {WPBlockType|string} [blockTypeOrName = block.name] Block type or name, inferred from block if not given. 12589 * 12590 * @return {[boolean,Array<LoggerItem>]} validation results. 12591 */ 12592 function validateBlock(block, blockTypeOrName = block.name) { 12593 const isFallbackBlock = block.name === getFreeformContentHandlerName() || block.name === getUnregisteredTypeHandlerName(); 12594 12595 // Shortcut to avoid costly validation. 12596 if (isFallbackBlock) { 12597 return [true, []]; 12598 } 12599 const logger = createQueuedLogger(); 12600 const blockType = normalizeBlockType(blockTypeOrName); 12601 let generatedBlockContent; 12602 try { 12603 generatedBlockContent = getSaveContent(blockType, block.attributes); 12604 } catch (error) { 12605 logger.error('Block validation failed because an error occurred while generating block content:\n\n%s', error.toString()); 12606 return [false, logger.getItems()]; 12607 } 12608 const isValid = isEquivalentHTML(block.originalContent, generatedBlockContent, logger); 12609 if (!isValid) { 12610 logger.error('Block validation failed for `%s` (%o).\n\nContent generated by `save` function:\n\n%s\n\nContent retrieved from post body:\n\n%s', blockType.name, blockType, generatedBlockContent, block.originalContent); 12611 } 12612 return [isValid, logger.getItems()]; 12613 } 12614 12615 /** 12616 * Returns true if the parsed block is valid given the input content. A block 12617 * is considered valid if, when serialized with assumed attributes, the content 12618 * matches the original value. 12619 * 12620 * Logs to console in development environments when invalid. 12621 * 12622 * @deprecated Use validateBlock instead to avoid data loss. 12623 * 12624 * @param {string|Object} blockTypeOrName Block type. 12625 * @param {Object} attributes Parsed block attributes. 12626 * @param {string} originalBlockContent Original block content. 12627 * 12628 * @return {boolean} Whether block is valid. 12629 */ 12630 function isValidBlockContent(blockTypeOrName, attributes, originalBlockContent) { 12631 external_wp_deprecated_default()('isValidBlockContent introduces opportunity for data loss', { 12632 since: '12.6', 12633 plugin: 'Gutenberg', 12634 alternative: 'validateBlock' 12635 }); 12636 const blockType = normalizeBlockType(blockTypeOrName); 12637 const block = { 12638 name: blockType.name, 12639 attributes, 12640 innerBlocks: [], 12641 originalContent: originalBlockContent 12642 }; 12643 const [isValid] = validateBlock(block, blockType); 12644 return isValid; 12645 } 12646 12647 ;// ./node_modules/@wordpress/blocks/build-module/api/parser/convert-legacy-block.js 12648 /** 12649 * Convert legacy blocks to their canonical form. This function is used 12650 * both in the parser level for previous content and to convert such blocks 12651 * used in Custom Post Types templates. 12652 * 12653 * @param {string} name The block's name 12654 * @param {Object} attributes The block's attributes 12655 * 12656 * @return {[string, Object]} The block's name and attributes, changed accordingly if a match was found 12657 */ 12658 function convertLegacyBlockNameAndAttributes(name, attributes) { 12659 const newAttributes = { 12660 ...attributes 12661 }; 12662 // Convert 'core/cover-image' block in existing content to 'core/cover'. 12663 if ('core/cover-image' === name) { 12664 name = 'core/cover'; 12665 } 12666 12667 // Convert 'core/text' blocks in existing content to 'core/paragraph'. 12668 if ('core/text' === name || 'core/cover-text' === name) { 12669 name = 'core/paragraph'; 12670 } 12671 12672 // Convert derivative blocks such as 'core/social-link-wordpress' to the 12673 // canonical form 'core/social-link'. 12674 if (name && name.indexOf('core/social-link-') === 0) { 12675 // Capture `social-link-wordpress` into `{"service":"wordpress"}` 12676 newAttributes.service = name.substring(17); 12677 name = 'core/social-link'; 12678 } 12679 12680 // Convert derivative blocks such as 'core-embed/instagram' to the 12681 // canonical form 'core/embed'. 12682 if (name && name.indexOf('core-embed/') === 0) { 12683 // Capture `core-embed/instagram` into `{"providerNameSlug":"instagram"}` 12684 const providerSlug = name.substring(11); 12685 const deprecated = { 12686 speaker: 'speaker-deck', 12687 polldaddy: 'crowdsignal' 12688 }; 12689 newAttributes.providerNameSlug = providerSlug in deprecated ? deprecated[providerSlug] : providerSlug; 12690 // This is needed as the `responsive` attribute was passed 12691 // in a different way before the refactoring to block variations. 12692 if (!['amazon-kindle', 'wordpress'].includes(providerSlug)) { 12693 newAttributes.responsive = true; 12694 } 12695 name = 'core/embed'; 12696 } 12697 12698 // Convert Post Comment blocks in existing content to Comment blocks. 12699 // TODO: Remove these checks when WordPress 6.0 is released. 12700 if (name === 'core/post-comment-author') { 12701 name = 'core/comment-author-name'; 12702 } 12703 if (name === 'core/post-comment-content') { 12704 name = 'core/comment-content'; 12705 } 12706 if (name === 'core/post-comment-date') { 12707 name = 'core/comment-date'; 12708 } 12709 if (name === 'core/comments-query-loop') { 12710 name = 'core/comments'; 12711 const { 12712 className = '' 12713 } = newAttributes; 12714 if (!className.includes('wp-block-comments-query-loop')) { 12715 newAttributes.className = ['wp-block-comments-query-loop', className].join(' '); 12716 } 12717 // Note that we also had to add a deprecation to the block in order 12718 // for the ID change to work. 12719 } 12720 if (name === 'core/post-comments') { 12721 name = 'core/comments'; 12722 newAttributes.legacy = true; 12723 } 12724 12725 // Column count was stored as a string from WP 6.3-6.6. Convert it to a number. 12726 if (attributes.layout?.type === 'grid' && typeof attributes.layout?.columnCount === 'string') { 12727 newAttributes.layout = { 12728 ...newAttributes.layout, 12729 columnCount: parseInt(attributes.layout.columnCount, 10) 12730 }; 12731 } 12732 12733 // Column span and row span were stored as strings in WP 6.6. Convert them to numbers. 12734 if (typeof attributes.style?.layout?.columnSpan === 'string') { 12735 const columnSpanNumber = parseInt(attributes.style.layout.columnSpan, 10); 12736 newAttributes.style = { 12737 ...newAttributes.style, 12738 layout: { 12739 ...newAttributes.style.layout, 12740 columnSpan: isNaN(columnSpanNumber) ? undefined : columnSpanNumber 12741 } 12742 }; 12743 } 12744 if (typeof attributes.style?.layout?.rowSpan === 'string') { 12745 const rowSpanNumber = parseInt(attributes.style.layout.rowSpan, 10); 12746 newAttributes.style = { 12747 ...newAttributes.style, 12748 layout: { 12749 ...newAttributes.style.layout, 12750 rowSpan: isNaN(rowSpanNumber) ? undefined : rowSpanNumber 12751 } 12752 }; 12753 } 12754 12755 // The following code is only relevant for the Gutenberg plugin. 12756 // It's a stand-alone if statement for dead-code elimination. 12757 if (false) {} 12758 return [name, newAttributes]; 12759 } 12760 12761 ;// ./node_modules/hpq/es/get-path.js 12762 /** 12763 * Given object and string of dot-delimited path segments, returns value at 12764 * path or undefined if path cannot be resolved. 12765 * 12766 * @param {Object} object Lookup object 12767 * @param {string} path Path to resolve 12768 * @return {?*} Resolved value 12769 */ 12770 function getPath(object, path) { 12771 var segments = path.split('.'); 12772 var segment; 12773 12774 while (segment = segments.shift()) { 12775 if (!(segment in object)) { 12776 return; 12777 } 12778 12779 object = object[segment]; 12780 } 12781 12782 return object; 12783 } 12784 ;// ./node_modules/hpq/es/index.js 12785 /** 12786 * Internal dependencies 12787 */ 12788 12789 /** 12790 * Function returning a DOM document created by `createHTMLDocument`. The same 12791 * document is returned between invocations. 12792 * 12793 * @return {Document} DOM document. 12794 */ 12795 12796 var getDocument = function () { 12797 var doc; 12798 return function () { 12799 if (!doc) { 12800 doc = document.implementation.createHTMLDocument(''); 12801 } 12802 12803 return doc; 12804 }; 12805 }(); 12806 /** 12807 * Given a markup string or DOM element, creates an object aligning with the 12808 * shape of the matchers object, or the value returned by the matcher. 12809 * 12810 * @param {(string|Element)} source Source content 12811 * @param {(Object|Function)} matchers Matcher function or object of matchers 12812 * @return {(Object|*)} Matched value(s), shaped by object 12813 */ 12814 12815 12816 function parse(source, matchers) { 12817 if (!matchers) { 12818 return; 12819 } // Coerce to element 12820 12821 12822 if ('string' === typeof source) { 12823 var doc = getDocument(); 12824 doc.body.innerHTML = source; 12825 source = doc.body; 12826 } // Return singular value 12827 12828 12829 if ('function' === typeof matchers) { 12830 return matchers(source); 12831 } // Bail if we can't handle matchers 12832 12833 12834 if (Object !== matchers.constructor) { 12835 return; 12836 } // Shape result by matcher object 12837 12838 12839 return Object.keys(matchers).reduce(function (memo, key) { 12840 memo[key] = parse(source, matchers[key]); 12841 return memo; 12842 }, {}); 12843 } 12844 /** 12845 * Generates a function which matches node of type selector, returning an 12846 * attribute by property if the attribute exists. If no selector is passed, 12847 * returns property of the query element. 12848 * 12849 * @param {?string} selector Optional selector 12850 * @param {string} name Property name 12851 * @return {*} Property value 12852 */ 12853 12854 function prop(selector, name) { 12855 if (1 === arguments.length) { 12856 name = selector; 12857 selector = undefined; 12858 } 12859 12860 return function (node) { 12861 var match = node; 12862 12863 if (selector) { 12864 match = node.querySelector(selector); 12865 } 12866 12867 if (match) { 12868 return getPath(match, name); 12869 } 12870 }; 12871 } 12872 /** 12873 * Generates a function which matches node of type selector, returning an 12874 * attribute by name if the attribute exists. If no selector is passed, 12875 * returns attribute of the query element. 12876 * 12877 * @param {?string} selector Optional selector 12878 * @param {string} name Attribute name 12879 * @return {?string} Attribute value 12880 */ 12881 12882 function attr(selector, name) { 12883 if (1 === arguments.length) { 12884 name = selector; 12885 selector = undefined; 12886 } 12887 12888 return function (node) { 12889 var attributes = prop(selector, 'attributes')(node); 12890 12891 if (attributes && attributes.hasOwnProperty(name)) { 12892 return attributes[name].value; 12893 } 12894 }; 12895 } 12896 /** 12897 * Convenience for `prop( selector, 'innerHTML' )`. 12898 * 12899 * @see prop() 12900 * 12901 * @param {?string} selector Optional selector 12902 * @return {string} Inner HTML 12903 */ 12904 12905 function html(selector) { 12906 return prop(selector, 'innerHTML'); 12907 } 12908 /** 12909 * Convenience for `prop( selector, 'textContent' )`. 12910 * 12911 * @see prop() 12912 * 12913 * @param {?string} selector Optional selector 12914 * @return {string} Text content 12915 */ 12916 12917 function es_text(selector) { 12918 return prop(selector, 'textContent'); 12919 } 12920 /** 12921 * Creates a new matching context by first finding elements matching selector 12922 * using querySelectorAll before then running another `parse` on `matchers` 12923 * scoped to the matched elements. 12924 * 12925 * @see parse() 12926 * 12927 * @param {string} selector Selector to match 12928 * @param {(Object|Function)} matchers Matcher function or object of matchers 12929 * @return {Array.<*,Object>} Array of matched value(s) 12930 */ 12931 12932 function query(selector, matchers) { 12933 return function (node) { 12934 var matches = node.querySelectorAll(selector); 12935 return [].map.call(matches, function (match) { 12936 return parse(match, matchers); 12937 }); 12938 }; 12939 } 12940 ;// ./node_modules/memize/dist/index.js 12941 /** 12942 * Memize options object. 12943 * 12944 * @typedef MemizeOptions 12945 * 12946 * @property {number} [maxSize] Maximum size of the cache. 12947 */ 12948 12949 /** 12950 * Internal cache entry. 12951 * 12952 * @typedef MemizeCacheNode 12953 * 12954 * @property {?MemizeCacheNode|undefined} [prev] Previous node. 12955 * @property {?MemizeCacheNode|undefined} [next] Next node. 12956 * @property {Array<*>} args Function arguments for cache 12957 * entry. 12958 * @property {*} val Function result. 12959 */ 12960 12961 /** 12962 * Properties of the enhanced function for controlling cache. 12963 * 12964 * @typedef MemizeMemoizedFunction 12965 * 12966 * @property {()=>void} clear Clear the cache. 12967 */ 12968 12969 /** 12970 * Accepts a function to be memoized, and returns a new memoized function, with 12971 * optional options. 12972 * 12973 * @template {(...args: any[]) => any} F 12974 * 12975 * @param {F} fn Function to memoize. 12976 * @param {MemizeOptions} [options] Options object. 12977 * 12978 * @return {((...args: Parameters<F>) => ReturnType<F>) & MemizeMemoizedFunction} Memoized function. 12979 */ 12980 function memize(fn, options) { 12981 var size = 0; 12982 12983 /** @type {?MemizeCacheNode|undefined} */ 12984 var head; 12985 12986 /** @type {?MemizeCacheNode|undefined} */ 12987 var tail; 12988 12989 options = options || {}; 12990 12991 function memoized(/* ...args */) { 12992 var node = head, 12993 len = arguments.length, 12994 args, 12995 i; 12996 12997 searchCache: while (node) { 12998 // Perform a shallow equality test to confirm that whether the node 12999 // under test is a candidate for the arguments passed. Two arrays 13000 // are shallowly equal if their length matches and each entry is 13001 // strictly equal between the two sets. Avoid abstracting to a 13002 // function which could incur an arguments leaking deoptimization. 13003 13004 // Check whether node arguments match arguments length 13005 if (node.args.length !== arguments.length) { 13006 node = node.next; 13007 continue; 13008 } 13009 13010 // Check whether node arguments match arguments values 13011 for (i = 0; i < len; i++) { 13012 if (node.args[i] !== arguments[i]) { 13013 node = node.next; 13014 continue searchCache; 13015 } 13016 } 13017 13018 // At this point we can assume we've found a match 13019 13020 // Surface matched node to head if not already 13021 if (node !== head) { 13022 // As tail, shift to previous. Must only shift if not also 13023 // head, since if both head and tail, there is no previous. 13024 if (node === tail) { 13025 tail = node.prev; 13026 } 13027 13028 // Adjust siblings to point to each other. If node was tail, 13029 // this also handles new tail's empty `next` assignment. 13030 /** @type {MemizeCacheNode} */ (node.prev).next = node.next; 13031 if (node.next) { 13032 node.next.prev = node.prev; 13033 } 13034 13035 node.next = head; 13036 node.prev = null; 13037 /** @type {MemizeCacheNode} */ (head).prev = node; 13038 head = node; 13039 } 13040 13041 // Return immediately 13042 return node.val; 13043 } 13044 13045 // No cached value found. Continue to insertion phase: 13046 13047 // Create a copy of arguments (avoid leaking deoptimization) 13048 args = new Array(len); 13049 for (i = 0; i < len; i++) { 13050 args[i] = arguments[i]; 13051 } 13052 13053 node = { 13054 args: args, 13055 13056 // Generate the result from original function 13057 val: fn.apply(null, args), 13058 }; 13059 13060 // Don't need to check whether node is already head, since it would 13061 // have been returned above already if it was 13062 13063 // Shift existing head down list 13064 if (head) { 13065 head.prev = node; 13066 node.next = head; 13067 } else { 13068 // If no head, follows that there's no tail (at initial or reset) 13069 tail = node; 13070 } 13071 13072 // Trim tail if we're reached max size and are pending cache insertion 13073 if (size === /** @type {MemizeOptions} */ (options).maxSize) { 13074 tail = /** @type {MemizeCacheNode} */ (tail).prev; 13075 /** @type {MemizeCacheNode} */ (tail).next = null; 13076 } else { 13077 size++; 13078 } 13079 13080 head = node; 13081 13082 return node.val; 13083 } 13084 13085 memoized.clear = function () { 13086 head = null; 13087 tail = null; 13088 size = 0; 13089 }; 13090 13091 // Ignore reason: There's not a clear solution to create an intersection of 13092 // the function with additional properties, where the goal is to retain the 13093 // function signature of the incoming argument and add control properties 13094 // on the return value. 13095 13096 // @ts-ignore 13097 return memoized; 13098 } 13099 13100 13101 13102 ;// ./node_modules/@wordpress/blocks/build-module/api/matchers.js 13103 /** 13104 * External dependencies 13105 */ 13106 13107 13108 /** 13109 * WordPress dependencies 13110 */ 13111 13112 13113 /** 13114 * Internal dependencies 13115 */ 13116 13117 13118 function matchers_html(selector, multilineTag) { 13119 return domNode => { 13120 let match = domNode; 13121 if (selector) { 13122 match = domNode.querySelector(selector); 13123 } 13124 if (!match) { 13125 return ''; 13126 } 13127 if (multilineTag) { 13128 let value = ''; 13129 const length = match.children.length; 13130 for (let index = 0; index < length; index++) { 13131 const child = match.children[index]; 13132 if (child.nodeName.toLowerCase() !== multilineTag) { 13133 continue; 13134 } 13135 value += child.outerHTML; 13136 } 13137 return value; 13138 } 13139 return match.innerHTML; 13140 }; 13141 } 13142 const richText = (selector, preserveWhiteSpace) => el => { 13143 const target = selector ? el.querySelector(selector) : el; 13144 return target ? external_wp_richText_namespaceObject.RichTextData.fromHTMLElement(target, { 13145 preserveWhiteSpace 13146 }) : external_wp_richText_namespaceObject.RichTextData.empty(); 13147 }; 13148 13149 ;// ./node_modules/@wordpress/blocks/build-module/api/node.js 13150 /** 13151 * WordPress dependencies 13152 */ 13153 13154 13155 /** 13156 * Internal dependencies 13157 */ 13158 13159 13160 /** 13161 * A representation of a single node within a block's rich text value. If 13162 * representing a text node, the value is simply a string of the node value. 13163 * As representing an element node, it is an object of: 13164 * 13165 * 1. `type` (string): Tag name. 13166 * 2. `props` (object): Attributes and children array of WPBlockNode. 13167 * 13168 * @typedef {string|Object} WPBlockNode 13169 */ 13170 13171 /** 13172 * Given a single node and a node type (e.g. `'br'`), returns true if the node 13173 * corresponds to that type, false otherwise. 13174 * 13175 * @param {WPBlockNode} node Block node to test 13176 * @param {string} type Node to type to test against. 13177 * 13178 * @return {boolean} Whether node is of intended type. 13179 */ 13180 function isNodeOfType(node, type) { 13181 external_wp_deprecated_default()('wp.blocks.node.isNodeOfType', { 13182 since: '6.1', 13183 version: '6.3', 13184 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 13185 }); 13186 return node && node.type === type; 13187 } 13188 13189 /** 13190 * Given an object implementing the NamedNodeMap interface, returns a plain 13191 * object equivalent value of name, value key-value pairs. 13192 * 13193 * @see https://dom.spec.whatwg.org/#interface-namednodemap 13194 * 13195 * @param {NamedNodeMap} nodeMap NamedNodeMap to convert to object. 13196 * 13197 * @return {Object} Object equivalent value of NamedNodeMap. 13198 */ 13199 function getNamedNodeMapAsObject(nodeMap) { 13200 const result = {}; 13201 for (let i = 0; i < nodeMap.length; i++) { 13202 const { 13203 name, 13204 value 13205 } = nodeMap[i]; 13206 result[name] = value; 13207 } 13208 return result; 13209 } 13210 13211 /** 13212 * Given a DOM Element or Text node, returns an equivalent block node. Throws 13213 * if passed any node type other than element or text. 13214 * 13215 * @throws {TypeError} If non-element/text node is passed. 13216 * 13217 * @param {Node} domNode DOM node to convert. 13218 * 13219 * @return {WPBlockNode} Block node equivalent to DOM node. 13220 */ 13221 function fromDOM(domNode) { 13222 external_wp_deprecated_default()('wp.blocks.node.fromDOM', { 13223 since: '6.1', 13224 version: '6.3', 13225 alternative: 'wp.richText.create', 13226 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 13227 }); 13228 if (domNode.nodeType === domNode.TEXT_NODE) { 13229 return domNode.nodeValue; 13230 } 13231 if (domNode.nodeType !== domNode.ELEMENT_NODE) { 13232 throw new TypeError('A block node can only be created from a node of type text or ' + 'element.'); 13233 } 13234 return { 13235 type: domNode.nodeName.toLowerCase(), 13236 props: { 13237 ...getNamedNodeMapAsObject(domNode.attributes), 13238 children: children_fromDOM(domNode.childNodes) 13239 } 13240 }; 13241 } 13242 13243 /** 13244 * Given a block node, returns its HTML string representation. 13245 * 13246 * @param {WPBlockNode} node Block node to convert to string. 13247 * 13248 * @return {string} String HTML representation of block node. 13249 */ 13250 function toHTML(node) { 13251 external_wp_deprecated_default()('wp.blocks.node.toHTML', { 13252 since: '6.1', 13253 version: '6.3', 13254 alternative: 'wp.richText.toHTMLString', 13255 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 13256 }); 13257 return children_toHTML([node]); 13258 } 13259 13260 /** 13261 * Given a selector, returns an hpq matcher generating a WPBlockNode value 13262 * matching the selector result. 13263 * 13264 * @param {string} selector DOM selector. 13265 * 13266 * @return {Function} hpq matcher. 13267 */ 13268 function matcher(selector) { 13269 external_wp_deprecated_default()('wp.blocks.node.matcher', { 13270 since: '6.1', 13271 version: '6.3', 13272 alternative: 'html source', 13273 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 13274 }); 13275 return domNode => { 13276 let match = domNode; 13277 if (selector) { 13278 match = domNode.querySelector(selector); 13279 } 13280 try { 13281 return fromDOM(match); 13282 } catch (error) { 13283 return null; 13284 } 13285 }; 13286 } 13287 13288 /** 13289 * Object of utility functions used in managing block attribute values of 13290 * source `node`. 13291 * 13292 * @see https://github.com/WordPress/gutenberg/pull/10439 13293 * 13294 * @deprecated since 4.0. The `node` source should not be used, and can be 13295 * replaced by the `html` source. 13296 * 13297 * @private 13298 */ 13299 /* harmony default export */ const node = ({ 13300 isNodeOfType, 13301 fromDOM, 13302 toHTML, 13303 matcher 13304 }); 13305 13306 ;// ./node_modules/@wordpress/blocks/build-module/api/children.js 13307 /** 13308 * WordPress dependencies 13309 */ 13310 13311 13312 13313 /** 13314 * Internal dependencies 13315 */ 13316 13317 13318 /** 13319 * A representation of a block's rich text value. 13320 * 13321 * @typedef {WPBlockNode[]} WPBlockChildren 13322 */ 13323 13324 /** 13325 * Given block children, returns a serialize-capable WordPress element. 13326 * 13327 * @param {WPBlockChildren} children Block children object to convert. 13328 * 13329 * @return {Element} A serialize-capable element. 13330 */ 13331 function getSerializeCapableElement(children) { 13332 // The fact that block children are compatible with the element serializer is 13333 // merely an implementation detail that currently serves to be true, but 13334 // should not be mistaken as being a guarantee on the external API. The 13335 // public API only offers guarantees to work with strings (toHTML) and DOM 13336 // elements (fromDOM), and should provide utilities to manipulate the value 13337 // rather than expect consumers to inspect or construct its shape (concat). 13338 return children; 13339 } 13340 13341 /** 13342 * Given block children, returns an array of block nodes. 13343 * 13344 * @param {WPBlockChildren} children Block children object to convert. 13345 * 13346 * @return {Array<WPBlockNode>} An array of individual block nodes. 13347 */ 13348 function getChildrenArray(children) { 13349 external_wp_deprecated_default()('wp.blocks.children.getChildrenArray', { 13350 since: '6.1', 13351 version: '6.3', 13352 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 13353 }); 13354 13355 // The fact that block children are compatible with the element serializer 13356 // is merely an implementation detail that currently serves to be true, but 13357 // should not be mistaken as being a guarantee on the external API. 13358 return children; 13359 } 13360 13361 /** 13362 * Given two or more block nodes, returns a new block node representing a 13363 * concatenation of its values. 13364 * 13365 * @param {...WPBlockChildren} blockNodes Block nodes to concatenate. 13366 * 13367 * @return {WPBlockChildren} Concatenated block node. 13368 */ 13369 function concat(...blockNodes) { 13370 external_wp_deprecated_default()('wp.blocks.children.concat', { 13371 since: '6.1', 13372 version: '6.3', 13373 alternative: 'wp.richText.concat', 13374 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 13375 }); 13376 const result = []; 13377 for (let i = 0; i < blockNodes.length; i++) { 13378 const blockNode = Array.isArray(blockNodes[i]) ? blockNodes[i] : [blockNodes[i]]; 13379 for (let j = 0; j < blockNode.length; j++) { 13380 const child = blockNode[j]; 13381 const canConcatToPreviousString = typeof child === 'string' && typeof result[result.length - 1] === 'string'; 13382 if (canConcatToPreviousString) { 13383 result[result.length - 1] += child; 13384 } else { 13385 result.push(child); 13386 } 13387 } 13388 } 13389 return result; 13390 } 13391 13392 /** 13393 * Given an iterable set of DOM nodes, returns equivalent block children. 13394 * Ignores any non-element/text nodes included in set. 13395 * 13396 * @param {Iterable.<Node>} domNodes Iterable set of DOM nodes to convert. 13397 * 13398 * @return {WPBlockChildren} Block children equivalent to DOM nodes. 13399 */ 13400 function children_fromDOM(domNodes) { 13401 external_wp_deprecated_default()('wp.blocks.children.fromDOM', { 13402 since: '6.1', 13403 version: '6.3', 13404 alternative: 'wp.richText.create', 13405 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 13406 }); 13407 const result = []; 13408 for (let i = 0; i < domNodes.length; i++) { 13409 try { 13410 result.push(fromDOM(domNodes[i])); 13411 } catch (error) { 13412 // Simply ignore if DOM node could not be converted. 13413 } 13414 } 13415 return result; 13416 } 13417 13418 /** 13419 * Given a block node, returns its HTML string representation. 13420 * 13421 * @param {WPBlockChildren} children Block node(s) to convert to string. 13422 * 13423 * @return {string} String HTML representation of block node. 13424 */ 13425 function children_toHTML(children) { 13426 external_wp_deprecated_default()('wp.blocks.children.toHTML', { 13427 since: '6.1', 13428 version: '6.3', 13429 alternative: 'wp.richText.toHTMLString', 13430 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 13431 }); 13432 const element = getSerializeCapableElement(children); 13433 return (0,external_wp_element_namespaceObject.renderToString)(element); 13434 } 13435 13436 /** 13437 * Given a selector, returns an hpq matcher generating a WPBlockChildren value 13438 * matching the selector result. 13439 * 13440 * @param {string} selector DOM selector. 13441 * 13442 * @return {Function} hpq matcher. 13443 */ 13444 function children_matcher(selector) { 13445 external_wp_deprecated_default()('wp.blocks.children.matcher', { 13446 since: '6.1', 13447 version: '6.3', 13448 alternative: 'html source', 13449 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/' 13450 }); 13451 return domNode => { 13452 let match = domNode; 13453 if (selector) { 13454 match = domNode.querySelector(selector); 13455 } 13456 if (match) { 13457 return children_fromDOM(match.childNodes); 13458 } 13459 return []; 13460 }; 13461 } 13462 13463 /** 13464 * Object of utility functions used in managing block attribute values of 13465 * source `children`. 13466 * 13467 * @see https://github.com/WordPress/gutenberg/pull/10439 13468 * 13469 * @deprecated since 4.0. The `children` source should not be used, and can be 13470 * replaced by the `html` source. 13471 * 13472 * @private 13473 */ 13474 /* harmony default export */ const children = ({ 13475 concat, 13476 getChildrenArray, 13477 fromDOM: children_fromDOM, 13478 toHTML: children_toHTML, 13479 matcher: children_matcher 13480 }); 13481 13482 ;// ./node_modules/@wordpress/blocks/build-module/api/parser/get-block-attributes.js 13483 /* wp:polyfill */ 13484 /** 13485 * External dependencies 13486 */ 13487 13488 13489 13490 /** 13491 * WordPress dependencies 13492 */ 13493 13494 13495 13496 /** 13497 * Internal dependencies 13498 */ 13499 13500 13501 13502 /** 13503 * Higher-order hpq matcher which enhances an attribute matcher to return true 13504 * or false depending on whether the original matcher returns undefined. This 13505 * is useful for boolean attributes (e.g. disabled) whose attribute values may 13506 * be technically falsey (empty string), though their mere presence should be 13507 * enough to infer as true. 13508 * 13509 * @param {Function} matcher Original hpq matcher. 13510 * 13511 * @return {Function} Enhanced hpq matcher. 13512 */ 13513 const toBooleanAttributeMatcher = matcher => value => matcher(value) !== undefined; 13514 13515 /** 13516 * Returns true if value is of the given JSON schema type, or false otherwise. 13517 * 13518 * @see http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.25 13519 * 13520 * @param {*} value Value to test. 13521 * @param {string} type Type to test. 13522 * 13523 * @return {boolean} Whether value is of type. 13524 */ 13525 function isOfType(value, type) { 13526 switch (type) { 13527 case 'rich-text': 13528 return value instanceof external_wp_richText_namespaceObject.RichTextData; 13529 case 'string': 13530 return typeof value === 'string'; 13531 case 'boolean': 13532 return typeof value === 'boolean'; 13533 case 'object': 13534 return !!value && value.constructor === Object; 13535 case 'null': 13536 return value === null; 13537 case 'array': 13538 return Array.isArray(value); 13539 case 'integer': 13540 case 'number': 13541 return typeof value === 'number'; 13542 } 13543 return true; 13544 } 13545 13546 /** 13547 * Returns true if value is of an array of given JSON schema types, or false 13548 * otherwise. 13549 * 13550 * @see http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.25 13551 * 13552 * @param {*} value Value to test. 13553 * @param {string[]} types Types to test. 13554 * 13555 * @return {boolean} Whether value is of types. 13556 */ 13557 function isOfTypes(value, types) { 13558 return types.some(type => isOfType(value, type)); 13559 } 13560 13561 /** 13562 * Given an attribute key, an attribute's schema, a block's raw content and the 13563 * commentAttributes returns the attribute value depending on its source 13564 * definition of the given attribute key. 13565 * 13566 * @param {string} attributeKey Attribute key. 13567 * @param {Object} attributeSchema Attribute's schema. 13568 * @param {Node} innerDOM Parsed DOM of block's inner HTML. 13569 * @param {Object} commentAttributes Block's comment attributes. 13570 * @param {string} innerHTML Raw HTML from block node's innerHTML property. 13571 * 13572 * @return {*} Attribute value. 13573 */ 13574 function getBlockAttribute(attributeKey, attributeSchema, innerDOM, commentAttributes, innerHTML) { 13575 let value; 13576 switch (attributeSchema.source) { 13577 // An undefined source means that it's an attribute serialized to the 13578 // block's "comment". 13579 case undefined: 13580 value = commentAttributes ? commentAttributes[attributeKey] : undefined; 13581 break; 13582 // raw source means that it's the original raw block content. 13583 case 'raw': 13584 value = innerHTML; 13585 break; 13586 case 'attribute': 13587 case 'property': 13588 case 'html': 13589 case 'text': 13590 case 'rich-text': 13591 case 'children': 13592 case 'node': 13593 case 'query': 13594 case 'tag': 13595 value = parseWithAttributeSchema(innerDOM, attributeSchema); 13596 break; 13597 } 13598 if (!isValidByType(value, attributeSchema.type) || !isValidByEnum(value, attributeSchema.enum)) { 13599 // Reject the value if it is not valid. Reverting to the undefined 13600 // value ensures the default is respected, if applicable. 13601 value = undefined; 13602 } 13603 if (value === undefined) { 13604 value = getDefault(attributeSchema); 13605 } 13606 return value; 13607 } 13608 13609 /** 13610 * Returns true if value is valid per the given block attribute schema type 13611 * definition, or false otherwise. 13612 * 13613 * @see https://json-schema.org/latest/json-schema-validation.html#rfc.section.6.1.1 13614 * 13615 * @param {*} value Value to test. 13616 * @param {?(Array<string>|string)} type Block attribute schema type. 13617 * 13618 * @return {boolean} Whether value is valid. 13619 */ 13620 function isValidByType(value, type) { 13621 return type === undefined || isOfTypes(value, Array.isArray(type) ? type : [type]); 13622 } 13623 13624 /** 13625 * Returns true if value is valid per the given block attribute schema enum 13626 * definition, or false otherwise. 13627 * 13628 * @see https://json-schema.org/latest/json-schema-validation.html#rfc.section.6.1.2 13629 * 13630 * @param {*} value Value to test. 13631 * @param {?Array} enumSet Block attribute schema enum. 13632 * 13633 * @return {boolean} Whether value is valid. 13634 */ 13635 function isValidByEnum(value, enumSet) { 13636 return !Array.isArray(enumSet) || enumSet.includes(value); 13637 } 13638 13639 /** 13640 * Returns an hpq matcher given a source object. 13641 * 13642 * @param {Object} sourceConfig Attribute Source object. 13643 * 13644 * @return {Function} A hpq Matcher. 13645 */ 13646 const matcherFromSource = memize(sourceConfig => { 13647 switch (sourceConfig.source) { 13648 case 'attribute': 13649 { 13650 let matcher = attr(sourceConfig.selector, sourceConfig.attribute); 13651 if (sourceConfig.type === 'boolean') { 13652 matcher = toBooleanAttributeMatcher(matcher); 13653 } 13654 return matcher; 13655 } 13656 case 'html': 13657 return matchers_html(sourceConfig.selector, sourceConfig.multiline); 13658 case 'text': 13659 return es_text(sourceConfig.selector); 13660 case 'rich-text': 13661 return richText(sourceConfig.selector, sourceConfig.__unstablePreserveWhiteSpace); 13662 case 'children': 13663 return children_matcher(sourceConfig.selector); 13664 case 'node': 13665 return matcher(sourceConfig.selector); 13666 case 'query': 13667 const subMatchers = Object.fromEntries(Object.entries(sourceConfig.query).map(([key, subSourceConfig]) => [key, matcherFromSource(subSourceConfig)])); 13668 return query(sourceConfig.selector, subMatchers); 13669 case 'tag': 13670 { 13671 const matcher = prop(sourceConfig.selector, 'nodeName'); 13672 return domNode => matcher(domNode)?.toLowerCase(); 13673 } 13674 default: 13675 // eslint-disable-next-line no-console 13676 console.error(`Unknown source type "$sourceConfig.source}"`); 13677 } 13678 }); 13679 13680 /** 13681 * Parse a HTML string into DOM tree. 13682 * 13683 * @param {string|Node} innerHTML HTML string or already parsed DOM node. 13684 * 13685 * @return {Node} Parsed DOM node. 13686 */ 13687 function parseHtml(innerHTML) { 13688 return parse(innerHTML, h => h); 13689 } 13690 13691 /** 13692 * Given a block's raw content and an attribute's schema returns the attribute's 13693 * value depending on its source. 13694 * 13695 * @param {string|Node} innerHTML Block's raw content. 13696 * @param {Object} attributeSchema Attribute's schema. 13697 * 13698 * @return {*} Attribute value. 13699 */ 13700 function parseWithAttributeSchema(innerHTML, attributeSchema) { 13701 return matcherFromSource(attributeSchema)(parseHtml(innerHTML)); 13702 } 13703 13704 /** 13705 * Returns the block attributes of a registered block node given its type. 13706 * 13707 * @param {string|Object} blockTypeOrName Block type or name. 13708 * @param {string|Node} innerHTML Raw block content. 13709 * @param {?Object} attributes Known block attributes (from delimiters). 13710 * 13711 * @return {Object} All block attributes. 13712 */ 13713 function getBlockAttributes(blockTypeOrName, innerHTML, attributes = {}) { 13714 var _blockType$attributes; 13715 const doc = parseHtml(innerHTML); 13716 const blockType = normalizeBlockType(blockTypeOrName); 13717 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)])); 13718 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getBlockAttributes', blockAttributes, blockType, innerHTML, attributes); 13719 } 13720 13721 ;// ./node_modules/@wordpress/blocks/build-module/api/parser/fix-custom-classname.js 13722 /* wp:polyfill */ 13723 /** 13724 * Internal dependencies 13725 */ 13726 13727 13728 13729 const CLASS_ATTR_SCHEMA = { 13730 type: 'string', 13731 source: 'attribute', 13732 selector: '[data-custom-class-name] > *', 13733 attribute: 'class' 13734 }; 13735 13736 /** 13737 * Given an HTML string, returns an array of class names assigned to the root 13738 * element in the markup. 13739 * 13740 * @param {string} innerHTML Markup string from which to extract classes. 13741 * 13742 * @return {string[]} Array of class names assigned to the root element. 13743 */ 13744 function getHTMLRootElementClasses(innerHTML) { 13745 const parsed = parseWithAttributeSchema(`<div data-custom-class-name>$innerHTML}</div>`, CLASS_ATTR_SCHEMA); 13746 return parsed ? parsed.trim().split(/\s+/) : []; 13747 } 13748 13749 /** 13750 * Given a parsed set of block attributes, if the block supports custom class 13751 * names and an unknown class (per the block's serialization behavior) is 13752 * found, the unknown classes are treated as custom classes. This prevents the 13753 * block from being considered as invalid. 13754 * 13755 * @param {Object} blockAttributes Original block attributes. 13756 * @param {Object} blockType Block type settings. 13757 * @param {string} innerHTML Original block markup. 13758 * 13759 * @return {Object} Filtered block attributes. 13760 */ 13761 function fixCustomClassname(blockAttributes, blockType, innerHTML) { 13762 if (!hasBlockSupport(blockType, 'customClassName', true)) { 13763 return blockAttributes; 13764 } 13765 const modifiedBlockAttributes = { 13766 ...blockAttributes 13767 }; 13768 // To determine difference, serialize block given the known set of 13769 // attributes, with the exception of `className`. This will determine 13770 // the default set of classes. From there, any difference in innerHTML 13771 // can be considered as custom classes. 13772 const { 13773 className: omittedClassName, 13774 ...attributesSansClassName 13775 } = modifiedBlockAttributes; 13776 const serialized = getSaveContent(blockType, attributesSansClassName); 13777 const defaultClasses = getHTMLRootElementClasses(serialized); 13778 const actualClasses = getHTMLRootElementClasses(innerHTML); 13779 const customClasses = actualClasses.filter(className => !defaultClasses.includes(className)); 13780 if (customClasses.length) { 13781 modifiedBlockAttributes.className = customClasses.join(' '); 13782 } else if (serialized) { 13783 delete modifiedBlockAttributes.className; 13784 } 13785 return modifiedBlockAttributes; 13786 } 13787 13788 ;// ./node_modules/@wordpress/blocks/build-module/api/parser/apply-built-in-validation-fixes.js 13789 /** 13790 * Internal dependencies 13791 */ 13792 13793 13794 /** 13795 * Attempts to fix block invalidation by applying build-in validation fixes 13796 * like moving all extra classNames to the className attribute. 13797 * 13798 * @param {WPBlock} block block object. 13799 * @param {import('../registration').WPBlockType} blockType Block type. This is normalize not necessary and 13800 * can be inferred from the block name, 13801 * but it's here for performance reasons. 13802 * 13803 * @return {WPBlock} Fixed block object 13804 */ 13805 function applyBuiltInValidationFixes(block, blockType) { 13806 const updatedBlockAttributes = fixCustomClassname(block.attributes, blockType, block.originalContent); 13807 return { 13808 ...block, 13809 attributes: updatedBlockAttributes 13810 }; 13811 } 13812 13813 ;// ./node_modules/@wordpress/blocks/build-module/api/parser/apply-block-deprecated-versions.js 13814 /** 13815 * Internal dependencies 13816 */ 13817 13818 13819 13820 13821 13822 13823 /** 13824 * Function that takes no arguments and always returns false. 13825 * 13826 * @return {boolean} Always returns false. 13827 */ 13828 function stubFalse() { 13829 return false; 13830 } 13831 13832 /** 13833 * Given a block object, returns a new copy of the block with any applicable 13834 * deprecated migrations applied, or the original block if it was both valid 13835 * and no eligible migrations exist. 13836 * 13837 * @param {import(".").WPBlock} block Parsed and invalid block object. 13838 * @param {import(".").WPRawBlock} rawBlock Raw block object. 13839 * @param {import('../registration').WPBlockType} blockType Block type. This is normalize not necessary and 13840 * can be inferred from the block name, 13841 * but it's here for performance reasons. 13842 * 13843 * @return {import(".").WPBlock} Migrated block object. 13844 */ 13845 function applyBlockDeprecatedVersions(block, rawBlock, blockType) { 13846 const parsedAttributes = rawBlock.attrs; 13847 const { 13848 deprecated: deprecatedDefinitions 13849 } = blockType; 13850 // Bail early if there are no registered deprecations to be handled. 13851 if (!deprecatedDefinitions || !deprecatedDefinitions.length) { 13852 return block; 13853 } 13854 13855 // By design, blocks lack any sort of version tracking. Instead, to process 13856 // outdated content the system operates a queue out of all the defined 13857 // attribute shapes and tries each definition until the input produces a 13858 // valid result. This mechanism seeks to avoid polluting the user-space with 13859 // machine-specific code. An invalid block is thus a block that could not be 13860 // matched successfully with any of the registered deprecation definitions. 13861 for (let i = 0; i < deprecatedDefinitions.length; i++) { 13862 // A block can opt into a migration even if the block is valid by 13863 // defining `isEligible` on its deprecation. If the block is both valid 13864 // and does not opt to migrate, skip. 13865 const { 13866 isEligible = stubFalse 13867 } = deprecatedDefinitions[i]; 13868 if (block.isValid && !isEligible(parsedAttributes, block.innerBlocks, { 13869 blockNode: rawBlock, 13870 block 13871 })) { 13872 continue; 13873 } 13874 13875 // Block type properties which could impact either serialization or 13876 // parsing are not considered in the deprecated block type by default, 13877 // and must be explicitly provided. 13878 const deprecatedBlockType = Object.assign(omit(blockType, DEPRECATED_ENTRY_KEYS), deprecatedDefinitions[i]); 13879 let migratedBlock = { 13880 ...block, 13881 attributes: getBlockAttributes(deprecatedBlockType, block.originalContent, parsedAttributes) 13882 }; 13883 13884 // Ignore the deprecation if it produces a block which is not valid. 13885 let [isValid] = validateBlock(migratedBlock, deprecatedBlockType); 13886 13887 // If the migrated block is not valid initially, try the built-in fixes. 13888 if (!isValid) { 13889 migratedBlock = applyBuiltInValidationFixes(migratedBlock, deprecatedBlockType); 13890 [isValid] = validateBlock(migratedBlock, deprecatedBlockType); 13891 } 13892 13893 // An invalid block does not imply incorrect HTML but the fact block 13894 // source information could be lost on re-serialization. 13895 if (!isValid) { 13896 continue; 13897 } 13898 let migratedInnerBlocks = migratedBlock.innerBlocks; 13899 let migratedAttributes = migratedBlock.attributes; 13900 13901 // A block may provide custom behavior to assign new attributes and/or 13902 // inner blocks. 13903 const { 13904 migrate 13905 } = deprecatedBlockType; 13906 if (migrate) { 13907 let migrated = migrate(migratedAttributes, block.innerBlocks); 13908 if (!Array.isArray(migrated)) { 13909 migrated = [migrated]; 13910 } 13911 [migratedAttributes = parsedAttributes, migratedInnerBlocks = block.innerBlocks] = migrated; 13912 } 13913 block = { 13914 ...block, 13915 attributes: migratedAttributes, 13916 innerBlocks: migratedInnerBlocks, 13917 isValid: true, 13918 validationIssues: [] 13919 }; 13920 } 13921 return block; 13922 } 13923 13924 ;// ./node_modules/@wordpress/blocks/build-module/api/parser/index.js 13925 /* wp:polyfill */ 13926 /** 13927 * WordPress dependencies 13928 */ 13929 13930 13931 13932 /** 13933 * Internal dependencies 13934 */ 13935 13936 13937 13938 13939 13940 13941 13942 13943 13944 13945 /** 13946 * The raw structure of a block includes its attributes, inner 13947 * blocks, and inner HTML. It is important to distinguish inner blocks from 13948 * the HTML content of the block as only the latter is relevant for block 13949 * validation and edit operations. 13950 * 13951 * @typedef WPRawBlock 13952 * 13953 * @property {string=} blockName Block name 13954 * @property {Object=} attrs Block raw or comment attributes. 13955 * @property {string} innerHTML HTML content of the block. 13956 * @property {(string|null)[]} innerContent Content without inner blocks. 13957 * @property {WPRawBlock[]} innerBlocks Inner Blocks. 13958 */ 13959 13960 /** 13961 * Fully parsed block object. 13962 * 13963 * @typedef WPBlock 13964 * 13965 * @property {string} name Block name 13966 * @property {Object} attributes Block raw or comment attributes. 13967 * @property {WPBlock[]} innerBlocks Inner Blocks. 13968 * @property {string} originalContent Original content of the block before validation fixes. 13969 * @property {boolean} isValid Whether the block is valid. 13970 * @property {Object[]} validationIssues Validation issues. 13971 * @property {WPRawBlock} [__unstableBlockSource] Un-processed original copy of block if created through parser. 13972 */ 13973 13974 /** 13975 * @typedef {Object} ParseOptions 13976 * @property {boolean?} __unstableSkipMigrationLogs If a block is migrated from a deprecated version, skip logging the migration details. 13977 * @property {boolean?} __unstableSkipAutop Whether to skip autop when processing freeform content. 13978 */ 13979 13980 /** 13981 * Convert legacy blocks to their canonical form. This function is used 13982 * both in the parser level for previous content and to convert such blocks 13983 * used in Custom Post Types templates. 13984 * 13985 * @param {WPRawBlock} rawBlock 13986 * 13987 * @return {WPRawBlock} The block's name and attributes, changed accordingly if a match was found 13988 */ 13989 function convertLegacyBlocks(rawBlock) { 13990 const [correctName, correctedAttributes] = convertLegacyBlockNameAndAttributes(rawBlock.blockName, rawBlock.attrs); 13991 return { 13992 ...rawBlock, 13993 blockName: correctName, 13994 attrs: correctedAttributes 13995 }; 13996 } 13997 13998 /** 13999 * Normalize the raw block by applying the fallback block name if none given, 14000 * sanitize the parsed HTML... 14001 * 14002 * @param {WPRawBlock} rawBlock The raw block object. 14003 * @param {ParseOptions?} options Extra options for handling block parsing. 14004 * 14005 * @return {WPRawBlock} The normalized block object. 14006 */ 14007 function normalizeRawBlock(rawBlock, options) { 14008 const fallbackBlockName = getFreeformContentHandlerName(); 14009 14010 // If the grammar parsing don't produce any block name, use the freeform block. 14011 const rawBlockName = rawBlock.blockName || getFreeformContentHandlerName(); 14012 const rawAttributes = rawBlock.attrs || {}; 14013 const rawInnerBlocks = rawBlock.innerBlocks || []; 14014 let rawInnerHTML = rawBlock.innerHTML.trim(); 14015 14016 // Fallback content may be upgraded from classic content expecting implicit 14017 // automatic paragraphs, so preserve them. Assumes wpautop is idempotent, 14018 // meaning there are no negative consequences to repeated autop calls. 14019 if (rawBlockName === fallbackBlockName && rawBlockName === 'core/freeform' && !options?.__unstableSkipAutop) { 14020 rawInnerHTML = (0,external_wp_autop_namespaceObject.autop)(rawInnerHTML).trim(); 14021 } 14022 return { 14023 ...rawBlock, 14024 blockName: rawBlockName, 14025 attrs: rawAttributes, 14026 innerHTML: rawInnerHTML, 14027 innerBlocks: rawInnerBlocks 14028 }; 14029 } 14030 14031 /** 14032 * Uses the "unregistered blockType" to create a block object. 14033 * 14034 * @param {WPRawBlock} rawBlock block. 14035 * 14036 * @return {WPRawBlock} The unregistered block object. 14037 */ 14038 function createMissingBlockType(rawBlock) { 14039 const unregisteredFallbackBlock = getUnregisteredTypeHandlerName() || getFreeformContentHandlerName(); 14040 14041 // Preserve undelimited content for use by the unregistered type 14042 // handler. A block node's `innerHTML` isn't enough, as that field only 14043 // carries the block's own HTML and not its nested blocks. 14044 const originalUndelimitedContent = serializeRawBlock(rawBlock, { 14045 isCommentDelimited: false 14046 }); 14047 14048 // Preserve full block content for use by the unregistered type 14049 // handler, block boundaries included. 14050 const originalContent = serializeRawBlock(rawBlock, { 14051 isCommentDelimited: true 14052 }); 14053 return { 14054 blockName: unregisteredFallbackBlock, 14055 attrs: { 14056 originalName: rawBlock.blockName, 14057 originalContent, 14058 originalUndelimitedContent 14059 }, 14060 innerHTML: rawBlock.blockName ? originalContent : rawBlock.innerHTML, 14061 innerBlocks: rawBlock.innerBlocks, 14062 innerContent: rawBlock.innerContent 14063 }; 14064 } 14065 14066 /** 14067 * Validates a block and wraps with validation meta. 14068 * 14069 * The name here is regrettable but `validateBlock` is already taken. 14070 * 14071 * @param {WPBlock} unvalidatedBlock 14072 * @param {import('../registration').WPBlockType} blockType 14073 * @return {WPBlock} validated block, with auto-fixes if initially invalid 14074 */ 14075 function applyBlockValidation(unvalidatedBlock, blockType) { 14076 // Attempt to validate the block. 14077 const [isValid] = validateBlock(unvalidatedBlock, blockType); 14078 if (isValid) { 14079 return { 14080 ...unvalidatedBlock, 14081 isValid, 14082 validationIssues: [] 14083 }; 14084 } 14085 14086 // If the block is invalid, attempt some built-in fixes 14087 // like custom classNames handling. 14088 const fixedBlock = applyBuiltInValidationFixes(unvalidatedBlock, blockType); 14089 // Attempt to validate the block once again after the built-in fixes. 14090 const [isFixedValid, validationIssues] = validateBlock(fixedBlock, blockType); 14091 return { 14092 ...fixedBlock, 14093 isValid: isFixedValid, 14094 validationIssues 14095 }; 14096 } 14097 14098 /** 14099 * Given a raw block returned by grammar parsing, returns a fully parsed block. 14100 * 14101 * @param {WPRawBlock} rawBlock The raw block object. 14102 * @param {ParseOptions} options Extra options for handling block parsing. 14103 * 14104 * @return {WPBlock | undefined} Fully parsed block. 14105 */ 14106 function parseRawBlock(rawBlock, options) { 14107 let normalizedBlock = normalizeRawBlock(rawBlock, options); 14108 14109 // During the lifecycle of the project, we renamed some old blocks 14110 // and transformed others to new blocks. To avoid breaking existing content, 14111 // we added this function to properly parse the old content. 14112 normalizedBlock = convertLegacyBlocks(normalizedBlock); 14113 14114 // Try finding the type for known block name. 14115 let blockType = getBlockType(normalizedBlock.blockName); 14116 14117 // If not blockType is found for the specified name, fallback to the "unregisteredBlockType". 14118 if (!blockType) { 14119 normalizedBlock = createMissingBlockType(normalizedBlock); 14120 blockType = getBlockType(normalizedBlock.blockName); 14121 } 14122 14123 // If it's an empty freeform block or there's no blockType (no missing block handler) 14124 // Then, just ignore the block. 14125 // It might be a good idea to throw a warning here. 14126 // TODO: I'm unsure about the unregisteredFallbackBlock check, 14127 // it might ignore some dynamic unregistered third party blocks wrongly. 14128 const isFallbackBlock = normalizedBlock.blockName === getFreeformContentHandlerName() || normalizedBlock.blockName === getUnregisteredTypeHandlerName(); 14129 if (!blockType || !normalizedBlock.innerHTML && isFallbackBlock) { 14130 return; 14131 } 14132 14133 // Parse inner blocks recursively. 14134 const parsedInnerBlocks = normalizedBlock.innerBlocks.map(innerBlock => parseRawBlock(innerBlock, options)) 14135 // See https://github.com/WordPress/gutenberg/pull/17164. 14136 .filter(innerBlock => !!innerBlock); 14137 14138 // Get the fully parsed block. 14139 const parsedBlock = createBlock(normalizedBlock.blockName, getBlockAttributes(blockType, normalizedBlock.innerHTML, normalizedBlock.attrs), parsedInnerBlocks); 14140 parsedBlock.originalContent = normalizedBlock.innerHTML; 14141 const validatedBlock = applyBlockValidation(parsedBlock, blockType); 14142 const { 14143 validationIssues 14144 } = validatedBlock; 14145 14146 // Run the block deprecation and migrations. 14147 // This is performed on both invalid and valid blocks because 14148 // migration using the `migrate` functions should run even 14149 // if the output is deemed valid. 14150 const updatedBlock = applyBlockDeprecatedVersions(validatedBlock, normalizedBlock, blockType); 14151 if (!updatedBlock.isValid) { 14152 // Preserve the original unprocessed version of the block 14153 // that we received (no fixes, no deprecations) so that 14154 // we can save it as close to exactly the same way as 14155 // we loaded it. This is important to avoid corruption 14156 // and data loss caused by block implementations trying 14157 // to process data that isn't fully recognized. 14158 updatedBlock.__unstableBlockSource = rawBlock; 14159 } 14160 if (!validatedBlock.isValid && updatedBlock.isValid && !options?.__unstableSkipMigrationLogs) { 14161 /* eslint-disable no-console */ 14162 console.groupCollapsed('Updated Block: %s', blockType.name); 14163 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); 14164 console.groupEnd(); 14165 /* eslint-enable no-console */ 14166 } else if (!validatedBlock.isValid && !updatedBlock.isValid) { 14167 validationIssues.forEach(({ 14168 log, 14169 args 14170 }) => log(...args)); 14171 } 14172 return updatedBlock; 14173 } 14174 14175 /** 14176 * Utilizes an optimized token-driven parser based on the Gutenberg grammar spec 14177 * defined through a parsing expression grammar to take advantage of the regular 14178 * cadence provided by block delimiters -- composed syntactically through HTML 14179 * comments -- which, given a general HTML document as an input, returns a block 14180 * list array representation. 14181 * 14182 * This is a recursive-descent parser that scans linearly once through the input 14183 * document. Instead of directly recursing it utilizes a trampoline mechanism to 14184 * prevent stack overflow. This initial pass is mainly interested in separating 14185 * and isolating the blocks serialized in the document and manifestly not in the 14186 * content within the blocks. 14187 * 14188 * @see 14189 * https://developer.wordpress.org/block-editor/packages/packages-block-serialization-default-parser/ 14190 * 14191 * @param {string} content The post content. 14192 * @param {ParseOptions} options Extra options for handling block parsing. 14193 * 14194 * @return {Array} Block list. 14195 */ 14196 function parser_parse(content, options) { 14197 return (0,external_wp_blockSerializationDefaultParser_namespaceObject.parse)(content).reduce((accumulator, rawBlock) => { 14198 const block = parseRawBlock(rawBlock, options); 14199 if (block) { 14200 accumulator.push(block); 14201 } 14202 return accumulator; 14203 }, []); 14204 } 14205 14206 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/get-raw-transforms.js 14207 /* wp:polyfill */ 14208 /** 14209 * Internal dependencies 14210 */ 14211 14212 function getRawTransforms() { 14213 return getBlockTransforms('from').filter(({ 14214 type 14215 }) => type === 'raw').map(transform => { 14216 return transform.isMatch ? transform : { 14217 ...transform, 14218 isMatch: node => transform.selector && node.matches(transform.selector) 14219 }; 14220 }); 14221 } 14222 14223 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/html-to-blocks.js 14224 /* wp:polyfill */ 14225 /** 14226 * WordPress dependencies 14227 */ 14228 14229 14230 /** 14231 * Internal dependencies 14232 */ 14233 14234 14235 14236 14237 14238 /** 14239 * Converts HTML directly to blocks. Looks for a matching transform for each 14240 * top-level tag. The HTML should be filtered to not have any text between 14241 * top-level tags and formatted in a way that blocks can handle the HTML. 14242 * 14243 * @param {string} html HTML to convert. 14244 * @param {Function} handler The handler calling htmlToBlocks: either rawHandler 14245 * or pasteHandler. 14246 * 14247 * @return {Array} An array of blocks. 14248 */ 14249 function htmlToBlocks(html, handler) { 14250 const doc = document.implementation.createHTMLDocument(''); 14251 doc.body.innerHTML = html; 14252 return Array.from(doc.body.children).flatMap(node => { 14253 const rawTransform = findTransform(getRawTransforms(), ({ 14254 isMatch 14255 }) => isMatch(node)); 14256 if (!rawTransform) { 14257 // Until the HTML block is supported in the native version, we'll parse it 14258 // instead of creating the block to generate it as an unsupported block. 14259 if (external_wp_element_namespaceObject.Platform.isNative) { 14260 return parser_parse(`<!-- wp:html -->$node.outerHTML}<!-- /wp:html -->`); 14261 } 14262 return createBlock( 14263 // Should not be hardcoded. 14264 'core/html', getBlockAttributes('core/html', node.outerHTML)); 14265 } 14266 const { 14267 transform, 14268 blockName 14269 } = rawTransform; 14270 if (transform) { 14271 const block = transform(node, handler); 14272 if (node.hasAttribute('class')) { 14273 block.attributes.className = node.getAttribute('class'); 14274 } 14275 return block; 14276 } 14277 return createBlock(blockName, getBlockAttributes(blockName, node.outerHTML)); 14278 }); 14279 } 14280 14281 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/normalise-blocks.js 14282 /** 14283 * WordPress dependencies 14284 */ 14285 14286 function normaliseBlocks(HTML, options = {}) { 14287 const decuDoc = document.implementation.createHTMLDocument(''); 14288 const accuDoc = document.implementation.createHTMLDocument(''); 14289 const decu = decuDoc.body; 14290 const accu = accuDoc.body; 14291 decu.innerHTML = HTML; 14292 while (decu.firstChild) { 14293 const node = decu.firstChild; 14294 14295 // Text nodes: wrap in a paragraph, or append to previous. 14296 if (node.nodeType === node.TEXT_NODE) { 14297 if ((0,external_wp_dom_namespaceObject.isEmpty)(node)) { 14298 decu.removeChild(node); 14299 } else { 14300 if (!accu.lastChild || accu.lastChild.nodeName !== 'P') { 14301 accu.appendChild(accuDoc.createElement('P')); 14302 } 14303 accu.lastChild.appendChild(node); 14304 } 14305 // Element nodes. 14306 } else if (node.nodeType === node.ELEMENT_NODE) { 14307 // BR nodes: create a new paragraph on double, or append to previous. 14308 if (node.nodeName === 'BR') { 14309 if (node.nextSibling && node.nextSibling.nodeName === 'BR') { 14310 accu.appendChild(accuDoc.createElement('P')); 14311 decu.removeChild(node.nextSibling); 14312 } 14313 14314 // Don't append to an empty paragraph. 14315 if (accu.lastChild && accu.lastChild.nodeName === 'P' && accu.lastChild.hasChildNodes()) { 14316 accu.lastChild.appendChild(node); 14317 } else { 14318 decu.removeChild(node); 14319 } 14320 } else if (node.nodeName === 'P') { 14321 // Only append non-empty paragraph nodes. 14322 if ((0,external_wp_dom_namespaceObject.isEmpty)(node) && !options.raw) { 14323 decu.removeChild(node); 14324 } else { 14325 accu.appendChild(node); 14326 } 14327 } else if ((0,external_wp_dom_namespaceObject.isPhrasingContent)(node)) { 14328 if (!accu.lastChild || accu.lastChild.nodeName !== 'P') { 14329 accu.appendChild(accuDoc.createElement('P')); 14330 } 14331 accu.lastChild.appendChild(node); 14332 } else { 14333 accu.appendChild(node); 14334 } 14335 } else { 14336 decu.removeChild(node); 14337 } 14338 } 14339 return accu.innerHTML; 14340 } 14341 14342 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/special-comment-converter.js 14343 /* wp:polyfill */ 14344 /** 14345 * WordPress dependencies 14346 */ 14347 14348 14349 /** 14350 * Looks for `<!--nextpage-->` and `<!--more-->` comments and 14351 * replaces them with a custom element representing a future block. 14352 * 14353 * The custom element is a way to bypass the rest of the `raw-handling` 14354 * transforms, which would eliminate other kinds of node with which to carry 14355 * `<!--more-->`'s data: nodes with `data` attributes, empty paragraphs, etc. 14356 * 14357 * The custom element is then expected to be recognized by any registered 14358 * block's `raw` transform. 14359 * 14360 * @param {Node} node The node to be processed. 14361 * @param {Document} doc The document of the node. 14362 * @return {void} 14363 */ 14364 function specialCommentConverter(node, doc) { 14365 if (node.nodeType !== node.COMMENT_NODE) { 14366 return; 14367 } 14368 if (node.nodeValue !== 'nextpage' && node.nodeValue.indexOf('more') !== 0) { 14369 return; 14370 } 14371 const block = special_comment_converter_createBlock(node, doc); 14372 14373 // If our `<!--more-->` comment is in the middle of a paragraph, we should 14374 // split the paragraph in two and insert the more block in between. If it's 14375 // inside an empty paragraph, we should still move it out of the paragraph 14376 // and remove the paragraph. If there's no paragraph, fall back to simply 14377 // replacing the comment. 14378 if (!node.parentNode || node.parentNode.nodeName !== 'P') { 14379 (0,external_wp_dom_namespaceObject.replace)(node, block); 14380 } else { 14381 const childNodes = Array.from(node.parentNode.childNodes); 14382 const nodeIndex = childNodes.indexOf(node); 14383 const wrapperNode = node.parentNode.parentNode || doc.body; 14384 const paragraphBuilder = (acc, child) => { 14385 if (!acc) { 14386 acc = doc.createElement('p'); 14387 } 14388 acc.appendChild(child); 14389 return acc; 14390 }; 14391 14392 // Split the original parent node and insert our more block 14393 [childNodes.slice(0, nodeIndex).reduce(paragraphBuilder, null), block, childNodes.slice(nodeIndex + 1).reduce(paragraphBuilder, null)].forEach(element => element && wrapperNode.insertBefore(element, node.parentNode)); 14394 14395 // Remove the old parent paragraph 14396 (0,external_wp_dom_namespaceObject.remove)(node.parentNode); 14397 } 14398 } 14399 function special_comment_converter_createBlock(commentNode, doc) { 14400 if (commentNode.nodeValue === 'nextpage') { 14401 return createNextpage(doc); 14402 } 14403 14404 // Grab any custom text in the comment. 14405 const customText = commentNode.nodeValue.slice(4).trim(); 14406 14407 /* 14408 * When a `<!--more-->` comment is found, we need to look for any 14409 * `<!--noteaser-->` sibling, but it may not be a direct sibling 14410 * (whitespace typically lies in between) 14411 */ 14412 let sibling = commentNode; 14413 let noTeaser = false; 14414 while (sibling = sibling.nextSibling) { 14415 if (sibling.nodeType === sibling.COMMENT_NODE && sibling.nodeValue === 'noteaser') { 14416 noTeaser = true; 14417 (0,external_wp_dom_namespaceObject.remove)(sibling); 14418 break; 14419 } 14420 } 14421 return createMore(customText, noTeaser, doc); 14422 } 14423 function createMore(customText, noTeaser, doc) { 14424 const node = doc.createElement('wp-block'); 14425 node.dataset.block = 'core/more'; 14426 if (customText) { 14427 node.dataset.customText = customText; 14428 } 14429 if (noTeaser) { 14430 // "Boolean" data attribute. 14431 node.dataset.noTeaser = ''; 14432 } 14433 return node; 14434 } 14435 function createNextpage(doc) { 14436 const node = doc.createElement('wp-block'); 14437 node.dataset.block = 'core/nextpage'; 14438 return node; 14439 } 14440 14441 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/list-reducer.js 14442 /* wp:polyfill */ 14443 /** 14444 * WordPress dependencies 14445 */ 14446 14447 function isList(node) { 14448 return node.nodeName === 'OL' || node.nodeName === 'UL'; 14449 } 14450 function shallowTextContent(element) { 14451 return Array.from(element.childNodes).map(({ 14452 nodeValue = '' 14453 }) => nodeValue).join(''); 14454 } 14455 function listReducer(node) { 14456 if (!isList(node)) { 14457 return; 14458 } 14459 const list = node; 14460 const prevElement = node.previousElementSibling; 14461 14462 // Merge with previous list if: 14463 // * There is a previous list of the same type. 14464 // * There is only one list item. 14465 if (prevElement && prevElement.nodeName === node.nodeName && list.children.length === 1) { 14466 // Move all child nodes, including any text nodes, if any. 14467 while (list.firstChild) { 14468 prevElement.appendChild(list.firstChild); 14469 } 14470 list.parentNode.removeChild(list); 14471 } 14472 const parentElement = node.parentNode; 14473 14474 // Nested list with empty parent item. 14475 if (parentElement && parentElement.nodeName === 'LI' && parentElement.children.length === 1 && !/\S/.test(shallowTextContent(parentElement))) { 14476 const parentListItem = parentElement; 14477 const prevListItem = parentListItem.previousElementSibling; 14478 const parentList = parentListItem.parentNode; 14479 if (prevListItem) { 14480 prevListItem.appendChild(list); 14481 parentList.removeChild(parentListItem); 14482 } 14483 } 14484 14485 // Invalid: OL/UL > OL/UL. 14486 if (parentElement && isList(parentElement)) { 14487 const prevListItem = node.previousElementSibling; 14488 if (prevListItem) { 14489 prevListItem.appendChild(node); 14490 } else { 14491 (0,external_wp_dom_namespaceObject.unwrap)(node); 14492 } 14493 } 14494 } 14495 14496 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/blockquote-normaliser.js 14497 /** 14498 * Internal dependencies 14499 */ 14500 14501 function blockquoteNormaliser(options) { 14502 return node => { 14503 if (node.nodeName !== 'BLOCKQUOTE') { 14504 return; 14505 } 14506 node.innerHTML = normaliseBlocks(node.innerHTML, options); 14507 }; 14508 } 14509 14510 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/figure-content-reducer.js 14511 /** 14512 * WordPress dependencies 14513 */ 14514 14515 14516 /** 14517 * Whether or not the given node is figure content. 14518 * 14519 * @param {Node} node The node to check. 14520 * @param {Object} schema The schema to use. 14521 * 14522 * @return {boolean} True if figure content, false if not. 14523 */ 14524 function isFigureContent(node, schema) { 14525 var _schema$figure$childr; 14526 const tag = node.nodeName.toLowerCase(); 14527 14528 // We are looking for tags that can be a child of the figure tag, excluding 14529 // `figcaption` and any phrasing content. 14530 if (tag === 'figcaption' || (0,external_wp_dom_namespaceObject.isTextContent)(node)) { 14531 return false; 14532 } 14533 return tag in ((_schema$figure$childr = schema?.figure?.children) !== null && _schema$figure$childr !== void 0 ? _schema$figure$childr : {}); 14534 } 14535 14536 /** 14537 * Whether or not the given node can have an anchor. 14538 * 14539 * @param {Node} node The node to check. 14540 * @param {Object} schema The schema to use. 14541 * 14542 * @return {boolean} True if it can, false if not. 14543 */ 14544 function canHaveAnchor(node, schema) { 14545 var _schema$figure$childr2; 14546 const tag = node.nodeName.toLowerCase(); 14547 return tag in ((_schema$figure$childr2 = schema?.figure?.children?.a?.children) !== null && _schema$figure$childr2 !== void 0 ? _schema$figure$childr2 : {}); 14548 } 14549 14550 /** 14551 * Wraps the given element in a figure element. 14552 * 14553 * @param {Element} element The element to wrap. 14554 * @param {Element} beforeElement The element before which to place the figure. 14555 */ 14556 function wrapFigureContent(element, beforeElement = element) { 14557 const figure = element.ownerDocument.createElement('figure'); 14558 beforeElement.parentNode.insertBefore(figure, beforeElement); 14559 figure.appendChild(element); 14560 } 14561 14562 /** 14563 * This filter takes figure content out of paragraphs, wraps it in a figure 14564 * element, and moves any anchors with it if needed. 14565 * 14566 * @param {Node} node The node to filter. 14567 * @param {Document} doc The document of the node. 14568 * @param {Object} schema The schema to use. 14569 * 14570 * @return {void} 14571 */ 14572 function figureContentReducer(node, doc, schema) { 14573 if (!isFigureContent(node, schema)) { 14574 return; 14575 } 14576 let nodeToInsert = node; 14577 const parentNode = node.parentNode; 14578 14579 // If the figure content can have an anchor and its parent is an anchor with 14580 // only the figure content, take the anchor out instead of just the content. 14581 if (canHaveAnchor(node, schema) && parentNode.nodeName === 'A' && parentNode.childNodes.length === 1) { 14582 nodeToInsert = node.parentNode; 14583 } 14584 const wrapper = nodeToInsert.closest('p,div'); 14585 14586 // If wrapped in a paragraph or div, only extract if it's aligned or if 14587 // there is no text content. 14588 // Otherwise, if directly at the root, wrap in a figure element. 14589 if (wrapper) { 14590 // In jsdom-jscore, 'node.classList' can be undefined. 14591 // In this case, default to extract as it offers a better UI experience on mobile. 14592 if (!node.classList) { 14593 wrapFigureContent(nodeToInsert, wrapper); 14594 } else if (node.classList.contains('alignright') || node.classList.contains('alignleft') || node.classList.contains('aligncenter') || !wrapper.textContent.trim()) { 14595 wrapFigureContent(nodeToInsert, wrapper); 14596 } 14597 } else { 14598 wrapFigureContent(nodeToInsert); 14599 } 14600 } 14601 14602 ;// external ["wp","shortcode"] 14603 const external_wp_shortcode_namespaceObject = window["wp"]["shortcode"]; 14604 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/shortcode-converter.js 14605 /* wp:polyfill */ 14606 /** 14607 * WordPress dependencies 14608 */ 14609 14610 14611 /** 14612 * Internal dependencies 14613 */ 14614 14615 14616 14617 14618 const castArray = maybeArray => Array.isArray(maybeArray) ? maybeArray : [maybeArray]; 14619 const beforeLineRegexp = /(\n|<p>)\s*$/; 14620 const afterLineRegexp = /^\s*(\n|<\/p>)/; 14621 function segmentHTMLToShortcodeBlock(HTML, lastIndex = 0, excludedBlockNames = []) { 14622 // Get all matches. 14623 const transformsFrom = getBlockTransforms('from'); 14624 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))); 14625 if (!transformation) { 14626 return [HTML]; 14627 } 14628 const transformTags = castArray(transformation.tag); 14629 const transformTag = transformTags.find(tag => (0,external_wp_shortcode_namespaceObject.regexp)(tag).test(HTML)); 14630 let match; 14631 const previousIndex = lastIndex; 14632 if (match = (0,external_wp_shortcode_namespaceObject.next)(transformTag, HTML, lastIndex)) { 14633 lastIndex = match.index + match.content.length; 14634 const beforeHTML = HTML.substr(0, match.index); 14635 const afterHTML = HTML.substr(lastIndex); 14636 14637 // If the shortcode content does not contain HTML and the shortcode is 14638 // not on a new line (or in paragraph from Markdown converter), 14639 // consider the shortcode as inline text, and thus skip conversion for 14640 // this segment. 14641 if (!match.shortcode.content?.includes('<') && !(beforeLineRegexp.test(beforeHTML) && afterLineRegexp.test(afterHTML))) { 14642 return segmentHTMLToShortcodeBlock(HTML, lastIndex); 14643 } 14644 14645 // If a transformation's `isMatch` predicate fails for the inbound 14646 // shortcode, try again by excluding the current block type. 14647 // 14648 // This is the only call to `segmentHTMLToShortcodeBlock` that should 14649 // ever carry over `excludedBlockNames`. Other calls in the module 14650 // should skip that argument as a way to reset the exclusion state, so 14651 // that one `isMatch` fail in an HTML fragment doesn't prevent any 14652 // valid matches in subsequent fragments. 14653 if (transformation.isMatch && !transformation.isMatch(match.shortcode.attrs)) { 14654 return segmentHTMLToShortcodeBlock(HTML, previousIndex, [...excludedBlockNames, transformation.blockName]); 14655 } 14656 let blocks = []; 14657 if (typeof transformation.transform === 'function') { 14658 // Passing all of `match` as second argument is intentionally broad 14659 // but shouldn't be too relied upon. 14660 // 14661 // See: https://github.com/WordPress/gutenberg/pull/3610#discussion_r152546926 14662 blocks = [].concat(transformation.transform(match.shortcode.attrs, match)); 14663 14664 // Applying the built-in fixes can enhance the attributes with missing content like "className". 14665 blocks = blocks.map(block => { 14666 block.originalContent = match.shortcode.content; 14667 return applyBuiltInValidationFixes(block, getBlockType(block.name)); 14668 }); 14669 } else { 14670 const attributes = Object.fromEntries(Object.entries(transformation.attributes).filter(([, schema]) => schema.shortcode) 14671 // Passing all of `match` as second argument is intentionally broad 14672 // but shouldn't be too relied upon. 14673 // 14674 // See: https://github.com/WordPress/gutenberg/pull/3610#discussion_r152546926 14675 .map(([key, schema]) => [key, schema.shortcode(match.shortcode.attrs, match)])); 14676 const blockType = getBlockType(transformation.blockName); 14677 if (!blockType) { 14678 return [HTML]; 14679 } 14680 const transformationBlockType = { 14681 ...blockType, 14682 attributes: transformation.attributes 14683 }; 14684 let block = createBlock(transformation.blockName, getBlockAttributes(transformationBlockType, match.shortcode.content, attributes)); 14685 14686 // Applying the built-in fixes can enhance the attributes with missing content like "className". 14687 block.originalContent = match.shortcode.content; 14688 block = applyBuiltInValidationFixes(block, transformationBlockType); 14689 blocks = [block]; 14690 } 14691 return [...segmentHTMLToShortcodeBlock(beforeHTML.replace(beforeLineRegexp, '')), ...blocks, ...segmentHTMLToShortcodeBlock(afterHTML.replace(afterLineRegexp, ''))]; 14692 } 14693 return [HTML]; 14694 } 14695 /* harmony default export */ const shortcode_converter = (segmentHTMLToShortcodeBlock); 14696 14697 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/utils.js 14698 /* wp:polyfill */ 14699 /** 14700 * WordPress dependencies 14701 */ 14702 14703 14704 /** 14705 * Internal dependencies 14706 */ 14707 14708 14709 function getBlockContentSchemaFromTransforms(transforms, context) { 14710 const phrasingContentSchema = (0,external_wp_dom_namespaceObject.getPhrasingContentSchema)(context); 14711 const schemaArgs = { 14712 phrasingContentSchema, 14713 isPaste: context === 'paste' 14714 }; 14715 const schemas = transforms.map(({ 14716 isMatch, 14717 blockName, 14718 schema 14719 }) => { 14720 const hasAnchorSupport = hasBlockSupport(blockName, 'anchor'); 14721 schema = typeof schema === 'function' ? schema(schemaArgs) : schema; 14722 14723 // If the block does not has anchor support and the transform does not 14724 // provides an isMatch we can return the schema right away. 14725 if (!hasAnchorSupport && !isMatch) { 14726 return schema; 14727 } 14728 if (!schema) { 14729 return {}; 14730 } 14731 return Object.fromEntries(Object.entries(schema).map(([key, value]) => { 14732 let attributes = value.attributes || []; 14733 // If the block supports the "anchor" functionality, it needs to keep its ID attribute. 14734 if (hasAnchorSupport) { 14735 attributes = [...attributes, 'id']; 14736 } 14737 return [key, { 14738 ...value, 14739 attributes, 14740 isMatch: isMatch ? isMatch : undefined 14741 }]; 14742 })); 14743 }); 14744 function mergeTagNameSchemaProperties(objValue, srcValue, key) { 14745 switch (key) { 14746 case 'children': 14747 { 14748 if (objValue === '*' || srcValue === '*') { 14749 return '*'; 14750 } 14751 return { 14752 ...objValue, 14753 ...srcValue 14754 }; 14755 } 14756 case 'attributes': 14757 case 'require': 14758 { 14759 return [...(objValue || []), ...(srcValue || [])]; 14760 } 14761 case 'isMatch': 14762 { 14763 // If one of the values being merge is undefined (matches everything), 14764 // the result of the merge will be undefined. 14765 if (!objValue || !srcValue) { 14766 return undefined; 14767 } 14768 // When merging two isMatch functions, the result is a new function 14769 // that returns if one of the source functions returns true. 14770 return (...args) => { 14771 return objValue(...args) || srcValue(...args); 14772 }; 14773 } 14774 } 14775 } 14776 14777 // A tagName schema is an object with children, attributes, require, and 14778 // isMatch properties. 14779 function mergeTagNameSchemas(a, b) { 14780 for (const key in b) { 14781 a[key] = a[key] ? mergeTagNameSchemaProperties(a[key], b[key], key) : { 14782 ...b[key] 14783 }; 14784 } 14785 return a; 14786 } 14787 14788 // A schema is an object with tagName schemas by tag name. 14789 function mergeSchemas(a, b) { 14790 for (const key in b) { 14791 a[key] = a[key] ? mergeTagNameSchemas(a[key], b[key]) : { 14792 ...b[key] 14793 }; 14794 } 14795 return a; 14796 } 14797 return schemas.reduce(mergeSchemas, {}); 14798 } 14799 14800 /** 14801 * Gets the block content schema, which is extracted and merged from all 14802 * registered blocks with raw transforms. 14803 * 14804 * @param {string} context Set to "paste" when in paste context, where the 14805 * schema is more strict. 14806 * 14807 * @return {Object} A complete block content schema. 14808 */ 14809 function getBlockContentSchema(context) { 14810 return getBlockContentSchemaFromTransforms(getRawTransforms(), context); 14811 } 14812 14813 /** 14814 * Checks whether HTML can be considered plain text. That is, it does not contain 14815 * any elements that are not line breaks. 14816 * 14817 * @param {string} HTML The HTML to check. 14818 * 14819 * @return {boolean} Whether the HTML can be considered plain text. 14820 */ 14821 function isPlain(HTML) { 14822 return !/<(?!br[ />])/i.test(HTML); 14823 } 14824 14825 /** 14826 * Given node filters, deeply filters and mutates a NodeList. 14827 * 14828 * @param {NodeList} nodeList The nodeList to filter. 14829 * @param {Array} filters An array of functions that can mutate with the provided node. 14830 * @param {Document} doc The document of the nodeList. 14831 * @param {Object} schema The schema to use. 14832 */ 14833 function deepFilterNodeList(nodeList, filters, doc, schema) { 14834 Array.from(nodeList).forEach(node => { 14835 deepFilterNodeList(node.childNodes, filters, doc, schema); 14836 filters.forEach(item => { 14837 // Make sure the node is still attached to the document. 14838 if (!doc.contains(node)) { 14839 return; 14840 } 14841 item(node, doc, schema); 14842 }); 14843 }); 14844 } 14845 14846 /** 14847 * Given node filters, deeply filters HTML tags. 14848 * Filters from the deepest nodes to the top. 14849 * 14850 * @param {string} HTML The HTML to filter. 14851 * @param {Array} filters An array of functions that can mutate with the provided node. 14852 * @param {Object} schema The schema to use. 14853 * 14854 * @return {string} The filtered HTML. 14855 */ 14856 function deepFilterHTML(HTML, filters = [], schema) { 14857 const doc = document.implementation.createHTMLDocument(''); 14858 doc.body.innerHTML = HTML; 14859 deepFilterNodeList(doc.body.childNodes, filters, doc, schema); 14860 return doc.body.innerHTML; 14861 } 14862 14863 /** 14864 * Gets a sibling within text-level context. 14865 * 14866 * @param {Element} node The subject node. 14867 * @param {string} which "next" or "previous". 14868 */ 14869 function getSibling(node, which) { 14870 const sibling = node[`$which}Sibling`]; 14871 if (sibling && (0,external_wp_dom_namespaceObject.isPhrasingContent)(sibling)) { 14872 return sibling; 14873 } 14874 const { 14875 parentNode 14876 } = node; 14877 if (!parentNode || !(0,external_wp_dom_namespaceObject.isPhrasingContent)(parentNode)) { 14878 return; 14879 } 14880 return getSibling(parentNode, which); 14881 } 14882 14883 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/index.js 14884 /* wp:polyfill */ 14885 /** 14886 * WordPress dependencies 14887 */ 14888 14889 14890 14891 /** 14892 * Internal dependencies 14893 */ 14894 14895 14896 14897 14898 14899 14900 14901 14902 14903 14904 function deprecatedGetPhrasingContentSchema(context) { 14905 external_wp_deprecated_default()('wp.blocks.getPhrasingContentSchema', { 14906 since: '5.6', 14907 alternative: 'wp.dom.getPhrasingContentSchema' 14908 }); 14909 return (0,external_wp_dom_namespaceObject.getPhrasingContentSchema)(context); 14910 } 14911 14912 /** 14913 * Converts an HTML string to known blocks. 14914 * 14915 * @param {Object} $1 14916 * @param {string} $1.HTML The HTML to convert. 14917 * 14918 * @return {Array} A list of blocks. 14919 */ 14920 function rawHandler({ 14921 HTML = '' 14922 }) { 14923 // If we detect block delimiters, parse entirely as blocks. 14924 if (HTML.indexOf('<!-- wp:') !== -1) { 14925 const parseResult = parser_parse(HTML); 14926 const isSingleFreeFormBlock = parseResult.length === 1 && parseResult[0].name === 'core/freeform'; 14927 if (!isSingleFreeFormBlock) { 14928 return parseResult; 14929 } 14930 } 14931 14932 // An array of HTML strings and block objects. The blocks replace matched 14933 // shortcodes. 14934 const pieces = shortcode_converter(HTML); 14935 const blockContentSchema = getBlockContentSchema(); 14936 return pieces.map(piece => { 14937 // Already a block from shortcode. 14938 if (typeof piece !== 'string') { 14939 return piece; 14940 } 14941 14942 // These filters are essential for some blocks to be able to transform 14943 // from raw HTML. These filters move around some content or add 14944 // additional tags, they do not remove any content. 14945 const filters = [ 14946 // Needed to adjust invalid lists. 14947 listReducer, 14948 // Needed to create more and nextpage blocks. 14949 specialCommentConverter, 14950 // Needed to create media blocks. 14951 figureContentReducer, 14952 // Needed to create the quote block, which cannot handle text 14953 // without wrapper paragraphs. 14954 blockquoteNormaliser({ 14955 raw: true 14956 })]; 14957 piece = deepFilterHTML(piece, filters, blockContentSchema); 14958 piece = normaliseBlocks(piece, { 14959 raw: true 14960 }); 14961 return htmlToBlocks(piece, rawHandler); 14962 }).flat().filter(Boolean); 14963 } 14964 14965 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/comment-remover.js 14966 /** 14967 * WordPress dependencies 14968 */ 14969 14970 14971 /** 14972 * Looks for comments, and removes them. 14973 * 14974 * @param {Node} node The node to be processed. 14975 * @return {void} 14976 */ 14977 function commentRemover(node) { 14978 if (node.nodeType === node.COMMENT_NODE) { 14979 (0,external_wp_dom_namespaceObject.remove)(node); 14980 } 14981 } 14982 14983 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/is-inline-content.js 14984 /* wp:polyfill */ 14985 /** 14986 * WordPress dependencies 14987 */ 14988 14989 14990 /** 14991 * Checks if the given node should be considered inline content, optionally 14992 * depending on a context tag. 14993 * 14994 * @param {Node} node Node name. 14995 * @param {string} contextTag Tag name. 14996 * 14997 * @return {boolean} True if the node is inline content, false if nohe. 14998 */ 14999 function isInline(node, contextTag) { 15000 if ((0,external_wp_dom_namespaceObject.isTextContent)(node)) { 15001 return true; 15002 } 15003 if (!contextTag) { 15004 return false; 15005 } 15006 const tag = node.nodeName.toLowerCase(); 15007 const inlineAllowedTagGroups = [['ul', 'li', 'ol'], ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']]; 15008 return inlineAllowedTagGroups.some(tagGroup => [tag, contextTag].filter(t => !tagGroup.includes(t)).length === 0); 15009 } 15010 function deepCheck(nodes, contextTag) { 15011 return nodes.every(node => isInline(node, contextTag) && deepCheck(Array.from(node.children), contextTag)); 15012 } 15013 function isDoubleBR(node) { 15014 return node.nodeName === 'BR' && node.previousSibling && node.previousSibling.nodeName === 'BR'; 15015 } 15016 function isInlineContent(HTML, contextTag) { 15017 const doc = document.implementation.createHTMLDocument(''); 15018 doc.body.innerHTML = HTML; 15019 const nodes = Array.from(doc.body.children); 15020 return !nodes.some(isDoubleBR) && deepCheck(nodes, contextTag); 15021 } 15022 15023 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/phrasing-content-reducer.js 15024 /** 15025 * WordPress dependencies 15026 */ 15027 15028 function phrasingContentReducer(node, doc) { 15029 // In jsdom-jscore, 'node.style' can be null. 15030 // TODO: Explore fixing this by patching jsdom-jscore. 15031 if (node.nodeName === 'SPAN' && node.style) { 15032 const { 15033 fontWeight, 15034 fontStyle, 15035 textDecorationLine, 15036 textDecoration, 15037 verticalAlign 15038 } = node.style; 15039 if (fontWeight === 'bold' || fontWeight === '700') { 15040 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('strong'), node); 15041 } 15042 if (fontStyle === 'italic') { 15043 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('em'), node); 15044 } 15045 15046 // Some DOM implementations (Safari, JSDom) don't support 15047 // style.textDecorationLine, so we check style.textDecoration as a 15048 // fallback. 15049 if (textDecorationLine === 'line-through' || textDecoration.includes('line-through')) { 15050 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('s'), node); 15051 } 15052 if (verticalAlign === 'super') { 15053 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('sup'), node); 15054 } else if (verticalAlign === 'sub') { 15055 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('sub'), node); 15056 } 15057 } else if (node.nodeName === 'B') { 15058 node = (0,external_wp_dom_namespaceObject.replaceTag)(node, 'strong'); 15059 } else if (node.nodeName === 'I') { 15060 node = (0,external_wp_dom_namespaceObject.replaceTag)(node, 'em'); 15061 } else if (node.nodeName === 'A') { 15062 // In jsdom-jscore, 'node.target' can be null. 15063 // TODO: Explore fixing this by patching jsdom-jscore. 15064 if (node.target && node.target.toLowerCase() === '_blank') { 15065 node.rel = 'noreferrer noopener'; 15066 } else { 15067 node.removeAttribute('target'); 15068 node.removeAttribute('rel'); 15069 } 15070 15071 // Saves anchor elements name attribute as id 15072 if (node.name && !node.id) { 15073 node.id = node.name; 15074 } 15075 15076 // Keeps id only if there is an internal link pointing to it 15077 if (node.id && !node.ownerDocument.querySelector(`[href="#$node.id}"]`)) { 15078 node.removeAttribute('id'); 15079 } 15080 } 15081 } 15082 15083 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/head-remover.js 15084 function headRemover(node) { 15085 if (node.nodeName !== 'SCRIPT' && node.nodeName !== 'NOSCRIPT' && node.nodeName !== 'TEMPLATE' && node.nodeName !== 'STYLE') { 15086 return; 15087 } 15088 node.parentNode.removeChild(node); 15089 } 15090 15091 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/ms-list-ignore.js 15092 /* wp:polyfill */ 15093 /** 15094 * Looks for comments, and removes them. 15095 * 15096 * @param {Node} node The node to be processed. 15097 * @return {void} 15098 */ 15099 function msListIgnore(node) { 15100 if (node.nodeType !== node.ELEMENT_NODE) { 15101 return; 15102 } 15103 const style = node.getAttribute('style'); 15104 if (!style || !style.includes('mso-list')) { 15105 return; 15106 } 15107 const rules = style.split(';').reduce((acc, rule) => { 15108 const [key, value] = rule.split(':'); 15109 if (key && value) { 15110 acc[key.trim().toLowerCase()] = value.trim().toLowerCase(); 15111 } 15112 return acc; 15113 }, {}); 15114 if (rules['mso-list'] === 'ignore') { 15115 node.remove(); 15116 } 15117 } 15118 15119 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/ms-list-converter.js 15120 /** 15121 * Internal dependencies 15122 */ 15123 15124 15125 function ms_list_converter_isList(node) { 15126 return node.nodeName === 'OL' || node.nodeName === 'UL'; 15127 } 15128 function msListConverter(node, doc) { 15129 if (node.nodeName !== 'P') { 15130 return; 15131 } 15132 const style = node.getAttribute('style'); 15133 if (!style || !style.includes('mso-list')) { 15134 return; 15135 } 15136 const prevNode = node.previousElementSibling; 15137 15138 // Add new list if no previous. 15139 if (!prevNode || !ms_list_converter_isList(prevNode)) { 15140 // See https://html.spec.whatwg.org/multipage/grouping-content.html#attr-ol-type. 15141 const type = node.textContent.trim().slice(0, 1); 15142 const isNumeric = /[1iIaA]/.test(type); 15143 const newListNode = doc.createElement(isNumeric ? 'ol' : 'ul'); 15144 if (isNumeric) { 15145 newListNode.setAttribute('type', type); 15146 } 15147 node.parentNode.insertBefore(newListNode, node); 15148 } 15149 const listNode = node.previousElementSibling; 15150 const listType = listNode.nodeName; 15151 const listItem = doc.createElement('li'); 15152 let receivingNode = listNode; 15153 15154 // Add content. 15155 listItem.innerHTML = deepFilterHTML(node.innerHTML, [msListIgnore]); 15156 const matches = /mso-list\s*:[^;]+level([0-9]+)/i.exec(style); 15157 let level = matches ? parseInt(matches[1], 10) - 1 || 0 : 0; 15158 15159 // Change pointer depending on indentation level. 15160 while (level--) { 15161 receivingNode = receivingNode.lastChild || receivingNode; 15162 15163 // If it's a list, move pointer to the last item. 15164 if (ms_list_converter_isList(receivingNode)) { 15165 receivingNode = receivingNode.lastChild || receivingNode; 15166 } 15167 } 15168 15169 // Make sure we append to a list. 15170 if (!ms_list_converter_isList(receivingNode)) { 15171 receivingNode = receivingNode.appendChild(doc.createElement(listType)); 15172 } 15173 15174 // Append the list item to the list. 15175 receivingNode.appendChild(listItem); 15176 15177 // Remove the wrapper paragraph. 15178 node.parentNode.removeChild(node); 15179 } 15180 15181 ;// external ["wp","blob"] 15182 const external_wp_blob_namespaceObject = window["wp"]["blob"]; 15183 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/image-corrector.js 15184 /* wp:polyfill */ 15185 /** 15186 * WordPress dependencies 15187 */ 15188 15189 function imageCorrector(node) { 15190 if (node.nodeName !== 'IMG') { 15191 return; 15192 } 15193 if (node.src.indexOf('file:') === 0) { 15194 node.src = ''; 15195 } 15196 15197 // This piece cannot be tested outside a browser env. 15198 if (node.src.indexOf('data:') === 0) { 15199 const [properties, data] = node.src.split(','); 15200 const [type] = properties.slice(5).split(';'); 15201 if (!data || !type) { 15202 node.src = ''; 15203 return; 15204 } 15205 let decoded; 15206 15207 // Can throw DOMException! 15208 try { 15209 decoded = atob(data); 15210 } catch (e) { 15211 node.src = ''; 15212 return; 15213 } 15214 const uint8Array = new Uint8Array(decoded.length); 15215 for (let i = 0; i < uint8Array.length; i++) { 15216 uint8Array[i] = decoded.charCodeAt(i); 15217 } 15218 const name = type.replace('/', '.'); 15219 const file = new window.File([uint8Array], name, { 15220 type 15221 }); 15222 node.src = (0,external_wp_blob_namespaceObject.createBlobURL)(file); 15223 } 15224 15225 // Remove trackers and hardly visible images. 15226 if (node.height === 1 || node.width === 1) { 15227 node.parentNode.removeChild(node); 15228 } 15229 } 15230 15231 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/div-normaliser.js 15232 /** 15233 * Internal dependencies 15234 */ 15235 15236 function divNormaliser(node) { 15237 if (node.nodeName !== 'DIV') { 15238 return; 15239 } 15240 node.innerHTML = normaliseBlocks(node.innerHTML); 15241 } 15242 15243 // EXTERNAL MODULE: ./node_modules/showdown/dist/showdown.js 15244 var showdown = __webpack_require__(1030); 15245 var showdown_default = /*#__PURE__*/__webpack_require__.n(showdown); 15246 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/markdown-converter.js 15247 /** 15248 * External dependencies 15249 */ 15250 15251 15252 // Reuse the same showdown converter. 15253 const converter = new (showdown_default()).Converter({ 15254 noHeaderId: true, 15255 tables: true, 15256 literalMidWordUnderscores: true, 15257 omitExtraWLInCodeBlocks: true, 15258 simpleLineBreaks: true, 15259 strikethrough: true 15260 }); 15261 15262 /** 15263 * Corrects the Slack Markdown variant of the code block. 15264 * If uncorrected, it will be converted to inline code. 15265 * 15266 * @see https://get.slack.help/hc/en-us/articles/202288908-how-can-i-add-formatting-to-my-messages-#code-blocks 15267 * 15268 * @param {string} text The potential Markdown text to correct. 15269 * 15270 * @return {string} The corrected Markdown. 15271 */ 15272 function slackMarkdownVariantCorrector(text) { 15273 return text.replace(/((?:^|\n)```)([^\n`]+)(```(?:$|\n))/, (match, p1, p2, p3) => `$p1}\n$p2}\n$p3}`); 15274 } 15275 function bulletsToAsterisks(text) { 15276 return text.replace(/(^|\n)•( +)/g, '$1*$2'); 15277 } 15278 15279 /** 15280 * Converts a piece of text into HTML based on any Markdown present. 15281 * Also decodes any encoded HTML. 15282 * 15283 * @param {string} text The plain text to convert. 15284 * 15285 * @return {string} HTML. 15286 */ 15287 function markdownConverter(text) { 15288 return converter.makeHtml(slackMarkdownVariantCorrector(bulletsToAsterisks(text))); 15289 } 15290 15291 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/iframe-remover.js 15292 /** 15293 * Removes iframes. 15294 * 15295 * @param {Node} node The node to check. 15296 * 15297 * @return {void} 15298 */ 15299 function iframeRemover(node) { 15300 if (node.nodeName === 'IFRAME') { 15301 const text = node.ownerDocument.createTextNode(node.src); 15302 node.parentNode.replaceChild(text, node); 15303 } 15304 } 15305 15306 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/google-docs-uid-remover.js 15307 /** 15308 * WordPress dependencies 15309 */ 15310 15311 function googleDocsUIdRemover(node) { 15312 if (!node.id || node.id.indexOf('docs-internal-guid-') !== 0) { 15313 return; 15314 } 15315 15316 // Google Docs sometimes wraps the content in a B tag. We don't want to keep 15317 // this. 15318 if (node.tagName === 'B') { 15319 (0,external_wp_dom_namespaceObject.unwrap)(node); 15320 } else { 15321 node.removeAttribute('id'); 15322 } 15323 } 15324 15325 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/html-formatting-remover.js 15326 /** 15327 * Internal dependencies 15328 */ 15329 15330 function isFormattingSpace(character) { 15331 return character === ' ' || character === '\r' || character === '\n' || character === '\t'; 15332 } 15333 15334 /** 15335 * Removes spacing that formats HTML. 15336 * 15337 * @see https://www.w3.org/TR/css-text-3/#white-space-processing 15338 * 15339 * @param {Node} node The node to be processed. 15340 * @return {void} 15341 */ 15342 function htmlFormattingRemover(node) { 15343 if (node.nodeType !== node.TEXT_NODE) { 15344 return; 15345 } 15346 15347 // Ignore pre content. Note that this does not use Element#closest due to 15348 // a combination of (a) node may not be Element and (b) node.parentElement 15349 // does not have full support in all browsers (Internet Exporer). 15350 // 15351 // See: https://developer.mozilla.org/en-US/docs/Web/API/Node/parentElement#Browser_compatibility 15352 15353 /** @type {Node?} */ 15354 let parent = node; 15355 while (parent = parent.parentNode) { 15356 if (parent.nodeType === parent.ELEMENT_NODE && parent.nodeName === 'PRE') { 15357 return; 15358 } 15359 } 15360 15361 // First, replace any sequence of HTML formatting space with a single space. 15362 let newData = node.data.replace(/[ \r\n\t]+/g, ' '); 15363 15364 // Remove the leading space if the text element is at the start of a block, 15365 // is preceded by a line break element, or has a space in the previous 15366 // node. 15367 if (newData[0] === ' ') { 15368 const previousSibling = getSibling(node, 'previous'); 15369 if (!previousSibling || previousSibling.nodeName === 'BR' || previousSibling.textContent.slice(-1) === ' ') { 15370 newData = newData.slice(1); 15371 } 15372 } 15373 15374 // Remove the trailing space if the text element is at the end of a block, 15375 // is succeeded by a line break element, or has a space in the next text 15376 // node. 15377 if (newData[newData.length - 1] === ' ') { 15378 const nextSibling = getSibling(node, 'next'); 15379 if (!nextSibling || nextSibling.nodeName === 'BR' || nextSibling.nodeType === nextSibling.TEXT_NODE && isFormattingSpace(nextSibling.textContent[0])) { 15380 newData = newData.slice(0, -1); 15381 } 15382 } 15383 15384 // If there's no data left, remove the node, so `previousSibling` stays 15385 // accurate. Otherwise, update the node data. 15386 if (!newData) { 15387 node.parentNode.removeChild(node); 15388 } else { 15389 node.data = newData; 15390 } 15391 } 15392 15393 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/br-remover.js 15394 /** 15395 * Internal dependencies 15396 */ 15397 15398 15399 /** 15400 * Removes trailing br elements from text-level content. 15401 * 15402 * @param {Element} node Node to check. 15403 */ 15404 function brRemover(node) { 15405 if (node.nodeName !== 'BR') { 15406 return; 15407 } 15408 if (getSibling(node, 'next')) { 15409 return; 15410 } 15411 node.parentNode.removeChild(node); 15412 } 15413 15414 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/empty-paragraph-remover.js 15415 /** 15416 * Removes empty paragraph elements. 15417 * 15418 * @param {Element} node Node to check. 15419 */ 15420 function emptyParagraphRemover(node) { 15421 if (node.nodeName !== 'P') { 15422 return; 15423 } 15424 if (node.hasChildNodes()) { 15425 return; 15426 } 15427 node.parentNode.removeChild(node); 15428 } 15429 15430 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/slack-paragraph-corrector.js 15431 /** 15432 * Replaces Slack paragraph markup with a double line break (later converted to 15433 * a proper paragraph). 15434 * 15435 * @param {Element} node Node to check. 15436 */ 15437 function slackParagraphCorrector(node) { 15438 if (node.nodeName !== 'SPAN') { 15439 return; 15440 } 15441 if (node.getAttribute('data-stringify-type') !== 'paragraph-break') { 15442 return; 15443 } 15444 const { 15445 parentNode 15446 } = node; 15447 parentNode.insertBefore(node.ownerDocument.createElement('br'), node); 15448 parentNode.insertBefore(node.ownerDocument.createElement('br'), node); 15449 parentNode.removeChild(node); 15450 } 15451 15452 ;// ./node_modules/@wordpress/blocks/build-module/api/raw-handling/paste-handler.js 15453 /* wp:polyfill */ 15454 /** 15455 * WordPress dependencies 15456 */ 15457 15458 15459 /** 15460 * Internal dependencies 15461 */ 15462 15463 15464 15465 15466 15467 15468 15469 15470 15471 15472 15473 15474 15475 15476 15477 15478 15479 15480 15481 15482 15483 15484 15485 15486 15487 15488 const log = (...args) => window?.console?.log?.(...args); 15489 15490 /** 15491 * Filters HTML to only contain phrasing content. 15492 * 15493 * @param {string} HTML The HTML to filter. 15494 * 15495 * @return {string} HTML only containing phrasing content. 15496 */ 15497 function filterInlineHTML(HTML) { 15498 HTML = deepFilterHTML(HTML, [headRemover, googleDocsUIdRemover, msListIgnore, phrasingContentReducer, commentRemover]); 15499 HTML = (0,external_wp_dom_namespaceObject.removeInvalidHTML)(HTML, (0,external_wp_dom_namespaceObject.getPhrasingContentSchema)('paste'), { 15500 inline: true 15501 }); 15502 HTML = deepFilterHTML(HTML, [htmlFormattingRemover, brRemover]); 15503 15504 // Allows us to ask for this information when we get a report. 15505 log('Processed inline HTML:\n\n', HTML); 15506 return HTML; 15507 } 15508 15509 /** 15510 * Converts an HTML string to known blocks. Strips everything else. 15511 * 15512 * @param {Object} options 15513 * @param {string} [options.HTML] The HTML to convert. 15514 * @param {string} [options.plainText] Plain text version. 15515 * @param {string} [options.mode] Handle content as blocks or inline content. 15516 * * 'AUTO': Decide based on the content passed. 15517 * * 'INLINE': Always handle as inline content, and return string. 15518 * * 'BLOCKS': Always handle as blocks, and return array of blocks. 15519 * @param {Array} [options.tagName] The tag into which content will be inserted. 15520 * 15521 * @return {Array|string} A list of blocks or a string, depending on `handlerMode`. 15522 */ 15523 function pasteHandler({ 15524 HTML = '', 15525 plainText = '', 15526 mode = 'AUTO', 15527 tagName 15528 }) { 15529 // First of all, strip any meta tags. 15530 HTML = HTML.replace(/<meta[^>]+>/g, ''); 15531 // Strip Windows markers. 15532 HTML = HTML.replace(/^\s*<html[^>]*>\s*<body[^>]*>(?:\s*<!--\s*StartFragment\s*-->)?/i, ''); 15533 HTML = HTML.replace(/(?:<!--\s*EndFragment\s*-->\s*)?<\/body>\s*<\/html>\s*$/i, ''); 15534 15535 // If we detect block delimiters in HTML, parse entirely as blocks. 15536 if (mode !== 'INLINE') { 15537 // Check plain text if there is no HTML. 15538 const content = HTML ? HTML : plainText; 15539 if (content.indexOf('<!-- wp:') !== -1) { 15540 const parseResult = parser_parse(content); 15541 const isSingleFreeFormBlock = parseResult.length === 1 && parseResult[0].name === 'core/freeform'; 15542 if (!isSingleFreeFormBlock) { 15543 return parseResult; 15544 } 15545 } 15546 } 15547 15548 // Normalize unicode to use composed characters. 15549 // Not normalizing the content will only affect older browsers and won't 15550 // entirely break the app. 15551 // See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize 15552 // See: https://core.trac.wordpress.org/ticket/30130 15553 // See: https://github.com/WordPress/gutenberg/pull/6983#pullrequestreview-125151075 15554 if (String.prototype.normalize) { 15555 HTML = HTML.normalize(); 15556 } 15557 15558 // Must be run before checking if it's inline content. 15559 HTML = deepFilterHTML(HTML, [slackParagraphCorrector]); 15560 15561 // Consider plain text if: 15562 // * There is a plain text version. 15563 // * There is no HTML version, or it has no formatting. 15564 const isPlainText = plainText && (!HTML || isPlain(HTML)); 15565 15566 // Parse Markdown (and encoded HTML) if it's considered plain text. 15567 if (isPlainText) { 15568 HTML = plainText; 15569 15570 // The markdown converter (Showdown) trims whitespace. 15571 if (!/^\s+$/.test(plainText)) { 15572 HTML = markdownConverter(HTML); 15573 } 15574 } 15575 15576 // An array of HTML strings and block objects. The blocks replace matched 15577 // shortcodes. 15578 const pieces = shortcode_converter(HTML); 15579 15580 // The call to shortcodeConverter will always return more than one element 15581 // if shortcodes are matched. The reason is when shortcodes are matched 15582 // empty HTML strings are included. 15583 const hasShortcodes = pieces.length > 1; 15584 if (isPlainText && !hasShortcodes) { 15585 // Switch to inline mode if: 15586 // * The current mode is AUTO. 15587 // * The original plain text had no line breaks. 15588 // * The original plain text was not an HTML paragraph. 15589 // * The converted text is just a paragraph. 15590 if (mode === 'AUTO' && plainText.indexOf('\n') === -1 && plainText.indexOf('<p>') !== 0 && HTML.indexOf('<p>') === 0) { 15591 mode = 'INLINE'; 15592 } 15593 } 15594 if (mode === 'INLINE') { 15595 return filterInlineHTML(HTML); 15596 } 15597 if (mode === 'AUTO' && !hasShortcodes && isInlineContent(HTML, tagName)) { 15598 return filterInlineHTML(HTML); 15599 } 15600 const phrasingContentSchema = (0,external_wp_dom_namespaceObject.getPhrasingContentSchema)('paste'); 15601 const blockContentSchema = getBlockContentSchema('paste'); 15602 const blocks = pieces.map(piece => { 15603 // Already a block from shortcode. 15604 if (typeof piece !== 'string') { 15605 return piece; 15606 } 15607 const filters = [googleDocsUIdRemover, msListConverter, headRemover, listReducer, imageCorrector, phrasingContentReducer, specialCommentConverter, commentRemover, iframeRemover, figureContentReducer, blockquoteNormaliser(), divNormaliser]; 15608 const schema = { 15609 ...blockContentSchema, 15610 // Keep top-level phrasing content, normalised by `normaliseBlocks`. 15611 ...phrasingContentSchema 15612 }; 15613 piece = deepFilterHTML(piece, filters, blockContentSchema); 15614 piece = (0,external_wp_dom_namespaceObject.removeInvalidHTML)(piece, schema); 15615 piece = normaliseBlocks(piece); 15616 piece = deepFilterHTML(piece, [htmlFormattingRemover, brRemover, emptyParagraphRemover], blockContentSchema); 15617 15618 // Allows us to ask for this information when we get a report. 15619 log('Processed HTML piece:\n\n', piece); 15620 return htmlToBlocks(piece, pasteHandler); 15621 }).flat().filter(Boolean); 15622 15623 // If we're allowed to return inline content, and there is only one 15624 // inlineable block, and the original plain text content does not have any 15625 // line breaks, then treat it as inline paste. 15626 if (mode === 'AUTO' && blocks.length === 1 && hasBlockSupport(blocks[0].name, '__unstablePasteTextInline', false)) { 15627 const trimRegex = /^[\n]+|[\n]+$/g; 15628 // Don't catch line breaks at the start or end. 15629 const trimmedPlainText = plainText.replace(trimRegex, ''); 15630 if (trimmedPlainText !== '' && trimmedPlainText.indexOf('\n') === -1) { 15631 return (0,external_wp_dom_namespaceObject.removeInvalidHTML)(getBlockInnerHTML(blocks[0]), phrasingContentSchema).replace(trimRegex, ''); 15632 } 15633 } 15634 return blocks; 15635 } 15636 15637 ;// ./node_modules/@wordpress/blocks/build-module/api/categories.js 15638 /** 15639 * WordPress dependencies 15640 */ 15641 15642 15643 /** 15644 * Internal dependencies 15645 */ 15646 15647 15648 /** @typedef {import('../store/reducer').WPBlockCategory} WPBlockCategory */ 15649 15650 /** 15651 * Returns all the block categories. 15652 * Ignored from documentation as the recommended usage is via useSelect from @wordpress/data. 15653 * 15654 * @ignore 15655 * 15656 * @return {WPBlockCategory[]} Block categories. 15657 */ 15658 function categories_getCategories() { 15659 return (0,external_wp_data_namespaceObject.select)(store).getCategories(); 15660 } 15661 15662 /** 15663 * Sets the block categories. 15664 * 15665 * @param {WPBlockCategory[]} categories Block categories. 15666 * 15667 * @example 15668 * ```js 15669 * import { __ } from '@wordpress/i18n'; 15670 * import { store as blocksStore, setCategories } from '@wordpress/blocks'; 15671 * import { useSelect } from '@wordpress/data'; 15672 * import { Button } from '@wordpress/components'; 15673 * 15674 * const ExampleComponent = () => { 15675 * // Retrieve the list of current categories. 15676 * const blockCategories = useSelect( 15677 * ( select ) => select( blocksStore ).getCategories(), 15678 * [] 15679 * ); 15680 * 15681 * return ( 15682 * <Button 15683 * onClick={ () => { 15684 * // Add a custom category to the existing list. 15685 * setCategories( [ 15686 * ...blockCategories, 15687 * { title: 'Custom Category', slug: 'custom-category' }, 15688 * ] ); 15689 * } } 15690 * > 15691 * { __( 'Add a new custom block category' ) } 15692 * </Button> 15693 * ); 15694 * }; 15695 * ``` 15696 */ 15697 function categories_setCategories(categories) { 15698 (0,external_wp_data_namespaceObject.dispatch)(store).setCategories(categories); 15699 } 15700 15701 /** 15702 * Updates a category. 15703 * 15704 * @param {string} slug Block category slug. 15705 * @param {WPBlockCategory} category Object containing the category properties 15706 * that should be updated. 15707 * 15708 * @example 15709 * ```js 15710 * import { __ } from '@wordpress/i18n'; 15711 * import { updateCategory } from '@wordpress/blocks'; 15712 * import { Button } from '@wordpress/components'; 15713 * 15714 * const ExampleComponent = () => { 15715 * return ( 15716 * <Button 15717 * onClick={ () => { 15718 * updateCategory( 'text', { title: __( 'Written Word' ) } ); 15719 * } } 15720 * > 15721 * { __( 'Update Text category title' ) } 15722 * </Button> 15723 * ) ; 15724 * }; 15725 * ``` 15726 */ 15727 function categories_updateCategory(slug, category) { 15728 (0,external_wp_data_namespaceObject.dispatch)(store).updateCategory(slug, category); 15729 } 15730 15731 ;// ./node_modules/@wordpress/blocks/build-module/api/templates.js 15732 /* wp:polyfill */ 15733 /** 15734 * WordPress dependencies 15735 */ 15736 15737 15738 /** 15739 * Internal dependencies 15740 */ 15741 15742 15743 15744 15745 /** 15746 * Checks whether a list of blocks matches a template by comparing the block names. 15747 * 15748 * @param {Array} blocks Block list. 15749 * @param {Array} template Block template. 15750 * 15751 * @return {boolean} Whether the list of blocks matches a templates. 15752 */ 15753 function doBlocksMatchTemplate(blocks = [], template = []) { 15754 return blocks.length === template.length && template.every(([name,, innerBlocksTemplate], index) => { 15755 const block = blocks[index]; 15756 return name === block.name && doBlocksMatchTemplate(block.innerBlocks, innerBlocksTemplate); 15757 }); 15758 } 15759 const isHTMLAttribute = attributeDefinition => attributeDefinition?.source === 'html'; 15760 const isQueryAttribute = attributeDefinition => attributeDefinition?.source === 'query'; 15761 function normalizeAttributes(schema, values) { 15762 if (!values) { 15763 return {}; 15764 } 15765 return Object.fromEntries(Object.entries(values).map(([key, value]) => [key, normalizeAttribute(schema[key], value)])); 15766 } 15767 function normalizeAttribute(definition, value) { 15768 if (isHTMLAttribute(definition) && Array.isArray(value)) { 15769 // Introduce a deprecated call at this point 15770 // When we're confident that "children" format should be removed from the templates. 15771 15772 return (0,external_wp_element_namespaceObject.renderToString)(value); 15773 } 15774 if (isQueryAttribute(definition) && value) { 15775 return value.map(subValues => { 15776 return normalizeAttributes(definition.query, subValues); 15777 }); 15778 } 15779 return value; 15780 } 15781 15782 /** 15783 * Synchronize a block list with a block template. 15784 * 15785 * Synchronizing a block list with a block template means that we loop over the blocks 15786 * keep the block as is if it matches the block at the same position in the template 15787 * (If it has the same name) and if doesn't match, we create a new block based on the template. 15788 * Extra blocks not present in the template are removed. 15789 * 15790 * @param {Array} blocks Block list. 15791 * @param {Array} template Block template. 15792 * 15793 * @return {Array} Updated Block list. 15794 */ 15795 function synchronizeBlocksWithTemplate(blocks = [], template) { 15796 // If no template is provided, return blocks unmodified. 15797 if (!template) { 15798 return blocks; 15799 } 15800 return template.map(([name, attributes, innerBlocksTemplate], index) => { 15801 var _blockType$attributes; 15802 const block = blocks[index]; 15803 if (block && block.name === name) { 15804 const innerBlocks = synchronizeBlocksWithTemplate(block.innerBlocks, innerBlocksTemplate); 15805 return { 15806 ...block, 15807 innerBlocks 15808 }; 15809 } 15810 15811 // To support old templates that were using the "children" format 15812 // for the attributes using "html" strings now, we normalize the template attributes 15813 // before creating the blocks. 15814 15815 const blockType = getBlockType(name); 15816 const normalizedAttributes = normalizeAttributes((_blockType$attributes = blockType?.attributes) !== null && _blockType$attributes !== void 0 ? _blockType$attributes : {}, attributes); 15817 const [blockName, blockAttributes] = convertLegacyBlockNameAndAttributes(name, normalizedAttributes); 15818 return createBlock(blockName, blockAttributes, synchronizeBlocksWithTemplate([], innerBlocksTemplate)); 15819 }); 15820 } 15821 15822 ;// ./node_modules/@wordpress/blocks/build-module/api/index.js 15823 /** 15824 * Internal dependencies 15825 */ 15826 15827 15828 15829 // The blocktype is the most important concept within the block API. It defines 15830 // all aspects of the block configuration and its interfaces, including `edit` 15831 // and `save`. The transforms specification allows converting one blocktype to 15832 // another through formulas defined by either the source or the destination. 15833 // Switching a blocktype is to be considered a one-way operation implying a 15834 // transformation in the opposite way has to be handled explicitly. 15835 15836 15837 // The block tree is composed of a collection of block nodes. Blocks contained 15838 // within other blocks are called inner blocks. An important design 15839 // consideration is that inner blocks are -- conceptually -- not part of the 15840 // territory established by the parent block that contains them. 15841 // 15842 // This has multiple practical implications: when parsing, we can safely dispose 15843 // of any block boundary found within a block from the innerHTML property when 15844 // transferring to state. Not doing so would have a compounding effect on memory 15845 // and uncertainty over the source of truth. This can be illustrated in how, 15846 // given a tree of `n` nested blocks, the entry node would have to contain the 15847 // actual content of each block while each subsequent block node in the state 15848 // tree would replicate the entire chain `n-1`, meaning the extreme end node 15849 // would have been replicated `n` times as the tree is traversed and would 15850 // generate uncertainty as to which one is to hold the current value of the 15851 // block. For composition, it also means inner blocks can effectively be child 15852 // components whose mechanisms can be shielded from the `edit` implementation 15853 // and just passed along. 15854 15855 15856 15857 15858 // While block transformations account for a specific surface of the API, there 15859 // are also raw transformations which handle arbitrary sources not made out of 15860 // blocks but producing block basaed on various heuristics. This includes 15861 // pasting rich text or HTML data. 15862 15863 15864 // The process of serialization aims to deflate the internal memory of the block 15865 // editor and its state representation back into an HTML valid string. This 15866 // process restores the document integrity and inserts invisible delimiters 15867 // around each block with HTML comment boundaries which can contain any extra 15868 // attributes needed to operate with the block later on. 15869 15870 15871 // Validation is the process of comparing a block source with its output before 15872 // there is any user input or interaction with a block. When this operation 15873 // fails -- for whatever reason -- the block is to be considered invalid. As 15874 // part of validating a block the system will attempt to run the source against 15875 // any provided deprecation definitions. 15876 // 15877 // Worth emphasizing that validation is not a case of whether the markup is 15878 // merely HTML spec-compliant but about how the editor knows to create such 15879 // markup and that its inability to create an identical result can be a strong 15880 // indicator of potential data loss (the invalidation is then a protective 15881 // measure). 15882 // 15883 // The invalidation process can also be deconstructed in phases: 1) validate the 15884 // block exists; 2) validate the source matches the output; 3) validate the 15885 // source matches deprecated outputs; 4) work through the significance of 15886 // differences. These are stacked in a way that favors performance and optimizes 15887 // for the majority of cases. That is to say, the evaluation logic can become 15888 // more sophisticated the further down it goes in the process as the cost is 15889 // accounted for. The first logic checks have to be extremely efficient since 15890 // they will be run for all valid and invalid blocks alike. However, once a 15891 // block is detected as invalid -- failing the three first steps -- it is 15892 // adequate to spend more time determining validity before throwing a conflict. 15893 15894 15895 15896 // Blocks are inherently indifferent about where the data they operate with ends 15897 // up being saved. For example, all blocks can have a static and dynamic aspect 15898 // to them depending on the needs. The static nature of a block is the `save()` 15899 // definition that is meant to be serialized into HTML and which can be left 15900 // void. Any block can also register a `render_callback` on the server, which 15901 // makes its output dynamic either in part or in its totality. 15902 // 15903 // Child blocks are defined as a relationship that builds on top of the inner 15904 // blocks mechanism. A child block is a block node of a particular type that can 15905 // only exist within the inner block boundaries of a specific parent type. This 15906 // allows block authors to compose specific blocks that are not meant to be used 15907 // outside of a specified parent block context. Thus, child blocks extend the 15908 // concept of inner blocks to support a more direct relationship between sets of 15909 // blocks. The addition of parent–child would be a subset of the inner block 15910 // functionality under the premise that certain blocks only make sense as 15911 // children of another block. 15912 15913 15914 15915 // Templates are, in a general sense, a basic collection of block nodes with any 15916 // given set of predefined attributes that are supplied as the initial state of 15917 // an inner blocks group. These nodes can, in turn, contain any number of nested 15918 // blocks within their definition. Templates allow both to specify a default 15919 // state for an editor session or a default set of blocks for any inner block 15920 // implementation within a specific block. 15921 15922 15923 15924 15925 const privateApis = {}; 15926 lock(privateApis, { 15927 isContentBlock: isContentBlock 15928 }); 15929 15930 ;// ./node_modules/@wordpress/blocks/build-module/deprecated.js 15931 /** 15932 * WordPress dependencies 15933 */ 15934 15935 15936 /** 15937 * A Higher Order Component used to inject BlockContent using context to the 15938 * wrapped component. 15939 * 15940 * @deprecated 15941 * 15942 * @param {Component} OriginalComponent The component to enhance. 15943 * @return {Component} The same component. 15944 */ 15945 function withBlockContentContext(OriginalComponent) { 15946 external_wp_deprecated_default()('wp.blocks.withBlockContentContext', { 15947 since: '6.1' 15948 }); 15949 return OriginalComponent; 15950 } 15951 15952 ;// ./node_modules/@wordpress/blocks/build-module/index.js 15953 // A "block" is the abstract term used to describe units of markup that, 15954 // when composed together, form the content or layout of a page. 15955 // The API for blocks is exposed via `wp.blocks`. 15956 // 15957 // Supported blocks are registered by calling `registerBlockType`. Once registered, 15958 // the block is made available as an option to the editor interface. 15959 // 15960 // Blocks are inferred from the HTML source of a post through a parsing mechanism 15961 // and then stored as objects in state, from which it is then rendered for editing. 15962 15963 15964 15965 15966 15967 })(); 15968 15969 (window.wp = window.wp || {}).blocks = __webpack_exports__; 15970 /******/ })() 15971 ;
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated : Fri Feb 21 08:20:01 2025 | Cross-referenced by PHPXref |