PluginProbe
Gutenberg / 16.5.0
Gutenberg v16.5.0
24.0.0 23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 All 403 releases
gutenberg / build / blocks / index.js

index.js in Gutenberg 16.5.0, at build/blocks/index.js

15,343 lines 525.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /******/ (() => { // webpackBootstrap
2 /******/ var __webpack_modules__ = ({
3
4 /***/ 1919:
5 /***/ ((module) => {
6
7 "use strict";
8
9
10 var isMergeableObject = function isMergeableObject(value) {
11 return isNonNullObject(value)
12 && !isSpecial(value)
13 };
14
15 function isNonNullObject(value) {
16 return !!value && typeof value === 'object'
17 }
18
19 function isSpecial(value) {
20 var stringValue = Object.prototype.toString.call(value);
21
22 return stringValue === '[object RegExp]'
23 || stringValue === '[object Date]'
24 || isReactElement(value)
25 }
26
27 // see https://github.com/facebook/react/blob/b5ac963fb791d1298e7f396236383bc955f916c1/src/isomorphic/classic/element/ReactElement.js#L21-L25
28 var canUseSymbol = typeof Symbol === 'function' && Symbol.for;
29 var REACT_ELEMENT_TYPE = canUseSymbol ? Symbol.for('react.element') : 0xeac7;
30
31 function isReactElement(value) {
32 return value.$$typeof === REACT_ELEMENT_TYPE
33 }
34
35 function emptyTarget(val) {
36 return Array.isArray(val) ? [] : {}
37 }
38
39 function cloneUnlessOtherwiseSpecified(value, options) {
40 return (options.clone !== false && options.isMergeableObject(value))
41 ? deepmerge(emptyTarget(value), value, options)
42 : value
43 }
44
45 function defaultArrayMerge(target, source, options) {
46 return target.concat(source).map(function(element) {
47 return cloneUnlessOtherwiseSpecified(element, options)
48 })
49 }
50
51 function getMergeFunction(key, options) {
52 if (!options.customMerge) {
53 return deepmerge
54 }
55 var customMerge = options.customMerge(key);
56 return typeof customMerge === 'function' ? customMerge : deepmerge
57 }
58
59 function getEnumerableOwnPropertySymbols(target) {
60 return Object.getOwnPropertySymbols
61 ? Object.getOwnPropertySymbols(target).filter(function(symbol) {
62 return Object.propertyIsEnumerable.call(target, symbol)
63 })
64 : []
65 }
66
67 function getKeys(target) {
68 return Object.keys(target).concat(getEnumerableOwnPropertySymbols(target))
69 }
70
71 function propertyIsOnObject(object, property) {
72 try {
73 return property in object
74 } catch(_) {
75 return false
76 }
77 }
78
79 // Protects from prototype poisoning and unexpected merging up the prototype chain.
80 function propertyIsUnsafe(target, key) {
81 return propertyIsOnObject(target, key) // Properties are safe to merge if they don't exist in the target yet,
82 && !(Object.hasOwnProperty.call(target, key) // unsafe if they exist up the prototype chain,
83 && Object.propertyIsEnumerable.call(target, key)) // and also unsafe if they're nonenumerable.
84 }
85
86 function mergeObject(target, source, options) {
87 var destination = {};
88 if (options.isMergeableObject(target)) {
89 getKeys(target).forEach(function(key) {
90 destination[key] = cloneUnlessOtherwiseSpecified(target[key], options);
91 });
92 }
93 getKeys(source).forEach(function(key) {
94 if (propertyIsUnsafe(target, key)) {
95 return
96 }
97
98 if (propertyIsOnObject(target, key) && options.isMergeableObject(source[key])) {
99 destination[key] = getMergeFunction(key, options)(target[key], source[key], options);
100 } else {
101 destination[key] = cloneUnlessOtherwiseSpecified(source[key], options);
102 }
103 });
104 return destination
105 }
106
107 function deepmerge(target, source, options) {
108 options = options || {};
109 options.arrayMerge = options.arrayMerge || defaultArrayMerge;
110 options.isMergeableObject = options.isMergeableObject || isMergeableObject;
111 // cloneUnlessOtherwiseSpecified is added to `options` so that custom arrayMerge()
112 // implementations can use it. The caller may not replace it.
113 options.cloneUnlessOtherwiseSpecified = cloneUnlessOtherwiseSpecified;
114
115 var sourceIsArray = Array.isArray(source);
116 var targetIsArray = Array.isArray(target);
117 var sourceAndTargetTypesMatch = sourceIsArray === targetIsArray;
118
119 if (!sourceAndTargetTypesMatch) {
120 return cloneUnlessOtherwiseSpecified(source, options)
121 } else if (sourceIsArray) {
122 return options.arrayMerge(target, source, options)
123 } else {
124 return mergeObject(target, source, options)
125 }
126 }
127
128 deepmerge.all = function deepmergeAll(array, options) {
129 if (!Array.isArray(array)) {
130 throw new Error('first argument should be an array')
131 }
132
133 return array.reduce(function(prev, next) {
134 return deepmerge(prev, next, options)
135 }, {})
136 };
137
138 var deepmerge_1 = deepmerge;
139
140 module.exports = deepmerge_1;
141
142
143 /***/ }),
144
145 /***/ 5619:
146 /***/ ((module) => {
147
148 "use strict";
149
150
151 // do not edit .js files directly - edit src/index.jst
152
153
154 var envHasBigInt64Array = typeof BigInt64Array !== 'undefined';
155
156
157 module.exports = function equal(a, b) {
158 if (a === b) return true;
159
160 if (a && b && typeof a == 'object' && typeof b == 'object') {
161 if (a.constructor !== b.constructor) return false;
162
163 var length, i, keys;
164 if (Array.isArray(a)) {
165 length = a.length;
166 if (length != b.length) return false;
167 for (i = length; i-- !== 0;)
168 if (!equal(a[i], b[i])) return false;
169 return true;
170 }
171
172
173 if ((a instanceof Map) && (b instanceof Map)) {
174 if (a.size !== b.size) return false;
175 for (i of a.entries())
176 if (!b.has(i[0])) return false;
177 for (i of a.entries())
178 if (!equal(i[1], b.get(i[0]))) return false;
179 return true;
180 }
181
182 if ((a instanceof Set) && (b instanceof Set)) {
183 if (a.size !== b.size) return false;
184 for (i of a.entries())
185 if (!b.has(i[0])) return false;
186 return true;
187 }
188
189 if (ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) {
190 length = a.length;
191 if (length != b.length) return false;
192 for (i = length; i-- !== 0;)
193 if (a[i] !== b[i]) return false;
194 return true;
195 }
196
197
198 if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags;
199 if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf();
200 if (a.toString !== Object.prototype.toString) return a.toString() === b.toString();
201
202 keys = Object.keys(a);
203 length = keys.length;
204 if (length !== Object.keys(b).length) return false;
205
206 for (i = length; i-- !== 0;)
207 if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false;
208
209 for (i = length; i-- !== 0;) {
210 var key = keys[i];
211
212 if (!equal(a[key], b[key])) return false;
213 }
214
215 return true;
216 }
217
218 // true if both NaN, false otherwise
219 return a!==a && b!==b;
220 };
221
222
223 /***/ }),
224
225 /***/ 4793:
226 /***/ ((module) => {
227
228 var characterMap = {
229 "À": "A",
230 "Á": "A",
231 "Â": "A",
232 "Ã": "A",
233 "Ä": "A",
234 "Å": "A",
235 "Ấ": "A",
236 "Ắ": "A",
237 "Ẳ": "A",
238 "Ẵ": "A",
239 "Ặ": "A",
240 "Æ": "AE",
241 "Ầ": "A",
242 "Ằ": "A",
243 "Ȃ": "A",
244 "Ả": "A",
245 "Ạ": "A",
246 "Ẩ": "A",
247 "Ẫ": "A",
248 "Ậ": "A",
249 "Ç": "C",
250 "Ḉ": "C",
251 "È": "E",
252 "É": "E",
253 "Ê": "E",
254 "Ë": "E",
255 "Ế": "E",
256 "Ḗ": "E",
257 "Ề": "E",
258 "Ḕ": "E",
259 "Ḝ": "E",
260 "Ȇ": "E",
261 "Ẻ": "E",
262 "Ẽ": "E",
263 "Ẹ": "E",
264 "Ể": "E",
265 "Ễ": "E",
266 "Ệ": "E",
267 "Ì": "I",
268 "Í": "I",
269 "Î": "I",
270 "Ï": "I",
271 "Ḯ": "I",
272 "Ȋ": "I",
273 "Ỉ": "I",
274 "Ị": "I",
275 "Ð": "D",
276 "Ñ": "N",
277 "Ò": "O",
278 "Ó": "O",
279 "Ô": "O",
280 "Õ": "O",
281 "Ö": "O",
282 "Ø": "O",
283 "Ố": "O",
284 "Ṍ": "O",
285 "Ṓ": "O",
286 "Ȏ": "O",
287 "Ỏ": "O",
288 "Ọ": "O",
289 "Ổ": "O",
290 "Ỗ": "O",
291 "Ộ": "O",
292 "Ờ": "O",
293 "Ở": "O",
294 "Ỡ": "O",
295 "Ớ": "O",
296 "Ợ": "O",
297 "Ù": "U",
298 "Ú": "U",
299 "Û": "U",
300 "Ü": "U",
301 "Ủ": "U",
302 "Ụ": "U",
303 "Ử": "U",
304 "Ữ": "U",
305 "Ự": "U",
306 "Ý": "Y",
307 "à": "a",
308 "á": "a",
309 "â": "a",
310 "ã": "a",
311 "ä": "a",
312 "å": "a",
313 "ấ": "a",
314 "ắ": "a",
315 "ẳ": "a",
316 "ẵ": "a",
317 "ặ": "a",
318 "æ": "ae",
319 "ầ": "a",
320 "ằ": "a",
321 "ȃ": "a",
322 "ả": "a",
323 "ạ": "a",
324 "ẩ": "a",
325 "ẫ": "a",
326 "ậ": "a",
327 "ç": "c",
328 "ḉ": "c",
329 "è": "e",
330 "é": "e",
331 "ê": "e",
332 "ë": "e",
333 "ế": "e",
334 "ḗ": "e",
335 "ề": "e",
336 "ḕ": "e",
337 "ḝ": "e",
338 "ȇ": "e",
339 "ẻ": "e",
340 "ẽ": "e",
341 "ẹ": "e",
342 "ể": "e",
343 "ễ": "e",
344 "ệ": "e",
345 "ì": "i",
346 "í": "i",
347 "î": "i",
348 "ï": "i",
349 "ḯ": "i",
350 "ȋ": "i",
351 "ỉ": "i",
352 "ị": "i",
353 "ð": "d",
354 "ñ": "n",
355 "ò": "o",
356 "ó": "o",
357 "ô": "o",
358 "õ": "o",
359 "ö": "o",
360 "ø": "o",
361 "ố": "o",
362 "ṍ": "o",
363 "ṓ": "o",
364 "ȏ": "o",
365 "ỏ": "o",
366 "ọ": "o",
367 "ổ": "o",
368 "ỗ": "o",
369 "ộ": "o",
370 "ờ": "o",
371 "ở": "o",
372 "ỡ": "o",
373 "ớ": "o",
374 "ợ": "o",
375 "ù": "u",
376 "ú": "u",
377 "û": "u",
378 "ü": "u",
379 "ủ": "u",
380 "ụ": "u",
381 "ử": "u",
382 "ữ": "u",
383 "ự": "u",
384 "ý": "y",
385 "ÿ": "y",
386 "Ā": "A",
387 "ā": "a",
388 "Ă": "A",
389 "ă": "a",
390 "Ą": "A",
391 "ą": "a",
392 "Ć": "C",
393 "ć": "c",
394 "Ĉ": "C",
395 "ĉ": "c",
396 "Ċ": "C",
397 "ċ": "c",
398 "Č": "C",
399 "č": "c",
400 "C̆": "C",
401 "c̆": "c",
402 "Ď": "D",
403 "ď": "d",
404 "Đ": "D",
405 "đ": "d",
406 "Ē": "E",
407 "ē": "e",
408 "Ĕ": "E",
409 "ĕ": "e",
410 "Ė": "E",
411 "ė": "e",
412 "Ę": "E",
413 "ę": "e",
414 "Ě": "E",
415 "ě": "e",
416 "Ĝ": "G",
417 "Ǵ": "G",
418 "ĝ": "g",
419 "ǵ": "g",
420 "Ğ": "G",
421 "ğ": "g",
422 "Ġ": "G",
423 "ġ": "g",
424 "Ģ": "G",
425 "ģ": "g",
426 "Ĥ": "H",
427 "ĥ": "h",
428 "Ħ": "H",
429 "ħ": "h",
430 "Ḫ": "H",
431 "ḫ": "h",
432 "Ĩ": "I",
433 "ĩ": "i",
434 "Ī": "I",
435 "ī": "i",
436 "Ĭ": "I",
437 "ĭ": "i",
438 "Į": "I",
439 "į": "i",
440 "İ": "I",
441 "ı": "i",
442 "IJ": "IJ",
443 "ij": "ij",
444 "Ĵ": "J",
445 "ĵ": "j",
446 "Ķ": "K",
447 "ķ": "k",
448 "Ḱ": "K",
449 "ḱ": "k",
450 "K̆": "K",
451 "k̆": "k",
452 "Ĺ": "L",
453 "ĺ": "l",
454 "Ļ": "L",
455 "ļ": "l",
456 "Ľ": "L",
457 "ľ": "l",
458 "Ŀ": "L",
459 "ŀ": "l",
460 "Ł": "l",
461 "ł": "l",
462 "Ḿ": "M",
463 "ḿ": "m",
464 "M̆": "M",
465 "m̆": "m",
466 "Ń": "N",
467 "ń": "n",
468 "Ņ": "N",
469 "ņ": "n",
470 "Ň": "N",
471 "ň": "n",
472 "ʼn": "n",
473 "N̆": "N",
474 "n̆": "n",
475 "Ō": "O",
476 "ō": "o",
477 "Ŏ": "O",
478 "ŏ": "o",
479 "Ő": "O",
480 "ő": "o",
481 "Œ": "OE",
482 "œ": "oe",
483 "P̆": "P",
484 "p̆": "p",
485 "Ŕ": "R",
486 "ŕ": "r",
487 "Ŗ": "R",
488 "ŗ": "r",
489 "Ř": "R",
490 "ř": "r",
491 "R̆": "R",
492 "r̆": "r",
493 "Ȓ": "R",
494 "ȓ": "r",
495 "Ś": "S",
496 "ś": "s",
497 "Ŝ": "S",
498 "ŝ": "s",
499 "Ş": "S",
500 "Ș": "S",
501 "ș": "s",
502 "ş": "s",
503 "Š": "S",
504 "š": "s",
505 "Ţ": "T",
506 "ţ": "t",
507 "ț": "t",
508 "Ț": "T",
509 "Ť": "T",
510 "ť": "t",
511 "Ŧ": "T",
512 "ŧ": "t",
513 "T̆": "T",
514 "t̆": "t",
515 "Ũ": "U",
516 "ũ": "u",
517 "Ū": "U",
518 "ū": "u",
519 "Ŭ": "U",
520 "ŭ": "u",
521 "Ů": "U",
522 "ů": "u",
523 "Ű": "U",
524 "ű": "u",
525 "Ų": "U",
526 "ų": "u",
527 "Ȗ": "U",
528 "ȗ": "u",
529 "V̆": "V",
530 "v̆": "v",
531 "Ŵ": "W",
532 "ŵ": "w",
533 "Ẃ": "W",
534 "ẃ": "w",
535 "X̆": "X",
536 "x̆": "x",
537 "Ŷ": "Y",
538 "ŷ": "y",
539 "Ÿ": "Y",
540 "Y̆": "Y",
541 "y̆": "y",
542 "Ź": "Z",
543 "ź": "z",
544 "Ż": "Z",
545 "ż": "z",
546 "Ž": "Z",
547 "ž": "z",
548 "ſ": "s",
549 "ƒ": "f",
550 "Ơ": "O",
551 "ơ": "o",
552 "Ư": "U",
553 "ư": "u",
554 "Ǎ": "A",
555 "ǎ": "a",
556 "Ǐ": "I",
557 "ǐ": "i",
558 "Ǒ": "O",
559 "ǒ": "o",
560 "Ǔ": "U",
561 "ǔ": "u",
562 "Ǖ": "U",
563 "ǖ": "u",
564 "Ǘ": "U",
565 "ǘ": "u",
566 "Ǚ": "U",
567 "ǚ": "u",
568 "Ǜ": "U",
569 "ǜ": "u",
570 "Ứ": "U",
571 "ứ": "u",
572 "Ṹ": "U",
573 "ṹ": "u",
574 "Ǻ": "A",
575 "ǻ": "a",
576 "Ǽ": "AE",
577 "ǽ": "ae",
578 "Ǿ": "O",
579 "ǿ": "o",
580 "Þ": "TH",
581 "þ": "th",
582 "Ṕ": "P",
583 "ṕ": "p",
584 "Ṥ": "S",
585 "ṥ": "s",
586 "X́": "X",
587 "x́": "x",
588 "Ѓ": "Г",
589 "ѓ": "г",
590 "Ќ": "К",
591 "ќ": "к",
592 "A̋": "A",
593 "a̋": "a",
594 "E̋": "E",
595 "e̋": "e",
596 "I̋": "I",
597 "i̋": "i",
598 "Ǹ": "N",
599 "ǹ": "n",
600 "Ồ": "O",
601 "ồ": "o",
602 "Ṑ": "O",
603 "ṑ": "o",
604 "Ừ": "U",
605 "ừ": "u",
606 "Ẁ": "W",
607 "ẁ": "w",
608 "Ỳ": "Y",
609 "ỳ": "y",
610 "Ȁ": "A",
611 "ȁ": "a",
612 "Ȅ": "E",
613 "ȅ": "e",
614 "Ȉ": "I",
615 "ȉ": "i",
616 "Ȍ": "O",
617 "ȍ": "o",
618 "Ȑ": "R",
619 "ȑ": "r",
620 "Ȕ": "U",
621 "ȕ": "u",
622 "B̌": "B",
623 "b̌": "b",
624 "Č̣": "C",
625 "č̣": "c",
626 "Ê̌": "E",
627 "ê̌": "e",
628 "F̌": "F",
629 "f̌": "f",
630 "Ǧ": "G",
631 "ǧ": "g",
632 "Ȟ": "H",
633 "ȟ": "h",
634 "J̌": "J",
635 "ǰ": "j",
636 "Ǩ": "K",
637 "ǩ": "k",
638 "M̌": "M",
639 "m̌": "m",
640 "P̌": "P",
641 "p̌": "p",
642 "Q̌": "Q",
643 "q̌": "q",
644 "Ř̩": "R",
645 "ř̩": "r",
646 "Ṧ": "S",
647 "ṧ": "s",
648 "V̌": "V",
649 "v̌": "v",
650 "W̌": "W",
651 "w̌": "w",
652 "X̌": "X",
653 "x̌": "x",
654 "Y̌": "Y",
655 "y̌": "y",
656 "A̧": "A",
657 "a̧": "a",
658 "B̧": "B",
659 "b̧": "b",
660 "Ḑ": "D",
661 "ḑ": "d",
662 "Ȩ": "E",
663 "ȩ": "e",
664 "Ɛ̧": "E",
665 "ɛ̧": "e",
666 "Ḩ": "H",
667 "ḩ": "h",
668 "I̧": "I",
669 "i̧": "i",
670 "Ɨ̧": "I",
671 "ɨ̧": "i",
672 "M̧": "M",
673 "m̧": "m",
674 "O̧": "O",
675 "o̧": "o",
676 "Q̧": "Q",
677 "q̧": "q",
678 "U̧": "U",
679 "u̧": "u",
680 "X̧": "X",
681 "x̧": "x",
682 "Z̧": "Z",
683 "z̧": "z",
684 "й":"и",
685 "Й":"И",
686 "ё":"е",
687 "Ё":"Е",
688 };
689
690 var chars = Object.keys(characterMap).join('|');
691 var allAccents = new RegExp(chars, 'g');
692 var firstAccent = new RegExp(chars, '');
693
694 function matcher(match) {
695 return characterMap[match];
696 }
697
698 var removeAccents = function(string) {
699 return string.replace(allAccents, matcher);
700 };
701
702 var hasAccents = function(string) {
703 return !!string.match(firstAccent);
704 };
705
706 module.exports = removeAccents;
707 module.exports.has = hasAccents;
708 module.exports.remove = removeAccents;
709
710
711 /***/ }),
712
713 /***/ 7308:
714 /***/ (function(module, exports, __webpack_require__) {
715
716 var __WEBPACK_AMD_DEFINE_RESULT__;;/*! showdown v 1.9.1 - 02-11-2019 */
717 (function(){
718 /**
719 * Created by Tivie on 13-07-2015.
720 */
721
722 function getDefaultOpts (simple) {
723 'use strict';
724
725 var defaultOptions = {
726 omitExtraWLInCodeBlocks: {
727 defaultValue: false,
728 describe: 'Omit the default extra whiteline added to code blocks',
729 type: 'boolean'
730 },
731 noHeaderId: {
732 defaultValue: false,
733 describe: 'Turn on/off generated header id',
734 type: 'boolean'
735 },
736 prefixHeaderId: {
737 defaultValue: false,
738 describe: 'Add a prefix to the generated header ids. Passing a string will prefix that string to the header id. Setting to true will add a generic \'section-\' prefix',
739 type: 'string'
740 },
741 rawPrefixHeaderId: {
742 defaultValue: false,
743 describe: 'Setting this option to true will prevent showdown from modifying the prefix. This might result in malformed IDs (if, for instance, the " char is used in the prefix)',
744 type: 'boolean'
745 },
746 ghCompatibleHeaderId: {
747 defaultValue: false,
748 describe: 'Generate header ids compatible with github style (spaces are replaced with dashes, a bunch of non alphanumeric chars are removed)',
749 type: 'boolean'
750 },
751 rawHeaderId: {
752 defaultValue: false,
753 describe: 'Remove only spaces, \' and " from generated header ids (including prefixes), replacing them with dashes (-). WARNING: This might result in malformed ids',
754 type: 'boolean'
755 },
756 headerLevelStart: {
757 defaultValue: false,
758 describe: 'The header blocks level start',
759 type: 'integer'
760 },
761 parseImgDimensions: {
762 defaultValue: false,
763 describe: 'Turn on/off image dimension parsing',
764 type: 'boolean'
765 },
766 simplifiedAutoLink: {
767 defaultValue: false,
768 describe: 'Turn on/off GFM autolink style',
769 type: 'boolean'
770 },
771 excludeTrailingPunctuationFromURLs: {
772 defaultValue: false,
773 describe: 'Excludes trailing punctuation from links generated with autoLinking',
774 type: 'boolean'
775 },
776 literalMidWordUnderscores: {
777 defaultValue: false,
778 describe: 'Parse midword underscores as literal underscores',
779 type: 'boolean'
780 },
781 literalMidWordAsterisks: {
782 defaultValue: false,
783 describe: 'Parse midword asterisks as literal asterisks',
784 type: 'boolean'
785 },
786 strikethrough: {
787 defaultValue: false,
788 describe: 'Turn on/off strikethrough support',
789 type: 'boolean'
790 },
791 tables: {
792 defaultValue: false,
793 describe: 'Turn on/off tables support',
794 type: 'boolean'
795 },
796 tablesHeaderId: {
797 defaultValue: false,
798 describe: 'Add an id to table headers',
799 type: 'boolean'
800 },
801 ghCodeBlocks: {
802 defaultValue: true,
803 describe: 'Turn on/off GFM fenced code blocks support',
804 type: 'boolean'
805 },
806 tasklists: {
807 defaultValue: false,
808 describe: 'Turn on/off GFM tasklist support',
809 type: 'boolean'
810 },
811 smoothLivePreview: {
812 defaultValue: false,
813 describe: 'Prevents weird effects in live previews due to incomplete input',
814 type: 'boolean'
815 },
816 smartIndentationFix: {
817 defaultValue: false,
818 description: 'Tries to smartly fix indentation in es6 strings',
819 type: 'boolean'
820 },
821 disableForced4SpacesIndentedSublists: {
822 defaultValue: false,
823 description: 'Disables the requirement of indenting nested sublists by 4 spaces',
824 type: 'boolean'
825 },
826 simpleLineBreaks: {
827 defaultValue: false,
828 description: 'Parses simple line breaks as <br> (GFM Style)',
829 type: 'boolean'
830 },
831 requireSpaceBeforeHeadingText: {
832 defaultValue: false,
833 description: 'Makes adding a space between `#` and the header text mandatory (GFM Style)',
834 type: 'boolean'
835 },
836 ghMentions: {
837 defaultValue: false,
838 description: 'Enables github @mentions',
839 type: 'boolean'
840 },
841 ghMentionsLink: {
842 defaultValue: 'https://github.com/{u}',
843 description: 'Changes the link generated by @mentions. Only applies if ghMentions option is enabled.',
844 type: 'string'
845 },
846 encodeEmails: {
847 defaultValue: true,
848 description: 'Encode e-mail addresses through the use of Character Entities, transforming ASCII e-mail addresses into its equivalent decimal entities',
849 type: 'boolean'
850 },
851 openLinksInNewWindow: {
852 defaultValue: false,
853 description: 'Open all links in new windows',
854 type: 'boolean'
855 },
856 backslashEscapesHTMLTags: {
857 defaultValue: false,
858 description: 'Support for HTML Tag escaping. ex: \<div>foo\</div>',
859 type: 'boolean'
860 },
861 emoji: {
862 defaultValue: false,
863 description: 'Enable emoji support. Ex: `this is a :smile: emoji`',
864 type: 'boolean'
865 },
866 underline: {
867 defaultValue: false,
868 description: 'Enable support for underline. Syntax is double or triple underscores: `__underline word__`. With this option enabled, underscores no longer parses into `<em>` and `<strong>`',
869 type: 'boolean'
870 },
871 completeHTMLDocument: {
872 defaultValue: false,
873 description: 'Outputs a complete html document, including `<html>`, `<head>` and `<body>` tags',
874 type: 'boolean'
875 },
876 metadata: {
877 defaultValue: false,
878 description: 'Enable support for document metadata (defined at the top of the document between `«««` and `»»»` or between `---` and `---`).',
879 type: 'boolean'
880 },
881 splitAdjacentBlockquotes: {
882 defaultValue: false,
883 description: 'Split adjacent blockquote blocks',
884 type: 'boolean'
885 }
886 };
887 if (simple === false) {
888 return JSON.parse(JSON.stringify(defaultOptions));
889 }
890 var ret = {};
891 for (var opt in defaultOptions) {
892 if (defaultOptions.hasOwnProperty(opt)) {
893 ret[opt] = defaultOptions[opt].defaultValue;
894 }
895 }
896 return ret;
897 }
898
899 function allOptionsOn () {
900 'use strict';
901 var options = getDefaultOpts(true),
902 ret = {};
903 for (var opt in options) {
904 if (options.hasOwnProperty(opt)) {
905 ret[opt] = true;
906 }
907 }
908 return ret;
909 }
910
911 /**
912 * Created by Tivie on 06-01-2015.
913 */
914
915 // Private properties
916 var showdown = {},
917 parsers = {},
918 extensions = {},
919 globalOptions = getDefaultOpts(true),
920 setFlavor = 'vanilla',
921 flavor = {
922 github: {
923 omitExtraWLInCodeBlocks: true,
924 simplifiedAutoLink: true,
925 excludeTrailingPunctuationFromURLs: true,
926 literalMidWordUnderscores: true,
927 strikethrough: true,
928 tables: true,
929 tablesHeaderId: true,
930 ghCodeBlocks: true,
931 tasklists: true,
932 disableForced4SpacesIndentedSublists: true,
933 simpleLineBreaks: true,
934 requireSpaceBeforeHeadingText: true,
935 ghCompatibleHeaderId: true,
936 ghMentions: true,
937 backslashEscapesHTMLTags: true,
938 emoji: true,
939 splitAdjacentBlockquotes: true
940 },
941 original: {
942 noHeaderId: true,
943 ghCodeBlocks: false
944 },
945 ghost: {
946 omitExtraWLInCodeBlocks: true,
947 parseImgDimensions: true,
948 simplifiedAutoLink: true,
949 excludeTrailingPunctuationFromURLs: true,
950 literalMidWordUnderscores: true,
951 strikethrough: true,
952 tables: true,
953 tablesHeaderId: true,
954 ghCodeBlocks: true,
955 tasklists: true,
956 smoothLivePreview: true,
957 simpleLineBreaks: true,
958 requireSpaceBeforeHeadingText: true,
959 ghMentions: false,
960 encodeEmails: true
961 },
962 vanilla: getDefaultOpts(true),
963 allOn: allOptionsOn()
964 };
965
966 /**
967 * helper namespace
968 * @type {{}}
969 */
970 showdown.helper = {};
971
972 /**
973 * TODO LEGACY SUPPORT CODE
974 * @type {{}}
975 */
976 showdown.extensions = {};
977
978 /**
979 * Set a global option
980 * @static
981 * @param {string} key
982 * @param {*} value
983 * @returns {showdown}
984 */
985 showdown.setOption = function (key, value) {
986 'use strict';
987 globalOptions[key] = value;
988 return this;
989 };
990
991 /**
992 * Get a global option
993 * @static
994 * @param {string} key
995 * @returns {*}
996 */
997 showdown.getOption = function (key) {
998 'use strict';
999 return globalOptions[key];
1000 };
1001
1002 /**
1003 * Get the global options
1004 * @static
1005 * @returns {{}}
1006 */
1007 showdown.getOptions = function () {
1008 'use strict';
1009 return globalOptions;
1010 };
1011
1012 /**
1013 * Reset global options to the default values
1014 * @static
1015 */
1016 showdown.resetOptions = function () {
1017 'use strict';
1018 globalOptions = getDefaultOpts(true);
1019 };
1020
1021 /**
1022 * Set the flavor showdown should use as default
1023 * @param {string} name
1024 */
1025 showdown.setFlavor = function (name) {
1026 'use strict';
1027 if (!flavor.hasOwnProperty(name)) {
1028 throw Error(name + ' flavor was not found');
1029 }
1030 showdown.resetOptions();
1031 var preset = flavor[name];
1032 setFlavor = name;
1033 for (var option in preset) {
1034 if (preset.hasOwnProperty(option)) {
1035 globalOptions[option] = preset[option];
1036 }
1037 }
1038 };
1039
1040 /**
1041 * Get the currently set flavor
1042 * @returns {string}
1043 */
1044 showdown.getFlavor = function () {
1045 'use strict';
1046 return setFlavor;
1047 };
1048
1049 /**
1050 * Get the options of a specified flavor. Returns undefined if the flavor was not found
1051 * @param {string} name Name of the flavor
1052 * @returns {{}|undefined}
1053 */
1054 showdown.getFlavorOptions = function (name) {
1055 'use strict';
1056 if (flavor.hasOwnProperty(name)) {
1057 return flavor[name];
1058 }
1059 };
1060
1061 /**
1062 * Get the default options
1063 * @static
1064 * @param {boolean} [simple=true]
1065 * @returns {{}}
1066 */
1067 showdown.getDefaultOptions = function (simple) {
1068 'use strict';
1069 return getDefaultOpts(simple);
1070 };
1071
1072 /**
1073 * Get or set a subParser
1074 *
1075 * subParser(name) - Get a registered subParser
1076 * subParser(name, func) - Register a subParser
1077 * @static
1078 * @param {string} name
1079 * @param {function} [func]
1080 * @returns {*}
1081 */
1082 showdown.subParser = function (name, func) {
1083 'use strict';
1084 if (showdown.helper.isString(name)) {
1085 if (typeof func !== 'undefined') {
1086 parsers[name] = func;
1087 } else {
1088 if (parsers.hasOwnProperty(name)) {
1089 return parsers[name];
1090 } else {
1091 throw Error('SubParser named ' + name + ' not registered!');
1092 }
1093 }
1094 }
1095 };
1096
1097 /**
1098 * Gets or registers an extension
1099 * @static
1100 * @param {string} name
1101 * @param {object|function=} ext
1102 * @returns {*}
1103 */
1104 showdown.extension = function (name, ext) {
1105 'use strict';
1106
1107 if (!showdown.helper.isString(name)) {
1108 throw Error('Extension \'name\' must be a string');
1109 }
1110
1111 name = showdown.helper.stdExtName(name);
1112
1113 // Getter
1114 if (showdown.helper.isUndefined(ext)) {
1115 if (!extensions.hasOwnProperty(name)) {
1116 throw Error('Extension named ' + name + ' is not registered!');
1117 }
1118 return extensions[name];
1119
1120 // Setter
1121 } else {
1122 // Expand extension if it's wrapped in a function
1123 if (typeof ext === 'function') {
1124 ext = ext();
1125 }
1126
1127 // Ensure extension is an array
1128 if (!showdown.helper.isArray(ext)) {
1129 ext = [ext];
1130 }
1131
1132 var validExtension = validate(ext, name);
1133
1134 if (validExtension.valid) {
1135 extensions[name] = ext;
1136 } else {
1137 throw Error(validExtension.error);
1138 }
1139 }
1140 };
1141
1142 /**
1143 * Gets all extensions registered
1144 * @returns {{}}
1145 */
1146 showdown.getAllExtensions = function () {
1147 'use strict';
1148 return extensions;
1149 };
1150
1151 /**
1152 * Remove an extension
1153 * @param {string} name
1154 */
1155 showdown.removeExtension = function (name) {
1156 'use strict';
1157 delete extensions[name];
1158 };
1159
1160 /**
1161 * Removes all extensions
1162 */
1163 showdown.resetExtensions = function () {
1164 'use strict';
1165 extensions = {};
1166 };
1167
1168 /**
1169 * Validate extension
1170 * @param {array} extension
1171 * @param {string} name
1172 * @returns {{valid: boolean, error: string}}
1173 */
1174 function validate (extension, name) {
1175 'use strict';
1176
1177 var errMsg = (name) ? 'Error in ' + name + ' extension->' : 'Error in unnamed extension',
1178 ret = {
1179 valid: true,
1180 error: ''
1181 };
1182
1183 if (!showdown.helper.isArray(extension)) {
1184 extension = [extension];
1185 }
1186
1187 for (var i = 0; i < extension.length; ++i) {
1188 var baseMsg = errMsg + ' sub-extension ' + i + ': ',
1189 ext = extension[i];
1190 if (typeof ext !== 'object') {
1191 ret.valid = false;
1192 ret.error = baseMsg + 'must be an object, but ' + typeof ext + ' given';
1193 return ret;
1194 }
1195
1196 if (!showdown.helper.isString(ext.type)) {
1197 ret.valid = false;
1198 ret.error = baseMsg + 'property "type" must be a string, but ' + typeof ext.type + ' given';
1199 return ret;
1200 }
1201
1202 var type = ext.type = ext.type.toLowerCase();
1203
1204 // normalize extension type
1205 if (type === 'language') {
1206 type = ext.type = 'lang';
1207 }
1208
1209 if (type === 'html') {
1210 type = ext.type = 'output';
1211 }
1212
1213 if (type !== 'lang' && type !== 'output' && type !== 'listener') {
1214 ret.valid = false;
1215 ret.error = baseMsg + 'type ' + type + ' is not recognized. Valid values: "lang/language", "output/html" or "listener"';
1216 return ret;
1217 }
1218
1219 if (type === 'listener') {
1220 if (showdown.helper.isUndefined(ext.listeners)) {
1221 ret.valid = false;
1222 ret.error = baseMsg + '. Extensions of type "listener" must have a property called "listeners"';
1223 return ret;
1224 }
1225 } else {
1226 if (showdown.helper.isUndefined(ext.filter) && showdown.helper.isUndefined(ext.regex)) {
1227 ret.valid = false;
1228 ret.error = baseMsg + type + ' extensions must define either a "regex" property or a "filter" method';
1229 return ret;
1230 }
1231 }
1232
1233 if (ext.listeners) {
1234 if (typeof ext.listeners !== 'object') {
1235 ret.valid = false;
1236 ret.error = baseMsg + '"listeners" property must be an object but ' + typeof ext.listeners + ' given';
1237 return ret;
1238 }
1239 for (var ln in ext.listeners) {
1240 if (ext.listeners.hasOwnProperty(ln)) {
1241 if (typeof ext.listeners[ln] !== 'function') {
1242 ret.valid = false;
1243 ret.error = baseMsg + '"listeners" property must be an hash of [event name]: [callback]. listeners.' + ln +
1244 ' must be a function but ' + typeof ext.listeners[ln] + ' given';
1245 return ret;
1246 }
1247 }
1248 }
1249 }
1250
1251 if (ext.filter) {
1252 if (typeof ext.filter !== 'function') {
1253 ret.valid = false;
1254 ret.error = baseMsg + '"filter" must be a function, but ' + typeof ext.filter + ' given';
1255 return ret;
1256 }
1257 } else if (ext.regex) {
1258 if (showdown.helper.isString(ext.regex)) {
1259 ext.regex = new RegExp(ext.regex, 'g');
1260 }
1261 if (!(ext.regex instanceof RegExp)) {
1262 ret.valid = false;
1263 ret.error = baseMsg + '"regex" property must either be a string or a RegExp object, but ' + typeof ext.regex + ' given';
1264 return ret;
1265 }
1266 if (showdown.helper.isUndefined(ext.replace)) {
1267 ret.valid = false;
1268 ret.error = baseMsg + '"regex" extensions must implement a replace string or function';
1269 return ret;
1270 }
1271 }
1272 }
1273 return ret;
1274 }
1275
1276 /**
1277 * Validate extension
1278 * @param {object} ext
1279 * @returns {boolean}
1280 */
1281 showdown.validateExtension = function (ext) {
1282 'use strict';
1283
1284 var validateExtension = validate(ext, null);
1285 if (!validateExtension.valid) {
1286 console.warn(validateExtension.error);
1287 return false;
1288 }
1289 return true;
1290 };
1291
1292 /**
1293 * showdownjs helper functions
1294 */
1295
1296 if (!showdown.hasOwnProperty('helper')) {
1297 showdown.helper = {};
1298 }
1299
1300 /**
1301 * Check if var is string
1302 * @static
1303 * @param {string} a
1304 * @returns {boolean}
1305 */
1306 showdown.helper.isString = function (a) {
1307 'use strict';
1308 return (typeof a === 'string' || a instanceof String);
1309 };
1310
1311 /**
1312 * Check if var is a function
1313 * @static
1314 * @param {*} a
1315 * @returns {boolean}
1316 */
1317 showdown.helper.isFunction = function (a) {
1318 'use strict';
1319 var getType = {};
1320 return a && getType.toString.call(a) === '[object Function]';
1321 };
1322
1323 /**
1324 * isArray helper function
1325 * @static
1326 * @param {*} a
1327 * @returns {boolean}
1328 */
1329 showdown.helper.isArray = function (a) {
1330 'use strict';
1331 return Array.isArray(a);
1332 };
1333
1334 /**
1335 * Check if value is undefined
1336 * @static
1337 * @param {*} value The value to check.
1338 * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
1339 */
1340 showdown.helper.isUndefined = function (value) {
1341 'use strict';
1342 return typeof value === 'undefined';
1343 };
1344
1345 /**
1346 * ForEach helper function
1347 * Iterates over Arrays and Objects (own properties only)
1348 * @static
1349 * @param {*} obj
1350 * @param {function} callback Accepts 3 params: 1. value, 2. key, 3. the original array/object
1351 */
1352 showdown.helper.forEach = function (obj, callback) {
1353 'use strict';
1354 // check if obj is defined
1355 if (showdown.helper.isUndefined(obj)) {
1356 throw new Error('obj param is required');
1357 }
1358
1359 if (showdown.helper.isUndefined(callback)) {
1360 throw new Error('callback param is required');
1361 }
1362
1363 if (!showdown.helper.isFunction(callback)) {
1364 throw new Error('callback param must be a function/closure');
1365 }
1366
1367 if (typeof obj.forEach === 'function') {
1368 obj.forEach(callback);
1369 } else if (showdown.helper.isArray(obj)) {
1370 for (var i = 0; i < obj.length; i++) {
1371 callback(obj[i], i, obj);
1372 }
1373 } else if (typeof (obj) === 'object') {
1374 for (var prop in obj) {
1375 if (obj.hasOwnProperty(prop)) {
1376 callback(obj[prop], prop, obj);
1377 }
1378 }
1379 } else {
1380 throw new Error('obj does not seem to be an array or an iterable object');
1381 }
1382 };
1383
1384 /**
1385 * Standardidize extension name
1386 * @static
1387 * @param {string} s extension name
1388 * @returns {string}
1389 */
1390 showdown.helper.stdExtName = function (s) {
1391 'use strict';
1392 return s.replace(/[_?*+\/\\.^-]/g, '').replace(/\s/g, '').toLowerCase();
1393 };
1394
1395 function escapeCharactersCallback (wholeMatch, m1) {
1396 'use strict';
1397 var charCodeToEscape = m1.charCodeAt(0);
1398 return '¨E' + charCodeToEscape + 'E';
1399 }
1400
1401 /**
1402 * Callback used to escape characters when passing through String.replace
1403 * @static
1404 * @param {string} wholeMatch
1405 * @param {string} m1
1406 * @returns {string}
1407 */
1408 showdown.helper.escapeCharactersCallback = escapeCharactersCallback;
1409
1410 /**
1411 * Escape characters in a string
1412 * @static
1413 * @param {string} text
1414 * @param {string} charsToEscape
1415 * @param {boolean} afterBackslash
1416 * @returns {XML|string|void|*}
1417 */
1418 showdown.helper.escapeCharacters = function (text, charsToEscape, afterBackslash) {
1419 'use strict';
1420 // First we have to escape the escape characters so that
1421 // we can build a character class out of them
1422 var regexString = '([' + charsToEscape.replace(/([\[\]\\])/g, '\\$1') + '])';
1423
1424 if (afterBackslash) {
1425 regexString = '\\\\' + regexString;
1426 }
1427
1428 var regex = new RegExp(regexString, 'g');
1429 text = text.replace(regex, escapeCharactersCallback);
1430
1431 return text;
1432 };
1433
1434 /**
1435 * Unescape HTML entities
1436 * @param txt
1437 * @returns {string}
1438 */
1439 showdown.helper.unescapeHTMLEntities = function (txt) {
1440 'use strict';
1441
1442 return txt
1443 .replace(/&quot;/g, '"')
1444 .replace(/&lt;/g, '<')
1445 .replace(/&gt;/g, '>')
1446 .replace(/&amp;/g, '&');
1447 };
1448
1449 var rgxFindMatchPos = function (str, left, right, flags) {
1450 'use strict';
1451 var f = flags || '',
1452 g = f.indexOf('g') > -1,
1453 x = new RegExp(left + '|' + right, 'g' + f.replace(/g/g, '')),
1454 l = new RegExp(left, f.replace(/g/g, '')),
1455 pos = [],
1456 t, s, m, start, end;
1457
1458 do {
1459 t = 0;
1460 while ((m = x.exec(str))) {
1461 if (l.test(m[0])) {
1462 if (!(t++)) {
1463 s = x.lastIndex;
1464 start = s - m[0].length;
1465 }
1466 } else if (t) {
1467 if (!--t) {
1468 end = m.index + m[0].length;
1469 var obj = {
1470 left: {start: start, end: s},
1471 match: {start: s, end: m.index},
1472 right: {start: m.index, end: end},
1473 wholeMatch: {start: start, end: end}
1474 };
1475 pos.push(obj);
1476 if (!g) {
1477 return pos;
1478 }
1479 }
1480 }
1481 }
1482 } while (t && (x.lastIndex = s));
1483
1484 return pos;
1485 };
1486
1487 /**
1488 * matchRecursiveRegExp
1489 *
1490 * (c) 2007 Steven Levithan <stevenlevithan.com>
1491 * MIT License
1492 *
1493 * Accepts a string to search, a left and right format delimiter
1494 * as regex patterns, and optional regex flags. Returns an array
1495 * of matches, allowing nested instances of left/right delimiters.
1496 * Use the "g" flag to return all matches, otherwise only the
1497 * first is returned. Be careful to ensure that the left and
1498 * right format delimiters produce mutually exclusive matches.
1499 * Backreferences are not supported within the right delimiter
1500 * due to how it is internally combined with the left delimiter.
1501 * When matching strings whose format delimiters are unbalanced
1502 * to the left or right, the output is intentionally as a
1503 * conventional regex library with recursion support would
1504 * produce, e.g. "<<x>" and "<x>>" both produce ["x"] when using
1505 * "<" and ">" as the delimiters (both strings contain a single,
1506 * balanced instance of "<x>").
1507 *
1508 * examples:
1509 * matchRecursiveRegExp("test", "\\(", "\\)")
1510 * returns: []
1511 * matchRecursiveRegExp("<t<<e>><s>>t<>", "<", ">", "g")
1512 * returns: ["t<<e>><s>", ""]
1513 * matchRecursiveRegExp("<div id=\"x\">test</div>", "<div\\b[^>]*>", "</div>", "gi")
1514 * returns: ["test"]
1515 */
1516 showdown.helper.matchRecursiveRegExp = function (str, left, right, flags) {
1517 'use strict';
1518
1519 var matchPos = rgxFindMatchPos (str, left, right, flags),
1520 results = [];
1521
1522 for (var i = 0; i < matchPos.length; ++i) {
1523 results.push([
1524 str.slice(matchPos[i].wholeMatch.start, matchPos[i].wholeMatch.end),
1525 str.slice(matchPos[i].match.start, matchPos[i].match.end),
1526 str.slice(matchPos[i].left.start, matchPos[i].left.end),
1527 str.slice(matchPos[i].right.start, matchPos[i].right.end)
1528 ]);
1529 }
1530 return results;
1531 };
1532
1533 /**
1534 *
1535 * @param {string} str
1536 * @param {string|function} replacement
1537 * @param {string} left
1538 * @param {string} right
1539 * @param {string} flags
1540 * @returns {string}
1541 */
1542 showdown.helper.replaceRecursiveRegExp = function (str, replacement, left, right, flags) {
1543 'use strict';
1544
1545 if (!showdown.helper.isFunction(replacement)) {
1546 var repStr = replacement;
1547 replacement = function () {
1548 return repStr;
1549 };
1550 }
1551
1552 var matchPos = rgxFindMatchPos(str, left, right, flags),
1553 finalStr = str,
1554 lng = matchPos.length;
1555
1556 if (lng > 0) {
1557 var bits = [];
1558 if (matchPos[0].wholeMatch.start !== 0) {
1559 bits.push(str.slice(0, matchPos[0].wholeMatch.start));
1560 }
1561 for (var i = 0; i < lng; ++i) {
1562 bits.push(
1563 replacement(
1564 str.slice(matchPos[i].wholeMatch.start, matchPos[i].wholeMatch.end),
1565 str.slice(matchPos[i].match.start, matchPos[i].match.end),
1566 str.slice(matchPos[i].left.start, matchPos[i].left.end),
1567 str.slice(matchPos[i].right.start, matchPos[i].right.end)
1568 )
1569 );
1570 if (i < lng - 1) {
1571 bits.push(str.slice(matchPos[i].wholeMatch.end, matchPos[i + 1].wholeMatch.start));
1572 }
1573 }
1574 if (matchPos[lng - 1].wholeMatch.end < str.length) {
1575 bits.push(str.slice(matchPos[lng - 1].wholeMatch.end));
1576 }
1577 finalStr = bits.join('');
1578 }
1579 return finalStr;
1580 };
1581
1582 /**
1583 * Returns the index within the passed String object of the first occurrence of the specified regex,
1584 * starting the search at fromIndex. Returns -1 if the value is not found.
1585 *
1586 * @param {string} str string to search
1587 * @param {RegExp} regex Regular expression to search
1588 * @param {int} [fromIndex = 0] Index to start the search
1589 * @returns {Number}
1590 * @throws InvalidArgumentError
1591 */
1592 showdown.helper.regexIndexOf = function (str, regex, fromIndex) {
1593 'use strict';
1594 if (!showdown.helper.isString(str)) {
1595 throw 'InvalidArgumentError: first parameter of showdown.helper.regexIndexOf function must be a string';
1596 }
1597 if (regex instanceof RegExp === false) {
1598 throw 'InvalidArgumentError: second parameter of showdown.helper.regexIndexOf function must be an instance of RegExp';
1599 }
1600 var indexOf = str.substring(fromIndex || 0).search(regex);
1601 return (indexOf >= 0) ? (indexOf + (fromIndex || 0)) : indexOf;
1602 };
1603
1604 /**
1605 * Splits the passed string object at the defined index, and returns an array composed of the two substrings
1606 * @param {string} str string to split
1607 * @param {int} index index to split string at
1608 * @returns {[string,string]}
1609 * @throws InvalidArgumentError
1610 */
1611 showdown.helper.splitAtIndex = function (str, index) {
1612 'use strict';
1613 if (!showdown.helper.isString(str)) {
1614 throw 'InvalidArgumentError: first parameter of showdown.helper.regexIndexOf function must be a string';
1615 }
1616 return [str.substring(0, index), str.substring(index)];
1617 };
1618
1619 /**
1620 * Obfuscate an e-mail address through the use of Character Entities,
1621 * transforming ASCII characters into their equivalent decimal or hex entities.
1622 *
1623 * Since it has a random component, subsequent calls to this function produce different results
1624 *
1625 * @param {string} mail
1626 * @returns {string}
1627 */
1628 showdown.helper.encodeEmailAddress = function (mail) {
1629 'use strict';
1630 var encode = [
1631 function (ch) {
1632 return '&#' + ch.charCodeAt(0) + ';';
1633 },
1634 function (ch) {
1635 return '&#x' + ch.charCodeAt(0).toString(16) + ';';
1636 },
1637 function (ch) {
1638 return ch;
1639 }
1640 ];
1641
1642 mail = mail.replace(/./g, function (ch) {
1643 if (ch === '@') {
1644 // this *must* be encoded. I insist.
1645 ch = encode[Math.floor(Math.random() * 2)](ch);
1646 } else {
1647 var r = Math.random();
1648 // roughly 10% raw, 45% hex, 45% dec
1649 ch = (
1650 r > 0.9 ? encode[2](ch) : r > 0.45 ? encode[1](ch) : encode[0](ch)
1651 );
1652 }
1653 return ch;
1654 });
1655
1656 return mail;
1657 };
1658
1659 /**
1660 *
1661 * @param str
1662 * @param targetLength
1663 * @param padString
1664 * @returns {string}
1665 */
1666 showdown.helper.padEnd = function padEnd (str, targetLength, padString) {
1667 'use strict';
1668 /*jshint bitwise: false*/
1669 // eslint-disable-next-line space-infix-ops
1670 targetLength = targetLength>>0; //floor if number or convert non-number to 0;
1671 /*jshint bitwise: true*/
1672 padString = String(padString || ' ');
1673 if (str.length > targetLength) {
1674 return String(str);
1675 } else {
1676 targetLength = targetLength - str.length;
1677 if (targetLength > padString.length) {
1678 padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed
1679 }
1680 return String(str) + padString.slice(0,targetLength);
1681 }
1682 };
1683
1684 /**
1685 * POLYFILLS
1686 */
1687 // use this instead of builtin is undefined for IE8 compatibility
1688 if (typeof console === 'undefined') {
1689 console = {
1690 warn: function (msg) {
1691 'use strict';
1692 alert(msg);
1693 },
1694 log: function (msg) {
1695 'use strict';
1696 alert(msg);
1697 },
1698 error: function (msg) {
1699 'use strict';
1700 throw msg;
1701 }
1702 };
1703 }
1704
1705 /**
1706 * Common regexes.
1707 * We declare some common regexes to improve performance
1708 */
1709 showdown.helper.regexes = {
1710 asteriskDashAndColon: /([*_:~])/g
1711 };
1712
1713 /**
1714 * EMOJIS LIST
1715 */
1716 showdown.helper.emojis = {
1717 '+1':'\ud83d\udc4d',
1718 '-1':'\ud83d\udc4e',
1719 '100':'\ud83d\udcaf',
1720 '1234':'\ud83d\udd22',
1721 '1st_place_medal':'\ud83e\udd47',
1722 '2nd_place_medal':'\ud83e\udd48',
1723 '3rd_place_medal':'\ud83e\udd49',
1724 '8ball':'\ud83c\udfb1',
1725 'a':'\ud83c\udd70\ufe0f',
1726 'ab':'\ud83c\udd8e',
1727 'abc':'\ud83d\udd24',
1728 'abcd':'\ud83d\udd21',
1729 'accept':'\ud83c\ude51',
1730 'aerial_tramway':'\ud83d\udea1',
1731 'airplane':'\u2708\ufe0f',
1732 'alarm_clock':'\u23f0',
1733 'alembic':'\u2697\ufe0f',
1734 'alien':'\ud83d\udc7d',
1735 'ambulance':'\ud83d\ude91',
1736 'amphora':'\ud83c\udffa',
1737 'anchor':'\u2693\ufe0f',
1738 'angel':'\ud83d\udc7c',
1739 'anger':'\ud83d\udca2',
1740 'angry':'\ud83d\ude20',
1741 'anguished':'\ud83d\ude27',
1742 'ant':'\ud83d\udc1c',
1743 'apple':'\ud83c\udf4e',
1744 'aquarius':'\u2652\ufe0f',
1745 'aries':'\u2648\ufe0f',
1746 'arrow_backward':'\u25c0\ufe0f',
1747 'arrow_double_down':'\u23ec',
1748 'arrow_double_up':'\u23eb',
1749 'arrow_down':'\u2b07\ufe0f',
1750 'arrow_down_small':'\ud83d\udd3d',
1751 'arrow_forward':'\u25b6\ufe0f',
1752 'arrow_heading_down':'\u2935\ufe0f',
1753 'arrow_heading_up':'\u2934\ufe0f',
1754 'arrow_left':'\u2b05\ufe0f',
1755 'arrow_lower_left':'\u2199\ufe0f',
1756 'arrow_lower_right':'\u2198\ufe0f',
1757 'arrow_right':'\u27a1\ufe0f',
1758 'arrow_right_hook':'\u21aa\ufe0f',
1759 'arrow_up':'\u2b06\ufe0f',
1760 'arrow_up_down':'\u2195\ufe0f',
1761 'arrow_up_small':'\ud83d\udd3c',
1762 'arrow_upper_left':'\u2196\ufe0f',
1763 'arrow_upper_right':'\u2197\ufe0f',
1764 'arrows_clockwise':'\ud83d\udd03',
1765 'arrows_counterclockwise':'\ud83d\udd04',
1766 'art':'\ud83c\udfa8',
1767 'articulated_lorry':'\ud83d\ude9b',
1768 'artificial_satellite':'\ud83d\udef0',
1769 'astonished':'\ud83d\ude32',
1770 'athletic_shoe':'\ud83d\udc5f',
1771 'atm':'\ud83c\udfe7',
1772 'atom_symbol':'\u269b\ufe0f',
1773 'avocado':'\ud83e\udd51',
1774 'b':'\ud83c\udd71\ufe0f',
1775 'baby':'\ud83d\udc76',
1776 'baby_bottle':'\ud83c\udf7c',
1777 'baby_chick':'\ud83d\udc24',
1778 'baby_symbol':'\ud83d\udebc',
1779 'back':'\ud83d\udd19',
1780 'bacon':'\ud83e\udd53',
1781 'badminton':'\ud83c\udff8',
1782 'baggage_claim':'\ud83d\udec4',
1783 'baguette_bread':'\ud83e\udd56',
1784 'balance_scale':'\u2696\ufe0f',
1785 'balloon':'\ud83c\udf88',
1786 'ballot_box':'\ud83d\uddf3',
1787 'ballot_box_with_check':'\u2611\ufe0f',
1788 'bamboo':'\ud83c\udf8d',
1789 'banana':'\ud83c\udf4c',
1790 'bangbang':'\u203c\ufe0f',
1791 'bank':'\ud83c\udfe6',
1792 'bar_chart':'\ud83d\udcca',
1793 'barber':'\ud83d\udc88',
1794 'baseball':'\u26be\ufe0f',
1795 'basketball':'\ud83c\udfc0',
1796 'basketball_man':'\u26f9\ufe0f',
1797 'basketball_woman':'\u26f9\ufe0f&zwj;\u2640\ufe0f',
1798 'bat':'\ud83e\udd87',
1799 'bath':'\ud83d\udec0',
1800 'bathtub':'\ud83d\udec1',
1801 'battery':'\ud83d\udd0b',
1802 'beach_umbrella':'\ud83c\udfd6',
1803 'bear':'\ud83d\udc3b',
1804 'bed':'\ud83d\udecf',
1805 'bee':'\ud83d\udc1d',
1806 'beer':'\ud83c\udf7a',
1807 'beers':'\ud83c\udf7b',
1808 'beetle':'\ud83d\udc1e',
1809 'beginner':'\ud83d\udd30',
1810 'bell':'\ud83d\udd14',
1811 'bellhop_bell':'\ud83d\udece',
1812 'bento':'\ud83c\udf71',
1813 'biking_man':'\ud83d\udeb4',
1814 'bike':'\ud83d\udeb2',
1815 'biking_woman':'\ud83d\udeb4&zwj;\u2640\ufe0f',
1816 'bikini':'\ud83d\udc59',
1817 'biohazard':'\u2623\ufe0f',
1818 'bird':'\ud83d\udc26',
1819 'birthday':'\ud83c\udf82',
1820 'black_circle':'\u26ab\ufe0f',
1821 'black_flag':'\ud83c\udff4',
1822 'black_heart':'\ud83d\udda4',
1823 'black_joker':'\ud83c\udccf',
1824 'black_large_square':'\u2b1b\ufe0f',
1825 'black_medium_small_square':'\u25fe\ufe0f',
1826 'black_medium_square':'\u25fc\ufe0f',
1827 'black_nib':'\u2712\ufe0f',
1828 'black_small_square':'\u25aa\ufe0f',
1829 'black_square_button':'\ud83d\udd32',
1830 'blonde_man':'\ud83d\udc71',
1831 'blonde_woman':'\ud83d\udc71&zwj;\u2640\ufe0f',
1832 'blossom':'\ud83c\udf3c',
1833 'blowfish':'\ud83d\udc21',
1834 'blue_book':'\ud83d\udcd8',
1835 'blue_car':'\ud83d\ude99',
1836 'blue_heart':'\ud83d\udc99',
1837 'blush':'\ud83d\ude0a',
1838 'boar':'\ud83d\udc17',
1839 'boat':'\u26f5\ufe0f',
1840 'bomb':'\ud83d\udca3',
1841 'book':'\ud83d\udcd6',
1842 'bookmark':'\ud83d\udd16',
1843 'bookmark_tabs':'\ud83d\udcd1',
1844 'books':'\ud83d\udcda',
1845 'boom':'\ud83d\udca5',
1846 'boot':'\ud83d\udc62',
1847 'bouquet':'\ud83d\udc90',
1848 'bowing_man':'\ud83d\ude47',
1849 'bow_and_arrow':'\ud83c\udff9',
1850 'bowing_woman':'\ud83d\ude47&zwj;\u2640\ufe0f',
1851 'bowling':'\ud83c\udfb3',
1852 'boxing_glove':'\ud83e\udd4a',
1853 'boy':'\ud83d\udc66',
1854 'bread':'\ud83c\udf5e',
1855 'bride_with_veil':'\ud83d\udc70',
1856 'bridge_at_night':'\ud83c\udf09',
1857 'briefcase':'\ud83d\udcbc',
1858 'broken_heart':'\ud83d\udc94',
1859 'bug':'\ud83d\udc1b',
1860 'building_construction':'\ud83c\udfd7',
1861 'bulb':'\ud83d\udca1',
1862 'bullettrain_front':'\ud83d\ude85',
1863 'bullettrain_side':'\ud83d\ude84',
1864 'burrito':'\ud83c\udf2f',
1865 'bus':'\ud83d\ude8c',
1866 'business_suit_levitating':'\ud83d\udd74',
1867 'busstop':'\ud83d\ude8f',
1868 'bust_in_silhouette':'\ud83d\udc64',
1869 'busts_in_silhouette':'\ud83d\udc65',
1870 'butterfly':'\ud83e\udd8b',
1871 'cactus':'\ud83c\udf35',
1872 'cake':'\ud83c\udf70',
1873 'calendar':'\ud83d\udcc6',
1874 'call_me_hand':'\ud83e\udd19',
1875 'calling':'\ud83d\udcf2',
1876 'camel':'\ud83d\udc2b',
1877 'camera':'\ud83d\udcf7',
1878 'camera_flash':'\ud83d\udcf8',
1879 'camping':'\ud83c\udfd5',
1880 'cancer':'\u264b\ufe0f',
1881 'candle':'\ud83d\udd6f',
1882 'candy':'\ud83c\udf6c',
1883 'canoe':'\ud83d\udef6',
1884 'capital_abcd':'\ud83d\udd20',
1885 'capricorn':'\u2651\ufe0f',
1886 'car':'\ud83d\ude97',
1887 'card_file_box':'\ud83d\uddc3',
1888 'card_index':'\ud83d\udcc7',
1889 'card_index_dividers':'\ud83d\uddc2',
1890 'carousel_horse':'\ud83c\udfa0',
1891 'carrot':'\ud83e\udd55',
1892 'cat':'\ud83d\udc31',
1893 'cat2':'\ud83d\udc08',
1894 'cd':'\ud83d\udcbf',
1895 'chains':'\u26d3',
1896 'champagne':'\ud83c\udf7e',
1897 'chart':'\ud83d\udcb9',
1898 'chart_with_downwards_trend':'\ud83d\udcc9',
1899 'chart_with_upwards_trend':'\ud83d\udcc8',
1900 'checkered_flag':'\ud83c\udfc1',
1901 'cheese':'\ud83e\uddc0',
1902 'cherries':'\ud83c\udf52',
1903 'cherry_blossom':'\ud83c\udf38',
1904 'chestnut':'\ud83c\udf30',
1905 'chicken':'\ud83d\udc14',
1906 'children_crossing':'\ud83d\udeb8',
1907 'chipmunk':'\ud83d\udc3f',
1908 'chocolate_bar':'\ud83c\udf6b',
1909 'christmas_tree':'\ud83c\udf84',
1910 'church':'\u26ea\ufe0f',
1911 'cinema':'\ud83c\udfa6',
1912 'circus_tent':'\ud83c\udfaa',
1913 'city_sunrise':'\ud83c\udf07',
1914 'city_sunset':'\ud83c\udf06',
1915 'cityscape':'\ud83c\udfd9',
1916 'cl':'\ud83c\udd91',
1917 'clamp':'\ud83d\udddc',
1918 'clap':'\ud83d\udc4f',
1919 'clapper':'\ud83c\udfac',
1920 'classical_building':'\ud83c\udfdb',
1921 'clinking_glasses':'\ud83e\udd42',
1922 'clipboard':'\ud83d\udccb',
1923 'clock1':'\ud83d\udd50',
1924 'clock10':'\ud83d\udd59',
1925 'clock1030':'\ud83d\udd65',
1926 'clock11':'\ud83d\udd5a',
1927 'clock1130':'\ud83d\udd66',
1928 'clock12':'\ud83d\udd5b',
1929 'clock1230':'\ud83d\udd67',
1930 'clock130':'\ud83d\udd5c',
1931 'clock2':'\ud83d\udd51',
1932 'clock230':'\ud83d\udd5d',
1933 'clock3':'\ud83d\udd52',
1934 'clock330':'\ud83d\udd5e',
1935 'clock4':'\ud83d\udd53',
1936 'clock430':'\ud83d\udd5f',
1937 'clock5':'\ud83d\udd54',
1938 'clock530':'\ud83d\udd60',
1939 'clock6':'\ud83d\udd55',
1940 'clock630':'\ud83d\udd61',
1941 'clock7':'\ud83d\udd56',
1942 'clock730':'\ud83d\udd62',
1943 'clock8':'\ud83d\udd57',
1944 'clock830':'\ud83d\udd63',
1945 'clock9':'\ud83d\udd58',
1946 'clock930':'\ud83d\udd64',
1947 'closed_book':'\ud83d\udcd5',
1948 'closed_lock_with_key':'\ud83d\udd10',
1949 'closed_umbrella':'\ud83c\udf02',
1950 'cloud':'\u2601\ufe0f',
1951 'cloud_with_lightning':'\ud83c\udf29',
1952 'cloud_with_lightning_and_rain':'\u26c8',
1953 'cloud_with_rain':'\ud83c\udf27',
1954 'cloud_with_snow':'\ud83c\udf28',
1955 'clown_face':'\ud83e\udd21',
1956 'clubs':'\u2663\ufe0f',
1957 'cocktail':'\ud83c\udf78',
1958 'coffee':'\u2615\ufe0f',
1959 'coffin':'\u26b0\ufe0f',
1960 'cold_sweat':'\ud83d\ude30',
1961 'comet':'\u2604\ufe0f',
1962 'computer':'\ud83d\udcbb',
1963 'computer_mouse':'\ud83d\uddb1',
1964 'confetti_ball':'\ud83c\udf8a',
1965 'confounded':'\ud83d\ude16',
1966 'confused':'\ud83d\ude15',
1967 'congratulations':'\u3297\ufe0f',
1968 'construction':'\ud83d\udea7',
1969 'construction_worker_man':'\ud83d\udc77',
1970 'construction_worker_woman':'\ud83d\udc77&zwj;\u2640\ufe0f',
1971 'control_knobs':'\ud83c\udf9b',
1972 'convenience_store':'\ud83c\udfea',
1973 'cookie':'\ud83c\udf6a',
1974 'cool':'\ud83c\udd92',
1975 'policeman':'\ud83d\udc6e',
1976 'copyright':'\u00a9\ufe0f',
1977 'corn':'\ud83c\udf3d',
1978 'couch_and_lamp':'\ud83d\udecb',
1979 'couple':'\ud83d\udc6b',
1980 'couple_with_heart_woman_man':'\ud83d\udc91',
1981 'couple_with_heart_man_man':'\ud83d\udc68&zwj;\u2764\ufe0f&zwj;\ud83d\udc68',
1982 'couple_with_heart_woman_woman':'\ud83d\udc69&zwj;\u2764\ufe0f&zwj;\ud83d\udc69',
1983 'couplekiss_man_man':'\ud83d\udc68&zwj;\u2764\ufe0f&zwj;\ud83d\udc8b&zwj;\ud83d\udc68',
1984 'couplekiss_man_woman':'\ud83d\udc8f',
1985 'couplekiss_woman_woman':'\ud83d\udc69&zwj;\u2764\ufe0f&zwj;\ud83d\udc8b&zwj;\ud83d\udc69',
1986 'cow':'\ud83d\udc2e',
1987 'cow2':'\ud83d\udc04',
1988 'cowboy_hat_face':'\ud83e\udd20',
1989 'crab':'\ud83e\udd80',
1990 'crayon':'\ud83d\udd8d',
1991 'credit_card':'\ud83d\udcb3',
1992 'crescent_moon':'\ud83c\udf19',
1993 'cricket':'\ud83c\udfcf',
1994 'crocodile':'\ud83d\udc0a',
1995 'croissant':'\ud83e\udd50',
1996 'crossed_fingers':'\ud83e\udd1e',
1997 'crossed_flags':'\ud83c\udf8c',
1998 'crossed_swords':'\u2694\ufe0f',
1999 'crown':'\ud83d\udc51',
2000 'cry':'\ud83d\ude22',
2001 'crying_cat_face':'\ud83d\ude3f',
2002 'crystal_ball':'\ud83d\udd2e',
2003 'cucumber':'\ud83e\udd52',
2004 'cupid':'\ud83d\udc98',
2005 'curly_loop':'\u27b0',
2006 'currency_exchange':'\ud83d\udcb1',
2007 'curry':'\ud83c\udf5b',
2008 'custard':'\ud83c\udf6e',
2009 'customs':'\ud83d\udec3',
2010 'cyclone':'\ud83c\udf00',
2011 'dagger':'\ud83d\udde1',
2012 'dancer':'\ud83d\udc83',
2013 'dancing_women':'\ud83d\udc6f',
2014 'dancing_men':'\ud83d\udc6f&zwj;\u2642\ufe0f',
2015 'dango':'\ud83c\udf61',
2016 'dark_sunglasses':'\ud83d\udd76',
2017 'dart':'\ud83c\udfaf',
2018 'dash':'\ud83d\udca8',
2019 'date':'\ud83d\udcc5',
2020 'deciduous_tree':'\ud83c\udf33',
2021 'deer':'\ud83e\udd8c',
2022 'department_store':'\ud83c\udfec',
2023 'derelict_house':'\ud83c\udfda',
2024 'desert':'\ud83c\udfdc',
2025 'desert_island':'\ud83c\udfdd',
2026 'desktop_computer':'\ud83d\udda5',
2027 'male_detective':'\ud83d\udd75\ufe0f',
2028 'diamond_shape_with_a_dot_inside':'\ud83d\udca0',
2029 'diamonds':'\u2666\ufe0f',
2030 'disappointed':'\ud83d\ude1e',
2031 'disappointed_relieved':'\ud83d\ude25',
2032 'dizzy':'\ud83d\udcab',
2033 'dizzy_face':'\ud83d\ude35',
2034 'do_not_litter':'\ud83d\udeaf',
2035 'dog':'\ud83d\udc36',
2036 'dog2':'\ud83d\udc15',
2037 'dollar':'\ud83d\udcb5',
2038 'dolls':'\ud83c\udf8e',
2039 'dolphin':'\ud83d\udc2c',
2040 'door':'\ud83d\udeaa',
2041 'doughnut':'\ud83c\udf69',
2042 'dove':'\ud83d\udd4a',
2043 'dragon':'\ud83d\udc09',
2044 'dragon_face':'\ud83d\udc32',
2045 'dress':'\ud83d\udc57',
2046 'dromedary_camel':'\ud83d\udc2a',
2047 'drooling_face':'\ud83e\udd24',
2048 'droplet':'\ud83d\udca7',
2049 'drum':'\ud83e\udd41',
2050 'duck':'\ud83e\udd86',
2051 'dvd':'\ud83d\udcc0',
2052 'e-mail':'\ud83d\udce7',
2053 'eagle':'\ud83e\udd85',
2054 'ear':'\ud83d\udc42',
2055 'ear_of_rice':'\ud83c\udf3e',
2056 'earth_africa':'\ud83c\udf0d',
2057 'earth_americas':'\ud83c\udf0e',
2058 'earth_asia':'\ud83c\udf0f',
2059 'egg':'\ud83e\udd5a',
2060 'eggplant':'\ud83c\udf46',
2061 'eight_pointed_black_star':'\u2734\ufe0f',
2062 'eight_spoked_asterisk':'\u2733\ufe0f',
2063 'electric_plug':'\ud83d\udd0c',
2064 'elephant':'\ud83d\udc18',
2065 'email':'\u2709\ufe0f',
2066 'end':'\ud83d\udd1a',
2067 'envelope_with_arrow':'\ud83d\udce9',
2068 'euro':'\ud83d\udcb6',
2069 'european_castle':'\ud83c\udff0',
2070 'european_post_office':'\ud83c\udfe4',
2071 'evergreen_tree':'\ud83c\udf32',
2072 'exclamation':'\u2757\ufe0f',
2073 'expressionless':'\ud83d\ude11',
2074 'eye':'\ud83d\udc41',
2075 'eye_speech_bubble':'\ud83d\udc41&zwj;\ud83d\udde8',
2076 'eyeglasses':'\ud83d\udc53',
2077 'eyes':'\ud83d\udc40',
2078 'face_with_head_bandage':'\ud83e\udd15',
2079 'face_with_thermometer':'\ud83e\udd12',
2080 'fist_oncoming':'\ud83d\udc4a',
2081 'factory':'\ud83c\udfed',
2082 'fallen_leaf':'\ud83c\udf42',
2083 'family_man_woman_boy':'\ud83d\udc6a',
2084 'family_man_boy':'\ud83d\udc68&zwj;\ud83d\udc66',
2085 'family_man_boy_boy':'\ud83d\udc68&zwj;\ud83d\udc66&zwj;\ud83d\udc66',
2086 'family_man_girl':'\ud83d\udc68&zwj;\ud83d\udc67',
2087 'family_man_girl_boy':'\ud83d\udc68&zwj;\ud83d\udc67&zwj;\ud83d\udc66',
2088 'family_man_girl_girl':'\ud83d\udc68&zwj;\ud83d\udc67&zwj;\ud83d\udc67',
2089 'family_man_man_boy':'\ud83d\udc68&zwj;\ud83d\udc68&zwj;\ud83d\udc66',
2090 'family_man_man_boy_boy':'\ud83d\udc68&zwj;\ud83d\udc68&zwj;\ud83d\udc66&zwj;\ud83d\udc66',
2091 'family_man_man_girl':'\ud83d\udc68&zwj;\ud83d\udc68&zwj;\ud83d\udc67',
2092 'family_man_man_girl_boy':'\ud83d\udc68&zwj;\ud83d\udc68&zwj;\ud83d\udc67&zwj;\ud83d\udc66',
2093 'family_man_man_girl_girl':'\ud83d\udc68&zwj;\ud83d\udc68&zwj;\ud83d\udc67&zwj;\ud83d\udc67',
2094 'family_man_woman_boy_boy':'\ud83d\udc68&zwj;\ud83d\udc69&zwj;\ud83d\udc66&zwj;\ud83d\udc66',
2095 'family_man_woman_girl':'\ud83d\udc68&zwj;\ud83d\udc69&zwj;\ud83d\udc67',
2096 'family_man_woman_girl_boy':'\ud83d\udc68&zwj;\ud83d\udc69&zwj;\ud83d\udc67&zwj;\ud83d\udc66',
2097 'family_man_woman_girl_girl':'\ud83d\udc68&zwj;\ud83d\udc69&zwj;\ud83d\udc67&zwj;\ud83d\udc67',
2098 'family_woman_boy':'\ud83d\udc69&zwj;\ud83d\udc66',
2099 'family_woman_boy_boy':'\ud83d\udc69&zwj;\ud83d\udc66&zwj;\ud83d\udc66',
2100 'family_woman_girl':'\ud83d\udc69&zwj;\ud83d\udc67',
2101 'family_woman_girl_boy':'\ud83d\udc69&zwj;\ud83d\udc67&zwj;\ud83d\udc66',
2102 'family_woman_girl_girl':'\ud83d\udc69&zwj;\ud83d\udc67&zwj;\ud83d\udc67',
2103 'family_woman_woman_boy':'\ud83d\udc69&zwj;\ud83d\udc69&zwj;\ud83d\udc66',
2104 'family_woman_woman_boy_boy':'\ud83d\udc69&zwj;\ud83d\udc69&zwj;\ud83d\udc66&zwj;\ud83d\udc66',
2105 'family_woman_woman_girl':'\ud83d\udc69&zwj;\ud83d\udc69&zwj;\ud83d\udc67',
2106 'family_woman_woman_girl_boy':'\ud83d\udc69&zwj;\ud83d\udc69&zwj;\ud83d\udc67&zwj;\ud83d\udc66',
2107 'family_woman_woman_girl_girl':'\ud83d\udc69&zwj;\ud83d\udc69&zwj;\ud83d\udc67&zwj;\ud83d\udc67',
2108 'fast_forward':'\u23e9',
2109 'fax':'\ud83d\udce0',
2110 'fearful':'\ud83d\ude28',
2111 'feet':'\ud83d\udc3e',
2112 'female_detective':'\ud83d\udd75\ufe0f&zwj;\u2640\ufe0f',
2113 'ferris_wheel':'\ud83c\udfa1',
2114 'ferry':'\u26f4',
2115 'field_hockey':'\ud83c\udfd1',
2116 'file_cabinet':'\ud83d\uddc4',
2117 'file_folder':'\ud83d\udcc1',
2118 'film_projector':'\ud83d\udcfd',
2119 'film_strip':'\ud83c\udf9e',
2120 'fire':'\ud83d\udd25',
2121 'fire_engine':'\ud83d\ude92',
2122 'fireworks':'\ud83c\udf86',
2123 'first_quarter_moon':'\ud83c\udf13',
2124 'first_quarter_moon_with_face':'\ud83c\udf1b',
2125 'fish':'\ud83d\udc1f',
2126 'fish_cake':'\ud83c\udf65',
2127 'fishing_pole_and_fish':'\ud83c\udfa3',
2128 'fist_raised':'\u270a',
2129 'fist_left':'\ud83e\udd1b',
2130 'fist_right':'\ud83e\udd1c',
2131 'flags':'\ud83c\udf8f',
2132 'flashlight':'\ud83d\udd26',
2133 'fleur_de_lis':'\u269c\ufe0f',
2134 'flight_arrival':'\ud83d\udeec',
2135 'flight_departure':'\ud83d\udeeb',
2136 'floppy_disk':'\ud83d\udcbe',
2137 'flower_playing_cards':'\ud83c\udfb4',
2138 'flushed':'\ud83d\ude33',
2139 'fog':'\ud83c\udf2b',
2140 'foggy':'\ud83c\udf01',
2141 'football':'\ud83c\udfc8',
2142 'footprints':'\ud83d\udc63',
2143 'fork_and_knife':'\ud83c\udf74',
2144 'fountain':'\u26f2\ufe0f',
2145 'fountain_pen':'\ud83d\udd8b',
2146 'four_leaf_clover':'\ud83c\udf40',
2147 'fox_face':'\ud83e\udd8a',
2148 'framed_picture':'\ud83d\uddbc',
2149 'free':'\ud83c\udd93',
2150 'fried_egg':'\ud83c\udf73',
2151 'fried_shrimp':'\ud83c\udf64',
2152 'fries':'\ud83c\udf5f',
2153 'frog':'\ud83d\udc38',
2154 'frowning':'\ud83d\ude26',
2155 'frowning_face':'\u2639\ufe0f',
2156 'frowning_man':'\ud83d\ude4d&zwj;\u2642\ufe0f',
2157 'frowning_woman':'\ud83d\ude4d',
2158 'middle_finger':'\ud83d\udd95',
2159 'fuelpump':'\u26fd\ufe0f',
2160 'full_moon':'\ud83c\udf15',
2161 'full_moon_with_face':'\ud83c\udf1d',
2162 'funeral_urn':'\u26b1\ufe0f',
2163 'game_die':'\ud83c\udfb2',
2164 'gear':'\u2699\ufe0f',
2165 'gem':'\ud83d\udc8e',
2166 'gemini':'\u264a\ufe0f',
2167 'ghost':'\ud83d\udc7b',
2168 'gift':'\ud83c\udf81',
2169 'gift_heart':'\ud83d\udc9d',
2170 'girl':'\ud83d\udc67',
2171 'globe_with_meridians':'\ud83c\udf10',
2172 'goal_net':'\ud83e\udd45',
2173 'goat':'\ud83d\udc10',
2174 'golf':'\u26f3\ufe0f',
2175 'golfing_man':'\ud83c\udfcc\ufe0f',
2176 'golfing_woman':'\ud83c\udfcc\ufe0f&zwj;\u2640\ufe0f',
2177 'gorilla':'\ud83e\udd8d',
2178 'grapes':'\ud83c\udf47',
2179 'green_apple':'\ud83c\udf4f',
2180 'green_book':'\ud83d\udcd7',
2181 'green_heart':'\ud83d\udc9a',
2182 'green_salad':'\ud83e\udd57',
2183 'grey_exclamation':'\u2755',
2184 'grey_question':'\u2754',
2185 'grimacing':'\ud83d\ude2c',
2186 'grin':'\ud83d\ude01',
2187 'grinning':'\ud83d\ude00',
2188 'guardsman':'\ud83d\udc82',
2189 'guardswoman':'\ud83d\udc82&zwj;\u2640\ufe0f',
2190 'guitar':'\ud83c\udfb8',
2191 'gun':'\ud83d\udd2b',
2192 'haircut_woman':'\ud83d\udc87',
2193 'haircut_man':'\ud83d\udc87&zwj;\u2642\ufe0f',
2194 'hamburger':'\ud83c\udf54',
2195 'hammer':'\ud83d\udd28',
2196 'hammer_and_pick':'\u2692',
2197 'hammer_and_wrench':'\ud83d\udee0',
2198 'hamster':'\ud83d\udc39',
2199 'hand':'\u270b',
2200 'handbag':'\ud83d\udc5c',
2201 'handshake':'\ud83e\udd1d',
2202 'hankey':'\ud83d\udca9',
2203 'hatched_chick':'\ud83d\udc25',
2204 'hatching_chick':'\ud83d\udc23',
2205 'headphones':'\ud83c\udfa7',
2206 'hear_no_evil':'\ud83d\ude49',
2207 'heart':'\u2764\ufe0f',
2208 'heart_decoration':'\ud83d\udc9f',
2209 'heart_eyes':'\ud83d\ude0d',
2210 'heart_eyes_cat':'\ud83d\ude3b',
2211 'heartbeat':'\ud83d\udc93',
2212 'heartpulse':'\ud83d\udc97',
2213 'hearts':'\u2665\ufe0f',
2214 'heavy_check_mark':'\u2714\ufe0f',
2215 'heavy_division_sign':'\u2797',
2216 'heavy_dollar_sign':'\ud83d\udcb2',
2217 'heavy_heart_exclamation':'\u2763\ufe0f',
2218 'heavy_minus_sign':'\u2796',
2219 'heavy_multiplication_x':'\u2716\ufe0f',
2220 'heavy_plus_sign':'\u2795',
2221 'helicopter':'\ud83d\ude81',
2222 'herb':'\ud83c\udf3f',
2223 'hibiscus':'\ud83c\udf3a',
2224 'high_brightness':'\ud83d\udd06',
2225 'high_heel':'\ud83d\udc60',
2226 'hocho':'\ud83d\udd2a',
2227 'hole':'\ud83d\udd73',
2228 'honey_pot':'\ud83c\udf6f',
2229 'horse':'\ud83d\udc34',
2230 'horse_racing':'\ud83c\udfc7',
2231 'hospital':'\ud83c\udfe5',
2232 'hot_pepper':'\ud83c\udf36',
2233 'hotdog':'\ud83c\udf2d',
2234 'hotel':'\ud83c\udfe8',
2235 'hotsprings':'\u2668\ufe0f',
2236 'hourglass':'\u231b\ufe0f',
2237 'hourglass_flowing_sand':'\u23f3',
2238 'house':'\ud83c\udfe0',
2239 'house_with_garden':'\ud83c\udfe1',
2240 'houses':'\ud83c\udfd8',
2241 'hugs':'\ud83e\udd17',
2242 'hushed':'\ud83d\ude2f',
2243 'ice_cream':'\ud83c\udf68',
2244 'ice_hockey':'\ud83c\udfd2',
2245 'ice_skate':'\u26f8',
2246 'icecream':'\ud83c\udf66',
2247 'id':'\ud83c\udd94',
2248 'ideograph_advantage':'\ud83c\ude50',
2249 'imp':'\ud83d\udc7f',
2250 'inbox_tray':'\ud83d\udce5',
2251 'incoming_envelope':'\ud83d\udce8',
2252 'tipping_hand_woman':'\ud83d\udc81',
2253 'information_source':'\u2139\ufe0f',
2254 'innocent':'\ud83d\ude07',
2255 'interrobang':'\u2049\ufe0f',
2256 'iphone':'\ud83d\udcf1',
2257 'izakaya_lantern':'\ud83c\udfee',
2258 'jack_o_lantern':'\ud83c\udf83',
2259 'japan':'\ud83d\uddfe',
2260 'japanese_castle':'\ud83c\udfef',
2261 'japanese_goblin':'\ud83d\udc7a',
2262 'japanese_ogre':'\ud83d\udc79',
2263 'jeans':'\ud83d\udc56',
2264 'joy':'\ud83d\ude02',
2265 'joy_cat':'\ud83d\ude39',
2266 'joystick':'\ud83d\udd79',
2267 'kaaba':'\ud83d\udd4b',
2268 'key':'\ud83d\udd11',
2269 'keyboard':'\u2328\ufe0f',
2270 'keycap_ten':'\ud83d\udd1f',
2271 'kick_scooter':'\ud83d\udef4',
2272 'kimono':'\ud83d\udc58',
2273 'kiss':'\ud83d\udc8b',
2274 'kissing':'\ud83d\ude17',
2275 'kissing_cat':'\ud83d\ude3d',
2276 'kissing_closed_eyes':'\ud83d\ude1a',
2277 'kissing_heart':'\ud83d\ude18',
2278 'kissing_smiling_eyes':'\ud83d\ude19',
2279 'kiwi_fruit':'\ud83e\udd5d',
2280 'koala':'\ud83d\udc28',
2281 'koko':'\ud83c\ude01',
2282 'label':'\ud83c\udff7',
2283 'large_blue_circle':'\ud83d\udd35',
2284 'large_blue_diamond':'\ud83d\udd37',
2285 'large_orange_diamond':'\ud83d\udd36',
2286 'last_quarter_moon':'\ud83c\udf17',
2287 'last_quarter_moon_with_face':'\ud83c\udf1c',
2288 'latin_cross':'\u271d\ufe0f',
2289 'laughing':'\ud83d\ude06',
2290 'leaves':'\ud83c\udf43',
2291 'ledger':'\ud83d\udcd2',
2292 'left_luggage':'\ud83d\udec5',
2293 'left_right_arrow':'\u2194\ufe0f',
2294 'leftwards_arrow_with_hook':'\u21a9\ufe0f',
2295 'lemon':'\ud83c\udf4b',
2296 'leo':'\u264c\ufe0f',
2297 'leopard':'\ud83d\udc06',
2298 'level_slider':'\ud83c\udf9a',
2299 'libra':'\u264e\ufe0f',
2300 'light_rail':'\ud83d\ude88',
2301 'link':'\ud83d\udd17',
2302 'lion':'\ud83e\udd81',
2303 'lips':'\ud83d\udc44',
2304 'lipstick':'\ud83d\udc84',
2305 'lizard':'\ud83e\udd8e',
2306 'lock':'\ud83d\udd12',
2307 'lock_with_ink_pen':'\ud83d\udd0f',
2308 'lollipop':'\ud83c\udf6d',
2309 'loop':'\u27bf',
2310 'loud_sound':'\ud83d\udd0a',
2311 'loudspeaker':'\ud83d\udce2',
2312 'love_hotel':'\ud83c\udfe9',
2313 'love_letter':'\ud83d\udc8c',
2314 'low_brightness':'\ud83d\udd05',
2315 'lying_face':'\ud83e\udd25',
2316 'm':'\u24c2\ufe0f',
2317 'mag':'\ud83d\udd0d',
2318 'mag_right':'\ud83d\udd0e',
2319 'mahjong':'\ud83c\udc04\ufe0f',
2320 'mailbox':'\ud83d\udceb',
2321 'mailbox_closed':'\ud83d\udcea',
2322 'mailbox_with_mail':'\ud83d\udcec',
2323 'mailbox_with_no_mail':'\ud83d\udced',
2324 'man':'\ud83d\udc68',
2325 'man_artist':'\ud83d\udc68&zwj;\ud83c\udfa8',
2326 'man_astronaut':'\ud83d\udc68&zwj;\ud83d\ude80',
2327 'man_cartwheeling':'\ud83e\udd38&zwj;\u2642\ufe0f',
2328 'man_cook':'\ud83d\udc68&zwj;\ud83c\udf73',
2329 'man_dancing':'\ud83d\udd7a',
2330 'man_facepalming':'\ud83e\udd26&zwj;\u2642\ufe0f',
2331 'man_factory_worker':'\ud83d\udc68&zwj;\ud83c\udfed',
2332 'man_farmer':'\ud83d\udc68&zwj;\ud83c\udf3e',
2333 'man_firefighter':'\ud83d\udc68&zwj;\ud83d\ude92',
2334 'man_health_worker':'\ud83d\udc68&zwj;\u2695\ufe0f',
2335 'man_in_tuxedo':'\ud83e\udd35',
2336 'man_judge':'\ud83d\udc68&zwj;\u2696\ufe0f',
2337 'man_juggling':'\ud83e\udd39&zwj;\u2642\ufe0f',
2338 'man_mechanic':'\ud83d\udc68&zwj;\ud83d\udd27',
2339 'man_office_worker':'\ud83d\udc68&zwj;\ud83d\udcbc',
2340 'man_pilot':'\ud83d\udc68&zwj;\u2708\ufe0f',
2341 'man_playing_handball':'\ud83e\udd3e&zwj;\u2642\ufe0f',
2342 'man_playing_water_polo':'\ud83e\udd3d&zwj;\u2642\ufe0f',
2343 'man_scientist':'\ud83d\udc68&zwj;\ud83d\udd2c',
2344 'man_shrugging':'\ud83e\udd37&zwj;\u2642\ufe0f',
2345 'man_singer':'\ud83d\udc68&zwj;\ud83c\udfa4',
2346 'man_student':'\ud83d\udc68&zwj;\ud83c\udf93',
2347 'man_teacher':'\ud83d\udc68&zwj;\ud83c\udfeb',
2348 'man_technologist':'\ud83d\udc68&zwj;\ud83d\udcbb',
2349 'man_with_gua_pi_mao':'\ud83d\udc72',
2350 'man_with_turban':'\ud83d\udc73',
2351 'tangerine':'\ud83c\udf4a',
2352 'mans_shoe':'\ud83d\udc5e',
2353 'mantelpiece_clock':'\ud83d\udd70',
2354 'maple_leaf':'\ud83c\udf41',
2355 'martial_arts_uniform':'\ud83e\udd4b',
2356 'mask':'\ud83d\ude37',
2357 'massage_woman':'\ud83d\udc86',
2358 'massage_man':'\ud83d\udc86&zwj;\u2642\ufe0f',
2359 'meat_on_bone':'\ud83c\udf56',
2360 'medal_military':'\ud83c\udf96',
2361 'medal_sports':'\ud83c\udfc5',
2362 'mega':'\ud83d\udce3',
2363 'melon':'\ud83c\udf48',
2364 'memo':'\ud83d\udcdd',
2365 'men_wrestling':'\ud83e\udd3c&zwj;\u2642\ufe0f',
2366 'menorah':'\ud83d\udd4e',
2367 'mens':'\ud83d\udeb9',
2368 'metal':'\ud83e\udd18',
2369 'metro':'\ud83d\ude87',
2370 'microphone':'\ud83c\udfa4',
2371 'microscope':'\ud83d\udd2c',
2372 'milk_glass':'\ud83e\udd5b',
2373 'milky_way':'\ud83c\udf0c',
2374 'minibus':'\ud83d\ude90',
2375 'minidisc':'\ud83d\udcbd',
2376 'mobile_phone_off':'\ud83d\udcf4',
2377 'money_mouth_face':'\ud83e\udd11',
2378 'money_with_wings':'\ud83d\udcb8',
2379 'moneybag':'\ud83d\udcb0',
2380 'monkey':'\ud83d\udc12',
2381 'monkey_face':'\ud83d\udc35',
2382 'monorail':'\ud83d\ude9d',
2383 'moon':'\ud83c\udf14',
2384 'mortar_board':'\ud83c\udf93',
2385 'mosque':'\ud83d\udd4c',
2386 'motor_boat':'\ud83d\udee5',
2387 'motor_scooter':'\ud83d\udef5',
2388 'motorcycle':'\ud83c\udfcd',
2389 'motorway':'\ud83d\udee3',
2390 'mount_fuji':'\ud83d\uddfb',
2391 'mountain':'\u26f0',
2392 'mountain_biking_man':'\ud83d\udeb5',
2393 'mountain_biking_woman':'\ud83d\udeb5&zwj;\u2640\ufe0f',
2394 'mountain_cableway':'\ud83d\udea0',
2395 'mountain_railway':'\ud83d\ude9e',
2396 'mountain_snow':'\ud83c\udfd4',
2397 'mouse':'\ud83d\udc2d',
2398 'mouse2':'\ud83d\udc01',
2399 'movie_camera':'\ud83c\udfa5',
2400 'moyai':'\ud83d\uddff',
2401 'mrs_claus':'\ud83e\udd36',
2402 'muscle':'\ud83d\udcaa',
2403 'mushroom':'\ud83c\udf44',
2404 'musical_keyboard':'\ud83c\udfb9',
2405 'musical_note':'\ud83c\udfb5',
2406 'musical_score':'\ud83c\udfbc',
2407 'mute':'\ud83d\udd07',
2408 'nail_care':'\ud83d\udc85',
2409 'name_badge':'\ud83d\udcdb',
2410 'national_park':'\ud83c\udfde',
2411 'nauseated_face':'\ud83e\udd22',
2412 'necktie':'\ud83d\udc54',
2413 'negative_squared_cross_mark':'\u274e',
2414 'nerd_face':'\ud83e\udd13',
2415 'neutral_face':'\ud83d\ude10',
2416 'new':'\ud83c\udd95',
2417 'new_moon':'\ud83c\udf11',
2418 'new_moon_with_face':'\ud83c\udf1a',
2419 'newspaper':'\ud83d\udcf0',
2420 'newspaper_roll':'\ud83d\uddde',
2421 'next_track_button':'\u23ed',
2422 'ng':'\ud83c\udd96',
2423 'no_good_man':'\ud83d\ude45&zwj;\u2642\ufe0f',
2424 'no_good_woman':'\ud83d\ude45',
2425 'night_with_stars':'\ud83c\udf03',
2426 'no_bell':'\ud83d\udd15',
2427 'no_bicycles':'\ud83d\udeb3',
2428 'no_entry':'\u26d4\ufe0f',
2429 'no_entry_sign':'\ud83d\udeab',
2430 'no_mobile_phones':'\ud83d\udcf5',
2431 'no_mouth':'\ud83d\ude36',
2432 'no_pedestrians':'\ud83d\udeb7',
2433 'no_smoking':'\ud83d\udead',
2434 'non-potable_water':'\ud83d\udeb1',
2435 'nose':'\ud83d\udc43',
2436 'notebook':'\ud83d\udcd3',
2437 'notebook_with_decorative_cover':'\ud83d\udcd4',
2438 'notes':'\ud83c\udfb6',
2439 'nut_and_bolt':'\ud83d\udd29',
2440 'o':'\u2b55\ufe0f',
2441 'o2':'\ud83c\udd7e\ufe0f',
2442 'ocean':'\ud83c\udf0a',
2443 'octopus':'\ud83d\udc19',
2444 'oden':'\ud83c\udf62',
2445 'office':'\ud83c\udfe2',
2446 'oil_drum':'\ud83d\udee2',
2447 'ok':'\ud83c\udd97',
2448 'ok_hand':'\ud83d\udc4c',
2449 'ok_man':'\ud83d\ude46&zwj;\u2642\ufe0f',
2450 'ok_woman':'\ud83d\ude46',
2451 'old_key':'\ud83d\udddd',
2452 'older_man':'\ud83d\udc74',
2453 'older_woman':'\ud83d\udc75',
2454 'om':'\ud83d\udd49',
2455 'on':'\ud83d\udd1b',
2456 'oncoming_automobile':'\ud83d\ude98',
2457 'oncoming_bus':'\ud83d\ude8d',
2458 'oncoming_police_car':'\ud83d\ude94',
2459 'oncoming_taxi':'\ud83d\ude96',
2460 'open_file_folder':'\ud83d\udcc2',
2461 'open_hands':'\ud83d\udc50',
2462 'open_mouth':'\ud83d\ude2e',
2463 'open_umbrella':'\u2602\ufe0f',
2464 'ophiuchus':'\u26ce',
2465 'orange_book':'\ud83d\udcd9',
2466 'orthodox_cross':'\u2626\ufe0f',
2467 'outbox_tray':'\ud83d\udce4',
2468 'owl':'\ud83e\udd89',
2469 'ox':'\ud83d\udc02',
2470 'package':'\ud83d\udce6',
2471 'page_facing_up':'\ud83d\udcc4',
2472 'page_with_curl':'\ud83d\udcc3',
2473 'pager':'\ud83d\udcdf',
2474 'paintbrush':'\ud83d\udd8c',
2475 'palm_tree':'\ud83c\udf34',
2476 'pancakes':'\ud83e\udd5e',
2477 'panda_face':'\ud83d\udc3c',
2478 'paperclip':'\ud83d\udcce',
2479 'paperclips':'\ud83d\udd87',
2480 'parasol_on_ground':'\u26f1',
2481 'parking':'\ud83c\udd7f\ufe0f',
2482 'part_alternation_mark':'\u303d\ufe0f',
2483 'partly_sunny':'\u26c5\ufe0f',
2484 'passenger_ship':'\ud83d\udef3',
2485 'passport_control':'\ud83d\udec2',
2486 'pause_button':'\u23f8',
2487 'peace_symbol':'\u262e\ufe0f',
2488 'peach':'\ud83c\udf51',
2489 'peanuts':'\ud83e\udd5c',
2490 'pear':'\ud83c\udf50',
2491 'pen':'\ud83d\udd8a',
2492 'pencil2':'\u270f\ufe0f',
2493 'penguin':'\ud83d\udc27',
2494 'pensive':'\ud83d\ude14',
2495 'performing_arts':'\ud83c\udfad',
2496 'persevere':'\ud83d\ude23',
2497 'person_fencing':'\ud83e\udd3a',
2498 'pouting_woman':'\ud83d\ude4e',
2499 'phone':'\u260e\ufe0f',
2500 'pick':'\u26cf',
2501 'pig':'\ud83d\udc37',
2502 'pig2':'\ud83d\udc16',
2503 'pig_nose':'\ud83d\udc3d',
2504 'pill':'\ud83d\udc8a',
2505 'pineapple':'\ud83c\udf4d',
2506 'ping_pong':'\ud83c\udfd3',
2507 'pisces':'\u2653\ufe0f',
2508 'pizza':'\ud83c\udf55',
2509 'place_of_worship':'\ud83d\uded0',
2510 'plate_with_cutlery':'\ud83c\udf7d',
2511 'play_or_pause_button':'\u23ef',
2512 'point_down':'\ud83d\udc47',
2513 'point_left':'\ud83d\udc48',
2514 'point_right':'\ud83d\udc49',
2515 'point_up':'\u261d\ufe0f',
2516 'point_up_2':'\ud83d\udc46',
2517 'police_car':'\ud83d\ude93',
2518 'policewoman':'\ud83d\udc6e&zwj;\u2640\ufe0f',
2519 'poodle':'\ud83d\udc29',
2520 'popcorn':'\ud83c\udf7f',
2521 'post_office':'\ud83c\udfe3',
2522 'postal_horn':'\ud83d\udcef',
2523 'postbox':'\ud83d\udcee',
2524 'potable_water':'\ud83d\udeb0',
2525 'potato':'\ud83e\udd54',
2526 'pouch':'\ud83d\udc5d',
2527 'poultry_leg':'\ud83c\udf57',
2528 'pound':'\ud83d\udcb7',
2529 'rage':'\ud83d\ude21',
2530 'pouting_cat':'\ud83d\ude3e',
2531 'pouting_man':'\ud83d\ude4e&zwj;\u2642\ufe0f',
2532 'pray':'\ud83d\ude4f',
2533 'prayer_beads':'\ud83d\udcff',
2534 'pregnant_woman':'\ud83e\udd30',
2535 'previous_track_button':'\u23ee',
2536 'prince':'\ud83e\udd34',
2537 'princess':'\ud83d\udc78',
2538 'printer':'\ud83d\udda8',
2539 'purple_heart':'\ud83d\udc9c',
2540 'purse':'\ud83d\udc5b',
2541 'pushpin':'\ud83d\udccc',
2542 'put_litter_in_its_place':'\ud83d\udeae',
2543 'question':'\u2753',
2544 'rabbit':'\ud83d\udc30',
2545 'rabbit2':'\ud83d\udc07',
2546 'racehorse':'\ud83d\udc0e',
2547 'racing_car':'\ud83c\udfce',
2548 'radio':'\ud83d\udcfb',
2549 'radio_button':'\ud83d\udd18',
2550 'radioactive':'\u2622\ufe0f',
2551 'railway_car':'\ud83d\ude83',
2552 'railway_track':'\ud83d\udee4',
2553 'rainbow':'\ud83c\udf08',
2554 'rainbow_flag':'\ud83c\udff3\ufe0f&zwj;\ud83c\udf08',
2555 'raised_back_of_hand':'\ud83e\udd1a',
2556 'raised_hand_with_fingers_splayed':'\ud83d\udd90',
2557 'raised_hands':'\ud83d\ude4c',
2558 'raising_hand_woman':'\ud83d\ude4b',
2559 'raising_hand_man':'\ud83d\ude4b&zwj;\u2642\ufe0f',
2560 'ram':'\ud83d\udc0f',
2561 'ramen':'\ud83c\udf5c',
2562 'rat':'\ud83d\udc00',
2563 'record_button':'\u23fa',
2564 'recycle':'\u267b\ufe0f',
2565 'red_circle':'\ud83d\udd34',
2566 'registered':'\u00ae\ufe0f',
2567 'relaxed':'\u263a\ufe0f',
2568 'relieved':'\ud83d\ude0c',
2569 'reminder_ribbon':'\ud83c\udf97',
2570 'repeat':'\ud83d\udd01',
2571 'repeat_one':'\ud83d\udd02',
2572 'rescue_worker_helmet':'\u26d1',
2573 'restroom':'\ud83d\udebb',
2574 'revolving_hearts':'\ud83d\udc9e',
2575 'rewind':'\u23ea',
2576 'rhinoceros':'\ud83e\udd8f',
2577 'ribbon':'\ud83c\udf80',
2578 'rice':'\ud83c\udf5a',
2579 'rice_ball':'\ud83c\udf59',
2580 'rice_cracker':'\ud83c\udf58',
2581 'rice_scene':'\ud83c\udf91',
2582 'right_anger_bubble':'\ud83d\uddef',
2583 'ring':'\ud83d\udc8d',
2584 'robot':'\ud83e\udd16',
2585 'rocket':'\ud83d\ude80',
2586 'rofl':'\ud83e\udd23',
2587 'roll_eyes':'\ud83d\ude44',
2588 'roller_coaster':'\ud83c\udfa2',
2589 'rooster':'\ud83d\udc13',
2590 'rose':'\ud83c\udf39',
2591 'rosette':'\ud83c\udff5',
2592 'rotating_light':'\ud83d\udea8',
2593 'round_pushpin':'\ud83d\udccd',
2594 'rowing_man':'\ud83d\udea3',
2595 'rowing_woman':'\ud83d\udea3&zwj;\u2640\ufe0f',
2596 'rugby_football':'\ud83c\udfc9',
2597 'running_man':'\ud83c\udfc3',
2598 'running_shirt_with_sash':'\ud83c\udfbd',
2599 'running_woman':'\ud83c\udfc3&zwj;\u2640\ufe0f',
2600 'sa':'\ud83c\ude02\ufe0f',
2601 'sagittarius':'\u2650\ufe0f',
2602 'sake':'\ud83c\udf76',
2603 'sandal':'\ud83d\udc61',
2604 'santa':'\ud83c\udf85',
2605 'satellite':'\ud83d\udce1',
2606 'saxophone':'\ud83c\udfb7',
2607 'school':'\ud83c\udfeb',
2608 'school_satchel':'\ud83c\udf92',
2609 'scissors':'\u2702\ufe0f',
2610 'scorpion':'\ud83e\udd82',
2611 'scorpius':'\u264f\ufe0f',
2612 'scream':'\ud83d\ude31',
2613 'scream_cat':'\ud83d\ude40',
2614 'scroll':'\ud83d\udcdc',
2615 'seat':'\ud83d\udcba',
2616 'secret':'\u3299\ufe0f',
2617 'see_no_evil':'\ud83d\ude48',
2618 'seedling':'\ud83c\udf31',
2619 'selfie':'\ud83e\udd33',
2620 'shallow_pan_of_food':'\ud83e\udd58',
2621 'shamrock':'\u2618\ufe0f',
2622 'shark':'\ud83e\udd88',
2623 'shaved_ice':'\ud83c\udf67',
2624 'sheep':'\ud83d\udc11',
2625 'shell':'\ud83d\udc1a',
2626 'shield':'\ud83d\udee1',
2627 'shinto_shrine':'\u26e9',
2628 'ship':'\ud83d\udea2',
2629 'shirt':'\ud83d\udc55',
2630 'shopping':'\ud83d\udecd',
2631 'shopping_cart':'\ud83d\uded2',
2632 'shower':'\ud83d\udebf',
2633 'shrimp':'\ud83e\udd90',
2634 'signal_strength':'\ud83d\udcf6',
2635 'six_pointed_star':'\ud83d\udd2f',
2636 'ski':'\ud83c\udfbf',
2637 'skier':'\u26f7',
2638 'skull':'\ud83d\udc80',
2639 'skull_and_crossbones':'\u2620\ufe0f',
2640 'sleeping':'\ud83d\ude34',
2641 'sleeping_bed':'\ud83d\udecc',
2642 'sleepy':'\ud83d\ude2a',
2643 'slightly_frowning_face':'\ud83d\ude41',
2644 'slightly_smiling_face':'\ud83d\ude42',
2645 'slot_machine':'\ud83c\udfb0',
2646 'small_airplane':'\ud83d\udee9',
2647 'small_blue_diamond':'\ud83d\udd39',
2648 'small_orange_diamond':'\ud83d\udd38',
2649 'small_red_triangle':'\ud83d\udd3a',
2650 'small_red_triangle_down':'\ud83d\udd3b',
2651 'smile':'\ud83d\ude04',
2652 'smile_cat':'\ud83d\ude38',
2653 'smiley':'\ud83d\ude03',
2654 'smiley_cat':'\ud83d\ude3a',
2655 'smiling_imp':'\ud83d\ude08',
2656 'smirk':'\ud83d\ude0f',
2657 'smirk_cat':'\ud83d\ude3c',
2658 'smoking':'\ud83d\udeac',
2659 'snail':'\ud83d\udc0c',
2660 'snake':'\ud83d\udc0d',
2661 'sneezing_face':'\ud83e\udd27',
2662 'snowboarder':'\ud83c\udfc2',
2663 'snowflake':'\u2744\ufe0f',
2664 'snowman':'\u26c4\ufe0f',
2665 'snowman_with_snow':'\u2603\ufe0f',
2666 'sob':'\ud83d\ude2d',
2667 'soccer':'\u26bd\ufe0f',
2668 'soon':'\ud83d\udd1c',
2669 'sos':'\ud83c\udd98',
2670 'sound':'\ud83d\udd09',
2671 'space_invader':'\ud83d\udc7e',
2672 'spades':'\u2660\ufe0f',
2673 'spaghetti':'\ud83c\udf5d',
2674 'sparkle':'\u2747\ufe0f',
2675 'sparkler':'\ud83c\udf87',
2676 'sparkles':'\u2728',
2677 'sparkling_heart':'\ud83d\udc96',
2678 'speak_no_evil':'\ud83d\ude4a',
2679 'speaker':'\ud83d\udd08',
2680 'speaking_head':'\ud83d\udde3',
2681 'speech_balloon':'\ud83d\udcac',
2682 'speedboat':'\ud83d\udea4',
2683 'spider':'\ud83d\udd77',
2684 'spider_web':'\ud83d\udd78',
2685 'spiral_calendar':'\ud83d\uddd3',
2686 'spiral_notepad':'\ud83d\uddd2',
2687 'spoon':'\ud83e\udd44',
2688 'squid':'\ud83e\udd91',
2689 'stadium':'\ud83c\udfdf',
2690 'star':'\u2b50\ufe0f',
2691 'star2':'\ud83c\udf1f',
2692 'star_and_crescent':'\u262a\ufe0f',
2693 'star_of_david':'\u2721\ufe0f',
2694 'stars':'\ud83c\udf20',
2695 'station':'\ud83d\ude89',
2696 'statue_of_liberty':'\ud83d\uddfd',
2697 'steam_locomotive':'\ud83d\ude82',
2698 'stew':'\ud83c\udf72',
2699 'stop_button':'\u23f9',
2700 'stop_sign':'\ud83d\uded1',
2701 'stopwatch':'\u23f1',
2702 'straight_ruler':'\ud83d\udccf',
2703 'strawberry':'\ud83c\udf53',
2704 'stuck_out_tongue':'\ud83d\ude1b',
2705 'stuck_out_tongue_closed_eyes':'\ud83d\ude1d',
2706 'stuck_out_tongue_winking_eye':'\ud83d\ude1c',
2707 'studio_microphone':'\ud83c\udf99',
2708 'stuffed_flatbread':'\ud83e\udd59',
2709 'sun_behind_large_cloud':'\ud83c\udf25',
2710 'sun_behind_rain_cloud':'\ud83c\udf26',
2711 'sun_behind_small_cloud':'\ud83c\udf24',
2712 'sun_with_face':'\ud83c\udf1e',
2713 'sunflower':'\ud83c\udf3b',
2714 'sunglasses':'\ud83d\ude0e',
2715 'sunny':'\u2600\ufe0f',
2716 'sunrise':'\ud83c\udf05',
2717 'sunrise_over_mountains':'\ud83c\udf04',
2718 'surfing_man':'\ud83c\udfc4',
2719 'surfing_woman':'\ud83c\udfc4&zwj;\u2640\ufe0f',
2720 'sushi':'\ud83c\udf63',
2721 'suspension_railway':'\ud83d\ude9f',
2722 'sweat':'\ud83d\ude13',
2723 'sweat_drops':'\ud83d\udca6',
2724 'sweat_smile':'\ud83d\ude05',
2725 'sweet_potato':'\ud83c\udf60',
2726 'swimming_man':'\ud83c\udfca',
2727 'swimming_woman':'\ud83c\udfca&zwj;\u2640\ufe0f',
2728 'symbols':'\ud83d\udd23',
2729 'synagogue':'\ud83d\udd4d',
2730 'syringe':'\ud83d\udc89',
2731 'taco':'\ud83c\udf2e',
2732 'tada':'\ud83c\udf89',
2733 'tanabata_tree':'\ud83c\udf8b',
2734 'taurus':'\u2649\ufe0f',
2735 'taxi':'\ud83d\ude95',
2736 'tea':'\ud83c\udf75',
2737 'telephone_receiver':'\ud83d\udcde',
2738 'telescope':'\ud83d\udd2d',
2739 'tennis':'\ud83c\udfbe',
2740 'tent':'\u26fa\ufe0f',
2741 'thermometer':'\ud83c\udf21',
2742 'thinking':'\ud83e\udd14',
2743 'thought_balloon':'\ud83d\udcad',
2744 'ticket':'\ud83c\udfab',
2745 'tickets':'\ud83c\udf9f',
2746 'tiger':'\ud83d\udc2f',
2747 'tiger2':'\ud83d\udc05',
2748 'timer_clock':'\u23f2',
2749 'tipping_hand_man':'\ud83d\udc81&zwj;\u2642\ufe0f',
2750 'tired_face':'\ud83d\ude2b',
2751 'tm':'\u2122\ufe0f',
2752 'toilet':'\ud83d\udebd',
2753 'tokyo_tower':'\ud83d\uddfc',
2754 'tomato':'\ud83c\udf45',
2755 'tongue':'\ud83d\udc45',
2756 'top':'\ud83d\udd1d',
2757 'tophat':'\ud83c\udfa9',
2758 'tornado':'\ud83c\udf2a',
2759 'trackball':'\ud83d\uddb2',
2760 'tractor':'\ud83d\ude9c',
2761 'traffic_light':'\ud83d\udea5',
2762 'train':'\ud83d\ude8b',
2763 'train2':'\ud83d\ude86',
2764 'tram':'\ud83d\ude8a',
2765 'triangular_flag_on_post':'\ud83d\udea9',
2766 'triangular_ruler':'\ud83d\udcd0',
2767 'trident':'\ud83d\udd31',
2768 'triumph':'\ud83d\ude24',
2769 'trolleybus':'\ud83d\ude8e',
2770 'trophy':'\ud83c\udfc6',
2771 'tropical_drink':'\ud83c\udf79',
2772 'tropical_fish':'\ud83d\udc20',
2773 'truck':'\ud83d\ude9a',
2774 'trumpet':'\ud83c\udfba',
2775 'tulip':'\ud83c\udf37',
2776 'tumbler_glass':'\ud83e\udd43',
2777 'turkey':'\ud83e\udd83',
2778 'turtle':'\ud83d\udc22',
2779 'tv':'\ud83d\udcfa',
2780 'twisted_rightwards_arrows':'\ud83d\udd00',
2781 'two_hearts':'\ud83d\udc95',
2782 'two_men_holding_hands':'\ud83d\udc6c',
2783 'two_women_holding_hands':'\ud83d\udc6d',
2784 'u5272':'\ud83c\ude39',
2785 'u5408':'\ud83c\ude34',
2786 'u55b6':'\ud83c\ude3a',
2787 'u6307':'\ud83c\ude2f\ufe0f',
2788 'u6708':'\ud83c\ude37\ufe0f',
2789 'u6709':'\ud83c\ude36',
2790 'u6e80':'\ud83c\ude35',
2791 'u7121':'\ud83c\ude1a\ufe0f',
2792 'u7533':'\ud83c\ude38',
2793 'u7981':'\ud83c\ude32',
2794 'u7a7a':'\ud83c\ude33',
2795 'umbrella':'\u2614\ufe0f',
2796 'unamused':'\ud83d\ude12',
2797 'underage':'\ud83d\udd1e',
2798 'unicorn':'\ud83e\udd84',
2799 'unlock':'\ud83d\udd13',
2800 'up':'\ud83c\udd99',
2801 'upside_down_face':'\ud83d\ude43',
2802 'v':'\u270c\ufe0f',
2803 'vertical_traffic_light':'\ud83d\udea6',
2804 'vhs':'\ud83d\udcfc',
2805 'vibration_mode':'\ud83d\udcf3',
2806 'video_camera':'\ud83d\udcf9',
2807 'video_game':'\ud83c\udfae',
2808 'violin':'\ud83c\udfbb',
2809 'virgo':'\u264d\ufe0f',
2810 'volcano':'\ud83c\udf0b',
2811 'volleyball':'\ud83c\udfd0',
2812 'vs':'\ud83c\udd9a',
2813 'vulcan_salute':'\ud83d\udd96',
2814 'walking_man':'\ud83d\udeb6',
2815 'walking_woman':'\ud83d\udeb6&zwj;\u2640\ufe0f',
2816 'waning_crescent_moon':'\ud83c\udf18',
2817 'waning_gibbous_moon':'\ud83c\udf16',
2818 'warning':'\u26a0\ufe0f',
2819 'wastebasket':'\ud83d\uddd1',
2820 'watch':'\u231a\ufe0f',
2821 'water_buffalo':'\ud83d\udc03',
2822 'watermelon':'\ud83c\udf49',
2823 'wave':'\ud83d\udc4b',
2824 'wavy_dash':'\u3030\ufe0f',
2825 'waxing_crescent_moon':'\ud83c\udf12',
2826 'wc':'\ud83d\udebe',
2827 'weary':'\ud83d\ude29',
2828 'wedding':'\ud83d\udc92',
2829 'weight_lifting_man':'\ud83c\udfcb\ufe0f',
2830 'weight_lifting_woman':'\ud83c\udfcb\ufe0f&zwj;\u2640\ufe0f',
2831 'whale':'\ud83d\udc33',
2832 'whale2':'\ud83d\udc0b',
2833 'wheel_of_dharma':'\u2638\ufe0f',
2834 'wheelchair':'\u267f\ufe0f',
2835 'white_check_mark':'\u2705',
2836 'white_circle':'\u26aa\ufe0f',
2837 'white_flag':'\ud83c\udff3\ufe0f',
2838 'white_flower':'\ud83d\udcae',
2839 'white_large_square':'\u2b1c\ufe0f',
2840 'white_medium_small_square':'\u25fd\ufe0f',
2841 'white_medium_square':'\u25fb\ufe0f',
2842 'white_small_square':'\u25ab\ufe0f',
2843 'white_square_button':'\ud83d\udd33',
2844 'wilted_flower':'\ud83e\udd40',
2845 'wind_chime':'\ud83c\udf90',
2846 'wind_face':'\ud83c\udf2c',
2847 'wine_glass':'\ud83c\udf77',
2848 'wink':'\ud83d\ude09',
2849 'wolf':'\ud83d\udc3a',
2850 'woman':'\ud83d\udc69',
2851 'woman_artist':'\ud83d\udc69&zwj;\ud83c\udfa8',
2852 'woman_astronaut':'\ud83d\udc69&zwj;\ud83d\ude80',
2853 'woman_cartwheeling':'\ud83e\udd38&zwj;\u2640\ufe0f',
2854 'woman_cook':'\ud83d\udc69&zwj;\ud83c\udf73',
2855 'woman_facepalming':'\ud83e\udd26&zwj;\u2640\ufe0f',
2856 'woman_factory_worker':'\ud83d\udc69&zwj;\ud83c\udfed',
2857 'woman_farmer':'\ud83d\udc69&zwj;\ud83c\udf3e',
2858 'woman_firefighter':'\ud83d\udc69&zwj;\ud83d\ude92',
2859 'woman_health_worker':'\ud83d\udc69&zwj;\u2695\ufe0f',
2860 'woman_judge':'\ud83d\udc69&zwj;\u2696\ufe0f',
2861 'woman_juggling':'\ud83e\udd39&zwj;\u2640\ufe0f',
2862 'woman_mechanic':'\ud83d\udc69&zwj;\ud83d\udd27',
2863 'woman_office_worker':'\ud83d\udc69&zwj;\ud83d\udcbc',
2864 'woman_pilot':'\ud83d\udc69&zwj;\u2708\ufe0f',
2865 'woman_playing_handball':'\ud83e\udd3e&zwj;\u2640\ufe0f',
2866 'woman_playing_water_polo':'\ud83e\udd3d&zwj;\u2640\ufe0f',
2867 'woman_scientist':'\ud83d\udc69&zwj;\ud83d\udd2c',
2868 'woman_shrugging':'\ud83e\udd37&zwj;\u2640\ufe0f',
2869 'woman_singer':'\ud83d\udc69&zwj;\ud83c\udfa4',
2870 'woman_student':'\ud83d\udc69&zwj;\ud83c\udf93',
2871 'woman_teacher':'\ud83d\udc69&zwj;\ud83c\udfeb',
2872 'woman_technologist':'\ud83d\udc69&zwj;\ud83d\udcbb',
2873 'woman_with_turban':'\ud83d\udc73&zwj;\u2640\ufe0f',
2874 'womans_clothes':'\ud83d\udc5a',
2875 'womans_hat':'\ud83d\udc52',
2876 'women_wrestling':'\ud83e\udd3c&zwj;\u2640\ufe0f',
2877 'womens':'\ud83d\udeba',
2878 'world_map':'\ud83d\uddfa',
2879 'worried':'\ud83d\ude1f',
2880 'wrench':'\ud83d\udd27',
2881 'writing_hand':'\u270d\ufe0f',
2882 'x':'\u274c',
2883 'yellow_heart':'\ud83d\udc9b',
2884 'yen':'\ud83d\udcb4',
2885 'yin_yang':'\u262f\ufe0f',
2886 'yum':'\ud83d\ude0b',
2887 'zap':'\u26a1\ufe0f',
2888 'zipper_mouth_face':'\ud83e\udd10',
2889 'zzz':'\ud83d\udca4',
2890
2891 /* special emojis :P */
2892 'octocat': '<img alt=":octocat:" height="20" width="20" align="absmiddle" src="https://assets-cdn.github.com/images/icons/emoji/octocat.png">',
2893 'showdown': '<span style="font-family: \'Anonymous Pro\', monospace; text-decoration: underline; text-decoration-style: dashed; text-decoration-color: #3e8b8a;text-underline-position: under;">S</span>'
2894 };
2895
2896 /**
2897 * Created by Estevao on 31-05-2015.
2898 */
2899
2900 /**
2901 * Showdown Converter class
2902 * @class
2903 * @param {object} [converterOptions]
2904 * @returns {Converter}
2905 */
2906 showdown.Converter = function (converterOptions) {
2907 'use strict';
2908
2909 var
2910 /**
2911 * Options used by this converter
2912 * @private
2913 * @type {{}}
2914 */
2915 options = {},
2916
2917 /**
2918 * Language extensions used by this converter
2919 * @private
2920 * @type {Array}
2921 */
2922 langExtensions = [],
2923
2924 /**
2925 * Output modifiers extensions used by this converter
2926 * @private
2927 * @type {Array}
2928 */
2929 outputModifiers = [],
2930
2931 /**
2932 * Event listeners
2933 * @private
2934 * @type {{}}
2935 */
2936 listeners = {},
2937
2938 /**
2939 * The flavor set in this converter
2940 */
2941 setConvFlavor = setFlavor,
2942
2943 /**
2944 * Metadata of the document
2945 * @type {{parsed: {}, raw: string, format: string}}
2946 */
2947 metadata = {
2948 parsed: {},
2949 raw: '',
2950 format: ''
2951 };
2952
2953 _constructor();
2954
2955 /**
2956 * Converter constructor
2957 * @private
2958 */
2959 function _constructor () {
2960 converterOptions = converterOptions || {};
2961
2962 for (var gOpt in globalOptions) {
2963 if (globalOptions.hasOwnProperty(gOpt)) {
2964 options[gOpt] = globalOptions[gOpt];
2965 }
2966 }
2967
2968 // Merge options
2969 if (typeof converterOptions === 'object') {
2970 for (var opt in converterOptions) {
2971 if (converterOptions.hasOwnProperty(opt)) {
2972 options[opt] = converterOptions[opt];
2973 }
2974 }
2975 } else {
2976 throw Error('Converter expects the passed parameter to be an object, but ' + typeof converterOptions +
2977 ' was passed instead.');
2978 }
2979
2980 if (options.extensions) {
2981 showdown.helper.forEach(options.extensions, _parseExtension);
2982 }
2983 }
2984
2985 /**
2986 * Parse extension
2987 * @param {*} ext
2988 * @param {string} [name='']
2989 * @private
2990 */
2991 function _parseExtension (ext, name) {
2992
2993 name = name || null;
2994 // If it's a string, the extension was previously loaded
2995 if (showdown.helper.isString(ext)) {
2996 ext = showdown.helper.stdExtName(ext);
2997 name = ext;
2998
2999 // LEGACY_SUPPORT CODE
3000 if (showdown.extensions[ext]) {
3001 console.warn('DEPRECATION WARNING: ' + ext + ' is an old extension that uses a deprecated loading method.' +
3002 'Please inform the developer that the extension should be updated!');
3003 legacyExtensionLoading(showdown.extensions[ext], ext);
3004 return;
3005 // END LEGACY SUPPORT CODE
3006
3007 } else if (!showdown.helper.isUndefined(extensions[ext])) {
3008 ext = extensions[ext];
3009
3010 } else {
3011 throw Error('Extension "' + ext + '" could not be loaded. It was either not found or is not a valid extension.');
3012 }
3013 }
3014
3015 if (typeof ext === 'function') {
3016 ext = ext();
3017 }
3018
3019 if (!showdown.helper.isArray(ext)) {
3020 ext = [ext];
3021 }
3022
3023 var validExt = validate(ext, name);
3024 if (!validExt.valid) {
3025 throw Error(validExt.error);
3026 }
3027
3028 for (var i = 0; i < ext.length; ++i) {
3029 switch (ext[i].type) {
3030
3031 case 'lang':
3032 langExtensions.push(ext[i]);
3033 break;
3034
3035 case 'output':
3036 outputModifiers.push(ext[i]);
3037 break;
3038 }
3039 if (ext[i].hasOwnProperty('listeners')) {
3040 for (var ln in ext[i].listeners) {
3041 if (ext[i].listeners.hasOwnProperty(ln)) {
3042 listen(ln, ext[i].listeners[ln]);
3043 }
3044 }
3045 }
3046 }
3047
3048 }
3049
3050 /**
3051 * LEGACY_SUPPORT
3052 * @param {*} ext
3053 * @param {string} name
3054 */
3055 function legacyExtensionLoading (ext, name) {
3056 if (typeof ext === 'function') {
3057 ext = ext(new showdown.Converter());
3058 }
3059 if (!showdown.helper.isArray(ext)) {
3060 ext = [ext];
3061 }
3062 var valid = validate(ext, name);
3063
3064 if (!valid.valid) {
3065 throw Error(valid.error);
3066 }
3067
3068 for (var i = 0; i < ext.length; ++i) {
3069 switch (ext[i].type) {
3070 case 'lang':
3071 langExtensions.push(ext[i]);
3072 break;
3073 case 'output':
3074 outputModifiers.push(ext[i]);
3075 break;
3076 default:// should never reach here
3077 throw Error('Extension loader error: Type unrecognized!!!');
3078 }
3079 }
3080 }
3081
3082 /**
3083 * Listen to an event
3084 * @param {string} name
3085 * @param {function} callback
3086 */
3087 function listen (name, callback) {
3088 if (!showdown.helper.isString(name)) {
3089 throw Error('Invalid argument in converter.listen() method: name must be a string, but ' + typeof name + ' given');
3090 }
3091
3092 if (typeof callback !== 'function') {
3093 throw Error('Invalid argument in converter.listen() method: callback must be a function, but ' + typeof callback + ' given');
3094 }
3095
3096 if (!listeners.hasOwnProperty(name)) {
3097 listeners[name] = [];
3098 }
3099 listeners[name].push(callback);
3100 }
3101
3102 function rTrimInputText (text) {
3103 var rsp = text.match(/^\s*/)[0].length,
3104 rgx = new RegExp('^\\s{0,' + rsp + '}', 'gm');
3105 return text.replace(rgx, '');
3106 }
3107
3108 /**
3109 * Dispatch an event
3110 * @private
3111 * @param {string} evtName Event name
3112 * @param {string} text Text
3113 * @param {{}} options Converter Options
3114 * @param {{}} globals
3115 * @returns {string}
3116 */
3117 this._dispatch = function dispatch (evtName, text, options, globals) {
3118 if (listeners.hasOwnProperty(evtName)) {
3119 for (var ei = 0; ei < listeners[evtName].length; ++ei) {
3120 var nText = listeners[evtName][ei](evtName, text, this, options, globals);
3121 if (nText && typeof nText !== 'undefined') {
3122 text = nText;
3123 }
3124 }
3125 }
3126 return text;
3127 };
3128
3129 /**
3130 * Listen to an event
3131 * @param {string} name
3132 * @param {function} callback
3133 * @returns {showdown.Converter}
3134 */
3135 this.listen = function (name, callback) {
3136 listen(name, callback);
3137 return this;
3138 };
3139
3140 /**
3141 * Converts a markdown string into HTML
3142 * @param {string} text
3143 * @returns {*}
3144 */
3145 this.makeHtml = function (text) {
3146 //check if text is not falsy
3147 if (!text) {
3148 return text;
3149 }
3150
3151 var globals = {
3152 gHtmlBlocks: [],
3153 gHtmlMdBlocks: [],
3154 gHtmlSpans: [],
3155 gUrls: {},
3156 gTitles: {},
3157 gDimensions: {},
3158 gListLevel: 0,
3159 hashLinkCounts: {},
3160 langExtensions: langExtensions,
3161 outputModifiers: outputModifiers,
3162 converter: this,
3163 ghCodeBlocks: [],
3164 metadata: {
3165 parsed: {},
3166 raw: '',
3167 format: ''
3168 }
3169 };
3170
3171 // This lets us use ¨ trema as an escape char to avoid md5 hashes
3172 // The choice of character is arbitrary; anything that isn't
3173 // magic in Markdown will work.
3174 text = text.replace(/¨/g, '¨T');
3175
3176 // Replace $ with ¨D
3177 // RegExp interprets $ as a special character
3178 // when it's in a replacement string
3179 text = text.replace(/\$/g, '¨D');
3180
3181 // Standardize line endings
3182 text = text.replace(/\r\n/g, '\n'); // DOS to Unix
3183 text = text.replace(/\r/g, '\n'); // Mac to Unix
3184
3185 // Stardardize line spaces
3186 text = text.replace(/\u00A0/g, '&nbsp;');
3187
3188 if (options.smartIndentationFix) {
3189 text = rTrimInputText(text);
3190 }
3191
3192 // Make sure text begins and ends with a couple of newlines:
3193 text = '\n\n' + text + '\n\n';
3194
3195 // detab
3196 text = showdown.subParser('detab')(text, options, globals);
3197
3198 /**
3199 * Strip any lines consisting only of spaces and tabs.
3200 * This makes subsequent regexs easier to write, because we can
3201 * match consecutive blank lines with /\n+/ instead of something
3202 * contorted like /[ \t]*\n+/
3203 */
3204 text = text.replace(/^[ \t]+$/mg, '');
3205
3206 //run languageExtensions
3207 showdown.helper.forEach(langExtensions, function (ext) {
3208 text = showdown.subParser('runExtension')(ext, text, options, globals);
3209 });
3210
3211 // run the sub parsers
3212 text = showdown.subParser('metadata')(text, options, globals);
3213 text = showdown.subParser('hashPreCodeTags')(text, options, globals);
3214 text = showdown.subParser('githubCodeBlocks')(text, options, globals);
3215 text = showdown.subParser('hashHTMLBlocks')(text, options, globals);
3216 text = showdown.subParser('hashCodeTags')(text, options, globals);
3217 text = showdown.subParser('stripLinkDefinitions')(text, options, globals);
3218 text = showdown.subParser('blockGamut')(text, options, globals);
3219 text = showdown.subParser('unhashHTMLSpans')(text, options, globals);
3220 text = showdown.subParser('unescapeSpecialChars')(text, options, globals);
3221
3222 // attacklab: Restore dollar signs
3223 text = text.replace(/¨D/g, '$$');
3224
3225 // attacklab: Restore tremas
3226 text = text.replace(/¨T/g, '¨');
3227
3228 // render a complete html document instead of a partial if the option is enabled
3229 text = showdown.subParser('completeHTMLDocument')(text, options, globals);
3230
3231 // Run output modifiers
3232 showdown.helper.forEach(outputModifiers, function (ext) {
3233 text = showdown.subParser('runExtension')(ext, text, options, globals);
3234 });
3235
3236 // update metadata
3237 metadata = globals.metadata;
3238 return text;
3239 };
3240
3241 /**
3242 * Converts an HTML string into a markdown string
3243 * @param src
3244 * @param [HTMLParser] A WHATWG DOM and HTML parser, such as JSDOM. If none is supplied, window.document will be used.
3245 * @returns {string}
3246 */
3247 this.makeMarkdown = this.makeMd = function (src, HTMLParser) {
3248
3249 // replace \r\n with \n
3250 src = src.replace(/\r\n/g, '\n');
3251 src = src.replace(/\r/g, '\n'); // old macs
3252
3253 // due to an edge case, we need to find this: > <
3254 // to prevent removing of non silent white spaces
3255 // ex: <em>this is</em> <strong>sparta</strong>
3256 src = src.replace(/>[ \t]+</, '>¨NBSP;<');
3257
3258 if (!HTMLParser) {
3259 if (window && window.document) {
3260 HTMLParser = window.document;
3261 } else {
3262 throw new Error('HTMLParser is undefined. If in a webworker or nodejs environment, you need to provide a WHATWG DOM and HTML such as JSDOM');
3263 }
3264 }
3265
3266 var doc = HTMLParser.createElement('div');
3267 doc.innerHTML = src;
3268
3269 var globals = {
3270 preList: substitutePreCodeTags(doc)
3271 };
3272
3273 // remove all newlines and collapse spaces
3274 clean(doc);
3275
3276 // some stuff, like accidental reference links must now be escaped
3277 // TODO
3278 // doc.innerHTML = doc.innerHTML.replace(/\[[\S\t ]]/);
3279
3280 var nodes = doc.childNodes,
3281 mdDoc = '';
3282
3283 for (var i = 0; i < nodes.length; i++) {
3284 mdDoc += showdown.subParser('makeMarkdown.node')(nodes[i], globals);
3285 }
3286
3287 function clean (node) {
3288 for (var n = 0; n < node.childNodes.length; ++n) {
3289 var child = node.childNodes[n];
3290 if (child.nodeType === 3) {
3291 if (!/\S/.test(child.nodeValue)) {
3292 node.removeChild(child);
3293 --n;
3294 } else {
3295 child.nodeValue = child.nodeValue.split('\n').join(' ');
3296 child.nodeValue = child.nodeValue.replace(/(\s)+/g, '$1');
3297 }
3298 } else if (child.nodeType === 1) {
3299 clean(child);
3300 }
3301 }
3302 }
3303
3304 // find all pre tags and replace contents with placeholder
3305 // we need this so that we can remove all indentation from html
3306 // to ease up parsing
3307 function substitutePreCodeTags (doc) {
3308
3309 var pres = doc.querySelectorAll('pre'),
3310 presPH = [];
3311
3312 for (var i = 0; i < pres.length; ++i) {
3313
3314 if (pres[i].childElementCount === 1 && pres[i].firstChild.tagName.toLowerCase() === 'code') {
3315 var content = pres[i].firstChild.innerHTML.trim(),
3316 language = pres[i].firstChild.getAttribute('data-language') || '';
3317
3318 // if data-language attribute is not defined, then we look for class language-*
3319 if (language === '') {
3320 var classes = pres[i].firstChild.className.split(' ');
3321 for (var c = 0; c < classes.length; ++c) {
3322 var matches = classes[c].match(/^language-(.+)$/);
3323 if (matches !== null) {
3324 language = matches[1];
3325 break;
3326 }
3327 }
3328 }
3329
3330 // unescape html entities in content
3331 content = showdown.helper.unescapeHTMLEntities(content);
3332
3333 presPH.push(content);
3334 pres[i].outerHTML = '<precode language="' + language + '" precodenum="' + i.toString() + '"></precode>';
3335 } else {
3336 presPH.push(pres[i].innerHTML);
3337 pres[i].innerHTML = '';
3338 pres[i].setAttribute('prenum', i.toString());
3339 }
3340 }
3341 return presPH;
3342 }
3343
3344 return mdDoc;
3345 };
3346
3347 /**
3348 * Set an option of this Converter instance
3349 * @param {string} key
3350 * @param {*} value
3351 */
3352 this.setOption = function (key, value) {
3353 options[key] = value;
3354 };
3355
3356 /**
3357 * Get the option of this Converter instance
3358 * @param {string} key
3359 * @returns {*}
3360 */
3361 this.getOption = function (key) {
3362 return options[key];
3363 };
3364
3365 /**
3366 * Get the options of this Converter instance
3367 * @returns {{}}
3368 */
3369 this.getOptions = function () {
3370 return options;
3371 };
3372
3373 /**
3374 * Add extension to THIS converter
3375 * @param {{}} extension
3376 * @param {string} [name=null]
3377 */
3378 this.addExtension = function (extension, name) {
3379 name = name || null;
3380 _parseExtension(extension, name);
3381 };
3382
3383 /**
3384 * Use a global registered extension with THIS converter
3385 * @param {string} extensionName Name of the previously registered extension
3386 */
3387 this.useExtension = function (extensionName) {
3388 _parseExtension(extensionName);
3389 };
3390
3391 /**
3392 * Set the flavor THIS converter should use
3393 * @param {string} name
3394 */
3395 this.setFlavor = function (name) {
3396 if (!flavor.hasOwnProperty(name)) {
3397 throw Error(name + ' flavor was not found');
3398 }
3399 var preset = flavor[name];
3400 setConvFlavor = name;
3401 for (var option in preset) {
3402 if (preset.hasOwnProperty(option)) {
3403 options[option] = preset[option];
3404 }
3405 }
3406 };
3407
3408 /**
3409 * Get the currently set flavor of this converter
3410 * @returns {string}
3411 */
3412 this.getFlavor = function () {
3413 return setConvFlavor;
3414 };
3415
3416 /**
3417 * Remove an extension from THIS converter.
3418 * Note: This is a costly operation. It's better to initialize a new converter
3419 * and specify the extensions you wish to use
3420 * @param {Array} extension
3421 */
3422 this.removeExtension = function (extension) {
3423 if (!showdown.helper.isArray(extension)) {
3424 extension = [extension];
3425 }
3426 for (var a = 0; a < extension.length; ++a) {
3427 var ext = extension[a];
3428 for (var i = 0; i < langExtensions.length; ++i) {
3429 if (langExtensions[i] === ext) {
3430 langExtensions[i].splice(i, 1);
3431 }
3432 }
3433 for (var ii = 0; ii < outputModifiers.length; ++i) {
3434 if (outputModifiers[ii] === ext) {
3435 outputModifiers[ii].splice(i, 1);
3436 }
3437 }
3438 }
3439 };
3440
3441 /**
3442 * Get all extension of THIS converter
3443 * @returns {{language: Array, output: Array}}
3444 */
3445 this.getAllExtensions = function () {
3446 return {
3447 language: langExtensions,
3448 output: outputModifiers
3449 };
3450 };
3451
3452 /**
3453 * Get the metadata of the previously parsed document
3454 * @param raw
3455 * @returns {string|{}}
3456 */
3457 this.getMetadata = function (raw) {
3458 if (raw) {
3459 return metadata.raw;
3460 } else {
3461 return metadata.parsed;
3462 }
3463 };
3464
3465 /**
3466 * Get the metadata format of the previously parsed document
3467 * @returns {string}
3468 */
3469 this.getMetadataFormat = function () {
3470 return metadata.format;
3471 };
3472
3473 /**
3474 * Private: set a single key, value metadata pair
3475 * @param {string} key
3476 * @param {string} value
3477 */
3478 this._setMetadataPair = function (key, value) {
3479 metadata.parsed[key] = value;
3480 };
3481
3482 /**
3483 * Private: set metadata format
3484 * @param {string} format
3485 */
3486 this._setMetadataFormat = function (format) {
3487 metadata.format = format;
3488 };
3489
3490 /**
3491 * Private: set metadata raw text
3492 * @param {string} raw
3493 */
3494 this._setMetadataRaw = function (raw) {
3495 metadata.raw = raw;
3496 };
3497 };
3498
3499 /**
3500 * Turn Markdown link shortcuts into XHTML <a> tags.
3501 */
3502 showdown.subParser('anchors', function (text, options, globals) {
3503 'use strict';
3504
3505 text = globals.converter._dispatch('anchors.before', text, options, globals);
3506
3507 var writeAnchorTag = function (wholeMatch, linkText, linkId, url, m5, m6, title) {
3508 if (showdown.helper.isUndefined(title)) {
3509 title = '';
3510 }
3511 linkId = linkId.toLowerCase();
3512
3513 // Special case for explicit empty url
3514 if (wholeMatch.search(/\(<?\s*>? ?(['"].*['"])?\)$/m) > -1) {
3515 url = '';
3516 } else if (!url) {
3517 if (!linkId) {
3518 // lower-case and turn embedded newlines into spaces
3519 linkId = linkText.toLowerCase().replace(/ ?\n/g, ' ');
3520 }
3521 url = '#' + linkId;
3522
3523 if (!showdown.helper.isUndefined(globals.gUrls[linkId])) {
3524 url = globals.gUrls[linkId];
3525 if (!showdown.helper.isUndefined(globals.gTitles[linkId])) {
3526 title = globals.gTitles[linkId];
3527 }
3528 } else {
3529 return wholeMatch;
3530 }
3531 }
3532
3533 //url = showdown.helper.escapeCharacters(url, '*_', false); // replaced line to improve performance
3534 url = url.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback);
3535
3536 var result = '<a href="' + url + '"';
3537
3538 if (title !== '' && title !== null) {
3539 title = title.replace(/"/g, '&quot;');
3540 //title = showdown.helper.escapeCharacters(title, '*_', false); // replaced line to improve performance
3541 title = title.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback);
3542 result += ' title="' + title + '"';
3543 }
3544
3545 // optionLinksInNewWindow only applies
3546 // to external links. Hash links (#) open in same page
3547 if (options.openLinksInNewWindow && !/^#/.test(url)) {
3548 // escaped _
3549 result += ' rel="noopener noreferrer" target="¨E95Eblank"';
3550 }
3551
3552 result += '>' + linkText + '</a>';
3553
3554 return result;
3555 };
3556
3557 // First, handle reference-style links: [link text] [id]
3558 text = text.replace(/\[((?:\[[^\]]*]|[^\[\]])*)] ?(?:\n *)?\[(.*?)]()()()()/g, writeAnchorTag);
3559
3560 // Next, inline-style links: [link text](url "optional title")
3561 // cases with crazy urls like ./image/cat1).png
3562 text = text.replace(/\[((?:\[[^\]]*]|[^\[\]])*)]()[ \t]*\([ \t]?<([^>]*)>(?:[ \t]*((["'])([^"]*?)\5))?[ \t]?\)/g,
3563 writeAnchorTag);
3564
3565 // normal cases
3566 text = text.replace(/\[((?:\[[^\]]*]|[^\[\]])*)]()[ \t]*\([ \t]?<?([\S]+?(?:\([\S]*?\)[\S]*?)?)>?(?:[ \t]*((["'])([^"]*?)\5))?[ \t]?\)/g,
3567 writeAnchorTag);
3568
3569 // handle reference-style shortcuts: [link text]
3570 // These must come last in case you've also got [link test][1]
3571 // or [link test](/foo)
3572 text = text.replace(/\[([^\[\]]+)]()()()()()/g, writeAnchorTag);
3573
3574 // Lastly handle GithubMentions if option is enabled
3575 if (options.ghMentions) {
3576 text = text.replace(/(^|\s)(\\)?(@([a-z\d]+(?:[a-z\d.-]+?[a-z\d]+)*))/gmi, function (wm, st, escape, mentions, username) {
3577 if (escape === '\\') {
3578 return st + mentions;
3579 }
3580
3581 //check if options.ghMentionsLink is a string
3582 if (!showdown.helper.isString(options.ghMentionsLink)) {
3583 throw new Error('ghMentionsLink option must be a string');
3584 }
3585 var lnk = options.ghMentionsLink.replace(/\{u}/g, username),
3586 target = '';
3587 if (options.openLinksInNewWindow) {
3588 target = ' rel="noopener noreferrer" target="¨E95Eblank"';
3589 }
3590 return st + '<a href="' + lnk + '"' + target + '>' + mentions + '</a>';
3591 });
3592 }
3593
3594 text = globals.converter._dispatch('anchors.after', text, options, globals);
3595 return text;
3596 });
3597
3598 // url allowed chars [a-z\d_.~:/?#[]@!$&'()*+,;=-]
3599
3600 var simpleURLRegex = /([*~_]+|\b)(((https?|ftp|dict):\/\/|www\.)[^'">\s]+?\.[^'">\s]+?)()(\1)?(?=\s|$)(?!["<>])/gi,
3601 simpleURLRegex2 = /([*~_]+|\b)(((https?|ftp|dict):\/\/|www\.)[^'">\s]+\.[^'">\s]+?)([.!?,()\[\]])?(\1)?(?=\s|$)(?!["<>])/gi,
3602 delimUrlRegex = /()<(((https?|ftp|dict):\/\/|www\.)[^'">\s]+)()>()/gi,
3603 simpleMailRegex = /(^|\s)(?:mailto:)?([A-Za-z0-9!#$%&'*+-/=?^_`{|}~.]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)(?=$|\s)/gmi,
3604 delimMailRegex = /<()(?:mailto:)?([-.\w]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi,
3605
3606 replaceLink = function (options) {
3607 'use strict';
3608 return function (wm, leadingMagicChars, link, m2, m3, trailingPunctuation, trailingMagicChars) {
3609 link = link.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback);
3610 var lnkTxt = link,
3611 append = '',
3612 target = '',
3613 lmc = leadingMagicChars || '',
3614 tmc = trailingMagicChars || '';
3615 if (/^www\./i.test(link)) {
3616 link = link.replace(/^www\./i, 'http://www.');
3617 }
3618 if (options.excludeTrailingPunctuationFromURLs && trailingPunctuation) {
3619 append = trailingPunctuation;
3620 }
3621 if (options.openLinksInNewWindow) {
3622 target = ' rel="noopener noreferrer" target="¨E95Eblank"';
3623 }
3624 return lmc + '<a href="' + link + '"' + target + '>' + lnkTxt + '</a>' + append + tmc;
3625 };
3626 },
3627
3628 replaceMail = function (options, globals) {
3629 'use strict';
3630 return function (wholeMatch, b, mail) {
3631 var href = 'mailto:';
3632 b = b || '';
3633 mail = showdown.subParser('unescapeSpecialChars')(mail, options, globals);
3634 if (options.encodeEmails) {
3635 href = showdown.helper.encodeEmailAddress(href + mail);
3636 mail = showdown.helper.encodeEmailAddress(mail);
3637 } else {
3638 href = href + mail;
3639 }
3640 return b + '<a href="' + href + '">' + mail + '</a>';
3641 };
3642 };
3643
3644 showdown.subParser('autoLinks', function (text, options, globals) {
3645 'use strict';
3646
3647 text = globals.converter._dispatch('autoLinks.before', text, options, globals);
3648
3649 text = text.replace(delimUrlRegex, replaceLink(options));
3650 text = text.replace(delimMailRegex, replaceMail(options, globals));
3651
3652 text = globals.converter._dispatch('autoLinks.after', text, options, globals);
3653
3654 return text;
3655 });
3656
3657 showdown.subParser('simplifiedAutoLinks', function (text, options, globals) {
3658 'use strict';
3659
3660 if (!options.simplifiedAutoLink) {
3661 return text;
3662 }
3663
3664 text = globals.converter._dispatch('simplifiedAutoLinks.before', text, options, globals);
3665
3666 if (options.excludeTrailingPunctuationFromURLs) {
3667 text = text.replace(simpleURLRegex2, replaceLink(options));
3668 } else {
3669 text = text.replace(simpleURLRegex, replaceLink(options));
3670 }
3671 text = text.replace(simpleMailRegex, replaceMail(options, globals));
3672
3673 text = globals.converter._dispatch('simplifiedAutoLinks.after', text, options, globals);
3674
3675 return text;
3676 });
3677
3678 /**
3679 * These are all the transformations that form block-level
3680 * tags like paragraphs, headers, and list items.
3681 */
3682 showdown.subParser('blockGamut', function (text, options, globals) {
3683 'use strict';
3684
3685 text = globals.converter._dispatch('blockGamut.before', text, options, globals);
3686
3687 // we parse blockquotes first so that we can have headings and hrs
3688 // inside blockquotes
3689 text = showdown.subParser('blockQuotes')(text, options, globals);
3690 text = showdown.subParser('headers')(text, options, globals);
3691
3692 // Do Horizontal Rules:
3693 text = showdown.subParser('horizontalRule')(text, options, globals);
3694
3695 text = showdown.subParser('lists')(text, options, globals);
3696 text = showdown.subParser('codeBlocks')(text, options, globals);
3697 text = showdown.subParser('tables')(text, options, globals);
3698
3699 // We already ran _HashHTMLBlocks() before, in Markdown(), but that
3700 // was to escape raw HTML in the original Markdown source. This time,
3701 // we're escaping the markup we've just created, so that we don't wrap
3702 // <p> tags around block-level tags.
3703 text = showdown.subParser('hashHTMLBlocks')(text, options, globals);
3704 text = showdown.subParser('paragraphs')(text, options, globals);
3705
3706 text = globals.converter._dispatch('blockGamut.after', text, options, globals);
3707
3708 return text;
3709 });
3710
3711 showdown.subParser('blockQuotes', function (text, options, globals) {
3712 'use strict';
3713
3714 text = globals.converter._dispatch('blockQuotes.before', text, options, globals);
3715
3716 // add a couple extra lines after the text and endtext mark
3717 text = text + '\n\n';
3718
3719 var rgx = /(^ {0,3}>[ \t]?.+\n(.+\n)*\n*)+/gm;
3720
3721 if (options.splitAdjacentBlockquotes) {
3722 rgx = /^ {0,3}>[\s\S]*?(?:\n\n)/gm;
3723 }
3724
3725 text = text.replace(rgx, function (bq) {
3726 // attacklab: hack around Konqueror 3.5.4 bug:
3727 // "----------bug".replace(/^-/g,"") == "bug"
3728 bq = bq.replace(/^[ \t]*>[ \t]?/gm, ''); // trim one level of quoting
3729
3730 // attacklab: clean up hack
3731 bq = bq.replace(/¨0/g, '');
3732
3733 bq = bq.replace(/^[ \t]+$/gm, ''); // trim whitespace-only lines
3734 bq = showdown.subParser('githubCodeBlocks')(bq, options, globals);
3735 bq = showdown.subParser('blockGamut')(bq, options, globals); // recurse
3736
3737 bq = bq.replace(/(^|\n)/g, '$1 ');
3738 // These leading spaces screw with <pre> content, so we need to fix that:
3739 bq = bq.replace(/(\s*<pre>[^\r]+?<\/pre>)/gm, function (wholeMatch, m1) {
3740 var pre = m1;
3741 // attacklab: hack around Konqueror 3.5.4 bug:
3742 pre = pre.replace(/^ /mg, '¨0');
3743 pre = pre.replace(/¨0/g, '');
3744 return pre;
3745 });
3746
3747 return showdown.subParser('hashBlock')('<blockquote>\n' + bq + '\n</blockquote>', options, globals);
3748 });
3749
3750 text = globals.converter._dispatch('blockQuotes.after', text, options, globals);
3751 return text;
3752 });
3753
3754 /**
3755 * Process Markdown `<pre><code>` blocks.
3756 */
3757 showdown.subParser('codeBlocks', function (text, options, globals) {
3758 'use strict';
3759
3760 text = globals.converter._dispatch('codeBlocks.before', text, options, globals);
3761
3762 // sentinel workarounds for lack of \A and \Z, safari\khtml bug
3763 text += '¨0';
3764
3765 var pattern = /(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=¨0))/g;
3766 text = text.replace(pattern, function (wholeMatch, m1, m2) {
3767 var codeblock = m1,
3768 nextChar = m2,
3769 end = '\n';
3770
3771 codeblock = showdown.subParser('outdent')(codeblock, options, globals);
3772 codeblock = showdown.subParser('encodeCode')(codeblock, options, globals);
3773 codeblock = showdown.subParser('detab')(codeblock, options, globals);
3774 codeblock = codeblock.replace(/^\n+/g, ''); // trim leading newlines
3775 codeblock = codeblock.replace(/\n+$/g, ''); // trim trailing newlines
3776
3777 if (options.omitExtraWLInCodeBlocks) {
3778 end = '';
3779 }
3780
3781 codeblock = '<pre><code>' + codeblock + end + '</code></pre>';
3782
3783 return showdown.subParser('hashBlock')(codeblock, options, globals) + nextChar;
3784 });
3785
3786 // strip sentinel
3787 text = text.replace(/¨0/, '');
3788
3789 text = globals.converter._dispatch('codeBlocks.after', text, options, globals);
3790 return text;
3791 });
3792
3793 /**
3794 *
3795 * * Backtick quotes are used for <code></code> spans.
3796 *
3797 * * You can use multiple backticks as the delimiters if you want to
3798 * include literal backticks in the code span. So, this input:
3799 *
3800 * Just type ``foo `bar` baz`` at the prompt.
3801 *
3802 * Will translate to:
3803 *
3804 * <p>Just type <code>foo `bar` baz</code> at the prompt.</p>
3805 *
3806 * There's no arbitrary limit to the number of backticks you
3807 * can use as delimters. If you need three consecutive backticks
3808 * in your code, use four for delimiters, etc.
3809 *
3810 * * You can use spaces to get literal backticks at the edges:
3811 *
3812 * ... type `` `bar` `` ...
3813 *
3814 * Turns to:
3815 *
3816 * ... type <code>`bar`</code> ...
3817 */
3818 showdown.subParser('codeSpans', function (text, options, globals) {
3819 'use strict';
3820
3821 text = globals.converter._dispatch('codeSpans.before', text, options, globals);
3822
3823 if (typeof text === 'undefined') {
3824 text = '';
3825 }
3826 text = text.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm,
3827 function (wholeMatch, m1, m2, m3) {
3828 var c = m3;
3829 c = c.replace(/^([ \t]*)/g, ''); // leading whitespace
3830 c = c.replace(/[ \t]*$/g, ''); // trailing whitespace
3831 c = showdown.subParser('encodeCode')(c, options, globals);
3832 c = m1 + '<code>' + c + '</code>';
3833 c = showdown.subParser('hashHTMLSpans')(c, options, globals);
3834 return c;
3835 }
3836 );
3837
3838 text = globals.converter._dispatch('codeSpans.after', text, options, globals);
3839 return text;
3840 });
3841
3842 /**
3843 * Create a full HTML document from the processed markdown
3844 */
3845 showdown.subParser('completeHTMLDocument', function (text, options, globals) {
3846 'use strict';
3847
3848 if (!options.completeHTMLDocument) {
3849 return text;
3850 }
3851
3852 text = globals.converter._dispatch('completeHTMLDocument.before', text, options, globals);
3853
3854 var doctype = 'html',
3855 doctypeParsed = '<!DOCTYPE HTML>\n',
3856 title = '',
3857 charset = '<meta charset="utf-8">\n',
3858 lang = '',
3859 metadata = '';
3860
3861 if (typeof globals.metadata.parsed.doctype !== 'undefined') {
3862 doctypeParsed = '<!DOCTYPE ' + globals.metadata.parsed.doctype + '>\n';
3863 doctype = globals.metadata.parsed.doctype.toString().toLowerCase();
3864 if (doctype === 'html' || doctype === 'html5') {
3865 charset = '<meta charset="utf-8">';
3866 }
3867 }
3868
3869 for (var meta in globals.metadata.parsed) {
3870 if (globals.metadata.parsed.hasOwnProperty(meta)) {
3871 switch (meta.toLowerCase()) {
3872 case 'doctype':
3873 break;
3874
3875 case 'title':
3876 title = '<title>' + globals.metadata.parsed.title + '</title>\n';
3877 break;
3878
3879 case 'charset':
3880 if (doctype === 'html' || doctype === 'html5') {
3881 charset = '<meta charset="' + globals.metadata.parsed.charset + '">\n';
3882 } else {
3883 charset = '<meta name="charset" content="' + globals.metadata.parsed.charset + '">\n';
3884 }
3885 break;
3886
3887 case 'language':
3888 case 'lang':
3889 lang = ' lang="' + globals.metadata.parsed[meta] + '"';
3890 metadata += '<meta name="' + meta + '" content="' + globals.metadata.parsed[meta] + '">\n';
3891 break;
3892
3893 default:
3894 metadata += '<meta name="' + meta + '" content="' + globals.metadata.parsed[meta] + '">\n';
3895 }
3896 }
3897 }
3898
3899 text = doctypeParsed + '<html' + lang + '>\n<head>\n' + title + charset + metadata + '</head>\n<body>\n' + text.trim() + '\n</body>\n</html>';
3900
3901 text = globals.converter._dispatch('completeHTMLDocument.after', text, options, globals);
3902 return text;
3903 });
3904
3905 /**
3906 * Convert all tabs to spaces
3907 */
3908 showdown.subParser('detab', function (text, options, globals) {
3909 'use strict';
3910 text = globals.converter._dispatch('detab.before', text, options, globals);
3911
3912 // expand first n-1 tabs
3913 text = text.replace(/\t(?=\t)/g, ' '); // g_tab_width
3914
3915 // replace the nth with two sentinels
3916 text = text.replace(/\t/g, '¨A¨B');
3917
3918 // use the sentinel to anchor our regex so it doesn't explode
3919 text = text.replace(/¨B(.+?)¨A/g, function (wholeMatch, m1) {
3920 var leadingText = m1,
3921 numSpaces = 4 - leadingText.length % 4; // g_tab_width
3922
3923 // there *must* be a better way to do this:
3924 for (var i = 0; i < numSpaces; i++) {
3925 leadingText += ' ';
3926 }
3927
3928 return leadingText;
3929 });
3930
3931 // clean up sentinels
3932 text = text.replace(/¨A/g, ' '); // g_tab_width
3933 text = text.replace(/¨B/g, '');
3934
3935 text = globals.converter._dispatch('detab.after', text, options, globals);
3936 return text;
3937 });
3938
3939 showdown.subParser('ellipsis', function (text, options, globals) {
3940 'use strict';
3941
3942 text = globals.converter._dispatch('ellipsis.before', text, options, globals);
3943
3944 text = text.replace(/\.\.\./g, '…');
3945
3946 text = globals.converter._dispatch('ellipsis.after', text, options, globals);
3947
3948 return text;
3949 });
3950
3951 /**
3952 * Turn emoji codes into emojis
3953 *
3954 * List of supported emojis: https://github.com/showdownjs/showdown/wiki/Emojis
3955 */
3956 showdown.subParser('emoji', function (text, options, globals) {
3957 'use strict';
3958
3959 if (!options.emoji) {
3960 return text;
3961 }
3962
3963 text = globals.converter._dispatch('emoji.before', text, options, globals);
3964
3965 var emojiRgx = /:([\S]+?):/g;
3966
3967 text = text.replace(emojiRgx, function (wm, emojiCode) {
3968 if (showdown.helper.emojis.hasOwnProperty(emojiCode)) {
3969 return showdown.helper.emojis[emojiCode];
3970 }
3971 return wm;
3972 });
3973
3974 text = globals.converter._dispatch('emoji.after', text, options, globals);
3975
3976 return text;
3977 });
3978
3979 /**
3980 * Smart processing for ampersands and angle brackets that need to be encoded.
3981 */
3982 showdown.subParser('encodeAmpsAndAngles', function (text, options, globals) {
3983 'use strict';
3984 text = globals.converter._dispatch('encodeAmpsAndAngles.before', text, options, globals);
3985
3986 // Ampersand-encoding based entirely on Nat Irons's Amputator MT plugin:
3987 // http://bumppo.net/projects/amputator/
3988 text = text.replace(/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/g, '&amp;');
3989
3990 // Encode naked <'s
3991 text = text.replace(/<(?![a-z\/?$!])/gi, '&lt;');
3992
3993 // Encode <
3994 text = text.replace(/</g, '&lt;');
3995
3996 // Encode >
3997 text = text.replace(/>/g, '&gt;');
3998
3999 text = globals.converter._dispatch('encodeAmpsAndAngles.after', text, options, globals);
4000 return text;
4001 });
4002
4003 /**
4004 * Returns the string, with after processing the following backslash escape sequences.
4005 *
4006 * attacklab: The polite way to do this is with the new escapeCharacters() function:
4007 *
4008 * text = escapeCharacters(text,"\\",true);
4009 * text = escapeCharacters(text,"`*_{}[]()>#+-.!",true);
4010 *
4011 * ...but we're sidestepping its use of the (slow) RegExp constructor
4012 * as an optimization for Firefox. This function gets called a LOT.
4013 */
4014 showdown.subParser('encodeBackslashEscapes', function (text, options, globals) {
4015 'use strict';
4016 text = globals.converter._dispatch('encodeBackslashEscapes.before', text, options, globals);
4017
4018 text = text.replace(/\\(\\)/g, showdown.helper.escapeCharactersCallback);
4019 text = text.replace(/\\([`*_{}\[\]()>#+.!~=|-])/g, showdown.helper.escapeCharactersCallback);
4020
4021 text = globals.converter._dispatch('encodeBackslashEscapes.after', text, options, globals);
4022 return text;
4023 });
4024
4025 /**
4026 * Encode/escape certain characters inside Markdown code runs.
4027 * The point is that in code, these characters are literals,
4028 * and lose their special Markdown meanings.
4029 */
4030 showdown.subParser('encodeCode', function (text, options, globals) {
4031 'use strict';
4032
4033 text = globals.converter._dispatch('encodeCode.before', text, options, globals);
4034
4035 // Encode all ampersands; HTML entities are not
4036 // entities within a Markdown code span.
4037 text = text
4038 .replace(/&/g, '&amp;')
4039 // Do the angle bracket song and dance:
4040 .replace(/</g, '&lt;')
4041 .replace(/>/g, '&gt;')
4042 // Now, escape characters that are magic in Markdown:
4043 .replace(/([*_{}\[\]\\=~-])/g, showdown.helper.escapeCharactersCallback);
4044
4045 text = globals.converter._dispatch('encodeCode.after', text, options, globals);
4046 return text;
4047 });
4048
4049 /**
4050 * Within tags -- meaning between < and > -- encode [\ ` * _ ~ =] so they
4051 * don't conflict with their use in Markdown for code, italics and strong.
4052 */
4053 showdown.subParser('escapeSpecialCharsWithinTagAttributes', function (text, options, globals) {
4054 'use strict';
4055 text = globals.converter._dispatch('escapeSpecialCharsWithinTagAttributes.before', text, options, globals);
4056
4057 // Build a regex to find HTML tags.
4058 var tags = /<\/?[a-z\d_:-]+(?:[\s]+[\s\S]+?)?>/gi,
4059 comments = /<!(--(?:(?:[^>-]|-[^>])(?:[^-]|-[^-])*)--)>/gi;
4060
4061 text = text.replace(tags, function (wholeMatch) {
4062 return wholeMatch
4063 .replace(/(.)<\/?code>(?=.)/g, '$1`')
4064 .replace(/([\\`*_~=|])/g, showdown.helper.escapeCharactersCallback);
4065 });
4066
4067 text = text.replace(comments, function (wholeMatch) {
4068 return wholeMatch
4069 .replace(/([\\`*_~=|])/g, showdown.helper.escapeCharactersCallback);
4070 });
4071
4072 text = globals.converter._dispatch('escapeSpecialCharsWithinTagAttributes.after', text, options, globals);
4073 return text;
4074 });
4075
4076 /**
4077 * Handle github codeblocks prior to running HashHTML so that
4078 * HTML contained within the codeblock gets escaped properly
4079 * Example:
4080 * ```ruby
4081 * def hello_world(x)
4082 * puts "Hello, #{x}"
4083 * end
4084 * ```
4085 */
4086 showdown.subParser('githubCodeBlocks', function (text, options, globals) {
4087 'use strict';
4088
4089 // early exit if option is not enabled
4090 if (!options.ghCodeBlocks) {
4091 return text;
4092 }
4093
4094 text = globals.converter._dispatch('githubCodeBlocks.before', text, options, globals);
4095
4096 text += '¨0';
4097
4098 text = text.replace(/(?:^|\n)(?: {0,3})(```+|~~~+)(?: *)([^\s`~]*)\n([\s\S]*?)\n(?: {0,3})\1/g, function (wholeMatch, delim, language, codeblock) {
4099 var end = (options.omitExtraWLInCodeBlocks) ? '' : '\n';
4100
4101 // First parse the github code block
4102 codeblock = showdown.subParser('encodeCode')(codeblock, options, globals);
4103 codeblock = showdown.subParser('detab')(codeblock, options, globals);
4104 codeblock = codeblock.replace(/^\n+/g, ''); // trim leading newlines
4105 codeblock = codeblock.replace(/\n+$/g, ''); // trim trailing whitespace
4106
4107 codeblock = '<pre><code' + (language ? ' class="' + language + ' language-' + language + '"' : '') + '>' + codeblock + end + '</code></pre>';
4108
4109 codeblock = showdown.subParser('hashBlock')(codeblock, options, globals);
4110
4111 // Since GHCodeblocks can be false positives, we need to
4112 // store the primitive text and the parsed text in a global var,
4113 // and then return a token
4114 return '\n\n¨G' + (globals.ghCodeBlocks.push({text: wholeMatch, codeblock: codeblock}) - 1) + 'G\n\n';
4115 });
4116
4117 // attacklab: strip sentinel
4118 text = text.replace(/¨0/, '');
4119
4120 return globals.converter._dispatch('githubCodeBlocks.after', text, options, globals);
4121 });
4122
4123 showdown.subParser('hashBlock', function (text, options, globals) {
4124 'use strict';
4125 text = globals.converter._dispatch('hashBlock.before', text, options, globals);
4126 text = text.replace(/(^\n+|\n+$)/g, '');
4127 text = '\n\n¨K' + (globals.gHtmlBlocks.push(text) - 1) + 'K\n\n';
4128 text = globals.converter._dispatch('hashBlock.after', text, options, globals);
4129 return text;
4130 });
4131
4132 /**
4133 * Hash and escape <code> elements that should not be parsed as markdown
4134 */
4135 showdown.subParser('hashCodeTags', function (text, options, globals) {
4136 'use strict';
4137 text = globals.converter._dispatch('hashCodeTags.before', text, options, globals);
4138
4139 var repFunc = function (wholeMatch, match, left, right) {
4140 var codeblock = left + showdown.subParser('encodeCode')(match, options, globals) + right;
4141 return '¨C' + (globals.gHtmlSpans.push(codeblock) - 1) + 'C';
4142 };
4143
4144 // Hash naked <code>
4145 text = showdown.helper.replaceRecursiveRegExp(text, repFunc, '<code\\b[^>]*>', '</code>', 'gim');
4146
4147 text = globals.converter._dispatch('hashCodeTags.after', text, options, globals);
4148 return text;
4149 });
4150
4151 showdown.subParser('hashElement', function (text, options, globals) {
4152 'use strict';
4153
4154 return function (wholeMatch, m1) {
4155 var blockText = m1;
4156
4157 // Undo double lines
4158 blockText = blockText.replace(/\n\n/g, '\n');
4159 blockText = blockText.replace(/^\n/, '');
4160
4161 // strip trailing blank lines
4162 blockText = blockText.replace(/\n+$/g, '');
4163
4164 // Replace the element text with a marker ("¨KxK" where x is its key)
4165 blockText = '\n\n¨K' + (globals.gHtmlBlocks.push(blockText) - 1) + 'K\n\n';
4166
4167 return blockText;
4168 };
4169 });
4170
4171 showdown.subParser('hashHTMLBlocks', function (text, options, globals) {
4172 'use strict';
4173 text = globals.converter._dispatch('hashHTMLBlocks.before', text, options, globals);
4174
4175 var blockTags = [
4176 'pre',
4177 'div',
4178 'h1',
4179 'h2',
4180 'h3',
4181 'h4',
4182 'h5',
4183 'h6',
4184 'blockquote',
4185 'table',
4186 'dl',
4187 'ol',
4188 'ul',
4189 'script',
4190 'noscript',
4191 'form',
4192 'fieldset',
4193 'iframe',
4194 'math',
4195 'style',
4196 'section',
4197 'header',
4198 'footer',
4199 'nav',
4200 'article',
4201 'aside',
4202 'address',
4203 'audio',
4204 'canvas',
4205 'figure',
4206 'hgroup',
4207 'output',
4208 'video',
4209 'p'
4210 ],
4211 repFunc = function (wholeMatch, match, left, right) {
4212 var txt = wholeMatch;
4213 // check if this html element is marked as markdown
4214 // if so, it's contents should be parsed as markdown
4215 if (left.search(/\bmarkdown\b/) !== -1) {
4216 txt = left + globals.converter.makeHtml(match) + right;
4217 }
4218 return '\n\n¨K' + (globals.gHtmlBlocks.push(txt) - 1) + 'K\n\n';
4219 };
4220
4221 if (options.backslashEscapesHTMLTags) {
4222 // encode backslash escaped HTML tags
4223 text = text.replace(/\\<(\/?[^>]+?)>/g, function (wm, inside) {
4224 return '&lt;' + inside + '&gt;';
4225 });
4226 }
4227
4228 // hash HTML Blocks
4229 for (var i = 0; i < blockTags.length; ++i) {
4230
4231 var opTagPos,
4232 rgx1 = new RegExp('^ {0,3}(<' + blockTags[i] + '\\b[^>]*>)', 'im'),
4233 patLeft = '<' + blockTags[i] + '\\b[^>]*>',
4234 patRight = '</' + blockTags[i] + '>';
4235 // 1. Look for the first position of the first opening HTML tag in the text
4236 while ((opTagPos = showdown.helper.regexIndexOf(text, rgx1)) !== -1) {
4237
4238 // if the HTML tag is \ escaped, we need to escape it and break
4239
4240
4241 //2. Split the text in that position
4242 var subTexts = showdown.helper.splitAtIndex(text, opTagPos),
4243 //3. Match recursively
4244 newSubText1 = showdown.helper.replaceRecursiveRegExp(subTexts[1], repFunc, patLeft, patRight, 'im');
4245
4246 // prevent an infinite loop
4247 if (newSubText1 === subTexts[1]) {
4248 break;
4249 }
4250 text = subTexts[0].concat(newSubText1);
4251 }
4252 }
4253 // HR SPECIAL CASE
4254 text = text.replace(/(\n {0,3}(<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g,
4255 showdown.subParser('hashElement')(text, options, globals));
4256
4257 // Special case for standalone HTML comments
4258 text = showdown.helper.replaceRecursiveRegExp(text, function (txt) {
4259 return '\n\n¨K' + (globals.gHtmlBlocks.push(txt) - 1) + 'K\n\n';
4260 }, '^ {0,3}<!--', '-->', 'gm');
4261
4262 // PHP and ASP-style processor instructions (<?...?> and <%...%>)
4263 text = text.replace(/(?:\n\n)( {0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g,
4264 showdown.subParser('hashElement')(text, options, globals));
4265
4266 text = globals.converter._dispatch('hashHTMLBlocks.after', text, options, globals);
4267 return text;
4268 });
4269
4270 /**
4271 * Hash span elements that should not be parsed as markdown
4272 */
4273 showdown.subParser('hashHTMLSpans', function (text, options, globals) {
4274 'use strict';
4275 text = globals.converter._dispatch('hashHTMLSpans.before', text, options, globals);
4276
4277 function hashHTMLSpan (html) {
4278 return '¨C' + (globals.gHtmlSpans.push(html) - 1) + 'C';
4279 }
4280
4281 // Hash Self Closing tags
4282 text = text.replace(/<[^>]+?\/>/gi, function (wm) {
4283 return hashHTMLSpan(wm);
4284 });
4285
4286 // Hash tags without properties
4287 text = text.replace(/<([^>]+?)>[\s\S]*?<\/\1>/g, function (wm) {
4288 return hashHTMLSpan(wm);
4289 });
4290
4291 // Hash tags with properties
4292 text = text.replace(/<([^>]+?)\s[^>]+?>[\s\S]*?<\/\1>/g, function (wm) {
4293 return hashHTMLSpan(wm);
4294 });
4295
4296 // Hash self closing tags without />
4297 text = text.replace(/<[^>]+?>/gi, function (wm) {
4298 return hashHTMLSpan(wm);
4299 });
4300
4301 /*showdown.helper.matchRecursiveRegExp(text, '<code\\b[^>]*>', '</code>', 'gi');*/
4302
4303 text = globals.converter._dispatch('hashHTMLSpans.after', text, options, globals);
4304 return text;
4305 });
4306
4307 /**
4308 * Unhash HTML spans
4309 */
4310 showdown.subParser('unhashHTMLSpans', function (text, options, globals) {
4311 'use strict';
4312 text = globals.converter._dispatch('unhashHTMLSpans.before', text, options, globals);
4313
4314 for (var i = 0; i < globals.gHtmlSpans.length; ++i) {
4315 var repText = globals.gHtmlSpans[i],
4316 // limiter to prevent infinite loop (assume 10 as limit for recurse)
4317 limit = 0;
4318
4319 while (/¨C(\d+)C/.test(repText)) {
4320 var num = RegExp.$1;
4321 repText = repText.replace('¨C' + num + 'C', globals.gHtmlSpans[num]);
4322 if (limit === 10) {
4323 console.error('maximum nesting of 10 spans reached!!!');
4324 break;
4325 }
4326 ++limit;
4327 }
4328 text = text.replace('¨C' + i + 'C', repText);
4329 }
4330
4331 text = globals.converter._dispatch('unhashHTMLSpans.after', text, options, globals);
4332 return text;
4333 });
4334
4335 /**
4336 * Hash and escape <pre><code> elements that should not be parsed as markdown
4337 */
4338 showdown.subParser('hashPreCodeTags', function (text, options, globals) {
4339 'use strict';
4340 text = globals.converter._dispatch('hashPreCodeTags.before', text, options, globals);
4341
4342 var repFunc = function (wholeMatch, match, left, right) {
4343 // encode html entities
4344 var codeblock = left + showdown.subParser('encodeCode')(match, options, globals) + right;
4345 return '\n\n¨G' + (globals.ghCodeBlocks.push({text: wholeMatch, codeblock: codeblock}) - 1) + 'G\n\n';
4346 };
4347
4348 // Hash <pre><code>
4349 text = showdown.helper.replaceRecursiveRegExp(text, repFunc, '^ {0,3}<pre\\b[^>]*>\\s*<code\\b[^>]*>', '^ {0,3}</code>\\s*</pre>', 'gim');
4350
4351 text = globals.converter._dispatch('hashPreCodeTags.after', text, options, globals);
4352 return text;
4353 });
4354
4355 showdown.subParser('headers', function (text, options, globals) {
4356 'use strict';
4357
4358 text = globals.converter._dispatch('headers.before', text, options, globals);
4359
4360 var headerLevelStart = (isNaN(parseInt(options.headerLevelStart))) ? 1 : parseInt(options.headerLevelStart),
4361
4362 // Set text-style headers:
4363 // Header 1
4364 // ========
4365 //
4366 // Header 2
4367 // --------
4368 //
4369 setextRegexH1 = (options.smoothLivePreview) ? /^(.+)[ \t]*\n={2,}[ \t]*\n+/gm : /^(.+)[ \t]*\n=+[ \t]*\n+/gm,
4370 setextRegexH2 = (options.smoothLivePreview) ? /^(.+)[ \t]*\n-{2,}[ \t]*\n+/gm : /^(.+)[ \t]*\n-+[ \t]*\n+/gm;
4371
4372 text = text.replace(setextRegexH1, function (wholeMatch, m1) {
4373
4374 var spanGamut = showdown.subParser('spanGamut')(m1, options, globals),
4375 hID = (options.noHeaderId) ? '' : ' id="' + headerId(m1) + '"',
4376 hLevel = headerLevelStart,
4377 hashBlock = '<h' + hLevel + hID + '>' + spanGamut + '</h' + hLevel + '>';
4378 return showdown.subParser('hashBlock')(hashBlock, options, globals);
4379 });
4380
4381 text = text.replace(setextRegexH2, function (matchFound, m1) {
4382 var spanGamut = showdown.subParser('spanGamut')(m1, options, globals),
4383 hID = (options.noHeaderId) ? '' : ' id="' + headerId(m1) + '"',
4384 hLevel = headerLevelStart + 1,
4385 hashBlock = '<h' + hLevel + hID + '>' + spanGamut + '</h' + hLevel + '>';
4386 return showdown.subParser('hashBlock')(hashBlock, options, globals);
4387 });
4388
4389 // atx-style headers:
4390 // # Header 1
4391 // ## Header 2
4392 // ## Header 2 with closing hashes ##
4393 // ...
4394 // ###### Header 6
4395 //
4396 var atxStyle = (options.requireSpaceBeforeHeadingText) ? /^(#{1,6})[ \t]+(.+?)[ \t]*#*\n+/gm : /^(#{1,6})[ \t]*(.+?)[ \t]*#*\n+/gm;
4397
4398 text = text.replace(atxStyle, function (wholeMatch, m1, m2) {
4399 var hText = m2;
4400 if (options.customizedHeaderId) {
4401 hText = m2.replace(/\s?\{([^{]+?)}\s*$/, '');
4402 }
4403
4404 var span = showdown.subParser('spanGamut')(hText, options, globals),
4405 hID = (options.noHeaderId) ? '' : ' id="' + headerId(m2) + '"',
4406 hLevel = headerLevelStart - 1 + m1.length,
4407 header = '<h' + hLevel + hID + '>' + span + '</h' + hLevel + '>';
4408
4409 return showdown.subParser('hashBlock')(header, options, globals);
4410 });
4411
4412 function headerId (m) {
4413 var title,
4414 prefix;
4415
4416 // It is separate from other options to allow combining prefix and customized
4417 if (options.customizedHeaderId) {
4418 var match = m.match(/\{([^{]+?)}\s*$/);
4419 if (match && match[1]) {
4420 m = match[1];
4421 }
4422 }
4423
4424 title = m;
4425
4426 // Prefix id to prevent causing inadvertent pre-existing style matches.
4427 if (showdown.helper.isString(options.prefixHeaderId)) {
4428 prefix = options.prefixHeaderId;
4429 } else if (options.prefixHeaderId === true) {
4430 prefix = 'section-';
4431 } else {
4432 prefix = '';
4433 }
4434
4435 if (!options.rawPrefixHeaderId) {
4436 title = prefix + title;
4437 }
4438
4439 if (options.ghCompatibleHeaderId) {
4440 title = title
4441 .replace(/ /g, '-')
4442 // replace previously escaped chars (&, ¨ and $)
4443 .replace(/&amp;/g, '')
4444 .replace(/¨T/g, '')
4445 .replace(/¨D/g, '')
4446 // replace rest of the chars (&~$ are repeated as they might have been escaped)
4447 // borrowed from github's redcarpet (some they should produce similar results)
4448 .replace(/[&+$,\/:;=?@"#{}|^¨~\[\]`\\*)(%.!'<>]/g, '')
4449 .toLowerCase();
4450 } else if (options.rawHeaderId) {
4451 title = title
4452 .replace(/ /g, '-')
4453 // replace previously escaped chars (&, ¨ and $)
4454 .replace(/&amp;/g, '&')
4455 .replace(/¨T/g, '¨')
4456 .replace(/¨D/g, '$')
4457 // replace " and '
4458 .replace(/["']/g, '-')
4459 .toLowerCase();
4460 } else {
4461 title = title
4462 .replace(/[^\w]/g, '')
4463 .toLowerCase();
4464 }
4465
4466 if (options.rawPrefixHeaderId) {
4467 title = prefix + title;
4468 }
4469
4470 if (globals.hashLinkCounts[title]) {
4471 title = title + '-' + (globals.hashLinkCounts[title]++);
4472 } else {
4473 globals.hashLinkCounts[title] = 1;
4474 }
4475 return title;
4476 }
4477
4478 text = globals.converter._dispatch('headers.after', text, options, globals);
4479 return text;
4480 });
4481
4482 /**
4483 * Turn Markdown link shortcuts into XHTML <a> tags.
4484 */
4485 showdown.subParser('horizontalRule', function (text, options, globals) {
4486 'use strict';
4487 text = globals.converter._dispatch('horizontalRule.before', text, options, globals);
4488
4489 var key = showdown.subParser('hashBlock')('<hr />', options, globals);
4490 text = text.replace(/^ {0,2}( ?-){3,}[ \t]*$/gm, key);
4491 text = text.replace(/^ {0,2}( ?\*){3,}[ \t]*$/gm, key);
4492 text = text.replace(/^ {0,2}( ?_){3,}[ \t]*$/gm, key);
4493
4494 text = globals.converter._dispatch('horizontalRule.after', text, options, globals);
4495 return text;
4496 });
4497
4498 /**
4499 * Turn Markdown image shortcuts into <img> tags.
4500 */
4501 showdown.subParser('images', function (text, options, globals) {
4502 'use strict';
4503
4504 text = globals.converter._dispatch('images.before', text, options, globals);
4505
4506 var inlineRegExp = /!\[([^\]]*?)][ \t]*()\([ \t]?<?([\S]+?(?:\([\S]*?\)[\S]*?)?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(["'])([^"]*?)\6)?[ \t]?\)/g,
4507 crazyRegExp = /!\[([^\]]*?)][ \t]*()\([ \t]?<([^>]*)>(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(?:(["'])([^"]*?)\6))?[ \t]?\)/g,
4508 base64RegExp = /!\[([^\]]*?)][ \t]*()\([ \t]?<?(data:.+?\/.+?;base64,[A-Za-z0-9+/=\n]+?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(["'])([^"]*?)\6)?[ \t]?\)/g,
4509 referenceRegExp = /!\[([^\]]*?)] ?(?:\n *)?\[([\s\S]*?)]()()()()()/g,
4510 refShortcutRegExp = /!\[([^\[\]]+)]()()()()()/g;
4511
4512 function writeImageTagBase64 (wholeMatch, altText, linkId, url, width, height, m5, title) {
4513 url = url.replace(/\s/g, '');
4514 return writeImageTag (wholeMatch, altText, linkId, url, width, height, m5, title);
4515 }
4516
4517 function writeImageTag (wholeMatch, altText, linkId, url, width, height, m5, title) {
4518
4519 var gUrls = globals.gUrls,
4520 gTitles = globals.gTitles,
4521 gDims = globals.gDimensions;
4522
4523 linkId = linkId.toLowerCase();
4524
4525 if (!title) {
4526 title = '';
4527 }
4528 // Special case for explicit empty url
4529 if (wholeMatch.search(/\(<?\s*>? ?(['"].*['"])?\)$/m) > -1) {
4530 url = '';
4531
4532 } else if (url === '' || url === null) {
4533 if (linkId === '' || linkId === null) {
4534 // lower-case and turn embedded newlines into spaces
4535 linkId = altText.toLowerCase().replace(/ ?\n/g, ' ');
4536 }
4537 url = '#' + linkId;
4538
4539 if (!showdown.helper.isUndefined(gUrls[linkId])) {
4540 url = gUrls[linkId];
4541 if (!showdown.helper.isUndefined(gTitles[linkId])) {
4542 title = gTitles[linkId];
4543 }
4544 if (!showdown.helper.isUndefined(gDims[linkId])) {
4545 width = gDims[linkId].width;
4546 height = gDims[linkId].height;
4547 }
4548 } else {
4549 return wholeMatch;
4550 }
4551 }
4552
4553 altText = altText
4554 .replace(/"/g, '&quot;')
4555 //altText = showdown.helper.escapeCharacters(altText, '*_', false);
4556 .replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback);
4557 //url = showdown.helper.escapeCharacters(url, '*_', false);
4558 url = url.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback);
4559 var result = '<img src="' + url + '" alt="' + altText + '"';
4560
4561 if (title && showdown.helper.isString(title)) {
4562 title = title
4563 .replace(/"/g, '&quot;')
4564 //title = showdown.helper.escapeCharacters(title, '*_', false);
4565 .replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback);
4566 result += ' title="' + title + '"';
4567 }
4568
4569 if (width && height) {
4570 width = (width === '*') ? 'auto' : width;
4571 height = (height === '*') ? 'auto' : height;
4572
4573 result += ' width="' + width + '"';
4574 result += ' height="' + height + '"';
4575 }
4576
4577 result += ' />';
4578
4579 return result;
4580 }
4581
4582 // First, handle reference-style labeled images: ![alt text][id]
4583 text = text.replace(referenceRegExp, writeImageTag);
4584
4585 // Next, handle inline images: ![alt text](url =<width>x<height> "optional title")
4586
4587 // base64 encoded images
4588 text = text.replace(base64RegExp, writeImageTagBase64);
4589
4590 // cases with crazy urls like ./image/cat1).png
4591 text = text.replace(crazyRegExp, writeImageTag);
4592
4593 // normal cases
4594 text = text.replace(inlineRegExp, writeImageTag);
4595
4596 // handle reference-style shortcuts: ![img text]
4597 text = text.replace(refShortcutRegExp, writeImageTag);
4598
4599 text = globals.converter._dispatch('images.after', text, options, globals);
4600 return text;
4601 });
4602
4603 showdown.subParser('italicsAndBold', function (text, options, globals) {
4604 'use strict';
4605
4606 text = globals.converter._dispatch('italicsAndBold.before', text, options, globals);
4607
4608 // it's faster to have 3 separate regexes for each case than have just one
4609 // because of backtracing, in some cases, it could lead to an exponential effect
4610 // called "catastrophic backtrace". Ominous!
4611
4612 function parseInside (txt, left, right) {
4613 /*
4614 if (options.simplifiedAutoLink) {
4615 txt = showdown.subParser('simplifiedAutoLinks')(txt, options, globals);
4616 }
4617 */
4618 return left + txt + right;
4619 }
4620
4621 // Parse underscores
4622 if (options.literalMidWordUnderscores) {
4623 text = text.replace(/\b___(\S[\s\S]*?)___\b/g, function (wm, txt) {
4624 return parseInside (txt, '<strong><em>', '</em></strong>');
4625 });
4626 text = text.replace(/\b__(\S[\s\S]*?)__\b/g, function (wm, txt) {
4627 return parseInside (txt, '<strong>', '</strong>');
4628 });
4629 text = text.replace(/\b_(\S[\s\S]*?)_\b/g, function (wm, txt) {
4630 return parseInside (txt, '<em>', '</em>');
4631 });
4632 } else {
4633 text = text.replace(/___(\S[\s\S]*?)___/g, function (wm, m) {
4634 return (/\S$/.test(m)) ? parseInside (m, '<strong><em>', '</em></strong>') : wm;
4635 });
4636 text = text.replace(/__(\S[\s\S]*?)__/g, function (wm, m) {
4637 return (/\S$/.test(m)) ? parseInside (m, '<strong>', '</strong>') : wm;
4638 });
4639 text = text.replace(/_([^\s_][\s\S]*?)_/g, function (wm, m) {
4640 // !/^_[^_]/.test(m) - test if it doesn't start with __ (since it seems redundant, we removed it)
4641 return (/\S$/.test(m)) ? parseInside (m, '<em>', '</em>') : wm;
4642 });
4643 }
4644
4645 // Now parse asterisks
4646 if (options.literalMidWordAsterisks) {
4647 text = text.replace(/([^*]|^)\B\*\*\*(\S[\s\S]*?)\*\*\*\B(?!\*)/g, function (wm, lead, txt) {
4648 return parseInside (txt, lead + '<strong><em>', '</em></strong>');
4649 });
4650 text = text.replace(/([^*]|^)\B\*\*(\S[\s\S]*?)\*\*\B(?!\*)/g, function (wm, lead, txt) {
4651 return parseInside (txt, lead + '<strong>', '</strong>');
4652 });
4653 text = text.replace(/([^*]|^)\B\*(\S[\s\S]*?)\*\B(?!\*)/g, function (wm, lead, txt) {
4654 return parseInside (txt, lead + '<em>', '</em>');
4655 });
4656 } else {
4657 text = text.replace(/\*\*\*(\S[\s\S]*?)\*\*\*/g, function (wm, m) {
4658 return (/\S$/.test(m)) ? parseInside (m, '<strong><em>', '</em></strong>') : wm;
4659 });
4660 text = text.replace(/\*\*(\S[\s\S]*?)\*\*/g, function (wm, m) {
4661 return (/\S$/.test(m)) ? parseInside (m, '<strong>', '</strong>') : wm;
4662 });
4663 text = text.replace(/\*([^\s*][\s\S]*?)\*/g, function (wm, m) {
4664 // !/^\*[^*]/.test(m) - test if it doesn't start with ** (since it seems redundant, we removed it)
4665 return (/\S$/.test(m)) ? parseInside (m, '<em>', '</em>') : wm;
4666 });
4667 }
4668
4669
4670 text = globals.converter._dispatch('italicsAndBold.after', text, options, globals);
4671 return text;
4672 });
4673
4674 /**
4675 * Form HTML ordered (numbered) and unordered (bulleted) lists.
4676 */
4677 showdown.subParser('lists', function (text, options, globals) {
4678 'use strict';
4679
4680 /**
4681 * Process the contents of a single ordered or unordered list, splitting it
4682 * into individual list items.
4683 * @param {string} listStr
4684 * @param {boolean} trimTrailing
4685 * @returns {string}
4686 */
4687 function processListItems (listStr, trimTrailing) {
4688 // The $g_list_level global keeps track of when we're inside a list.
4689 // Each time we enter a list, we increment it; when we leave a list,
4690 // we decrement. If it's zero, we're not in a list anymore.
4691 //
4692 // We do this because when we're not inside a list, we want to treat
4693 // something like this:
4694 //
4695 // I recommend upgrading to version
4696 // 8. Oops, now this line is treated
4697 // as a sub-list.
4698 //
4699 // As a single paragraph, despite the fact that the second line starts
4700 // with a digit-period-space sequence.
4701 //
4702 // Whereas when we're inside a list (or sub-list), that line will be
4703 // treated as the start of a sub-list. What a kludge, huh? This is
4704 // an aspect of Markdown's syntax that's hard to parse perfectly
4705 // without resorting to mind-reading. Perhaps the solution is to
4706 // change the syntax rules such that sub-lists must start with a
4707 // starting cardinal number; e.g. "1." or "a.".
4708 globals.gListLevel++;
4709
4710 // trim trailing blank lines:
4711 listStr = listStr.replace(/\n{2,}$/, '\n');
4712
4713 // attacklab: add sentinel to emulate \z
4714 listStr += '¨0';
4715
4716 var rgx = /(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0| {0,3}([*+-]|\d+[.])[ \t]+))/gm,
4717 isParagraphed = (/\n[ \t]*\n(?!¨0)/.test(listStr));
4718
4719 // Since version 1.5, nesting sublists requires 4 spaces (or 1 tab) indentation,
4720 // which is a syntax breaking change
4721 // activating this option reverts to old behavior
4722 if (options.disableForced4SpacesIndentedSublists) {
4723 rgx = /(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0|\2([*+-]|\d+[.])[ \t]+))/gm;
4724 }
4725
4726 listStr = listStr.replace(rgx, function (wholeMatch, m1, m2, m3, m4, taskbtn, checked) {
4727 checked = (checked && checked.trim() !== '');
4728
4729 var item = showdown.subParser('outdent')(m4, options, globals),
4730 bulletStyle = '';
4731
4732 // Support for github tasklists
4733 if (taskbtn && options.tasklists) {
4734 bulletStyle = ' class="task-list-item" style="list-style-type: none;"';
4735 item = item.replace(/^[ \t]*\[(x|X| )?]/m, function () {
4736 var otp = '<input type="checkbox" disabled style="margin: 0px 0.35em 0.25em -1.6em; vertical-align: middle;"';
4737 if (checked) {
4738 otp += ' checked';
4739 }
4740 otp += '>';
4741 return otp;
4742 });
4743 }
4744
4745 // ISSUE #312
4746 // This input: - - - a
4747 // causes trouble to the parser, since it interprets it as:
4748 // <ul><li><li><li>a</li></li></li></ul>
4749 // instead of:
4750 // <ul><li>- - a</li></ul>
4751 // So, to prevent it, we will put a marker (¨A)in the beginning of the line
4752 // Kind of hackish/monkey patching, but seems more effective than overcomplicating the list parser
4753 item = item.replace(/^([-*+]|\d\.)[ \t]+[\S\n ]*/g, function (wm2) {
4754 return '¨A' + wm2;
4755 });
4756
4757 // m1 - Leading line or
4758 // Has a double return (multi paragraph) or
4759 // Has sublist
4760 if (m1 || (item.search(/\n{2,}/) > -1)) {
4761 item = showdown.subParser('githubCodeBlocks')(item, options, globals);
4762 item = showdown.subParser('blockGamut')(item, options, globals);
4763 } else {
4764 // Recursion for sub-lists:
4765 item = showdown.subParser('lists')(item, options, globals);
4766 item = item.replace(/\n$/, ''); // chomp(item)
4767 item = showdown.subParser('hashHTMLBlocks')(item, options, globals);
4768
4769 // Colapse double linebreaks
4770 item = item.replace(/\n\n+/g, '\n\n');
4771 if (isParagraphed) {
4772 item = showdown.subParser('paragraphs')(item, options, globals);
4773 } else {
4774 item = showdown.subParser('spanGamut')(item, options, globals);
4775 }
4776 }
4777
4778 // now we need to remove the marker (¨A)
4779 item = item.replace('¨A', '');
4780 // we can finally wrap the line in list item tags
4781 item = '<li' + bulletStyle + '>' + item + '</li>\n';
4782
4783 return item;
4784 });
4785
4786 // attacklab: strip sentinel
4787 listStr = listStr.replace(/¨0/g, '');
4788
4789 globals.gListLevel--;
4790
4791 if (trimTrailing) {
4792 listStr = listStr.replace(/\s+$/, '');
4793 }
4794
4795 return listStr;
4796 }
4797
4798 function styleStartNumber (list, listType) {
4799 // check if ol and starts by a number different than 1
4800 if (listType === 'ol') {
4801 var res = list.match(/^ *(\d+)\./);
4802 if (res && res[1] !== '1') {
4803 return ' start="' + res[1] + '"';
4804 }
4805 }
4806 return '';
4807 }
4808
4809 /**
4810 * Check and parse consecutive lists (better fix for issue #142)
4811 * @param {string} list
4812 * @param {string} listType
4813 * @param {boolean} trimTrailing
4814 * @returns {string}
4815 */
4816 function parseConsecutiveLists (list, listType, trimTrailing) {
4817 // check if we caught 2 or more consecutive lists by mistake
4818 // we use the counterRgx, meaning if listType is UL we look for OL and vice versa
4819 var olRgx = (options.disableForced4SpacesIndentedSublists) ? /^ ?\d+\.[ \t]/gm : /^ {0,3}\d+\.[ \t]/gm,
4820 ulRgx = (options.disableForced4SpacesIndentedSublists) ? /^ ?[*+-][ \t]/gm : /^ {0,3}[*+-][ \t]/gm,
4821 counterRxg = (listType === 'ul') ? olRgx : ulRgx,
4822 result = '';
4823
4824 if (list.search(counterRxg) !== -1) {
4825 (function parseCL (txt) {
4826 var pos = txt.search(counterRxg),
4827 style = styleStartNumber(list, listType);
4828 if (pos !== -1) {
4829 // slice
4830 result += '\n\n<' + listType + style + '>\n' + processListItems(txt.slice(0, pos), !!trimTrailing) + '</' + listType + '>\n';
4831
4832 // invert counterType and listType
4833 listType = (listType === 'ul') ? 'ol' : 'ul';
4834 counterRxg = (listType === 'ul') ? olRgx : ulRgx;
4835
4836 //recurse
4837 parseCL(txt.slice(pos));
4838 } else {
4839 result += '\n\n<' + listType + style + '>\n' + processListItems(txt, !!trimTrailing) + '</' + listType + '>\n';
4840 }
4841 })(list);
4842 } else {
4843 var style = styleStartNumber(list, listType);
4844 result = '\n\n<' + listType + style + '>\n' + processListItems(list, !!trimTrailing) + '</' + listType + '>\n';
4845 }
4846
4847 return result;
4848 }
4849
4850 /** Start of list parsing **/
4851 text = globals.converter._dispatch('lists.before', text, options, globals);
4852 // add sentinel to hack around khtml/safari bug:
4853 // http://bugs.webkit.org/show_bug.cgi?id=11231
4854 text += '¨0';
4855
4856 if (globals.gListLevel) {
4857 text = text.replace(/^(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(¨0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm,
4858 function (wholeMatch, list, m2) {
4859 var listType = (m2.search(/[*+-]/g) > -1) ? 'ul' : 'ol';
4860 return parseConsecutiveLists(list, listType, true);
4861 }
4862 );
4863 } else {
4864 text = text.replace(/(\n\n|^\n?)(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(¨0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm,
4865 function (wholeMatch, m1, list, m3) {
4866 var listType = (m3.search(/[*+-]/g) > -1) ? 'ul' : 'ol';
4867 return parseConsecutiveLists(list, listType, false);
4868 }
4869 );
4870 }
4871
4872 // strip sentinel
4873 text = text.replace(/¨0/, '');
4874 text = globals.converter._dispatch('lists.after', text, options, globals);
4875 return text;
4876 });
4877
4878 /**
4879 * Parse metadata at the top of the document
4880 */
4881 showdown.subParser('metadata', function (text, options, globals) {
4882 'use strict';
4883
4884 if (!options.metadata) {
4885 return text;
4886 }
4887
4888 text = globals.converter._dispatch('metadata.before', text, options, globals);
4889
4890 function parseMetadataContents (content) {
4891 // raw is raw so it's not changed in any way
4892 globals.metadata.raw = content;
4893
4894 // escape chars forbidden in html attributes
4895 // double quotes
4896 content = content
4897 // ampersand first
4898 .replace(/&/g, '&amp;')
4899 // double quotes
4900 .replace(/"/g, '&quot;');
4901
4902 content = content.replace(/\n {4}/g, ' ');
4903 content.replace(/^([\S ]+): +([\s\S]+?)$/gm, function (wm, key, value) {
4904 globals.metadata.parsed[key] = value;
4905 return '';
4906 });
4907 }
4908
4909 text = text.replace(/^\s*«««+(\S*?)\n([\s\S]+?)\n»»»+\n/, function (wholematch, format, content) {
4910 parseMetadataContents(content);
4911 return '¨M';
4912 });
4913
4914 text = text.replace(/^\s*---+(\S*?)\n([\s\S]+?)\n---+\n/, function (wholematch, format, content) {
4915 if (format) {
4916 globals.metadata.format = format;
4917 }
4918 parseMetadataContents(content);
4919 return '¨M';
4920 });
4921
4922 text = text.replace(/¨M/g, '');
4923
4924 text = globals.converter._dispatch('metadata.after', text, options, globals);
4925 return text;
4926 });
4927
4928 /**
4929 * Remove one level of line-leading tabs or spaces
4930 */
4931 showdown.subParser('outdent', function (text, options, globals) {
4932 'use strict';
4933 text = globals.converter._dispatch('outdent.before', text, options, globals);
4934
4935 // attacklab: hack around Konqueror 3.5.4 bug:
4936 // "----------bug".replace(/^-/g,"") == "bug"
4937 text = text.replace(/^(\t|[ ]{1,4})/gm, '¨0'); // attacklab: g_tab_width
4938
4939 // attacklab: clean up hack
4940 text = text.replace(/¨0/g, '');
4941
4942 text = globals.converter._dispatch('outdent.after', text, options, globals);
4943 return text;
4944 });
4945
4946 /**
4947 *
4948 */
4949 showdown.subParser('paragraphs', function (text, options, globals) {
4950 'use strict';
4951
4952 text = globals.converter._dispatch('paragraphs.before', text, options, globals);
4953 // Strip leading and trailing lines:
4954 text = text.replace(/^\n+/g, '');
4955 text = text.replace(/\n+$/g, '');
4956
4957 var grafs = text.split(/\n{2,}/g),
4958 grafsOut = [],
4959 end = grafs.length; // Wrap <p> tags
4960
4961 for (var i = 0; i < end; i++) {
4962 var str = grafs[i];
4963 // if this is an HTML marker, copy it
4964 if (str.search(/¨(K|G)(\d+)\1/g) >= 0) {
4965 grafsOut.push(str);
4966
4967 // test for presence of characters to prevent empty lines being parsed
4968 // as paragraphs (resulting in undesired extra empty paragraphs)
4969 } else if (str.search(/\S/) >= 0) {
4970 str = showdown.subParser('spanGamut')(str, options, globals);
4971 str = str.replace(/^([ \t]*)/g, '<p>');
4972 str += '</p>';
4973 grafsOut.push(str);
4974 }
4975 }
4976
4977 /** Unhashify HTML blocks */
4978 end = grafsOut.length;
4979 for (i = 0; i < end; i++) {
4980 var blockText = '',
4981 grafsOutIt = grafsOut[i],
4982 codeFlag = false;
4983 // if this is a marker for an html block...
4984 // use RegExp.test instead of string.search because of QML bug
4985 while (/¨(K|G)(\d+)\1/.test(grafsOutIt)) {
4986 var delim = RegExp.$1,
4987 num = RegExp.$2;
4988
4989 if (delim === 'K') {
4990 blockText = globals.gHtmlBlocks[num];
4991 } else {
4992 // we need to check if ghBlock is a false positive
4993 if (codeFlag) {
4994 // use encoded version of all text
4995 blockText = showdown.subParser('encodeCode')(globals.ghCodeBlocks[num].text, options, globals);
4996 } else {
4997 blockText = globals.ghCodeBlocks[num].codeblock;
4998 }
4999 }
5000 blockText = blockText.replace(/\$/g, '$$$$'); // Escape any dollar signs
5001
5002 grafsOutIt = grafsOutIt.replace(/(\n\n)?¨(K|G)\d+\2(\n\n)?/, blockText);
5003 // Check if grafsOutIt is a pre->code
5004 if (/^<pre\b[^>]*>\s*<code\b[^>]*>/.test(grafsOutIt)) {
5005 codeFlag = true;
5006 }
5007 }
5008 grafsOut[i] = grafsOutIt;
5009 }
5010 text = grafsOut.join('\n');
5011 // Strip leading and trailing lines:
5012 text = text.replace(/^\n+/g, '');
5013 text = text.replace(/\n+$/g, '');
5014 return globals.converter._dispatch('paragraphs.after', text, options, globals);
5015 });
5016
5017 /**
5018 * Run extension
5019 */
5020 showdown.subParser('runExtension', function (ext, text, options, globals) {
5021 'use strict';
5022
5023 if (ext.filter) {
5024 text = ext.filter(text, globals.converter, options);
5025
5026 } else if (ext.regex) {
5027 // TODO remove this when old extension loading mechanism is deprecated
5028 var re = ext.regex;
5029 if (!(re instanceof RegExp)) {
5030 re = new RegExp(re, 'g');
5031 }
5032 text = text.replace(re, ext.replace);
5033 }
5034
5035 return text;
5036 });
5037
5038 /**
5039 * These are all the transformations that occur *within* block-level
5040 * tags like paragraphs, headers, and list items.
5041 */
5042 showdown.subParser('spanGamut', function (text, options, globals) {
5043 'use strict';
5044
5045 text = globals.converter._dispatch('spanGamut.before', text, options, globals);
5046 text = showdown.subParser('codeSpans')(text, options, globals);
5047 text = showdown.subParser('escapeSpecialCharsWithinTagAttributes')(text, options, globals);
5048 text = showdown.subParser('encodeBackslashEscapes')(text, options, globals);
5049
5050 // Process anchor and image tags. Images must come first,
5051 // because ![foo][f] looks like an anchor.
5052 text = showdown.subParser('images')(text, options, globals);
5053 text = showdown.subParser('anchors')(text, options, globals);
5054
5055 // Make links out of things like `<http://example.com/>`
5056 // Must come after anchors, because you can use < and >
5057 // delimiters in inline links like [this](<url>).
5058 text = showdown.subParser('autoLinks')(text, options, globals);
5059 text = showdown.subParser('simplifiedAutoLinks')(text, options, globals);
5060 text = showdown.subParser('emoji')(text, options, globals);
5061 text = showdown.subParser('underline')(text, options, globals);
5062 text = showdown.subParser('italicsAndBold')(text, options, globals);
5063 text = showdown.subParser('strikethrough')(text, options, globals);
5064 text = showdown.subParser('ellipsis')(text, options, globals);
5065
5066 // we need to hash HTML tags inside spans
5067 text = showdown.subParser('hashHTMLSpans')(text, options, globals);
5068
5069 // now we encode amps and angles
5070 text = showdown.subParser('encodeAmpsAndAngles')(text, options, globals);
5071
5072 // Do hard breaks
5073 if (options.simpleLineBreaks) {
5074 // GFM style hard breaks
5075 // only add line breaks if the text does not contain a block (special case for lists)
5076 if (!/\n\n¨K/.test(text)) {
5077 text = text.replace(/\n+/g, '<br />\n');
5078 }
5079 } else {
5080 // Vanilla hard breaks
5081 text = text.replace(/ +\n/g, '<br />\n');
5082 }
5083
5084 text = globals.converter._dispatch('spanGamut.after', text, options, globals);
5085 return text;
5086 });
5087
5088 showdown.subParser('strikethrough', function (text, options, globals) {
5089 'use strict';
5090
5091 function parseInside (txt) {
5092 if (options.simplifiedAutoLink) {
5093 txt = showdown.subParser('simplifiedAutoLinks')(txt, options, globals);
5094 }
5095 return '<del>' + txt + '</del>';
5096 }
5097
5098 if (options.strikethrough) {
5099 text = globals.converter._dispatch('strikethrough.before', text, options, globals);
5100 text = text.replace(/(?:~){2}([\s\S]+?)(?:~){2}/g, function (wm, txt) { return parseInside(txt); });
5101 text = globals.converter._dispatch('strikethrough.after', text, options, globals);
5102 }
5103
5104 return text;
5105 });
5106
5107 /**
5108 * Strips link definitions from text, stores the URLs and titles in
5109 * hash references.
5110 * Link defs are in the form: ^[id]: url "optional title"
5111 */
5112 showdown.subParser('stripLinkDefinitions', function (text, options, globals) {
5113 'use strict';
5114
5115 var regex = /^ {0,3}\[(.+)]:[ \t]*\n?[ \t]*<?([^>\s]+)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*\n?[ \t]*(?:(\n*)["|'(](.+?)["|')][ \t]*)?(?:\n+|(?=¨0))/gm,
5116 base64Regex = /^ {0,3}\[(.+)]:[ \t]*\n?[ \t]*<?(data:.+?\/.+?;base64,[A-Za-z0-9+/=\n]+?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*\n?[ \t]*(?:(\n*)["|'(](.+?)["|')][ \t]*)?(?:\n\n|(?=¨0)|(?=\n\[))/gm;
5117
5118 // attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug
5119 text += '¨0';
5120
5121 var replaceFunc = function (wholeMatch, linkId, url, width, height, blankLines, title) {
5122 linkId = linkId.toLowerCase();
5123 if (url.match(/^data:.+?\/.+?;base64,/)) {
5124 // remove newlines
5125 globals.gUrls[linkId] = url.replace(/\s/g, '');
5126 } else {
5127 globals.gUrls[linkId] = showdown.subParser('encodeAmpsAndAngles')(url, options, globals); // Link IDs are case-insensitive
5128 }
5129
5130 if (blankLines) {
5131 // Oops, found blank lines, so it's not a title.
5132 // Put back the parenthetical statement we stole.
5133 return blankLines + title;
5134
5135 } else {
5136 if (title) {
5137 globals.gTitles[linkId] = title.replace(/"|'/g, '&quot;');
5138 }
5139 if (options.parseImgDimensions && width && height) {
5140 globals.gDimensions[linkId] = {
5141 width: width,
5142 height: height
5143 };
5144 }
5145 }
5146 // Completely remove the definition from the text
5147 return '';
5148 };
5149
5150 // first we try to find base64 link references
5151 text = text.replace(base64Regex, replaceFunc);
5152
5153 text = text.replace(regex, replaceFunc);
5154
5155 // attacklab: strip sentinel
5156 text = text.replace(/¨0/, '');
5157
5158 return text;
5159 });
5160
5161 showdown.subParser('tables', function (text, options, globals) {
5162 'use strict';
5163
5164 if (!options.tables) {
5165 return text;
5166 }
5167
5168 var tableRgx = /^ {0,3}\|?.+\|.+\n {0,3}\|?[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*:?[ \t]*(?:[-=]){2,}[\s\S]+?(?:\n\n|¨0)/gm,
5169 //singeColTblRgx = /^ {0,3}\|.+\|\n {0,3}\|[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*\n(?: {0,3}\|.+\|\n)+(?:\n\n|¨0)/gm;
5170 singeColTblRgx = /^ {0,3}\|.+\|[ \t]*\n {0,3}\|[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*\n( {0,3}\|.+\|[ \t]*\n)*(?:\n|¨0)/gm;
5171
5172 function parseStyles (sLine) {
5173 if (/^:[ \t]*--*$/.test(sLine)) {
5174 return ' style="text-align:left;"';
5175 } else if (/^--*[ \t]*:[ \t]*$/.test(sLine)) {
5176 return ' style="text-align:right;"';
5177 } else if (/^:[ \t]*--*[ \t]*:$/.test(sLine)) {
5178 return ' style="text-align:center;"';
5179 } else {
5180 return '';
5181 }
5182 }
5183
5184 function parseHeaders (header, style) {
5185 var id = '';
5186 header = header.trim();
5187 // support both tablesHeaderId and tableHeaderId due to error in documentation so we don't break backwards compatibility
5188 if (options.tablesHeaderId || options.tableHeaderId) {
5189 id = ' id="' + header.replace(/ /g, '_').toLowerCase() + '"';
5190 }
5191 header = showdown.subParser('spanGamut')(header, options, globals);
5192
5193 return '<th' + id + style + '>' + header + '</th>\n';
5194 }
5195
5196 function parseCells (cell, style) {
5197 var subText = showdown.subParser('spanGamut')(cell, options, globals);
5198 return '<td' + style + '>' + subText + '</td>\n';
5199 }
5200
5201 function buildTable (headers, cells) {
5202 var tb = '<table>\n<thead>\n<tr>\n',
5203 tblLgn = headers.length;
5204
5205 for (var i = 0; i < tblLgn; ++i) {
5206 tb += headers[i];
5207 }
5208 tb += '</tr>\n</thead>\n<tbody>\n';
5209
5210 for (i = 0; i < cells.length; ++i) {
5211 tb += '<tr>\n';
5212 for (var ii = 0; ii < tblLgn; ++ii) {
5213 tb += cells[i][ii];
5214 }
5215 tb += '</tr>\n';
5216 }
5217 tb += '</tbody>\n</table>\n';
5218 return tb;
5219 }
5220
5221 function parseTable (rawTable) {
5222 var i, tableLines = rawTable.split('\n');
5223
5224 for (i = 0; i < tableLines.length; ++i) {
5225 // strip wrong first and last column if wrapped tables are used
5226 if (/^ {0,3}\|/.test(tableLines[i])) {
5227 tableLines[i] = tableLines[i].replace(/^ {0,3}\|/, '');
5228 }
5229 if (/\|[ \t]*$/.test(tableLines[i])) {
5230 tableLines[i] = tableLines[i].replace(/\|[ \t]*$/, '');
5231 }
5232 // parse code spans first, but we only support one line code spans
5233 tableLines[i] = showdown.subParser('codeSpans')(tableLines[i], options, globals);
5234 }
5235
5236 var rawHeaders = tableLines[0].split('|').map(function (s) { return s.trim();}),
5237 rawStyles = tableLines[1].split('|').map(function (s) { return s.trim();}),
5238 rawCells = [],
5239 headers = [],
5240 styles = [],
5241 cells = [];
5242
5243 tableLines.shift();
5244 tableLines.shift();
5245
5246 for (i = 0; i < tableLines.length; ++i) {
5247 if (tableLines[i].trim() === '') {
5248 continue;
5249 }
5250 rawCells.push(
5251 tableLines[i]
5252 .split('|')
5253 .map(function (s) {
5254 return s.trim();
5255 })
5256 );
5257 }
5258
5259 if (rawHeaders.length < rawStyles.length) {
5260 return rawTable;
5261 }
5262
5263 for (i = 0; i < rawStyles.length; ++i) {
5264 styles.push(parseStyles(rawStyles[i]));
5265 }
5266
5267 for (i = 0; i < rawHeaders.length; ++i) {
5268 if (showdown.helper.isUndefined(styles[i])) {
5269 styles[i] = '';
5270 }
5271 headers.push(parseHeaders(rawHeaders[i], styles[i]));
5272 }
5273
5274 for (i = 0; i < rawCells.length; ++i) {
5275 var row = [];
5276 for (var ii = 0; ii < headers.length; ++ii) {
5277 if (showdown.helper.isUndefined(rawCells[i][ii])) {
5278
5279 }
5280 row.push(parseCells(rawCells[i][ii], styles[ii]));
5281 }
5282 cells.push(row);
5283 }
5284
5285 return buildTable(headers, cells);
5286 }
5287
5288 text = globals.converter._dispatch('tables.before', text, options, globals);
5289
5290 // find escaped pipe characters
5291 text = text.replace(/\\(\|)/g, showdown.helper.escapeCharactersCallback);
5292
5293 // parse multi column tables
5294 text = text.replace(tableRgx, parseTable);
5295
5296 // parse one column tables
5297 text = text.replace(singeColTblRgx, parseTable);
5298
5299 text = globals.converter._dispatch('tables.after', text, options, globals);
5300
5301 return text;
5302 });
5303
5304 showdown.subParser('underline', function (text, options, globals) {
5305 'use strict';
5306
5307 if (!options.underline) {
5308 return text;
5309 }
5310
5311 text = globals.converter._dispatch('underline.before', text, options, globals);
5312
5313 if (options.literalMidWordUnderscores) {
5314 text = text.replace(/\b___(\S[\s\S]*?)___\b/g, function (wm, txt) {
5315 return '<u>' + txt + '</u>';
5316 });
5317 text = text.replace(/\b__(\S[\s\S]*?)__\b/g, function (wm, txt) {
5318 return '<u>' + txt + '</u>';
5319 });
5320 } else {
5321 text = text.replace(/___(\S[\s\S]*?)___/g, function (wm, m) {
5322 return (/\S$/.test(m)) ? '<u>' + m + '</u>' : wm;
5323 });
5324 text = text.replace(/__(\S[\s\S]*?)__/g, function (wm, m) {
5325 return (/\S$/.test(m)) ? '<u>' + m + '</u>' : wm;
5326 });
5327 }
5328
5329 // escape remaining underscores to prevent them being parsed by italic and bold
5330 text = text.replace(/(_)/g, showdown.helper.escapeCharactersCallback);
5331
5332 text = globals.converter._dispatch('underline.after', text, options, globals);
5333
5334 return text;
5335 });
5336
5337 /**
5338 * Swap back in all the special characters we've hidden.
5339 */
5340 showdown.subParser('unescapeSpecialChars', function (text, options, globals) {
5341 'use strict';
5342 text = globals.converter._dispatch('unescapeSpecialChars.before', text, options, globals);
5343
5344 text = text.replace(/¨E(\d+)E/g, function (wholeMatch, m1) {
5345 var charCodeToReplace = parseInt(m1);
5346 return String.fromCharCode(charCodeToReplace);
5347 });
5348
5349 text = globals.converter._dispatch('unescapeSpecialChars.after', text, options, globals);
5350 return text;
5351 });
5352
5353 showdown.subParser('makeMarkdown.blockquote', function (node, globals) {
5354 'use strict';
5355
5356 var txt = '';
5357 if (node.hasChildNodes()) {
5358 var children = node.childNodes,
5359 childrenLength = children.length;
5360
5361 for (var i = 0; i < childrenLength; ++i) {
5362 var innerTxt = showdown.subParser('makeMarkdown.node')(children[i], globals);
5363
5364 if (innerTxt === '') {
5365 continue;
5366 }
5367 txt += innerTxt;
5368 }
5369 }
5370 // cleanup
5371 txt = txt.trim();
5372 txt = '> ' + txt.split('\n').join('\n> ');
5373 return txt;
5374 });
5375
5376 showdown.subParser('makeMarkdown.codeBlock', function (node, globals) {
5377 'use strict';
5378
5379 var lang = node.getAttribute('language'),
5380 num = node.getAttribute('precodenum');
5381 return '```' + lang + '\n' + globals.preList[num] + '\n```';
5382 });
5383
5384 showdown.subParser('makeMarkdown.codeSpan', function (node) {
5385 'use strict';
5386
5387 return '`' + node.innerHTML + '`';
5388 });
5389
5390 showdown.subParser('makeMarkdown.emphasis', function (node, globals) {
5391 'use strict';
5392
5393 var txt = '';
5394 if (node.hasChildNodes()) {
5395 txt += '*';
5396 var children = node.childNodes,
5397 childrenLength = children.length;
5398 for (var i = 0; i < childrenLength; ++i) {
5399 txt += showdown.subParser('makeMarkdown.node')(children[i], globals);
5400 }
5401 txt += '*';
5402 }
5403 return txt;
5404 });
5405
5406 showdown.subParser('makeMarkdown.header', function (node, globals, headerLevel) {
5407 'use strict';
5408
5409 var headerMark = new Array(headerLevel + 1).join('#'),
5410 txt = '';
5411
5412 if (node.hasChildNodes()) {
5413 txt = headerMark + ' ';
5414 var children = node.childNodes,
5415 childrenLength = children.length;
5416
5417 for (var i = 0; i < childrenLength; ++i) {
5418 txt += showdown.subParser('makeMarkdown.node')(children[i], globals);
5419 }
5420 }
5421 return txt;
5422 });
5423
5424 showdown.subParser('makeMarkdown.hr', function () {
5425 'use strict';
5426
5427 return '---';
5428 });
5429
5430 showdown.subParser('makeMarkdown.image', function (node) {
5431 'use strict';
5432
5433 var txt = '';
5434 if (node.hasAttribute('src')) {
5435 txt += '![' + node.getAttribute('alt') + '](';
5436 txt += '<' + node.getAttribute('src') + '>';
5437 if (node.hasAttribute('width') && node.hasAttribute('height')) {
5438 txt += ' =' + node.getAttribute('width') + 'x' + node.getAttribute('height');
5439 }
5440
5441 if (node.hasAttribute('title')) {
5442 txt += ' "' + node.getAttribute('title') + '"';
5443 }
5444 txt += ')';
5445 }
5446 return txt;
5447 });
5448
5449 showdown.subParser('makeMarkdown.links', function (node, globals) {
5450 'use strict';
5451
5452 var txt = '';
5453 if (node.hasChildNodes() && node.hasAttribute('href')) {
5454 var children = node.childNodes,
5455 childrenLength = children.length;
5456 txt = '[';
5457 for (var i = 0; i < childrenLength; ++i) {
5458 txt += showdown.subParser('makeMarkdown.node')(children[i], globals);
5459 }
5460 txt += '](';
5461 txt += '<' + node.getAttribute('href') + '>';
5462 if (node.hasAttribute('title')) {
5463 txt += ' "' + node.getAttribute('title') + '"';
5464 }
5465 txt += ')';
5466 }
5467 return txt;
5468 });
5469
5470 showdown.subParser('makeMarkdown.list', function (node, globals, type) {
5471 'use strict';
5472
5473 var txt = '';
5474 if (!node.hasChildNodes()) {
5475 return '';
5476 }
5477 var listItems = node.childNodes,
5478 listItemsLenght = listItems.length,
5479 listNum = node.getAttribute('start') || 1;
5480
5481 for (var i = 0; i < listItemsLenght; ++i) {
5482 if (typeof listItems[i].tagName === 'undefined' || listItems[i].tagName.toLowerCase() !== 'li') {
5483 continue;
5484 }
5485
5486 // define the bullet to use in list
5487 var bullet = '';
5488 if (type === 'ol') {
5489 bullet = listNum.toString() + '. ';
5490 } else {
5491 bullet = '- ';
5492 }
5493
5494 // parse list item
5495 txt += bullet + showdown.subParser('makeMarkdown.listItem')(listItems[i], globals);
5496 ++listNum;
5497 }
5498
5499 // add comment at the end to prevent consecutive lists to be parsed as one
5500 txt += '\n<!-- -->\n';
5501 return txt.trim();
5502 });
5503
5504 showdown.subParser('makeMarkdown.listItem', function (node, globals) {
5505 'use strict';
5506
5507 var listItemTxt = '';
5508
5509 var children = node.childNodes,
5510 childrenLenght = children.length;
5511
5512 for (var i = 0; i < childrenLenght; ++i) {
5513 listItemTxt += showdown.subParser('makeMarkdown.node')(children[i], globals);
5514 }
5515 // if it's only one liner, we need to add a newline at the end
5516 if (!/\n$/.test(listItemTxt)) {
5517 listItemTxt += '\n';
5518 } else {
5519 // it's multiparagraph, so we need to indent
5520 listItemTxt = listItemTxt
5521 .split('\n')
5522 .join('\n ')
5523 .replace(/^ {4}$/gm, '')
5524 .replace(/\n\n+/g, '\n\n');
5525 }
5526
5527 return listItemTxt;
5528 });
5529
5530
5531
5532 showdown.subParser('makeMarkdown.node', function (node, globals, spansOnly) {
5533 'use strict';
5534
5535 spansOnly = spansOnly || false;
5536
5537 var txt = '';
5538
5539 // edge case of text without wrapper paragraph
5540 if (node.nodeType === 3) {
5541 return showdown.subParser('makeMarkdown.txt')(node, globals);
5542 }
5543
5544 // HTML comment
5545 if (node.nodeType === 8) {
5546 return '<!--' + node.data + '-->\n\n';
5547 }
5548
5549 // process only node elements
5550 if (node.nodeType !== 1) {
5551 return '';
5552 }
5553
5554 var tagName = node.tagName.toLowerCase();
5555
5556 switch (tagName) {
5557
5558 //
5559 // BLOCKS
5560 //
5561 case 'h1':
5562 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 1) + '\n\n'; }
5563 break;
5564 case 'h2':
5565 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 2) + '\n\n'; }
5566 break;
5567 case 'h3':
5568 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 3) + '\n\n'; }
5569 break;
5570 case 'h4':
5571 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 4) + '\n\n'; }
5572 break;
5573 case 'h5':
5574 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 5) + '\n\n'; }
5575 break;
5576 case 'h6':
5577 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 6) + '\n\n'; }
5578 break;
5579
5580 case 'p':
5581 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.paragraph')(node, globals) + '\n\n'; }
5582 break;
5583
5584 case 'blockquote':
5585 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.blockquote')(node, globals) + '\n\n'; }
5586 break;
5587
5588 case 'hr':
5589 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.hr')(node, globals) + '\n\n'; }
5590 break;
5591
5592 case 'ol':
5593 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.list')(node, globals, 'ol') + '\n\n'; }
5594 break;
5595
5596 case 'ul':
5597 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.list')(node, globals, 'ul') + '\n\n'; }
5598 break;
5599
5600 case 'precode':
5601 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.codeBlock')(node, globals) + '\n\n'; }
5602 break;
5603
5604 case 'pre':
5605 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.pre')(node, globals) + '\n\n'; }
5606 break;
5607
5608 case 'table':
5609 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.table')(node, globals) + '\n\n'; }
5610 break;
5611
5612 //
5613 // SPANS
5614 //
5615 case 'code':
5616 txt = showdown.subParser('makeMarkdown.codeSpan')(node, globals);
5617 break;
5618
5619 case 'em':
5620 case 'i':
5621 txt = showdown.subParser('makeMarkdown.emphasis')(node, globals);
5622 break;
5623
5624 case 'strong':
5625 case 'b':
5626 txt = showdown.subParser('makeMarkdown.strong')(node, globals);
5627 break;
5628
5629 case 'del':
5630 txt = showdown.subParser('makeMarkdown.strikethrough')(node, globals);
5631 break;
5632
5633 case 'a':
5634 txt = showdown.subParser('makeMarkdown.links')(node, globals);
5635 break;
5636
5637 case 'img':
5638 txt = showdown.subParser('makeMarkdown.image')(node, globals);
5639 break;
5640
5641 default:
5642 txt = node.outerHTML + '\n\n';
5643 }
5644
5645 // common normalization
5646 // TODO eventually
5647
5648 return txt;
5649 });
5650
5651 showdown.subParser('makeMarkdown.paragraph', function (node, globals) {
5652 'use strict';
5653
5654 var txt = '';
5655 if (node.hasChildNodes()) {
5656 var children = node.childNodes,
5657 childrenLength = children.length;
5658 for (var i = 0; i < childrenLength; ++i) {
5659 txt += showdown.subParser('makeMarkdown.node')(children[i], globals);
5660 }
5661 }
5662
5663 // some text normalization
5664 txt = txt.trim();
5665
5666 return txt;
5667 });
5668
5669 showdown.subParser('makeMarkdown.pre', function (node, globals) {
5670 'use strict';
5671
5672 var num = node.getAttribute('prenum');
5673 return '<pre>' + globals.preList[num] + '</pre>';
5674 });
5675
5676 showdown.subParser('makeMarkdown.strikethrough', function (node, globals) {
5677 'use strict';
5678
5679 var txt = '';
5680 if (node.hasChildNodes()) {
5681 txt += '~~';
5682 var children = node.childNodes,
5683 childrenLength = children.length;
5684 for (var i = 0; i < childrenLength; ++i) {
5685 txt += showdown.subParser('makeMarkdown.node')(children[i], globals);
5686 }
5687 txt += '~~';
5688 }
5689 return txt;
5690 });
5691
5692 showdown.subParser('makeMarkdown.strong', function (node, globals) {
5693 'use strict';
5694
5695 var txt = '';
5696 if (node.hasChildNodes()) {
5697 txt += '**';
5698 var children = node.childNodes,
5699 childrenLength = children.length;
5700 for (var i = 0; i < childrenLength; ++i) {
5701 txt += showdown.subParser('makeMarkdown.node')(children[i], globals);
5702 }
5703 txt += '**';
5704 }
5705 return txt;
5706 });
5707
5708 showdown.subParser('makeMarkdown.table', function (node, globals) {
5709 'use strict';
5710
5711 var txt = '',
5712 tableArray = [[], []],
5713 headings = node.querySelectorAll('thead>tr>th'),
5714 rows = node.querySelectorAll('tbody>tr'),
5715 i, ii;
5716 for (i = 0; i < headings.length; ++i) {
5717 var headContent = showdown.subParser('makeMarkdown.tableCell')(headings[i], globals),
5718 allign = '---';
5719
5720 if (headings[i].hasAttribute('style')) {
5721 var style = headings[i].getAttribute('style').toLowerCase().replace(/\s/g, '');
5722 switch (style) {
5723 case 'text-align:left;':
5724 allign = ':---';
5725 break;
5726 case 'text-align:right;':
5727 allign = '---:';
5728 break;
5729 case 'text-align:center;':
5730 allign = ':---:';
5731 break;
5732 }
5733 }
5734 tableArray[0][i] = headContent.trim();
5735 tableArray[1][i] = allign;
5736 }
5737
5738 for (i = 0; i < rows.length; ++i) {
5739 var r = tableArray.push([]) - 1,
5740 cols = rows[i].getElementsByTagName('td');
5741
5742 for (ii = 0; ii < headings.length; ++ii) {
5743 var cellContent = ' ';
5744 if (typeof cols[ii] !== 'undefined') {
5745 cellContent = showdown.subParser('makeMarkdown.tableCell')(cols[ii], globals);
5746 }
5747 tableArray[r].push(cellContent);
5748 }
5749 }
5750
5751 var cellSpacesCount = 3;
5752 for (i = 0; i < tableArray.length; ++i) {
5753 for (ii = 0; ii < tableArray[i].length; ++ii) {
5754 var strLen = tableArray[i][ii].length;
5755 if (strLen > cellSpacesCount) {
5756 cellSpacesCount = strLen;
5757 }
5758 }
5759 }
5760
5761 for (i = 0; i < tableArray.length; ++i) {
5762 for (ii = 0; ii < tableArray[i].length; ++ii) {
5763 if (i === 1) {
5764 if (tableArray[i][ii].slice(-1) === ':') {
5765 tableArray[i][ii] = showdown.helper.padEnd(tableArray[i][ii].slice(-1), cellSpacesCount - 1, '-') + ':';
5766 } else {
5767 tableArray[i][ii] = showdown.helper.padEnd(tableArray[i][ii], cellSpacesCount, '-');
5768 }
5769 } else {
5770 tableArray[i][ii] = showdown.helper.padEnd(tableArray[i][ii], cellSpacesCount);
5771 }
5772 }
5773 txt += '| ' + tableArray[i].join(' | ') + ' |\n';
5774 }
5775
5776 return txt.trim();
5777 });
5778
5779 showdown.subParser('makeMarkdown.tableCell', function (node, globals) {
5780 'use strict';
5781
5782 var txt = '';
5783 if (!node.hasChildNodes()) {
5784 return '';
5785 }
5786 var children = node.childNodes,
5787 childrenLength = children.length;
5788
5789 for (var i = 0; i < childrenLength; ++i) {
5790 txt += showdown.subParser('makeMarkdown.node')(children[i], globals, true);
5791 }
5792 return txt.trim();
5793 });
5794
5795 showdown.subParser('makeMarkdown.txt', function (node) {
5796 'use strict';
5797
5798 var txt = node.nodeValue;
5799
5800 // multiple spaces are collapsed
5801 txt = txt.replace(/ +/g, ' ');
5802
5803 // replace the custom ¨NBSP; with a space
5804 txt = txt.replace(/¨NBSP;/g, ' ');
5805
5806 // ", <, > and & should replace escaped html entities
5807 txt = showdown.helper.unescapeHTMLEntities(txt);
5808
5809 // escape markdown magic characters
5810 // emphasis, strong and strikethrough - can appear everywhere
5811 // we also escape pipe (|) because of tables
5812 // and escape ` because of code blocks and spans
5813 txt = txt.replace(/([*_~|`])/g, '\\$1');
5814
5815 // escape > because of blockquotes
5816 txt = txt.replace(/^(\s*)>/g, '\\$1>');
5817
5818 // hash character, only troublesome at the beginning of a line because of headers
5819 txt = txt.replace(/^#/gm, '\\#');
5820
5821 // horizontal rules
5822 txt = txt.replace(/^(\s*)([-=]{3,})(\s*)$/, '$1\\$2$3');
5823
5824 // dot, because of ordered lists, only troublesome at the beginning of a line when preceded by an integer
5825 txt = txt.replace(/^( {0,3}\d+)\./gm, '$1\\.');
5826
5827 // +, * and -, at the beginning of a line becomes a list, so we need to escape them also (asterisk was already escaped)
5828 txt = txt.replace(/^( {0,3})([+-])/gm, '$1\\$2');
5829
5830 // images and links, ] followed by ( is problematic, so we escape it
5831 txt = txt.replace(/]([\s]*)\(/g, '\\]$1\\(');
5832
5833 // reference URIs must also be escaped
5834 txt = txt.replace(/^ {0,3}\[([\S \t]*?)]:/gm, '\\[$1]:');
5835
5836 return txt;
5837 });
5838
5839 var root = this;
5840
5841 // AMD Loader
5842 if (true) {
5843 !(__WEBPACK_AMD_DEFINE_RESULT__ = (function () {
5844 'use strict';
5845 return showdown;
5846 }).call(exports, __webpack_require__, exports, module),
5847 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
5848
5849 // CommonJS/nodeJS Loader
5850 } else {}
5851 }).call(this);
5852
5853
5854
5855
5856 /***/ })
5857
5858 /******/ });
5859 /************************************************************************/
5860 /******/ // The module cache
5861 /******/ var __webpack_module_cache__ = {};
5862 /******/
5863 /******/ // The require function
5864 /******/ function __webpack_require__(moduleId) {
5865 /******/ // Check if module is in cache
5866 /******/ var cachedModule = __webpack_module_cache__[moduleId];
5867 /******/ if (cachedModule !== undefined) {
5868 /******/ return cachedModule.exports;
5869 /******/ }
5870 /******/ // Create a new module (and put it into the cache)
5871 /******/ var module = __webpack_module_cache__[moduleId] = {
5872 /******/ // no module.id needed
5873 /******/ // no module.loaded needed
5874 /******/ exports: {}
5875 /******/ };
5876 /******/
5877 /******/ // Execute the module function
5878 /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
5879 /******/
5880 /******/ // Return the exports of the module
5881 /******/ return module.exports;
5882 /******/ }
5883 /******/
5884 /************************************************************************/
5885 /******/ /* webpack/runtime/compat get default export */
5886 /******/ (() => {
5887 /******/ // getDefaultExport function for compatibility with non-harmony modules
5888 /******/ __webpack_require__.n = (module) => {
5889 /******/ var getter = module && module.__esModule ?
5890 /******/ () => (module['default']) :
5891 /******/ () => (module);
5892 /******/ __webpack_require__.d(getter, { a: getter });
5893 /******/ return getter;
5894 /******/ };
5895 /******/ })();
5896 /******/
5897 /******/ /* webpack/runtime/define property getters */
5898 /******/ (() => {
5899 /******/ // define getter functions for harmony exports
5900 /******/ __webpack_require__.d = (exports, definition) => {
5901 /******/ for(var key in definition) {
5902 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
5903 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
5904 /******/ }
5905 /******/ }
5906 /******/ };
5907 /******/ })();
5908 /******/
5909 /******/ /* webpack/runtime/hasOwnProperty shorthand */
5910 /******/ (() => {
5911 /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
5912 /******/ })();
5913 /******/
5914 /******/ /* webpack/runtime/make namespace object */
5915 /******/ (() => {
5916 /******/ // define __esModule on exports
5917 /******/ __webpack_require__.r = (exports) => {
5918 /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
5919 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
5920 /******/ }
5921 /******/ Object.defineProperty(exports, '__esModule', { value: true });
5922 /******/ };
5923 /******/ })();
5924 /******/
5925 /************************************************************************/
5926 var __webpack_exports__ = {};
5927 // This entry need to be wrapped in an IIFE because it need to be in strict mode.
5928 (() => {
5929 "use strict";
5930 // ESM COMPAT FLAG
5931 __webpack_require__.r(__webpack_exports__);
5932
5933 // EXPORTS
5934 __webpack_require__.d(__webpack_exports__, {
5935 "__EXPERIMENTAL_ELEMENTS": () => (/* reexport */ __EXPERIMENTAL_ELEMENTS),
5936 "__EXPERIMENTAL_PATHS_WITH_MERGE": () => (/* reexport */ __EXPERIMENTAL_PATHS_WITH_MERGE),
5937 "__EXPERIMENTAL_STYLE_PROPERTY": () => (/* reexport */ __EXPERIMENTAL_STYLE_PROPERTY),
5938 "__experimentalCloneSanitizedBlock": () => (/* reexport */ __experimentalCloneSanitizedBlock),
5939 "__experimentalGetAccessibleBlockLabel": () => (/* reexport */ getAccessibleBlockLabel),
5940 "__experimentalGetBlockAttributesNamesByRole": () => (/* reexport */ __experimentalGetBlockAttributesNamesByRole),
5941 "__experimentalGetBlockLabel": () => (/* reexport */ getBlockLabel),
5942 "__experimentalSanitizeBlockAttributes": () => (/* reexport */ __experimentalSanitizeBlockAttributes),
5943 "__unstableGetBlockProps": () => (/* reexport */ getBlockProps),
5944 "__unstableGetInnerBlocksProps": () => (/* reexport */ getInnerBlocksProps),
5945 "__unstableSerializeAndClean": () => (/* reexport */ __unstableSerializeAndClean),
5946 "children": () => (/* reexport */ children),
5947 "cloneBlock": () => (/* reexport */ cloneBlock),
5948 "createBlock": () => (/* reexport */ createBlock),
5949 "createBlocksFromInnerBlocksTemplate": () => (/* reexport */ createBlocksFromInnerBlocksTemplate),
5950 "doBlocksMatchTemplate": () => (/* reexport */ doBlocksMatchTemplate),
5951 "findTransform": () => (/* reexport */ findTransform),
5952 "getBlockAttributes": () => (/* reexport */ getBlockAttributes),
5953 "getBlockContent": () => (/* reexport */ getBlockInnerHTML),
5954 "getBlockDefaultClassName": () => (/* reexport */ getBlockDefaultClassName),
5955 "getBlockFromExample": () => (/* reexport */ getBlockFromExample),
5956 "getBlockMenuDefaultClassName": () => (/* reexport */ getBlockMenuDefaultClassName),
5957 "getBlockSupport": () => (/* reexport */ getBlockSupport),
5958 "getBlockTransforms": () => (/* reexport */ getBlockTransforms),
5959 "getBlockType": () => (/* reexport */ getBlockType),
5960 "getBlockTypes": () => (/* reexport */ getBlockTypes),
5961 "getBlockVariations": () => (/* reexport */ getBlockVariations),
5962 "getCategories": () => (/* reexport */ categories_getCategories),
5963 "getChildBlockNames": () => (/* reexport */ getChildBlockNames),
5964 "getDefaultBlockName": () => (/* reexport */ getDefaultBlockName),
5965 "getFreeformContentHandlerName": () => (/* reexport */ getFreeformContentHandlerName),
5966 "getGroupingBlockName": () => (/* reexport */ getGroupingBlockName),
5967 "getPhrasingContentSchema": () => (/* reexport */ deprecatedGetPhrasingContentSchema),
5968 "getPossibleBlockTransformations": () => (/* reexport */ getPossibleBlockTransformations),
5969 "getSaveContent": () => (/* reexport */ getSaveContent),
5970 "getSaveElement": () => (/* reexport */ getSaveElement),
5971 "getUnregisteredTypeHandlerName": () => (/* reexport */ getUnregisteredTypeHandlerName),
5972 "hasBlockSupport": () => (/* reexport */ hasBlockSupport),
5973 "hasChildBlocks": () => (/* reexport */ hasChildBlocks),
5974 "hasChildBlocksWithInserterSupport": () => (/* reexport */ hasChildBlocksWithInserterSupport),
5975 "isReusableBlock": () => (/* reexport */ isReusableBlock),
5976 "isTemplatePart": () => (/* reexport */ isTemplatePart),
5977 "isUnmodifiedBlock": () => (/* reexport */ isUnmodifiedBlock),
5978 "isUnmodifiedDefaultBlock": () => (/* reexport */ isUnmodifiedDefaultBlock),
5979 "isValidBlockContent": () => (/* reexport */ isValidBlockContent),
5980 "isValidIcon": () => (/* reexport */ isValidIcon),
5981 "node": () => (/* reexport */ node),
5982 "normalizeIconObject": () => (/* reexport */ normalizeIconObject),
5983 "parse": () => (/* reexport */ parser_parse),
5984 "parseWithAttributeSchema": () => (/* reexport */ parseWithAttributeSchema),
5985 "pasteHandler": () => (/* reexport */ pasteHandler),
5986 "rawHandler": () => (/* reexport */ rawHandler),
5987 "registerBlockCollection": () => (/* reexport */ registerBlockCollection),
5988 "registerBlockStyle": () => (/* reexport */ registerBlockStyle),
5989 "registerBlockType": () => (/* reexport */ registerBlockType),
5990 "registerBlockVariation": () => (/* reexport */ registerBlockVariation),
5991 "serialize": () => (/* reexport */ serialize),
5992 "serializeRawBlock": () => (/* reexport */ serializeRawBlock),
5993 "setCategories": () => (/* reexport */ categories_setCategories),
5994 "setDefaultBlockName": () => (/* reexport */ setDefaultBlockName),
5995 "setFreeformContentHandlerName": () => (/* reexport */ setFreeformContentHandlerName),
5996 "setGroupingBlockName": () => (/* reexport */ setGroupingBlockName),
5997 "setUnregisteredTypeHandlerName": () => (/* reexport */ setUnregisteredTypeHandlerName),
5998 "store": () => (/* reexport */ store),
5999 "switchToBlockType": () => (/* reexport */ switchToBlockType),
6000 "synchronizeBlocksWithTemplate": () => (/* reexport */ synchronizeBlocksWithTemplate),
6001 "unregisterBlockStyle": () => (/* reexport */ unregisterBlockStyle),
6002 "unregisterBlockType": () => (/* reexport */ unregisterBlockType),
6003 "unregisterBlockVariation": () => (/* reexport */ unregisterBlockVariation),
6004 "unstable__bootstrapServerSideBlockDefinitions": () => (/* reexport */ unstable__bootstrapServerSideBlockDefinitions),
6005 "updateCategory": () => (/* reexport */ categories_updateCategory),
6006 "validateBlock": () => (/* reexport */ validateBlock),
6007 "withBlockContentContext": () => (/* reexport */ withBlockContentContext)
6008 });
6009
6010 // NAMESPACE OBJECT: ./packages/blocks/build-module/store/selectors.js
6011 var selectors_namespaceObject = {};
6012 __webpack_require__.r(selectors_namespaceObject);
6013 __webpack_require__.d(selectors_namespaceObject, {
6014 "__experimentalGetUnprocessedBlockTypes": () => (__experimentalGetUnprocessedBlockTypes),
6015 "__experimentalHasContentRoleAttribute": () => (__experimentalHasContentRoleAttribute),
6016 "getActiveBlockVariation": () => (getActiveBlockVariation),
6017 "getBlockStyles": () => (getBlockStyles),
6018 "getBlockSupport": () => (selectors_getBlockSupport),
6019 "getBlockType": () => (selectors_getBlockType),
6020 "getBlockTypes": () => (selectors_getBlockTypes),
6021 "getBlockVariations": () => (selectors_getBlockVariations),
6022 "getCategories": () => (getCategories),
6023 "getChildBlockNames": () => (selectors_getChildBlockNames),
6024 "getCollections": () => (getCollections),
6025 "getDefaultBlockName": () => (selectors_getDefaultBlockName),
6026 "getDefaultBlockVariation": () => (getDefaultBlockVariation),
6027 "getFreeformFallbackBlockName": () => (getFreeformFallbackBlockName),
6028 "getGroupingBlockName": () => (selectors_getGroupingBlockName),
6029 "getUnregisteredFallbackBlockName": () => (getUnregisteredFallbackBlockName),
6030 "hasBlockSupport": () => (selectors_hasBlockSupport),
6031 "hasChildBlocks": () => (selectors_hasChildBlocks),
6032 "hasChildBlocksWithInserterSupport": () => (selectors_hasChildBlocksWithInserterSupport),
6033 "isMatchingSearchTerm": () => (isMatchingSearchTerm)
6034 });
6035
6036 // NAMESPACE OBJECT: ./packages/blocks/build-module/store/private-selectors.js
6037 var private_selectors_namespaceObject = {};
6038 __webpack_require__.r(private_selectors_namespaceObject);
6039 __webpack_require__.d(private_selectors_namespaceObject, {
6040 "getSupportedStyles": () => (getSupportedStyles)
6041 });
6042
6043 // NAMESPACE OBJECT: ./packages/blocks/build-module/store/actions.js
6044 var actions_namespaceObject = {};
6045 __webpack_require__.r(actions_namespaceObject);
6046 __webpack_require__.d(actions_namespaceObject, {
6047 "__experimentalReapplyBlockTypeFilters": () => (__experimentalReapplyBlockTypeFilters),
6048 "__experimentalRegisterBlockType": () => (__experimentalRegisterBlockType),
6049 "addBlockCollection": () => (addBlockCollection),
6050 "addBlockStyles": () => (addBlockStyles),
6051 "addBlockTypes": () => (addBlockTypes),
6052 "addBlockVariations": () => (addBlockVariations),
6053 "removeBlockCollection": () => (removeBlockCollection),
6054 "removeBlockStyles": () => (removeBlockStyles),
6055 "removeBlockTypes": () => (removeBlockTypes),
6056 "removeBlockVariations": () => (removeBlockVariations),
6057 "setCategories": () => (setCategories),
6058 "setDefaultBlockName": () => (actions_setDefaultBlockName),
6059 "setFreeformFallbackBlockName": () => (setFreeformFallbackBlockName),
6060 "setGroupingBlockName": () => (actions_setGroupingBlockName),
6061 "setUnregisteredFallbackBlockName": () => (setUnregisteredFallbackBlockName),
6062 "updateCategory": () => (updateCategory)
6063 });
6064
6065 ;// CONCATENATED MODULE: external ["wp","data"]
6066 const external_wp_data_namespaceObject = window["wp"]["data"];
6067 ;// CONCATENATED MODULE: external ["wp","i18n"]
6068 const external_wp_i18n_namespaceObject = window["wp"]["i18n"];
6069 ;// CONCATENATED MODULE: ./node_modules/colord/index.mjs
6070 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()})};
6071
6072 ;// CONCATENATED MODULE: ./node_modules/colord/plugins/names.mjs
6073 /* 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"])}
6074
6075 ;// CONCATENATED MODULE: ./node_modules/colord/plugins/a11y.mjs
6076 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}}
6077
6078 ;// CONCATENATED MODULE: external ["wp","element"]
6079 const external_wp_element_namespaceObject = window["wp"]["element"];
6080 ;// CONCATENATED MODULE: external ["wp","dom"]
6081 const external_wp_dom_namespaceObject = window["wp"]["dom"];
6082 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/constants.js
6083 const BLOCK_ICON_DEFAULT = 'block-default';
6084
6085 /**
6086 * Array of valid keys in a block type settings deprecation object.
6087 *
6088 * @type {string[]}
6089 */
6090 const DEPRECATED_ENTRY_KEYS = ['attributes', 'supports', 'save', 'migrate', 'isEligible', 'apiVersion'];
6091 const __EXPERIMENTAL_STYLE_PROPERTY = {
6092 // Kept for back-compatibility purposes.
6093 '--wp--style--color--link': {
6094 value: ['color', 'link'],
6095 support: ['color', 'link']
6096 },
6097 background: {
6098 value: ['color', 'gradient'],
6099 support: ['color', 'gradients'],
6100 useEngine: true
6101 },
6102 backgroundColor: {
6103 value: ['color', 'background'],
6104 support: ['color', 'background'],
6105 requiresOptOut: true,
6106 useEngine: true
6107 },
6108 borderColor: {
6109 value: ['border', 'color'],
6110 support: ['__experimentalBorder', 'color'],
6111 useEngine: true
6112 },
6113 borderRadius: {
6114 value: ['border', 'radius'],
6115 support: ['__experimentalBorder', 'radius'],
6116 properties: {
6117 borderTopLeftRadius: 'topLeft',
6118 borderTopRightRadius: 'topRight',
6119 borderBottomLeftRadius: 'bottomLeft',
6120 borderBottomRightRadius: 'bottomRight'
6121 },
6122 useEngine: true
6123 },
6124 borderStyle: {
6125 value: ['border', 'style'],
6126 support: ['__experimentalBorder', 'style'],
6127 useEngine: true
6128 },
6129 borderWidth: {
6130 value: ['border', 'width'],
6131 support: ['__experimentalBorder', 'width'],
6132 useEngine: true
6133 },
6134 borderTopColor: {
6135 value: ['border', 'top', 'color'],
6136 support: ['__experimentalBorder', 'color'],
6137 useEngine: true
6138 },
6139 borderTopStyle: {
6140 value: ['border', 'top', 'style'],
6141 support: ['__experimentalBorder', 'style'],
6142 useEngine: true
6143 },
6144 borderTopWidth: {
6145 value: ['border', 'top', 'width'],
6146 support: ['__experimentalBorder', 'width'],
6147 useEngine: true
6148 },
6149 borderRightColor: {
6150 value: ['border', 'right', 'color'],
6151 support: ['__experimentalBorder', 'color'],
6152 useEngine: true
6153 },
6154 borderRightStyle: {
6155 value: ['border', 'right', 'style'],
6156 support: ['__experimentalBorder', 'style'],
6157 useEngine: true
6158 },
6159 borderRightWidth: {
6160 value: ['border', 'right', 'width'],
6161 support: ['__experimentalBorder', 'width'],
6162 useEngine: true
6163 },
6164 borderBottomColor: {
6165 value: ['border', 'bottom', 'color'],
6166 support: ['__experimentalBorder', 'color'],
6167 useEngine: true
6168 },
6169 borderBottomStyle: {
6170 value: ['border', 'bottom', 'style'],
6171 support: ['__experimentalBorder', 'style'],
6172 useEngine: true
6173 },
6174 borderBottomWidth: {
6175 value: ['border', 'bottom', 'width'],
6176 support: ['__experimentalBorder', 'width'],
6177 useEngine: true
6178 },
6179 borderLeftColor: {
6180 value: ['border', 'left', 'color'],
6181 support: ['__experimentalBorder', 'color'],
6182 useEngine: true
6183 },
6184 borderLeftStyle: {
6185 value: ['border', 'left', 'style'],
6186 support: ['__experimentalBorder', 'style'],
6187 useEngine: true
6188 },
6189 borderLeftWidth: {
6190 value: ['border', 'left', 'width'],
6191 support: ['__experimentalBorder', 'width'],
6192 useEngine: true
6193 },
6194 color: {
6195 value: ['color', 'text'],
6196 support: ['color', 'text'],
6197 requiresOptOut: true,
6198 useEngine: true
6199 },
6200 columnCount: {
6201 value: ['typography', 'textColumns'],
6202 support: ['typography', 'textColumns'],
6203 useEngine: true
6204 },
6205 filter: {
6206 value: ['filter', 'duotone'],
6207 support: ['filter', 'duotone']
6208 },
6209 linkColor: {
6210 value: ['elements', 'link', 'color', 'text'],
6211 support: ['color', 'link']
6212 },
6213 captionColor: {
6214 value: ['elements', 'caption', 'color', 'text'],
6215 support: ['color', 'caption']
6216 },
6217 buttonColor: {
6218 value: ['elements', 'button', 'color', 'text'],
6219 support: ['color', 'button']
6220 },
6221 buttonBackgroundColor: {
6222 value: ['elements', 'button', 'color', 'background'],
6223 support: ['color', 'button']
6224 },
6225 headingColor: {
6226 value: ['elements', 'heading', 'color', 'text'],
6227 support: ['color', 'heading']
6228 },
6229 headingBackgroundColor: {
6230 value: ['elements', 'heading', 'color', 'background'],
6231 support: ['color', 'heading']
6232 },
6233 fontFamily: {
6234 value: ['typography', 'fontFamily'],
6235 support: ['typography', '__experimentalFontFamily'],
6236 useEngine: true
6237 },
6238 fontSize: {
6239 value: ['typography', 'fontSize'],
6240 support: ['typography', 'fontSize'],
6241 useEngine: true
6242 },
6243 fontStyle: {
6244 value: ['typography', 'fontStyle'],
6245 support: ['typography', '__experimentalFontStyle'],
6246 useEngine: true
6247 },
6248 fontWeight: {
6249 value: ['typography', 'fontWeight'],
6250 support: ['typography', '__experimentalFontWeight'],
6251 useEngine: true
6252 },
6253 lineHeight: {
6254 value: ['typography', 'lineHeight'],
6255 support: ['typography', 'lineHeight'],
6256 useEngine: true
6257 },
6258 margin: {
6259 value: ['spacing', 'margin'],
6260 support: ['spacing', 'margin'],
6261 properties: {
6262 marginTop: 'top',
6263 marginRight: 'right',
6264 marginBottom: 'bottom',
6265 marginLeft: 'left'
6266 },
6267 useEngine: true
6268 },
6269 minHeight: {
6270 value: ['dimensions', 'minHeight'],
6271 support: ['dimensions', 'minHeight'],
6272 useEngine: true
6273 },
6274 padding: {
6275 value: ['spacing', 'padding'],
6276 support: ['spacing', 'padding'],
6277 properties: {
6278 paddingTop: 'top',
6279 paddingRight: 'right',
6280 paddingBottom: 'bottom',
6281 paddingLeft: 'left'
6282 },
6283 useEngine: true
6284 },
6285 textDecoration: {
6286 value: ['typography', 'textDecoration'],
6287 support: ['typography', '__experimentalTextDecoration'],
6288 useEngine: true
6289 },
6290 textTransform: {
6291 value: ['typography', 'textTransform'],
6292 support: ['typography', '__experimentalTextTransform'],
6293 useEngine: true
6294 },
6295 letterSpacing: {
6296 value: ['typography', 'letterSpacing'],
6297 support: ['typography', '__experimentalLetterSpacing'],
6298 useEngine: true
6299 },
6300 writingMode: {
6301 value: ['typography', 'writingMode'],
6302 support: ['typography', '__experimentalWritingMode'],
6303 useEngine: true
6304 },
6305 '--wp--style--root--padding': {
6306 value: ['spacing', 'padding'],
6307 support: ['spacing', 'padding'],
6308 properties: {
6309 '--wp--style--root--padding-top': 'top',
6310 '--wp--style--root--padding-right': 'right',
6311 '--wp--style--root--padding-bottom': 'bottom',
6312 '--wp--style--root--padding-left': 'left'
6313 },
6314 rootOnly: true
6315 }
6316 };
6317 const __EXPERIMENTAL_ELEMENTS = {
6318 link: 'a',
6319 heading: 'h1, h2, h3, h4, h5, h6',
6320 h1: 'h1',
6321 h2: 'h2',
6322 h3: 'h3',
6323 h4: 'h4',
6324 h5: 'h5',
6325 h6: 'h6',
6326 button: '.wp-element-button, .wp-block-button__link',
6327 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',
6328 cite: 'cite'
6329 };
6330 const __EXPERIMENTAL_PATHS_WITH_MERGE = {
6331 'color.duotone': true,
6332 'color.gradients': true,
6333 'color.palette': true,
6334 'typography.fontFamilies': true,
6335 'typography.fontSizes': true,
6336 'spacing.spacingSizes': true
6337 };
6338
6339 ;// CONCATENATED MODULE: ./node_modules/tslib/tslib.es6.mjs
6340 /******************************************************************************
6341 Copyright (c) Microsoft Corporation.
6342
6343 Permission to use, copy, modify, and/or distribute this software for any
6344 purpose with or without fee is hereby granted.
6345
6346 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
6347 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
6348 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
6349 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
6350 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
6351 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
6352 PERFORMANCE OF THIS SOFTWARE.
6353 ***************************************************************************** */
6354 /* global Reflect, Promise, SuppressedError, Symbol */
6355
6356 var extendStatics = function(d, b) {
6357 extendStatics = Object.setPrototypeOf ||
6358 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6359 function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
6360 return extendStatics(d, b);
6361 };
6362
6363 function __extends(d, b) {
6364 if (typeof b !== "function" && b !== null)
6365 throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
6366 extendStatics(d, b);
6367 function __() { this.constructor = d; }
6368 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
6369 }
6370
6371 var __assign = function() {
6372 __assign = Object.assign || function __assign(t) {
6373 for (var s, i = 1, n = arguments.length; i < n; i++) {
6374 s = arguments[i];
6375 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
6376 }
6377 return t;
6378 }
6379 return __assign.apply(this, arguments);
6380 }
6381
6382 function __rest(s, e) {
6383 var t = {};
6384 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
6385 t[p] = s[p];
6386 if (s != null && typeof Object.getOwnPropertySymbols === "function")
6387 for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
6388 if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
6389 t[p[i]] = s[p[i]];
6390 }
6391 return t;
6392 }
6393
6394 function __decorate(decorators, target, key, desc) {
6395 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
6396 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
6397 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;
6398 return c > 3 && r && Object.defineProperty(target, key, r), r;
6399 }
6400
6401 function __param(paramIndex, decorator) {
6402 return function (target, key) { decorator(target, key, paramIndex); }
6403 }
6404
6405 function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
6406 function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
6407 var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
6408 var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
6409 var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
6410 var _, done = false;
6411 for (var i = decorators.length - 1; i >= 0; i--) {
6412 var context = {};
6413 for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
6414 for (var p in contextIn.access) context.access[p] = contextIn.access[p];
6415 context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
6416 var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
6417 if (kind === "accessor") {
6418 if (result === void 0) continue;
6419 if (result === null || typeof result !== "object") throw new TypeError("Object expected");
6420 if (_ = accept(result.get)) descriptor.get = _;
6421 if (_ = accept(result.set)) descriptor.set = _;
6422 if (_ = accept(result.init)) initializers.unshift(_);
6423 }
6424 else if (_ = accept(result)) {
6425 if (kind === "field") initializers.unshift(_);
6426 else descriptor[key] = _;
6427 }
6428 }
6429 if (target) Object.defineProperty(target, contextIn.name, descriptor);
6430 done = true;
6431 };
6432
6433 function __runInitializers(thisArg, initializers, value) {
6434 var useValue = arguments.length > 2;
6435 for (var i = 0; i < initializers.length; i++) {
6436 value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
6437 }
6438 return useValue ? value : void 0;
6439 };
6440
6441 function __propKey(x) {
6442 return typeof x === "symbol" ? x : "".concat(x);
6443 };
6444
6445 function __setFunctionName(f, name, prefix) {
6446 if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
6447 return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
6448 };
6449
6450 function __metadata(metadataKey, metadataValue) {
6451 if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
6452 }
6453
6454 function __awaiter(thisArg, _arguments, P, generator) {
6455 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
6456 return new (P || (P = Promise))(function (resolve, reject) {
6457 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6458 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6459 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
6460 step((generator = generator.apply(thisArg, _arguments || [])).next());
6461 });
6462 }
6463
6464 function __generator(thisArg, body) {
6465 var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
6466 return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
6467 function verb(n) { return function (v) { return step([n, v]); }; }
6468 function step(op) {
6469 if (f) throw new TypeError("Generator is already executing.");
6470 while (g && (g = 0, op[0] && (_ = 0)), _) try {
6471 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;
6472 if (y = 0, t) op = [op[0] & 2, t.value];
6473 switch (op[0]) {
6474 case 0: case 1: t = op; break;
6475 case 4: _.label++; return { value: op[1], done: false };
6476 case 5: _.label++; y = op[1]; op = [0]; continue;
6477 case 7: op = _.ops.pop(); _.trys.pop(); continue;
6478 default:
6479 if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
6480 if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
6481 if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
6482 if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
6483 if (t[2]) _.ops.pop();
6484 _.trys.pop(); continue;
6485 }
6486 op = body.call(thisArg, _);
6487 } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
6488 if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
6489 }
6490 }
6491
6492 var __createBinding = Object.create ? (function(o, m, k, k2) {
6493 if (k2 === undefined) k2 = k;
6494 var desc = Object.getOwnPropertyDescriptor(m, k);
6495 if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6496 desc = { enumerable: true, get: function() { return m[k]; } };
6497 }
6498 Object.defineProperty(o, k2, desc);
6499 }) : (function(o, m, k, k2) {
6500 if (k2 === undefined) k2 = k;
6501 o[k2] = m[k];
6502 });
6503
6504 function __exportStar(m, o) {
6505 for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);
6506 }
6507
6508 function __values(o) {
6509 var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
6510 if (m) return m.call(o);
6511 if (o && typeof o.length === "number") return {
6512 next: function () {
6513 if (o && i >= o.length) o = void 0;
6514 return { value: o && o[i++], done: !o };
6515 }
6516 };
6517 throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
6518 }
6519
6520 function __read(o, n) {
6521 var m = typeof Symbol === "function" && o[Symbol.iterator];
6522 if (!m) return o;
6523 var i = m.call(o), r, ar = [], e;
6524 try {
6525 while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
6526 }
6527 catch (error) { e = { error: error }; }
6528 finally {
6529 try {
6530 if (r && !r.done && (m = i["return"])) m.call(i);
6531 }
6532 finally { if (e) throw e.error; }
6533 }
6534 return ar;
6535 }
6536
6537 /** @deprecated */
6538 function __spread() {
6539 for (var ar = [], i = 0; i < arguments.length; i++)
6540 ar = ar.concat(__read(arguments[i]));
6541 return ar;
6542 }
6543
6544 /** @deprecated */
6545 function __spreadArrays() {
6546 for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
6547 for (var r = Array(s), k = 0, i = 0; i < il; i++)
6548 for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
6549 r[k] = a[j];
6550 return r;
6551 }
6552
6553 function __spreadArray(to, from, pack) {
6554 if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
6555 if (ar || !(i in from)) {
6556 if (!ar) ar = Array.prototype.slice.call(from, 0, i);
6557 ar[i] = from[i];
6558 }
6559 }
6560 return to.concat(ar || Array.prototype.slice.call(from));
6561 }
6562
6563 function __await(v) {
6564 return this instanceof __await ? (this.v = v, this) : new __await(v);
6565 }
6566
6567 function __asyncGenerator(thisArg, _arguments, generator) {
6568 if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
6569 var g = generator.apply(thisArg, _arguments || []), i, q = [];
6570 return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
6571 function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
6572 function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
6573 function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
6574 function fulfill(value) { resume("next", value); }
6575 function reject(value) { resume("throw", value); }
6576 function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
6577 }
6578
6579 function __asyncDelegator(o) {
6580 var i, p;
6581 return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
6582 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; }
6583 }
6584
6585 function __asyncValues(o) {
6586 if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
6587 var m = o[Symbol.asyncIterator], i;
6588 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);
6589 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); }); }; }
6590 function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
6591 }
6592
6593 function __makeTemplateObject(cooked, raw) {
6594 if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
6595 return cooked;
6596 };
6597
6598 var __setModuleDefault = Object.create ? (function(o, v) {
6599 Object.defineProperty(o, "default", { enumerable: true, value: v });
6600 }) : function(o, v) {
6601 o["default"] = v;
6602 };
6603
6604 function __importStar(mod) {
6605 if (mod && mod.__esModule) return mod;
6606 var result = {};
6607 if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
6608 __setModuleDefault(result, mod);
6609 return result;
6610 }
6611
6612 function __importDefault(mod) {
6613 return (mod && mod.__esModule) ? mod : { default: mod };
6614 }
6615
6616 function __classPrivateFieldGet(receiver, state, kind, f) {
6617 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
6618 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");
6619 return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6620 }
6621
6622 function __classPrivateFieldSet(receiver, state, value, kind, f) {
6623 if (kind === "m") throw new TypeError("Private method is not writable");
6624 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
6625 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");
6626 return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
6627 }
6628
6629 function __classPrivateFieldIn(state, receiver) {
6630 if (receiver === null || (typeof receiver !== "object" && typeof receiver !== "function")) throw new TypeError("Cannot use 'in' operator on non-object");
6631 return typeof state === "function" ? receiver === state : state.has(receiver);
6632 }
6633
6634 function __addDisposableResource(env, value, async) {
6635 if (value !== null && value !== void 0) {
6636 if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
6637 var dispose;
6638 if (async) {
6639 if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
6640 dispose = value[Symbol.asyncDispose];
6641 }
6642 if (dispose === void 0) {
6643 if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
6644 dispose = value[Symbol.dispose];
6645 }
6646 if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
6647 env.stack.push({ value: value, dispose: dispose, async: async });
6648 }
6649 else if (async) {
6650 env.stack.push({ async: true });
6651 }
6652 return value;
6653 }
6654
6655 var _SuppressedError = typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
6656 var e = new Error(message);
6657 return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
6658 };
6659
6660 function __disposeResources(env) {
6661 function fail(e) {
6662 env.error = env.hasError ? new _SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
6663 env.hasError = true;
6664 }
6665 function next() {
6666 while (env.stack.length) {
6667 var rec = env.stack.pop();
6668 try {
6669 var result = rec.dispose && rec.dispose.call(rec.value);
6670 if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
6671 }
6672 catch (e) {
6673 fail(e);
6674 }
6675 }
6676 if (env.hasError) throw env.error;
6677 }
6678 return next();
6679 }
6680
6681 /* harmony default export */ const tslib_es6 = ({
6682 __extends,
6683 __assign,
6684 __rest,
6685 __decorate,
6686 __param,
6687 __metadata,
6688 __awaiter,
6689 __generator,
6690 __createBinding,
6691 __exportStar,
6692 __values,
6693 __read,
6694 __spread,
6695 __spreadArrays,
6696 __spreadArray,
6697 __await,
6698 __asyncGenerator,
6699 __asyncDelegator,
6700 __asyncValues,
6701 __makeTemplateObject,
6702 __importStar,
6703 __importDefault,
6704 __classPrivateFieldGet,
6705 __classPrivateFieldSet,
6706 __classPrivateFieldIn,
6707 __addDisposableResource,
6708 __disposeResources,
6709 });
6710
6711 ;// CONCATENATED MODULE: ./node_modules/lower-case/dist.es2015/index.js
6712 /**
6713 * Source: ftp://ftp.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt
6714 */
6715 var SUPPORTED_LOCALE = {
6716 tr: {
6717 regexp: /\u0130|\u0049|\u0049\u0307/g,
6718 map: {
6719 İ: "\u0069",
6720 I: "\u0131",
6721 İ: "\u0069",
6722 },
6723 },
6724 az: {
6725 regexp: /\u0130/g,
6726 map: {
6727 İ: "\u0069",
6728 I: "\u0131",
6729 İ: "\u0069",
6730 },
6731 },
6732 lt: {
6733 regexp: /\u0049|\u004A|\u012E|\u00CC|\u00CD|\u0128/g,
6734 map: {
6735 I: "\u0069\u0307",
6736 J: "\u006A\u0307",
6737 Į: "\u012F\u0307",
6738 Ì: "\u0069\u0307\u0300",
6739 Í: "\u0069\u0307\u0301",
6740 Ĩ: "\u0069\u0307\u0303",
6741 },
6742 },
6743 };
6744 /**
6745 * Localized lower case.
6746 */
6747 function localeLowerCase(str, locale) {
6748 var lang = SUPPORTED_LOCALE[locale.toLowerCase()];
6749 if (lang)
6750 return lowerCase(str.replace(lang.regexp, function (m) { return lang.map[m]; }));
6751 return lowerCase(str);
6752 }
6753 /**
6754 * Lower case as a function.
6755 */
6756 function lowerCase(str) {
6757 return str.toLowerCase();
6758 }
6759
6760 ;// CONCATENATED MODULE: ./node_modules/no-case/dist.es2015/index.js
6761
6762 // Support camel case ("camelCase" -> "camel Case" and "CAMELCase" -> "CAMEL Case").
6763 var DEFAULT_SPLIT_REGEXP = [/([a-z0-9])([A-Z])/g, /([A-Z])([A-Z][a-z])/g];
6764 // Remove all non-word characters.
6765 var DEFAULT_STRIP_REGEXP = /[^A-Z0-9]+/gi;
6766 /**
6767 * Normalize the string into something other libraries can manipulate easier.
6768 */
6769 function noCase(input, options) {
6770 if (options === void 0) { options = {}; }
6771 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;
6772 var result = replace(replace(input, splitRegexp, "$1\0$2"), stripRegexp, "\0");
6773 var start = 0;
6774 var end = result.length;
6775 // Trim the delimiter from around the output string.
6776 while (result.charAt(start) === "\0")
6777 start++;
6778 while (result.charAt(end - 1) === "\0")
6779 end--;
6780 // Transform each token independently.
6781 return result.slice(start, end).split("\0").map(transform).join(delimiter);
6782 }
6783 /**
6784 * Replace `re` in the input string with the replacement value.
6785 */
6786 function replace(input, re, value) {
6787 if (re instanceof RegExp)
6788 return input.replace(re, value);
6789 return re.reduce(function (input, re) { return input.replace(re, value); }, input);
6790 }
6791
6792 ;// CONCATENATED MODULE: ./node_modules/pascal-case/dist.es2015/index.js
6793
6794
6795 function pascalCaseTransform(input, index) {
6796 var firstChar = input.charAt(0);
6797 var lowerChars = input.substr(1).toLowerCase();
6798 if (index > 0 && firstChar >= "0" && firstChar <= "9") {
6799 return "_" + firstChar + lowerChars;
6800 }
6801 return "" + firstChar.toUpperCase() + lowerChars;
6802 }
6803 function dist_es2015_pascalCaseTransformMerge(input) {
6804 return input.charAt(0).toUpperCase() + input.slice(1).toLowerCase();
6805 }
6806 function pascalCase(input, options) {
6807 if (options === void 0) { options = {}; }
6808 return noCase(input, __assign({ delimiter: "", transform: pascalCaseTransform }, options));
6809 }
6810
6811 ;// CONCATENATED MODULE: ./node_modules/camel-case/dist.es2015/index.js
6812
6813
6814 function camelCaseTransform(input, index) {
6815 if (index === 0)
6816 return input.toLowerCase();
6817 return pascalCaseTransform(input, index);
6818 }
6819 function camelCaseTransformMerge(input, index) {
6820 if (index === 0)
6821 return input.toLowerCase();
6822 return pascalCaseTransformMerge(input);
6823 }
6824 function camelCase(input, options) {
6825 if (options === void 0) { options = {}; }
6826 return pascalCase(input, __assign({ transform: camelCaseTransform }, options));
6827 }
6828
6829 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/registration.js
6830 /* eslint no-console: [ 'error', { allow: [ 'error', 'warn' ] } ] */
6831
6832 /**
6833 * External dependencies
6834 */
6835
6836
6837 /**
6838 * WordPress dependencies
6839 */
6840
6841
6842
6843 /**
6844 * Internal dependencies
6845 */
6846 const i18nBlockSchema = {
6847 title: "block title",
6848 description: "block description",
6849 keywords: ["block keyword"],
6850 styles: [{
6851 label: "block style label"
6852 }],
6853 variations: [{
6854 title: "block variation title",
6855 description: "block variation description",
6856 keywords: ["block variation keyword"]
6857 }]
6858 };
6859
6860
6861
6862 /**
6863 * An icon type definition. One of a Dashicon slug, an element,
6864 * or a component.
6865 *
6866 * @typedef {(string|WPElement|WPComponent)} WPIcon
6867 *
6868 * @see https://developer.wordpress.org/resource/dashicons/
6869 */
6870
6871 /**
6872 * Render behavior of a block type icon; one of a Dashicon slug, an element,
6873 * or a component.
6874 *
6875 * @typedef {WPIcon} WPBlockTypeIconRender
6876 */
6877
6878 /**
6879 * An object describing a normalized block type icon.
6880 *
6881 * @typedef {Object} WPBlockTypeIconDescriptor
6882 *
6883 * @property {WPBlockTypeIconRender} src Render behavior of the icon,
6884 * one of a Dashicon slug, an
6885 * element, or a component.
6886 * @property {string} background Optimal background hex string
6887 * color when displaying icon.
6888 * @property {string} foreground Optimal foreground hex string
6889 * color when displaying icon.
6890 * @property {string} shadowColor Optimal shadow hex string
6891 * color when displaying icon.
6892 */
6893
6894 /**
6895 * Value to use to render the icon for a block type in an editor interface,
6896 * either a Dashicon slug, an element, a component, or an object describing
6897 * the icon.
6898 *
6899 * @typedef {(WPBlockTypeIconDescriptor|WPBlockTypeIconRender)} WPBlockTypeIcon
6900 */
6901
6902 /**
6903 * Named block variation scopes.
6904 *
6905 * @typedef {'block'|'inserter'|'transform'} WPBlockVariationScope
6906 */
6907
6908 /**
6909 * An object describing a variation defined for the block type.
6910 *
6911 * @typedef {Object} WPBlockVariation
6912 *
6913 * @property {string} name The unique and machine-readable name.
6914 * @property {string} title A human-readable variation title.
6915 * @property {string} [description] A detailed variation description.
6916 * @property {string} [category] Block type category classification,
6917 * used in search interfaces to arrange
6918 * block types by category.
6919 * @property {WPIcon} [icon] An icon helping to visualize the variation.
6920 * @property {boolean} [isDefault] Indicates whether the current variation is
6921 * the default one. Defaults to `false`.
6922 * @property {Object} [attributes] Values which override block attributes.
6923 * @property {Array[]} [innerBlocks] Initial configuration of nested blocks.
6924 * @property {Object} [example] Example provides structured data for
6925 * the block preview. You can set to
6926 * `undefined` to disable the preview shown
6927 * for the block type.
6928 * @property {WPBlockVariationScope[]} [scope] The list of scopes where the variation
6929 * is applicable. When not provided, it
6930 * assumes all available scopes.
6931 * @property {string[]} [keywords] An array of terms (which can be translated)
6932 * that help users discover the variation
6933 * while searching.
6934 * @property {Function|string[]} [isActive] This can be a function or an array of block attributes.
6935 * Function that accepts a block's attributes and the
6936 * variation's attributes and determines if a variation is active.
6937 * This function doesn't try to find a match dynamically based
6938 * on all block's attributes, as in many cases some attributes are irrelevant.
6939 * An example would be for `embed` block where we only care
6940 * about `providerNameSlug` attribute's value.
6941 * We can also use a `string[]` to tell which attributes
6942 * should be compared as a shorthand. Each attributes will
6943 * be matched and the variation will be active if all of them are matching.
6944 */
6945
6946 /**
6947 * Defined behavior of a block type.
6948 *
6949 * @typedef {Object} WPBlockType
6950 *
6951 * @property {string} name Block type's namespaced name.
6952 * @property {string} title Human-readable block type label.
6953 * @property {string} [description] A detailed block type description.
6954 * @property {string} [category] Block type category classification,
6955 * used in search interfaces to arrange
6956 * block types by category.
6957 * @property {WPBlockTypeIcon} [icon] Block type icon.
6958 * @property {string[]} [keywords] Additional keywords to produce block
6959 * type as result in search interfaces.
6960 * @property {Object} [attributes] Block type attributes.
6961 * @property {WPComponent} [save] Optional component describing
6962 * serialized markup structure of a
6963 * block type.
6964 * @property {WPComponent} edit Component rendering an element to
6965 * manipulate the attributes of a block
6966 * in the context of an editor.
6967 * @property {WPBlockVariation[]} [variations] The list of block variations.
6968 * @property {Object} [example] Example provides structured data for
6969 * the block preview. When not defined
6970 * then no preview is shown.
6971 */
6972
6973 const serverSideBlockDefinitions = {};
6974 function isObject(object) {
6975 return object !== null && typeof object === 'object';
6976 }
6977
6978 /**
6979 * Sets the server side block definition of blocks.
6980 *
6981 * @param {Object} definitions Server-side block definitions
6982 */
6983 // eslint-disable-next-line camelcase
6984 function unstable__bootstrapServerSideBlockDefinitions(definitions) {
6985 for (const blockName of Object.keys(definitions)) {
6986 // Don't overwrite if already set. It covers the case when metadata
6987 // was initialized from the server.
6988 if (serverSideBlockDefinitions[blockName]) {
6989 // We still need to polyfill `apiVersion` for WordPress version
6990 // lower than 5.7. If it isn't present in the definition shared
6991 // from the server, we try to fallback to the definition passed.
6992 // @see https://github.com/WordPress/gutenberg/pull/29279
6993 if (serverSideBlockDefinitions[blockName].apiVersion === undefined && definitions[blockName].apiVersion) {
6994 serverSideBlockDefinitions[blockName].apiVersion = definitions[blockName].apiVersion;
6995 }
6996 // The `ancestor` prop is not included in the definitions shared
6997 // from the server yet, so it needs to be polyfilled as well.
6998 // @see https://github.com/WordPress/gutenberg/pull/39894
6999 if (serverSideBlockDefinitions[blockName].ancestor === undefined && definitions[blockName].ancestor) {
7000 serverSideBlockDefinitions[blockName].ancestor = definitions[blockName].ancestor;
7001 }
7002 // The `selectors` prop is not yet included in the server provided
7003 // definitions. Polyfill it as well. This can be removed when the
7004 // minimum supported WordPress is >= 6.3.
7005 if (serverSideBlockDefinitions[blockName].selectors === undefined && definitions[blockName].selectors) {
7006 serverSideBlockDefinitions[blockName].selectors = definitions[blockName].selectors;
7007 }
7008 continue;
7009 }
7010 serverSideBlockDefinitions[blockName] = Object.fromEntries(Object.entries(definitions[blockName]).filter(([, value]) => value !== null && value !== undefined).map(([key, value]) => [camelCase(key), value]));
7011 }
7012 }
7013
7014 /**
7015 * Gets block settings from metadata loaded from `block.json` file.
7016 *
7017 * @param {Object} metadata Block metadata loaded from `block.json`.
7018 * @param {string} metadata.textdomain Textdomain to use with translations.
7019 *
7020 * @return {Object} Block settings.
7021 */
7022 function getBlockSettingsFromMetadata({
7023 textdomain,
7024 ...metadata
7025 }) {
7026 const allowedFields = ['apiVersion', 'title', 'category', 'parent', 'ancestor', 'icon', 'description', 'keywords', 'attributes', 'providesContext', 'usesContext', 'selectors', 'supports', 'styles', 'example', 'variations'];
7027 const settings = Object.fromEntries(Object.entries(metadata).filter(([key]) => allowedFields.includes(key)));
7028 if (textdomain) {
7029 Object.keys(i18nBlockSchema).forEach(key => {
7030 if (!settings[key]) {
7031 return;
7032 }
7033 settings[key] = translateBlockSettingUsingI18nSchema(i18nBlockSchema[key], settings[key], textdomain);
7034 });
7035 }
7036 return settings;
7037 }
7038
7039 /**
7040 * Registers a new block provided a unique name and an object defining its
7041 * behavior. Once registered, the block is made available as an option to any
7042 * editor interface where blocks are implemented.
7043 *
7044 * For more in-depth information on registering a custom block see the
7045 * [Create a block tutorial](https://developer.wordpress.org/block-editor/getting-started/create-block/).
7046 *
7047 * @param {string|Object} blockNameOrMetadata Block type name or its metadata.
7048 * @param {Object} settings Block settings.
7049 *
7050 * @example
7051 * ```js
7052 * import { __ } from '@wordpress/i18n';
7053 * import { registerBlockType } from '@wordpress/blocks'
7054 *
7055 * registerBlockType( 'namespace/block-name', {
7056 * title: __( 'My First Block' ),
7057 * edit: () => <div>{ __( 'Hello from the editor!' ) }</div>,
7058 * save: () => <div>Hello from the saved content!</div>,
7059 * } );
7060 * ```
7061 *
7062 * @return {WPBlockType | undefined} The block, if it has been successfully registered;
7063 * otherwise `undefined`.
7064 */
7065 function registerBlockType(blockNameOrMetadata, settings) {
7066 const name = isObject(blockNameOrMetadata) ? blockNameOrMetadata.name : blockNameOrMetadata;
7067 if (typeof name !== 'string') {
7068 console.error('Block names must be strings.');
7069 return;
7070 }
7071 if (!/^[a-z][a-z0-9-]*\/[a-z][a-z0-9-]*$/.test(name)) {
7072 console.error('Block names must contain a namespace prefix, include only lowercase alphanumeric characters or dashes, and start with a letter. Example: my-plugin/my-custom-block');
7073 return;
7074 }
7075 if ((0,external_wp_data_namespaceObject.select)(store).getBlockType(name)) {
7076 console.error('Block "' + name + '" is already registered.');
7077 return;
7078 }
7079 if (isObject(blockNameOrMetadata)) {
7080 unstable__bootstrapServerSideBlockDefinitions({
7081 [name]: getBlockSettingsFromMetadata(blockNameOrMetadata)
7082 });
7083 }
7084 const blockType = {
7085 name,
7086 icon: BLOCK_ICON_DEFAULT,
7087 keywords: [],
7088 attributes: {},
7089 providesContext: {},
7090 usesContext: [],
7091 selectors: {},
7092 supports: {},
7093 styles: [],
7094 variations: [],
7095 save: () => null,
7096 ...serverSideBlockDefinitions?.[name],
7097 ...settings
7098 };
7099 (0,external_wp_data_namespaceObject.dispatch)(store).__experimentalRegisterBlockType(blockType);
7100 return (0,external_wp_data_namespaceObject.select)(store).getBlockType(name);
7101 }
7102
7103 /**
7104 * Translates block settings provided with metadata using the i18n schema.
7105 *
7106 * @param {string|string[]|Object[]} i18nSchema I18n schema for the block setting.
7107 * @param {string|string[]|Object[]} settingValue Value for the block setting.
7108 * @param {string} textdomain Textdomain to use with translations.
7109 *
7110 * @return {string|string[]|Object[]} Translated setting.
7111 */
7112 function translateBlockSettingUsingI18nSchema(i18nSchema, settingValue, textdomain) {
7113 if (typeof i18nSchema === 'string' && typeof settingValue === 'string') {
7114 // eslint-disable-next-line @wordpress/i18n-no-variables, @wordpress/i18n-text-domain
7115 return (0,external_wp_i18n_namespaceObject._x)(settingValue, i18nSchema, textdomain);
7116 }
7117 if (Array.isArray(i18nSchema) && i18nSchema.length && Array.isArray(settingValue)) {
7118 return settingValue.map(value => translateBlockSettingUsingI18nSchema(i18nSchema[0], value, textdomain));
7119 }
7120 if (isObject(i18nSchema) && Object.entries(i18nSchema).length && isObject(settingValue)) {
7121 return Object.keys(settingValue).reduce((accumulator, key) => {
7122 if (!i18nSchema[key]) {
7123 accumulator[key] = settingValue[key];
7124 return accumulator;
7125 }
7126 accumulator[key] = translateBlockSettingUsingI18nSchema(i18nSchema[key], settingValue[key], textdomain);
7127 return accumulator;
7128 }, {});
7129 }
7130 return settingValue;
7131 }
7132
7133 /**
7134 * Registers a new block collection to group blocks in the same namespace in the inserter.
7135 *
7136 * @param {string} namespace The namespace to group blocks by in the inserter; corresponds to the block namespace.
7137 * @param {Object} settings The block collection settings.
7138 * @param {string} settings.title The title to display in the block inserter.
7139 * @param {Object} [settings.icon] The icon to display in the block inserter.
7140 *
7141 * @example
7142 * ```js
7143 * import { __ } from '@wordpress/i18n';
7144 * import { registerBlockCollection, registerBlockType } from '@wordpress/blocks';
7145 *
7146 * // Register the collection.
7147 * registerBlockCollection( 'my-collection', {
7148 * title: __( 'Custom Collection' ),
7149 * } );
7150 *
7151 * // Register a block in the same namespace to add it to the collection.
7152 * registerBlockType( 'my-collection/block-name', {
7153 * title: __( 'My First Block' ),
7154 * edit: () => <div>{ __( 'Hello from the editor!' ) }</div>,
7155 * save: () => <div>'Hello from the saved content!</div>,
7156 * } );
7157 * ```
7158 */
7159 function registerBlockCollection(namespace, {
7160 title,
7161 icon
7162 }) {
7163 (0,external_wp_data_namespaceObject.dispatch)(store).addBlockCollection(namespace, title, icon);
7164 }
7165
7166 /**
7167 * Unregisters a block collection
7168 *
7169 * @param {string} namespace The namespace to group blocks by in the inserter; corresponds to the block namespace
7170 *
7171 * @example
7172 * ```js
7173 * import { unregisterBlockCollection } from '@wordpress/blocks';
7174 *
7175 * unregisterBlockCollection( 'my-collection' );
7176 * ```
7177 */
7178 function unregisterBlockCollection(namespace) {
7179 dispatch(blocksStore).removeBlockCollection(namespace);
7180 }
7181
7182 /**
7183 * Unregisters a block.
7184 *
7185 * @param {string} name Block name.
7186 *
7187 * @example
7188 * ```js
7189 * import { __ } from '@wordpress/i18n';
7190 * import { unregisterBlockType } from '@wordpress/blocks';
7191 *
7192 * const ExampleComponent = () => {
7193 * return (
7194 * <Button
7195 * onClick={ () =>
7196 * unregisterBlockType( 'my-collection/block-name' )
7197 * }
7198 * >
7199 * { __( 'Unregister my custom block.' ) }
7200 * </Button>
7201 * );
7202 * };
7203 * ```
7204 *
7205 * @return {WPBlockType | undefined} The previous block value, if it has been successfully
7206 * unregistered; otherwise `undefined`.
7207 */
7208 function unregisterBlockType(name) {
7209 const oldBlock = (0,external_wp_data_namespaceObject.select)(store).getBlockType(name);
7210 if (!oldBlock) {
7211 console.error('Block "' + name + '" is not registered.');
7212 return;
7213 }
7214 (0,external_wp_data_namespaceObject.dispatch)(store).removeBlockTypes(name);
7215 return oldBlock;
7216 }
7217
7218 /**
7219 * Assigns name of block for handling non-block content.
7220 *
7221 * @param {string} blockName Block name.
7222 */
7223 function setFreeformContentHandlerName(blockName) {
7224 (0,external_wp_data_namespaceObject.dispatch)(store).setFreeformFallbackBlockName(blockName);
7225 }
7226
7227 /**
7228 * Retrieves name of block handling non-block content, or undefined if no
7229 * handler has been defined.
7230 *
7231 * @return {?string} Block name.
7232 */
7233 function getFreeformContentHandlerName() {
7234 return (0,external_wp_data_namespaceObject.select)(store).getFreeformFallbackBlockName();
7235 }
7236
7237 /**
7238 * Retrieves name of block used for handling grouping interactions.
7239 *
7240 * @return {?string} Block name.
7241 */
7242 function getGroupingBlockName() {
7243 return (0,external_wp_data_namespaceObject.select)(store).getGroupingBlockName();
7244 }
7245
7246 /**
7247 * Assigns name of block handling unregistered block types.
7248 *
7249 * @param {string} blockName Block name.
7250 */
7251 function setUnregisteredTypeHandlerName(blockName) {
7252 (0,external_wp_data_namespaceObject.dispatch)(store).setUnregisteredFallbackBlockName(blockName);
7253 }
7254
7255 /**
7256 * Retrieves name of block handling unregistered block types, or undefined if no
7257 * handler has been defined.
7258 *
7259 * @return {?string} Block name.
7260 */
7261 function getUnregisteredTypeHandlerName() {
7262 return (0,external_wp_data_namespaceObject.select)(store).getUnregisteredFallbackBlockName();
7263 }
7264
7265 /**
7266 * Assigns the default block name.
7267 *
7268 * @param {string} name Block name.
7269 *
7270 * @example
7271 * ```js
7272 * import { setDefaultBlockName } from '@wordpress/blocks';
7273 *
7274 * const ExampleComponent = () => {
7275 *
7276 * return (
7277 * <Button onClick={ () => setDefaultBlockName( 'core/heading' ) }>
7278 * { __( 'Set the default block to Heading' ) }
7279 * </Button>
7280 * );
7281 * };
7282 * ```
7283 */
7284 function setDefaultBlockName(name) {
7285 (0,external_wp_data_namespaceObject.dispatch)(store).setDefaultBlockName(name);
7286 }
7287
7288 /**
7289 * Assigns name of block for handling block grouping interactions.
7290 *
7291 * This function lets you select a different block to group other blocks in instead of the
7292 * default `core/group` block. This function must be used in a component or when the DOM is fully
7293 * loaded. See https://developer.wordpress.org/block-editor/reference-guides/packages/packages-dom-ready/
7294 *
7295 * @param {string} name Block name.
7296 *
7297 * @example
7298 * ```js
7299 * import { setGroupingBlockName } from '@wordpress/blocks';
7300 *
7301 * const ExampleComponent = () => {
7302 *
7303 * return (
7304 * <Button onClick={ () => setGroupingBlockName( 'core/columns' ) }>
7305 * { __( 'Wrap in columns' ) }
7306 * </Button>
7307 * );
7308 * };
7309 * ```
7310 */
7311 function setGroupingBlockName(name) {
7312 (0,external_wp_data_namespaceObject.dispatch)(store).setGroupingBlockName(name);
7313 }
7314
7315 /**
7316 * Retrieves the default block name.
7317 *
7318 * @return {?string} Block name.
7319 */
7320 function getDefaultBlockName() {
7321 return (0,external_wp_data_namespaceObject.select)(store).getDefaultBlockName();
7322 }
7323
7324 /**
7325 * Returns a registered block type.
7326 *
7327 * @param {string} name Block name.
7328 *
7329 * @return {?Object} Block type.
7330 */
7331 function getBlockType(name) {
7332 return (0,external_wp_data_namespaceObject.select)(store)?.getBlockType(name);
7333 }
7334
7335 /**
7336 * Returns all registered blocks.
7337 *
7338 * @return {Array} Block settings.
7339 */
7340 function getBlockTypes() {
7341 return (0,external_wp_data_namespaceObject.select)(store).getBlockTypes();
7342 }
7343
7344 /**
7345 * Returns the block support value for a feature, if defined.
7346 *
7347 * @param {(string|Object)} nameOrType Block name or type object
7348 * @param {string} feature Feature to retrieve
7349 * @param {*} defaultSupports Default value to return if not
7350 * explicitly defined
7351 *
7352 * @return {?*} Block support value
7353 */
7354 function getBlockSupport(nameOrType, feature, defaultSupports) {
7355 return (0,external_wp_data_namespaceObject.select)(store).getBlockSupport(nameOrType, feature, defaultSupports);
7356 }
7357
7358 /**
7359 * Returns true if the block defines support for a feature, or false otherwise.
7360 *
7361 * @param {(string|Object)} nameOrType Block name or type object.
7362 * @param {string} feature Feature to test.
7363 * @param {boolean} defaultSupports Whether feature is supported by
7364 * default if not explicitly defined.
7365 *
7366 * @return {boolean} Whether block supports feature.
7367 */
7368 function hasBlockSupport(nameOrType, feature, defaultSupports) {
7369 return (0,external_wp_data_namespaceObject.select)(store).hasBlockSupport(nameOrType, feature, defaultSupports);
7370 }
7371
7372 /**
7373 * Determines whether or not the given block is a reusable block. This is a
7374 * special block type that is used to point to a global block stored via the
7375 * API.
7376 *
7377 * @param {Object} blockOrType Block or Block Type to test.
7378 *
7379 * @return {boolean} Whether the given block is a reusable block.
7380 */
7381 function isReusableBlock(blockOrType) {
7382 return blockOrType?.name === 'core/block';
7383 }
7384
7385 /**
7386 * Determines whether or not the given block is a template part. This is a
7387 * special block type that allows composing a page template out of reusable
7388 * design elements.
7389 *
7390 * @param {Object} blockOrType Block or Block Type to test.
7391 *
7392 * @return {boolean} Whether the given block is a template part.
7393 */
7394 function isTemplatePart(blockOrType) {
7395 return blockOrType?.name === 'core/template-part';
7396 }
7397
7398 /**
7399 * Returns an array with the child blocks of a given block.
7400 *
7401 * @param {string} blockName Name of block (example: “latest-posts”).
7402 *
7403 * @return {Array} Array of child block names.
7404 */
7405 const getChildBlockNames = blockName => {
7406 return (0,external_wp_data_namespaceObject.select)(store).getChildBlockNames(blockName);
7407 };
7408
7409 /**
7410 * Returns a boolean indicating if a block has child blocks or not.
7411 *
7412 * @param {string} blockName Name of block (example: “latest-posts”).
7413 *
7414 * @return {boolean} True if a block contains child blocks and false otherwise.
7415 */
7416 const hasChildBlocks = blockName => {
7417 return (0,external_wp_data_namespaceObject.select)(store).hasChildBlocks(blockName);
7418 };
7419
7420 /**
7421 * Returns a boolean indicating if a block has at least one child block with inserter support.
7422 *
7423 * @param {string} blockName Block type name.
7424 *
7425 * @return {boolean} True if a block contains at least one child blocks with inserter support
7426 * and false otherwise.
7427 */
7428 const hasChildBlocksWithInserterSupport = blockName => {
7429 return (0,external_wp_data_namespaceObject.select)(store).hasChildBlocksWithInserterSupport(blockName);
7430 };
7431
7432 /**
7433 * Registers a new block style for the given block.
7434 *
7435 * For more information on connecting the styles with CSS
7436 * [the official documentation](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-styles/#styles).
7437 *
7438 * @param {string} blockName Name of block (example: “core/latest-posts”).
7439 * @param {Object} styleVariation Object containing `name` which is the class name applied to the block and `label` which identifies the variation to the user.
7440 *
7441 * @example
7442 * ```js
7443 * import { __ } from '@wordpress/i18n';
7444 * import { registerBlockStyle } from '@wordpress/blocks';
7445 * import { Button } from '@wordpress/components';
7446 *
7447 *
7448 * const ExampleComponent = () => {
7449 * return (
7450 * <Button
7451 * onClick={ () => {
7452 * registerBlockStyle( 'core/quote', {
7453 * name: 'fancy-quote',
7454 * label: __( 'Fancy Quote' ),
7455 * } );
7456 * } }
7457 * >
7458 * { __( 'Add a new block style for core/quote' ) }
7459 * </Button>
7460 * );
7461 * };
7462 * ```
7463 */
7464 const registerBlockStyle = (blockName, styleVariation) => {
7465 (0,external_wp_data_namespaceObject.dispatch)(store).addBlockStyles(blockName, styleVariation);
7466 };
7467
7468 /**
7469 * Unregisters a block style for the given block.
7470 *
7471 * @param {string} blockName Name of block (example: “core/latest-posts”).
7472 * @param {string} styleVariationName Name of class applied to the block.
7473 *
7474 * @example
7475 * ```js
7476 * import { __ } from '@wordpress/i18n';
7477 * import { unregisterBlockStyle } from '@wordpress/blocks';
7478 * import { Button } from '@wordpress/components';
7479 *
7480 * const ExampleComponent = () => {
7481 * return (
7482 * <Button
7483 * onClick={ () => {
7484 * unregisterBlockStyle( 'core/quote', 'plain' );
7485 * } }
7486 * >
7487 * { __( 'Remove the "Plain" block style for core/quote' ) }
7488 * </Button>
7489 * );
7490 * };
7491 * ```
7492 */
7493 const unregisterBlockStyle = (blockName, styleVariationName) => {
7494 (0,external_wp_data_namespaceObject.dispatch)(store).removeBlockStyles(blockName, styleVariationName);
7495 };
7496
7497 /**
7498 * Returns an array with the variations of a given block type.
7499 * Ignored from documentation as the recommended usage is via useSelect from @wordpress/data.
7500 *
7501 * @ignore
7502 *
7503 * @param {string} blockName Name of block (example: “core/columns”).
7504 * @param {WPBlockVariationScope} [scope] Block variation scope name.
7505 *
7506 * @return {(WPBlockVariation[]|void)} Block variations.
7507 */
7508 const getBlockVariations = (blockName, scope) => {
7509 return (0,external_wp_data_namespaceObject.select)(store).getBlockVariations(blockName, scope);
7510 };
7511
7512 /**
7513 * Registers a new block variation for the given block type.
7514 *
7515 * For more information on block variations see
7516 * [the official documentation ](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-variations/).
7517 *
7518 * @param {string} blockName Name of the block (example: “core/columns”).
7519 * @param {WPBlockVariation} variation Object describing a block variation.
7520 *
7521 * @example
7522 * ```js
7523 * import { __ } from '@wordpress/i18n';
7524 * import { registerBlockVariation } from '@wordpress/blocks';
7525 * import { Button } from '@wordpress/components';
7526 *
7527 * const ExampleComponent = () => {
7528 * return (
7529 * <Button
7530 * onClick={ () => {
7531 * registerBlockVariation( 'core/embed', {
7532 * name: 'custom',
7533 * title: __( 'My Custom Embed' ),
7534 * attributes: { providerNameSlug: 'custom' },
7535 * } );
7536 * } }
7537 * >
7538 * __( 'Add a custom variation for core/embed' ) }
7539 * </Button>
7540 * );
7541 * };
7542 * ```
7543 */
7544 const registerBlockVariation = (blockName, variation) => {
7545 (0,external_wp_data_namespaceObject.dispatch)(store).addBlockVariations(blockName, variation);
7546 };
7547
7548 /**
7549 * Unregisters a block variation defined for the given block type.
7550 *
7551 * @param {string} blockName Name of the block (example: “core/columns”).
7552 * @param {string} variationName Name of the variation defined for the block.
7553 *
7554 * @example
7555 * ```js
7556 * import { __ } from '@wordpress/i18n';
7557 * import { unregisterBlockVariation } from '@wordpress/blocks';
7558 * import { Button } from '@wordpress/components';
7559 *
7560 * const ExampleComponent = () => {
7561 * return (
7562 * <Button
7563 * onClick={ () => {
7564 * unregisterBlockVariation( 'core/embed', 'youtube' );
7565 * } }
7566 * >
7567 * { __( 'Remove the YouTube variation from core/embed' ) }
7568 * </Button>
7569 * );
7570 * };
7571 * ```
7572 */
7573 const unregisterBlockVariation = (blockName, variationName) => {
7574 (0,external_wp_data_namespaceObject.dispatch)(store).removeBlockVariations(blockName, variationName);
7575 };
7576
7577 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/rng.js
7578 // Unique ID creation requires a high quality random # generator. In the browser we therefore
7579 // require the crypto API and do not support built-in fallback to lower quality random number
7580 // generators (like Math.random()).
7581 // getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. Also,
7582 // find the complete implementation of crypto (msCrypto) on IE11.
7583 var getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || typeof msCrypto !== 'undefined' && typeof msCrypto.getRandomValues === 'function' && msCrypto.getRandomValues.bind(msCrypto);
7584 var rnds8 = new Uint8Array(16);
7585 function rng() {
7586 if (!getRandomValues) {
7587 throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');
7588 }
7589
7590 return getRandomValues(rnds8);
7591 }
7592 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/regex.js
7593 /* harmony default export */ const regex = (/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i);
7594 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/validate.js
7595
7596
7597 function validate(uuid) {
7598 return typeof uuid === 'string' && regex.test(uuid);
7599 }
7600
7601 /* harmony default export */ const esm_browser_validate = (validate);
7602 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/stringify.js
7603
7604 /**
7605 * Convert array of 16 byte values to UUID string format of the form:
7606 * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
7607 */
7608
7609 var byteToHex = [];
7610
7611 for (var stringify_i = 0; stringify_i < 256; ++stringify_i) {
7612 byteToHex.push((stringify_i + 0x100).toString(16).substr(1));
7613 }
7614
7615 function stringify(arr) {
7616 var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
7617 // Note: Be careful editing this code! It's been tuned for performance
7618 // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
7619 var uuid = (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); // Consistency check for valid UUID. If this throws, it's likely due to one
7620 // of the following:
7621 // - One or more input array values don't map to a hex octet (leading to
7622 // "undefined" in the uuid)
7623 // - Invalid input values for the RFC `version` or `variant` fields
7624
7625 if (!esm_browser_validate(uuid)) {
7626 throw TypeError('Stringified UUID is invalid');
7627 }
7628
7629 return uuid;
7630 }
7631
7632 /* harmony default export */ const esm_browser_stringify = (stringify);
7633 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/v4.js
7634
7635
7636
7637 function v4(options, buf, offset) {
7638 options = options || {};
7639 var rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
7640
7641 rnds[6] = rnds[6] & 0x0f | 0x40;
7642 rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided
7643
7644 if (buf) {
7645 offset = offset || 0;
7646
7647 for (var i = 0; i < 16; ++i) {
7648 buf[offset + i] = rnds[i];
7649 }
7650
7651 return buf;
7652 }
7653
7654 return esm_browser_stringify(rnds);
7655 }
7656
7657 /* harmony default export */ const esm_browser_v4 = (v4);
7658 ;// CONCATENATED MODULE: external ["wp","hooks"]
7659 const external_wp_hooks_namespaceObject = window["wp"]["hooks"];
7660 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/factory.js
7661 /**
7662 * External dependencies
7663 */
7664
7665
7666 /**
7667 * WordPress dependencies
7668 */
7669
7670
7671 /**
7672 * Internal dependencies
7673 */
7674
7675
7676
7677 /**
7678 * Returns a block object given its type and attributes.
7679 *
7680 * @param {string} name Block name.
7681 * @param {Object} attributes Block attributes.
7682 * @param {?Array} innerBlocks Nested blocks.
7683 *
7684 * @return {Object} Block object.
7685 */
7686 function createBlock(name, attributes = {}, innerBlocks = []) {
7687 const sanitizedAttributes = __experimentalSanitizeBlockAttributes(name, attributes);
7688 const clientId = esm_browser_v4();
7689
7690 // Blocks are stored with a unique ID, the assigned type name, the block
7691 // attributes, and their inner blocks.
7692 return {
7693 clientId,
7694 name,
7695 isValid: true,
7696 attributes: sanitizedAttributes,
7697 innerBlocks
7698 };
7699 }
7700
7701 /**
7702 * Given an array of InnerBlocks templates or Block Objects,
7703 * returns an array of created Blocks from them.
7704 * It handles the case of having InnerBlocks as Blocks by
7705 * converting them to the proper format to continue recursively.
7706 *
7707 * @param {Array} innerBlocksOrTemplate Nested blocks or InnerBlocks templates.
7708 *
7709 * @return {Object[]} Array of Block objects.
7710 */
7711 function createBlocksFromInnerBlocksTemplate(innerBlocksOrTemplate = []) {
7712 return innerBlocksOrTemplate.map(innerBlock => {
7713 const innerBlockTemplate = Array.isArray(innerBlock) ? innerBlock : [innerBlock.name, innerBlock.attributes, innerBlock.innerBlocks];
7714 const [name, attributes, innerBlocks = []] = innerBlockTemplate;
7715 return createBlock(name, attributes, createBlocksFromInnerBlocksTemplate(innerBlocks));
7716 });
7717 }
7718
7719 /**
7720 * Given a block object, returns a copy of the block object while sanitizing its attributes,
7721 * optionally merging new attributes and/or replacing its inner blocks.
7722 *
7723 * @param {Object} block Block instance.
7724 * @param {Object} mergeAttributes Block attributes.
7725 * @param {?Array} newInnerBlocks Nested blocks.
7726 *
7727 * @return {Object} A cloned block.
7728 */
7729 function __experimentalCloneSanitizedBlock(block, mergeAttributes = {}, newInnerBlocks) {
7730 const clientId = esm_browser_v4();
7731 const sanitizedAttributes = __experimentalSanitizeBlockAttributes(block.name, {
7732 ...block.attributes,
7733 ...mergeAttributes
7734 });
7735 return {
7736 ...block,
7737 clientId,
7738 attributes: sanitizedAttributes,
7739 innerBlocks: newInnerBlocks || block.innerBlocks.map(innerBlock => __experimentalCloneSanitizedBlock(innerBlock))
7740 };
7741 }
7742
7743 /**
7744 * Given a block object, returns a copy of the block object,
7745 * optionally merging new attributes and/or replacing its inner blocks.
7746 *
7747 * @param {Object} block Block instance.
7748 * @param {Object} mergeAttributes Block attributes.
7749 * @param {?Array} newInnerBlocks Nested blocks.
7750 *
7751 * @return {Object} A cloned block.
7752 */
7753 function cloneBlock(block, mergeAttributes = {}, newInnerBlocks) {
7754 const clientId = esm_browser_v4();
7755 return {
7756 ...block,
7757 clientId,
7758 attributes: {
7759 ...block.attributes,
7760 ...mergeAttributes
7761 },
7762 innerBlocks: newInnerBlocks || block.innerBlocks.map(innerBlock => cloneBlock(innerBlock))
7763 };
7764 }
7765
7766 /**
7767 * Returns a boolean indicating whether a transform is possible based on
7768 * various bits of context.
7769 *
7770 * @param {Object} transform The transform object to validate.
7771 * @param {string} direction Is this a 'from' or 'to' transform.
7772 * @param {Array} blocks The blocks to transform from.
7773 *
7774 * @return {boolean} Is the transform possible?
7775 */
7776 const isPossibleTransformForSource = (transform, direction, blocks) => {
7777 if (!blocks.length) {
7778 return false;
7779 }
7780
7781 // If multiple blocks are selected, only multi block transforms
7782 // or wildcard transforms are allowed.
7783 const isMultiBlock = blocks.length > 1;
7784 const firstBlockName = blocks[0].name;
7785 const isValidForMultiBlocks = isWildcardBlockTransform(transform) || !isMultiBlock || transform.isMultiBlock;
7786 if (!isValidForMultiBlocks) {
7787 return false;
7788 }
7789
7790 // Check non-wildcard transforms to ensure that transform is valid
7791 // for a block selection of multiple blocks of different types.
7792 if (!isWildcardBlockTransform(transform) && !blocks.every(block => block.name === firstBlockName)) {
7793 return false;
7794 }
7795
7796 // Only consider 'block' type transforms as valid.
7797 const isBlockType = transform.type === 'block';
7798 if (!isBlockType) {
7799 return false;
7800 }
7801
7802 // Check if the transform's block name matches the source block (or is a wildcard)
7803 // only if this is a transform 'from'.
7804 const sourceBlock = blocks[0];
7805 const hasMatchingName = direction !== 'from' || transform.blocks.indexOf(sourceBlock.name) !== -1 || isWildcardBlockTransform(transform);
7806 if (!hasMatchingName) {
7807 return false;
7808 }
7809
7810 // Don't allow single Grouping blocks to be transformed into
7811 // a Grouping block.
7812 if (!isMultiBlock && direction === 'from' && isContainerGroupBlock(sourceBlock.name) && isContainerGroupBlock(transform.blockName)) {
7813 return false;
7814 }
7815
7816 // If the transform has a `isMatch` function specified, check that it returns true.
7817 if (!maybeCheckTransformIsMatch(transform, blocks)) {
7818 return false;
7819 }
7820 return true;
7821 };
7822
7823 /**
7824 * Returns block types that the 'blocks' can be transformed into, based on
7825 * 'from' transforms on other blocks.
7826 *
7827 * @param {Array} blocks The blocks to transform from.
7828 *
7829 * @return {Array} Block types that the blocks can be transformed into.
7830 */
7831 const getBlockTypesForPossibleFromTransforms = blocks => {
7832 if (!blocks.length) {
7833 return [];
7834 }
7835 const allBlockTypes = getBlockTypes();
7836
7837 // filter all blocks to find those with a 'from' transform.
7838 const blockTypesWithPossibleFromTransforms = allBlockTypes.filter(blockType => {
7839 const fromTransforms = getBlockTransforms('from', blockType.name);
7840 return !!findTransform(fromTransforms, transform => {
7841 return isPossibleTransformForSource(transform, 'from', blocks);
7842 });
7843 });
7844 return blockTypesWithPossibleFromTransforms;
7845 };
7846
7847 /**
7848 * Returns block types that the 'blocks' can be transformed into, based on
7849 * the source block's own 'to' transforms.
7850 *
7851 * @param {Array} blocks The blocks to transform from.
7852 *
7853 * @return {Array} Block types that the source can be transformed into.
7854 */
7855 const getBlockTypesForPossibleToTransforms = blocks => {
7856 if (!blocks.length) {
7857 return [];
7858 }
7859 const sourceBlock = blocks[0];
7860 const blockType = getBlockType(sourceBlock.name);
7861 const transformsTo = blockType ? getBlockTransforms('to', blockType.name) : [];
7862
7863 // filter all 'to' transforms to find those that are possible.
7864 const possibleTransforms = transformsTo.filter(transform => {
7865 return transform && isPossibleTransformForSource(transform, 'to', blocks);
7866 });
7867
7868 // Build a list of block names using the possible 'to' transforms.
7869 const blockNames = possibleTransforms.map(transformation => transformation.blocks).flat();
7870
7871 // Map block names to block types.
7872 return blockNames.map(getBlockType);
7873 };
7874
7875 /**
7876 * Determines whether transform is a "block" type
7877 * and if so whether it is a "wildcard" transform
7878 * ie: targets "any" block type
7879 *
7880 * @param {Object} t the Block transform object
7881 *
7882 * @return {boolean} whether transform is a wildcard transform
7883 */
7884 const isWildcardBlockTransform = t => t && t.type === 'block' && Array.isArray(t.blocks) && t.blocks.includes('*');
7885
7886 /**
7887 * Determines whether the given Block is the core Block which
7888 * acts as a container Block for other Blocks as part of the
7889 * Grouping mechanics
7890 *
7891 * @param {string} name the name of the Block to test against
7892 *
7893 * @return {boolean} whether or not the Block is the container Block type
7894 */
7895 const isContainerGroupBlock = name => name === getGroupingBlockName();
7896
7897 /**
7898 * Returns an array of block types that the set of blocks received as argument
7899 * can be transformed into.
7900 *
7901 * @param {Array} blocks Blocks array.
7902 *
7903 * @return {Array} Block types that the blocks argument can be transformed to.
7904 */
7905 function getPossibleBlockTransformations(blocks) {
7906 if (!blocks.length) {
7907 return [];
7908 }
7909 const blockTypesForFromTransforms = getBlockTypesForPossibleFromTransforms(blocks);
7910 const blockTypesForToTransforms = getBlockTypesForPossibleToTransforms(blocks);
7911 return [...new Set([...blockTypesForFromTransforms, ...blockTypesForToTransforms])];
7912 }
7913
7914 /**
7915 * Given an array of transforms, returns the highest-priority transform where
7916 * the predicate function returns a truthy value. A higher-priority transform
7917 * is one with a lower priority value (i.e. first in priority order). Returns
7918 * null if the transforms set is empty or the predicate function returns a
7919 * falsey value for all entries.
7920 *
7921 * @param {Object[]} transforms Transforms to search.
7922 * @param {Function} predicate Function returning true on matching transform.
7923 *
7924 * @return {?Object} Highest-priority transform candidate.
7925 */
7926 function findTransform(transforms, predicate) {
7927 // The hooks library already has built-in mechanisms for managing priority
7928 // queue, so leverage via locally-defined instance.
7929 const hooks = (0,external_wp_hooks_namespaceObject.createHooks)();
7930 for (let i = 0; i < transforms.length; i++) {
7931 const candidate = transforms[i];
7932 if (predicate(candidate)) {
7933 hooks.addFilter('transform', 'transform/' + i.toString(), result => result ? result : candidate, candidate.priority);
7934 }
7935 }
7936
7937 // Filter name is arbitrarily chosen but consistent with above aggregation.
7938 return hooks.applyFilters('transform', null);
7939 }
7940
7941 /**
7942 * Returns normal block transforms for a given transform direction, optionally
7943 * for a specific block by name, or an empty array if there are no transforms.
7944 * If no block name is provided, returns transforms for all blocks. A normal
7945 * transform object includes `blockName` as a property.
7946 *
7947 * @param {string} direction Transform direction ("to", "from").
7948 * @param {string|Object} blockTypeOrName Block type or name.
7949 *
7950 * @return {Array} Block transforms for direction.
7951 */
7952 function getBlockTransforms(direction, blockTypeOrName) {
7953 // When retrieving transforms for all block types, recurse into self.
7954 if (blockTypeOrName === undefined) {
7955 return getBlockTypes().map(({
7956 name
7957 }) => getBlockTransforms(direction, name)).flat();
7958 }
7959
7960 // Validate that block type exists and has array of direction.
7961 const blockType = normalizeBlockType(blockTypeOrName);
7962 const {
7963 name: blockName,
7964 transforms
7965 } = blockType || {};
7966 if (!transforms || !Array.isArray(transforms[direction])) {
7967 return [];
7968 }
7969 const usingMobileTransformations = transforms.supportedMobileTransforms && Array.isArray(transforms.supportedMobileTransforms);
7970 const filteredTransforms = usingMobileTransformations ? transforms[direction].filter(t => {
7971 if (t.type === 'raw') {
7972 return true;
7973 }
7974 if (!t.blocks || !t.blocks.length) {
7975 return false;
7976 }
7977 if (isWildcardBlockTransform(t)) {
7978 return true;
7979 }
7980 return t.blocks.every(transformBlockName => transforms.supportedMobileTransforms.includes(transformBlockName));
7981 }) : transforms[direction];
7982
7983 // Map transforms to normal form.
7984 return filteredTransforms.map(transform => ({
7985 ...transform,
7986 blockName,
7987 usingMobileTransformations
7988 }));
7989 }
7990
7991 /**
7992 * Checks that a given transforms isMatch method passes for given source blocks.
7993 *
7994 * @param {Object} transform A transform object.
7995 * @param {Array} blocks Blocks array.
7996 *
7997 * @return {boolean} True if given blocks are a match for the transform.
7998 */
7999 function maybeCheckTransformIsMatch(transform, blocks) {
8000 if (typeof transform.isMatch !== 'function') {
8001 return true;
8002 }
8003 const sourceBlock = blocks[0];
8004 const attributes = transform.isMultiBlock ? blocks.map(block => block.attributes) : sourceBlock.attributes;
8005 const block = transform.isMultiBlock ? blocks : sourceBlock;
8006 return transform.isMatch(attributes, block);
8007 }
8008
8009 /**
8010 * Switch one or more blocks into one or more blocks of the new block type.
8011 *
8012 * @param {Array|Object} blocks Blocks array or block object.
8013 * @param {string} name Block name.
8014 *
8015 * @return {?Array} Array of blocks or null.
8016 */
8017 function switchToBlockType(blocks, name) {
8018 const blocksArray = Array.isArray(blocks) ? blocks : [blocks];
8019 const isMultiBlock = blocksArray.length > 1;
8020 const firstBlock = blocksArray[0];
8021 const sourceName = firstBlock.name;
8022
8023 // Find the right transformation by giving priority to the "to"
8024 // transformation.
8025 const transformationsFrom = getBlockTransforms('from', name);
8026 const transformationsTo = getBlockTransforms('to', sourceName);
8027 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));
8028
8029 // Stop if there is no valid transformation.
8030 if (!transformation) {
8031 return null;
8032 }
8033 let transformationResults;
8034 if (transformation.isMultiBlock) {
8035 if ('__experimentalConvert' in transformation) {
8036 transformationResults = transformation.__experimentalConvert(blocksArray);
8037 } else {
8038 transformationResults = transformation.transform(blocksArray.map(currentBlock => currentBlock.attributes), blocksArray.map(currentBlock => currentBlock.innerBlocks));
8039 }
8040 } else if ('__experimentalConvert' in transformation) {
8041 transformationResults = transformation.__experimentalConvert(firstBlock);
8042 } else {
8043 transformationResults = transformation.transform(firstBlock.attributes, firstBlock.innerBlocks);
8044 }
8045
8046 // Ensure that the transformation function returned an object or an array
8047 // of objects.
8048 if (transformationResults === null || typeof transformationResults !== 'object') {
8049 return null;
8050 }
8051
8052 // If the transformation function returned a single object, we want to work
8053 // with an array instead.
8054 transformationResults = Array.isArray(transformationResults) ? transformationResults : [transformationResults];
8055
8056 // Ensure that every block object returned by the transformation has a
8057 // valid block type.
8058 if (transformationResults.some(result => !getBlockType(result.name))) {
8059 return null;
8060 }
8061 const hasSwitchedBlock = transformationResults.some(result => result.name === name);
8062
8063 // Ensure that at least one block object returned by the transformation has
8064 // the expected "destination" block type.
8065 if (!hasSwitchedBlock) {
8066 return null;
8067 }
8068 const ret = transformationResults.map((result, index, results) => {
8069 /**
8070 * Filters an individual transform result from block transformation.
8071 * All of the original blocks are passed, since transformations are
8072 * many-to-many, not one-to-one.
8073 *
8074 * @param {Object} transformedBlock The transformed block.
8075 * @param {Object[]} blocks Original blocks transformed.
8076 * @param {Object[]} index Index of the transformed block on the array of results.
8077 * @param {Object[]} results An array all the blocks that resulted from the transformation.
8078 */
8079 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.switchToBlockType.transformedBlock', result, blocks, index, results);
8080 });
8081 return ret;
8082 }
8083
8084 /**
8085 * Create a block object from the example API.
8086 *
8087 * @param {string} name
8088 * @param {Object} example
8089 *
8090 * @return {Object} block.
8091 */
8092 const getBlockFromExample = (name, example) => {
8093 var _example$innerBlocks;
8094 return createBlock(name, example.attributes, ((_example$innerBlocks = example.innerBlocks) !== null && _example$innerBlocks !== void 0 ? _example$innerBlocks : []).map(innerBlock => getBlockFromExample(innerBlock.name, innerBlock)));
8095 };
8096
8097 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/utils.js
8098 /**
8099 * External dependencies
8100 */
8101
8102
8103
8104
8105 /**
8106 * WordPress dependencies
8107 */
8108
8109
8110
8111
8112 /**
8113 * Internal dependencies
8114 */
8115
8116
8117
8118 k([names, a11y]);
8119
8120 /**
8121 * Array of icon colors containing a color to be used if the icon color
8122 * was not explicitly set but the icon background color was.
8123 *
8124 * @type {Object}
8125 */
8126 const ICON_COLORS = ['#191e23', '#f8f9f9'];
8127
8128 /**
8129 * Determines whether the block's attributes are equal to the default attributes
8130 * which means the block is unmodified.
8131 *
8132 * @param {WPBlock} block Block Object
8133 *
8134 * @return {boolean} Whether the block is an unmodified block.
8135 */
8136 function isUnmodifiedBlock(block) {
8137 var _blockType$attributes;
8138 // Cache a created default block if no cache exists or the default block
8139 // name changed.
8140 if (!isUnmodifiedBlock[block.name]) {
8141 isUnmodifiedBlock[block.name] = createBlock(block.name);
8142 }
8143 const newBlock = isUnmodifiedBlock[block.name];
8144 const blockType = getBlockType(block.name);
8145 return Object.keys((_blockType$attributes = blockType?.attributes) !== null && _blockType$attributes !== void 0 ? _blockType$attributes : {}).every(key => newBlock.attributes[key] === block.attributes[key]);
8146 }
8147
8148 /**
8149 * Determines whether the block is a default block and its attributes are equal
8150 * to the default attributes which means the block is unmodified.
8151 *
8152 * @param {WPBlock} block Block Object
8153 *
8154 * @return {boolean} Whether the block is an unmodified default block.
8155 */
8156 function isUnmodifiedDefaultBlock(block) {
8157 return block.name === getDefaultBlockName() && isUnmodifiedBlock(block);
8158 }
8159
8160 /**
8161 * Function that checks if the parameter is a valid icon.
8162 *
8163 * @param {*} icon Parameter to be checked.
8164 *
8165 * @return {boolean} True if the parameter is a valid icon and false otherwise.
8166 */
8167
8168 function isValidIcon(icon) {
8169 return !!icon && (typeof icon === 'string' || (0,external_wp_element_namespaceObject.isValidElement)(icon) || typeof icon === 'function' || icon instanceof external_wp_element_namespaceObject.Component);
8170 }
8171
8172 /**
8173 * Function that receives an icon as set by the blocks during the registration
8174 * and returns a new icon object that is normalized so we can rely on just on possible icon structure
8175 * in the codebase.
8176 *
8177 * @param {WPBlockTypeIconRender} icon Render behavior of a block type icon;
8178 * one of a Dashicon slug, an element, or a
8179 * component.
8180 *
8181 * @return {WPBlockTypeIconDescriptor} Object describing the icon.
8182 */
8183 function normalizeIconObject(icon) {
8184 icon = icon || BLOCK_ICON_DEFAULT;
8185 if (isValidIcon(icon)) {
8186 return {
8187 src: icon
8188 };
8189 }
8190 if ('background' in icon) {
8191 const colordBgColor = w(icon.background);
8192 const getColorContrast = iconColor => colordBgColor.contrast(iconColor);
8193 const maxContrast = Math.max(...ICON_COLORS.map(getColorContrast));
8194 return {
8195 ...icon,
8196 foreground: icon.foreground ? icon.foreground : ICON_COLORS.find(iconColor => getColorContrast(iconColor) === maxContrast),
8197 shadowColor: colordBgColor.alpha(0.3).toRgbString()
8198 };
8199 }
8200 return icon;
8201 }
8202
8203 /**
8204 * Normalizes block type passed as param. When string is passed then
8205 * it converts it to the matching block type object.
8206 * It passes the original object otherwise.
8207 *
8208 * @param {string|Object} blockTypeOrName Block type or name.
8209 *
8210 * @return {?Object} Block type.
8211 */
8212 function normalizeBlockType(blockTypeOrName) {
8213 if (typeof blockTypeOrName === 'string') {
8214 return getBlockType(blockTypeOrName);
8215 }
8216 return blockTypeOrName;
8217 }
8218
8219 /**
8220 * Get the label for the block, usually this is either the block title,
8221 * or the value of the block's `label` function when that's specified.
8222 *
8223 * @param {Object} blockType The block type.
8224 * @param {Object} attributes The values of the block's attributes.
8225 * @param {Object} context The intended use for the label.
8226 *
8227 * @return {string} The block label.
8228 */
8229 function getBlockLabel(blockType, attributes, context = 'visual') {
8230 const {
8231 __experimentalLabel: getLabel,
8232 title
8233 } = blockType;
8234 const label = getLabel && getLabel(attributes, {
8235 context
8236 });
8237 if (!label) {
8238 return title;
8239 }
8240
8241 // Strip any HTML (i.e. RichText formatting) before returning.
8242 return (0,external_wp_dom_namespaceObject.__unstableStripHTML)(label);
8243 }
8244
8245 /**
8246 * Get a label for the block for use by screenreaders, this is more descriptive
8247 * than the visual label and includes the block title and the value of the
8248 * `getLabel` function if it's specified.
8249 *
8250 * @param {?Object} blockType The block type.
8251 * @param {Object} attributes The values of the block's attributes.
8252 * @param {?number} position The position of the block in the block list.
8253 * @param {string} [direction='vertical'] The direction of the block layout.
8254 *
8255 * @return {string} The block label.
8256 */
8257 function getAccessibleBlockLabel(blockType, attributes, position, direction = 'vertical') {
8258 // `title` is already localized, `label` is a user-supplied value.
8259 const title = blockType?.title;
8260 const label = blockType ? getBlockLabel(blockType, attributes, 'accessibility') : '';
8261 const hasPosition = position !== undefined;
8262
8263 // getBlockLabel returns the block title as a fallback when there's no label,
8264 // if it did return the title, this function needs to avoid adding the
8265 // title twice within the accessible label. Use this `hasLabel` boolean to
8266 // handle that.
8267 const hasLabel = label && label !== title;
8268 if (hasPosition && direction === 'vertical') {
8269 if (hasLabel) {
8270 return (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: accessibility text. 1: The block title. 2: The block row number. 3: The block label.. */
8271 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. Row %2$d. %3$s'), title, position, label);
8272 }
8273 return (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: accessibility text. 1: The block title. 2: The block row number. */
8274 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. Row %2$d'), title, position);
8275 } else if (hasPosition && direction === 'horizontal') {
8276 if (hasLabel) {
8277 return (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: accessibility text. 1: The block title. 2: The block column number. 3: The block label.. */
8278 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. Column %2$d. %3$s'), title, position, label);
8279 }
8280 return (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: accessibility text. 1: The block title. 2: The block column number. */
8281 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. Column %2$d'), title, position);
8282 }
8283 if (hasLabel) {
8284 return (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: accessibility text. %1: The block title. %2: The block label. */
8285 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. %2$s'), title, label);
8286 }
8287 return (0,external_wp_i18n_namespaceObject.sprintf)( /* translators: accessibility text. %s: The block title. */
8288 (0,external_wp_i18n_namespaceObject.__)('%s Block'), title);
8289 }
8290
8291 /**
8292 * Ensure attributes contains only values defined by block type, and merge
8293 * default values for missing attributes.
8294 *
8295 * @param {string} name The block's name.
8296 * @param {Object} attributes The block's attributes.
8297 * @return {Object} The sanitized attributes.
8298 */
8299 function __experimentalSanitizeBlockAttributes(name, attributes) {
8300 // Get the type definition associated with a registered block.
8301 const blockType = getBlockType(name);
8302 if (undefined === blockType) {
8303 throw new Error(`Block type '${name}' is not registered.`);
8304 }
8305 return Object.entries(blockType.attributes).reduce((accumulator, [key, schema]) => {
8306 const value = attributes[key];
8307 if (undefined !== value) {
8308 accumulator[key] = value;
8309 } else if (schema.hasOwnProperty('default')) {
8310 accumulator[key] = schema.default;
8311 }
8312 if (['node', 'children'].indexOf(schema.source) !== -1) {
8313 // Ensure value passed is always an array, which we're expecting in
8314 // the RichText component to handle the deprecated value.
8315 if (typeof accumulator[key] === 'string') {
8316 accumulator[key] = [accumulator[key]];
8317 } else if (!Array.isArray(accumulator[key])) {
8318 accumulator[key] = [];
8319 }
8320 }
8321 return accumulator;
8322 }, {});
8323 }
8324
8325 /**
8326 * Filter block attributes by `role` and return their names.
8327 *
8328 * @param {string} name Block attribute's name.
8329 * @param {string} role The role of a block attribute.
8330 *
8331 * @return {string[]} The attribute names that have the provided role.
8332 */
8333 function __experimentalGetBlockAttributesNamesByRole(name, role) {
8334 const attributes = getBlockType(name)?.attributes;
8335 if (!attributes) return [];
8336 const attributesNames = Object.keys(attributes);
8337 if (!role) return attributesNames;
8338 return attributesNames.filter(attributeName => attributes[attributeName]?.__experimentalRole === role);
8339 }
8340
8341 /**
8342 * Return a new object with the specified keys omitted.
8343 *
8344 * @param {Object} object Original object.
8345 * @param {Array} keys Keys to be omitted.
8346 *
8347 * @return {Object} Object with omitted keys.
8348 */
8349 function omit(object, keys) {
8350 return Object.fromEntries(Object.entries(object).filter(([key]) => !keys.includes(key)));
8351 }
8352
8353 ;// CONCATENATED MODULE: ./packages/blocks/build-module/store/reducer.js
8354 /**
8355 * WordPress dependencies
8356 */
8357
8358
8359
8360 /**
8361 * Internal dependencies
8362 */
8363
8364
8365 /**
8366 * @typedef {Object} WPBlockCategory
8367 *
8368 * @property {string} slug Unique category slug.
8369 * @property {string} title Category label, for display in user interface.
8370 */
8371
8372 /**
8373 * Default set of categories.
8374 *
8375 * @type {WPBlockCategory[]}
8376 */
8377 const DEFAULT_CATEGORIES = [{
8378 slug: 'text',
8379 title: (0,external_wp_i18n_namespaceObject.__)('Text')
8380 }, {
8381 slug: 'media',
8382 title: (0,external_wp_i18n_namespaceObject.__)('Media')
8383 }, {
8384 slug: 'design',
8385 title: (0,external_wp_i18n_namespaceObject.__)('Design')
8386 }, {
8387 slug: 'widgets',
8388 title: (0,external_wp_i18n_namespaceObject.__)('Widgets')
8389 }, {
8390 slug: 'theme',
8391 title: (0,external_wp_i18n_namespaceObject.__)('Theme')
8392 }, {
8393 slug: 'embed',
8394 title: (0,external_wp_i18n_namespaceObject.__)('Embeds')
8395 }, {
8396 slug: 'reusable',
8397 title: (0,external_wp_i18n_namespaceObject.__)('Reusable blocks')
8398 }];
8399
8400 // Key block types by their name.
8401 function keyBlockTypesByName(types) {
8402 return types.reduce((newBlockTypes, block) => ({
8403 ...newBlockTypes,
8404 [block.name]: block
8405 }), {});
8406 }
8407
8408 // Filter items to ensure they're unique by their name.
8409 function getUniqueItemsByName(items) {
8410 return items.reduce((acc, currentItem) => {
8411 if (!acc.some(item => item.name === currentItem.name)) {
8412 acc.push(currentItem);
8413 }
8414 return acc;
8415 }, []);
8416 }
8417
8418 /**
8419 * Reducer managing the unprocessed block types in a form passed when registering the by block.
8420 * It's for internal use only. It allows recomputing the processed block types on-demand after block type filters
8421 * get added or removed.
8422 *
8423 * @param {Object} state Current state.
8424 * @param {Object} action Dispatched action.
8425 *
8426 * @return {Object} Updated state.
8427 */
8428 function unprocessedBlockTypes(state = {}, action) {
8429 switch (action.type) {
8430 case 'ADD_UNPROCESSED_BLOCK_TYPE':
8431 return {
8432 ...state,
8433 [action.blockType.name]: action.blockType
8434 };
8435 case 'REMOVE_BLOCK_TYPES':
8436 return omit(state, action.names);
8437 }
8438 return state;
8439 }
8440
8441 /**
8442 * Reducer managing the processed block types with all filters applied.
8443 * The state is derived from the `unprocessedBlockTypes` reducer.
8444 *
8445 * @param {Object} state Current state.
8446 * @param {Object} action Dispatched action.
8447 *
8448 * @return {Object} Updated state.
8449 */
8450 function blockTypes(state = {}, action) {
8451 switch (action.type) {
8452 case 'ADD_BLOCK_TYPES':
8453 return {
8454 ...state,
8455 ...keyBlockTypesByName(action.blockTypes)
8456 };
8457 case 'REMOVE_BLOCK_TYPES':
8458 return omit(state, action.names);
8459 }
8460 return state;
8461 }
8462
8463 /**
8464 * Reducer managing the block styles.
8465 *
8466 * @param {Object} state Current state.
8467 * @param {Object} action Dispatched action.
8468 *
8469 * @return {Object} Updated state.
8470 */
8471 function blockStyles(state = {}, action) {
8472 var _state$action$blockNa, _state$action$blockNa2;
8473 switch (action.type) {
8474 case 'ADD_BLOCK_TYPES':
8475 return {
8476 ...state,
8477 ...Object.fromEntries(Object.entries(keyBlockTypesByName(action.blockTypes)).map(([name, blockType]) => {
8478 var _blockType$styles, _state$blockType$name;
8479 return [name, getUniqueItemsByName([...((_blockType$styles = blockType.styles) !== null && _blockType$styles !== void 0 ? _blockType$styles : []).map(style => ({
8480 ...style,
8481 source: 'block'
8482 })), ...((_state$blockType$name = state[blockType.name]) !== null && _state$blockType$name !== void 0 ? _state$blockType$name : []).filter(({
8483 source
8484 }) => 'block' !== source)])];
8485 }))
8486 };
8487 case 'ADD_BLOCK_STYLES':
8488 return {
8489 ...state,
8490 [action.blockName]: getUniqueItemsByName([...((_state$action$blockNa = state[action.blockName]) !== null && _state$action$blockNa !== void 0 ? _state$action$blockNa : []), ...action.styles])
8491 };
8492 case 'REMOVE_BLOCK_STYLES':
8493 return {
8494 ...state,
8495 [action.blockName]: ((_state$action$blockNa2 = state[action.blockName]) !== null && _state$action$blockNa2 !== void 0 ? _state$action$blockNa2 : []).filter(style => action.styleNames.indexOf(style.name) === -1)
8496 };
8497 }
8498 return state;
8499 }
8500
8501 /**
8502 * Reducer managing the block variations.
8503 *
8504 * @param {Object} state Current state.
8505 * @param {Object} action Dispatched action.
8506 *
8507 * @return {Object} Updated state.
8508 */
8509 function blockVariations(state = {}, action) {
8510 var _state$action$blockNa3, _state$action$blockNa4;
8511 switch (action.type) {
8512 case 'ADD_BLOCK_TYPES':
8513 return {
8514 ...state,
8515 ...Object.fromEntries(Object.entries(keyBlockTypesByName(action.blockTypes)).map(([name, blockType]) => {
8516 var _blockType$variations, _state$blockType$name2;
8517 return [name, getUniqueItemsByName([...((_blockType$variations = blockType.variations) !== null && _blockType$variations !== void 0 ? _blockType$variations : []).map(variation => ({
8518 ...variation,
8519 source: 'block'
8520 })), ...((_state$blockType$name2 = state[blockType.name]) !== null && _state$blockType$name2 !== void 0 ? _state$blockType$name2 : []).filter(({
8521 source
8522 }) => 'block' !== source)])];
8523 }))
8524 };
8525 case 'ADD_BLOCK_VARIATIONS':
8526 return {
8527 ...state,
8528 [action.blockName]: getUniqueItemsByName([...((_state$action$blockNa3 = state[action.blockName]) !== null && _state$action$blockNa3 !== void 0 ? _state$action$blockNa3 : []), ...action.variations])
8529 };
8530 case 'REMOVE_BLOCK_VARIATIONS':
8531 return {
8532 ...state,
8533 [action.blockName]: ((_state$action$blockNa4 = state[action.blockName]) !== null && _state$action$blockNa4 !== void 0 ? _state$action$blockNa4 : []).filter(variation => action.variationNames.indexOf(variation.name) === -1)
8534 };
8535 }
8536 return state;
8537 }
8538
8539 /**
8540 * Higher-order Reducer creating a reducer keeping track of given block name.
8541 *
8542 * @param {string} setActionType Action type.
8543 *
8544 * @return {Function} Reducer.
8545 */
8546 function createBlockNameSetterReducer(setActionType) {
8547 return (state = null, action) => {
8548 switch (action.type) {
8549 case 'REMOVE_BLOCK_TYPES':
8550 if (action.names.indexOf(state) !== -1) {
8551 return null;
8552 }
8553 return state;
8554 case setActionType:
8555 return action.name || null;
8556 }
8557 return state;
8558 };
8559 }
8560 const defaultBlockName = createBlockNameSetterReducer('SET_DEFAULT_BLOCK_NAME');
8561 const freeformFallbackBlockName = createBlockNameSetterReducer('SET_FREEFORM_FALLBACK_BLOCK_NAME');
8562 const unregisteredFallbackBlockName = createBlockNameSetterReducer('SET_UNREGISTERED_FALLBACK_BLOCK_NAME');
8563 const groupingBlockName = createBlockNameSetterReducer('SET_GROUPING_BLOCK_NAME');
8564
8565 /**
8566 * Reducer managing the categories
8567 *
8568 * @param {WPBlockCategory[]} state Current state.
8569 * @param {Object} action Dispatched action.
8570 *
8571 * @return {WPBlockCategory[]} Updated state.
8572 */
8573 function categories(state = DEFAULT_CATEGORIES, action) {
8574 switch (action.type) {
8575 case 'SET_CATEGORIES':
8576 return action.categories || [];
8577 case 'UPDATE_CATEGORY':
8578 {
8579 if (!action.category || !Object.keys(action.category).length) {
8580 return state;
8581 }
8582 const categoryToChange = state.find(({
8583 slug
8584 }) => slug === action.slug);
8585 if (categoryToChange) {
8586 return state.map(category => {
8587 if (category.slug === action.slug) {
8588 return {
8589 ...category,
8590 ...action.category
8591 };
8592 }
8593 return category;
8594 });
8595 }
8596 }
8597 }
8598 return state;
8599 }
8600 function collections(state = {}, action) {
8601 switch (action.type) {
8602 case 'ADD_BLOCK_COLLECTION':
8603 return {
8604 ...state,
8605 [action.namespace]: {
8606 title: action.title,
8607 icon: action.icon
8608 }
8609 };
8610 case 'REMOVE_BLOCK_COLLECTION':
8611 return omit(state, action.namespace);
8612 }
8613 return state;
8614 }
8615 /* harmony default export */ const reducer = ((0,external_wp_data_namespaceObject.combineReducers)({
8616 unprocessedBlockTypes,
8617 blockTypes,
8618 blockStyles,
8619 blockVariations,
8620 defaultBlockName,
8621 freeformFallbackBlockName,
8622 unregisteredFallbackBlockName,
8623 groupingBlockName,
8624 categories,
8625 collections
8626 }));
8627
8628 ;// CONCATENATED MODULE: ./node_modules/rememo/rememo.js
8629
8630
8631 /** @typedef {(...args: any[]) => *[]} GetDependants */
8632
8633 /** @typedef {() => void} Clear */
8634
8635 /**
8636 * @typedef {{
8637 * getDependants: GetDependants,
8638 * clear: Clear
8639 * }} EnhancedSelector
8640 */
8641
8642 /**
8643 * Internal cache entry.
8644 *
8645 * @typedef CacheNode
8646 *
8647 * @property {?CacheNode|undefined} [prev] Previous node.
8648 * @property {?CacheNode|undefined} [next] Next node.
8649 * @property {*[]} args Function arguments for cache entry.
8650 * @property {*} val Function result.
8651 */
8652
8653 /**
8654 * @typedef Cache
8655 *
8656 * @property {Clear} clear Function to clear cache.
8657 * @property {boolean} [isUniqueByDependants] Whether dependants are valid in
8658 * considering cache uniqueness. A cache is unique if dependents are all arrays
8659 * or objects.
8660 * @property {CacheNode?} [head] Cache head.
8661 * @property {*[]} [lastDependants] Dependants from previous invocation.
8662 */
8663
8664 /**
8665 * Arbitrary value used as key for referencing cache object in WeakMap tree.
8666 *
8667 * @type {{}}
8668 */
8669 var LEAF_KEY = {};
8670
8671 /**
8672 * Returns the first argument as the sole entry in an array.
8673 *
8674 * @template T
8675 *
8676 * @param {T} value Value to return.
8677 *
8678 * @return {[T]} Value returned as entry in array.
8679 */
8680 function arrayOf(value) {
8681 return [value];
8682 }
8683
8684 /**
8685 * Returns true if the value passed is object-like, or false otherwise. A value
8686 * is object-like if it can support property assignment, e.g. object or array.
8687 *
8688 * @param {*} value Value to test.
8689 *
8690 * @return {boolean} Whether value is object-like.
8691 */
8692 function isObjectLike(value) {
8693 return !!value && 'object' === typeof value;
8694 }
8695
8696 /**
8697 * Creates and returns a new cache object.
8698 *
8699 * @return {Cache} Cache object.
8700 */
8701 function createCache() {
8702 /** @type {Cache} */
8703 var cache = {
8704 clear: function () {
8705 cache.head = null;
8706 },
8707 };
8708
8709 return cache;
8710 }
8711
8712 /**
8713 * Returns true if entries within the two arrays are strictly equal by
8714 * reference from a starting index.
8715 *
8716 * @param {*[]} a First array.
8717 * @param {*[]} b Second array.
8718 * @param {number} fromIndex Index from which to start comparison.
8719 *
8720 * @return {boolean} Whether arrays are shallowly equal.
8721 */
8722 function isShallowEqual(a, b, fromIndex) {
8723 var i;
8724
8725 if (a.length !== b.length) {
8726 return false;
8727 }
8728
8729 for (i = fromIndex; i < a.length; i++) {
8730 if (a[i] !== b[i]) {
8731 return false;
8732 }
8733 }
8734
8735 return true;
8736 }
8737
8738 /**
8739 * Returns a memoized selector function. The getDependants function argument is
8740 * called before the memoized selector and is expected to return an immutable
8741 * reference or array of references on which the selector depends for computing
8742 * its own return value. The memoize cache is preserved only as long as those
8743 * dependant references remain the same. If getDependants returns a different
8744 * reference(s), the cache is cleared and the selector value regenerated.
8745 *
8746 * @template {(...args: *[]) => *} S
8747 *
8748 * @param {S} selector Selector function.
8749 * @param {GetDependants=} getDependants Dependant getter returning an array of
8750 * references used in cache bust consideration.
8751 */
8752 /* harmony default export */ function rememo(selector, getDependants) {
8753 /** @type {WeakMap<*,*>} */
8754 var rootCache;
8755
8756 /** @type {GetDependants} */
8757 var normalizedGetDependants = getDependants ? getDependants : arrayOf;
8758
8759 /**
8760 * Returns the cache for a given dependants array. When possible, a WeakMap
8761 * will be used to create a unique cache for each set of dependants. This
8762 * is feasible due to the nature of WeakMap in allowing garbage collection
8763 * to occur on entries where the key object is no longer referenced. Since
8764 * WeakMap requires the key to be an object, this is only possible when the
8765 * dependant is object-like. The root cache is created as a hierarchy where
8766 * each top-level key is the first entry in a dependants set, the value a
8767 * WeakMap where each key is the next dependant, and so on. This continues
8768 * so long as the dependants are object-like. If no dependants are object-
8769 * like, then the cache is shared across all invocations.
8770 *
8771 * @see isObjectLike
8772 *
8773 * @param {*[]} dependants Selector dependants.
8774 *
8775 * @return {Cache} Cache object.
8776 */
8777 function getCache(dependants) {
8778 var caches = rootCache,
8779 isUniqueByDependants = true,
8780 i,
8781 dependant,
8782 map,
8783 cache;
8784
8785 for (i = 0; i < dependants.length; i++) {
8786 dependant = dependants[i];
8787
8788 // Can only compose WeakMap from object-like key.
8789 if (!isObjectLike(dependant)) {
8790 isUniqueByDependants = false;
8791 break;
8792 }
8793
8794 // Does current segment of cache already have a WeakMap?
8795 if (caches.has(dependant)) {
8796 // Traverse into nested WeakMap.
8797 caches = caches.get(dependant);
8798 } else {
8799 // Create, set, and traverse into a new one.
8800 map = new WeakMap();
8801 caches.set(dependant, map);
8802 caches = map;
8803 }
8804 }
8805
8806 // We use an arbitrary (but consistent) object as key for the last item
8807 // in the WeakMap to serve as our running cache.
8808 if (!caches.has(LEAF_KEY)) {
8809 cache = createCache();
8810 cache.isUniqueByDependants = isUniqueByDependants;
8811 caches.set(LEAF_KEY, cache);
8812 }
8813
8814 return caches.get(LEAF_KEY);
8815 }
8816
8817 /**
8818 * Resets root memoization cache.
8819 */
8820 function clear() {
8821 rootCache = new WeakMap();
8822 }
8823
8824 /* eslint-disable jsdoc/check-param-names */
8825 /**
8826 * The augmented selector call, considering first whether dependants have
8827 * changed before passing it to underlying memoize function.
8828 *
8829 * @param {*} source Source object for derivation.
8830 * @param {...*} extraArgs Additional arguments to pass to selector.
8831 *
8832 * @return {*} Selector result.
8833 */
8834 /* eslint-enable jsdoc/check-param-names */
8835 function callSelector(/* source, ...extraArgs */) {
8836 var len = arguments.length,
8837 cache,
8838 node,
8839 i,
8840 args,
8841 dependants;
8842
8843 // Create copy of arguments (avoid leaking deoptimization).
8844 args = new Array(len);
8845 for (i = 0; i < len; i++) {
8846 args[i] = arguments[i];
8847 }
8848
8849 dependants = normalizedGetDependants.apply(null, args);
8850 cache = getCache(dependants);
8851
8852 // If not guaranteed uniqueness by dependants (primitive type), shallow
8853 // compare against last dependants and, if references have changed,
8854 // destroy cache to recalculate result.
8855 if (!cache.isUniqueByDependants) {
8856 if (
8857 cache.lastDependants &&
8858 !isShallowEqual(dependants, cache.lastDependants, 0)
8859 ) {
8860 cache.clear();
8861 }
8862
8863 cache.lastDependants = dependants;
8864 }
8865
8866 node = cache.head;
8867 while (node) {
8868 // Check whether node arguments match arguments
8869 if (!isShallowEqual(node.args, args, 1)) {
8870 node = node.next;
8871 continue;
8872 }
8873
8874 // At this point we can assume we've found a match
8875
8876 // Surface matched node to head if not already
8877 if (node !== cache.head) {
8878 // Adjust siblings to point to each other.
8879 /** @type {CacheNode} */ (node.prev).next = node.next;
8880 if (node.next) {
8881 node.next.prev = node.prev;
8882 }
8883
8884 node.next = cache.head;
8885 node.prev = null;
8886 /** @type {CacheNode} */ (cache.head).prev = node;
8887 cache.head = node;
8888 }
8889
8890 // Return immediately
8891 return node.val;
8892 }
8893
8894 // No cached value found. Continue to insertion phase:
8895
8896 node = /** @type {CacheNode} */ ({
8897 // Generate the result from original function
8898 val: selector.apply(null, args),
8899 });
8900
8901 // Avoid including the source object in the cache.
8902 args[0] = null;
8903 node.args = args;
8904
8905 // Don't need to check whether node is already head, since it would
8906 // have been returned above already if it was
8907
8908 // Shift existing head down list
8909 if (cache.head) {
8910 cache.head.prev = node;
8911 node.next = cache.head;
8912 }
8913
8914 cache.head = node;
8915
8916 return node.val;
8917 }
8918
8919 callSelector.getDependants = normalizedGetDependants;
8920 callSelector.clear = clear;
8921 clear();
8922
8923 return /** @type {S & EnhancedSelector} */ (callSelector);
8924 }
8925
8926 // EXTERNAL MODULE: ./node_modules/remove-accents/index.js
8927 var remove_accents = __webpack_require__(4793);
8928 var remove_accents_default = /*#__PURE__*/__webpack_require__.n(remove_accents);
8929 ;// CONCATENATED MODULE: external ["wp","compose"]
8930 const external_wp_compose_namespaceObject = window["wp"]["compose"];
8931 ;// CONCATENATED MODULE: ./packages/blocks/build-module/store/utils.js
8932 /**
8933 * Helper util to return a value from a certain path of the object.
8934 * Path is specified as either:
8935 * - a string of properties, separated by dots, for example: "x.y".
8936 * - an array of properties, for example `[ 'x', 'y' ]`.
8937 * You can also specify a default value in case the result is nullish.
8938 *
8939 * @param {Object} object Input object.
8940 * @param {string|Array} path Path to the object property.
8941 * @param {*} defaultValue Default value if the value at the specified path is nullish.
8942 * @return {*} Value of the object property at the specified path.
8943 */
8944 const getValueFromObjectPath = (object, path, defaultValue) => {
8945 var _value;
8946 const normalizedPath = Array.isArray(path) ? path : path.split('.');
8947 let value = object;
8948 normalizedPath.forEach(fieldName => {
8949 value = value?.[fieldName];
8950 });
8951 return (_value = value) !== null && _value !== void 0 ? _value : defaultValue;
8952 };
8953
8954 ;// CONCATENATED MODULE: ./packages/blocks/build-module/store/selectors.js
8955 /**
8956 * External dependencies
8957 */
8958
8959
8960
8961 /**
8962 * WordPress dependencies
8963 */
8964
8965
8966 /**
8967 * Internal dependencies
8968 */
8969
8970
8971 /** @typedef {import('../api/registration').WPBlockVariation} WPBlockVariation */
8972 /** @typedef {import('../api/registration').WPBlockVariationScope} WPBlockVariationScope */
8973 /** @typedef {import('./reducer').WPBlockCategory} WPBlockCategory */
8974
8975 /**
8976 * Given a block name or block type object, returns the corresponding
8977 * normalized block type object.
8978 *
8979 * @param {Object} state Blocks state.
8980 * @param {(string|Object)} nameOrType Block name or type object
8981 *
8982 * @return {Object} Block type object.
8983 */
8984 const getNormalizedBlockType = (state, nameOrType) => 'string' === typeof nameOrType ? selectors_getBlockType(state, nameOrType) : nameOrType;
8985
8986 /**
8987 * Returns all the unprocessed block types as passed during the registration.
8988 *
8989 * @param {Object} state Data state.
8990 *
8991 * @return {Array} Unprocessed block types.
8992 */
8993 function __experimentalGetUnprocessedBlockTypes(state) {
8994 return state.unprocessedBlockTypes;
8995 }
8996
8997 /**
8998 * Returns all the available block types.
8999 *
9000 * @param {Object} state Data state.
9001 *
9002 * @example
9003 * ```js
9004 * import { store as blocksStore } from '@wordpress/blocks';
9005 * import { useSelect } from '@wordpress/data';
9006 *
9007 * const ExampleComponent = () => {
9008 * const blockTypes = useSelect(
9009 * ( select ) => select( blocksStore ).getBlockTypes(),
9010 * []
9011 * );
9012 *
9013 * return (
9014 * <ul>
9015 * { blockTypes.map( ( block ) => (
9016 * <li key={ block.name }>{ block.title }</li>
9017 * ) ) }
9018 * </ul>
9019 * );
9020 * };
9021 * ```
9022 *
9023 * @return {Array} Block Types.
9024 */
9025 const selectors_getBlockTypes = rememo(state => Object.values(state.blockTypes), state => [state.blockTypes]);
9026
9027 /**
9028 * Returns a block type by name.
9029 *
9030 * @param {Object} state Data state.
9031 * @param {string} name Block type name.
9032 *
9033 * @example
9034 * ```js
9035 * import { store as blocksStore } from '@wordpress/blocks';
9036 * import { useSelect } from '@wordpress/data';
9037 *
9038 * const ExampleComponent = () => {
9039 * const paragraphBlock = useSelect( ( select ) =>
9040 * ( select ) => select( blocksStore ).getBlockType( 'core/paragraph' ),
9041 * []
9042 * );
9043 *
9044 * return (
9045 * <ul>
9046 * { paragraphBlock &&
9047 * Object.entries( paragraphBlock.supports ).map(
9048 * ( blockSupportsEntry ) => {
9049 * const [ propertyName, value ] = blockSupportsEntry;
9050 * return (
9051 * <li
9052 * key={ propertyName }
9053 * >{ `${ propertyName } : ${ value }` }</li>
9054 * );
9055 * }
9056 * ) }
9057 * </ul>
9058 * );
9059 * };
9060 * ```
9061 *
9062 * @return {Object?} Block Type.
9063 */
9064 function selectors_getBlockType(state, name) {
9065 return state.blockTypes[name];
9066 }
9067
9068 /**
9069 * Returns block styles by block name.
9070 *
9071 * @param {Object} state Data state.
9072 * @param {string} name Block type name.
9073 *
9074 * @example
9075 * ```js
9076 * import { store as blocksStore } from '@wordpress/blocks';
9077 * import { useSelect } from '@wordpress/data';
9078 *
9079 * const ExampleComponent = () => {
9080 * const buttonBlockStyles = useSelect( ( select ) =>
9081 * select( blocksStore ).getBlockStyles( 'core/button' ),
9082 * []
9083 * );
9084 *
9085 * return (
9086 * <ul>
9087 * { buttonBlockStyles &&
9088 * buttonBlockStyles.map( ( style ) => (
9089 * <li key={ style.name }>{ style.label }</li>
9090 * ) ) }
9091 * </ul>
9092 * );
9093 * };
9094 * ```
9095 *
9096 * @return {Array?} Block Styles.
9097 */
9098 function getBlockStyles(state, name) {
9099 return state.blockStyles[name];
9100 }
9101
9102 /**
9103 * Returns block variations by block name.
9104 *
9105 * @param {Object} state Data state.
9106 * @param {string} blockName Block type name.
9107 * @param {WPBlockVariationScope} [scope] Block variation scope name.
9108 *
9109 * @example
9110 * ```js
9111 * import { store as blocksStore } from '@wordpress/blocks';
9112 * import { useSelect } from '@wordpress/data';
9113 *
9114 * const ExampleComponent = () => {
9115 * const socialLinkVariations = useSelect( ( select ) =>
9116 * select( blocksStore ).getBlockVariations( 'core/social-link' ),
9117 * []
9118 * );
9119 *
9120 * return (
9121 * <ul>
9122 * { socialLinkVariations &&
9123 * socialLinkVariations.map( ( variation ) => (
9124 * <li key={ variation.name }>{ variation.title }</li>
9125 * ) ) }
9126 * </ul>
9127 * );
9128 * };
9129 * ```
9130 *
9131 * @return {(WPBlockVariation[]|void)} Block variations.
9132 */
9133 const selectors_getBlockVariations = rememo((state, blockName, scope) => {
9134 const variations = state.blockVariations[blockName];
9135 if (!variations || !scope) {
9136 return variations;
9137 }
9138 return variations.filter(variation => {
9139 // For backward compatibility reasons, variation's scope defaults to
9140 // `block` and `inserter` when not set.
9141 return (variation.scope || ['block', 'inserter']).includes(scope);
9142 });
9143 }, (state, blockName) => [state.blockVariations[blockName]]);
9144
9145 /**
9146 * Returns the active block variation for a given block based on its attributes.
9147 * Variations are determined by their `isActive` property.
9148 * Which is either an array of block attribute keys or a function.
9149 *
9150 * In case of an array of block attribute keys, the `attributes` are compared
9151 * to the variation's attributes using strict equality check.
9152 *
9153 * In case of function type, the function should accept a block's attributes
9154 * and the variation's attributes and determines if a variation is active.
9155 * A function that accepts a block's attributes and the variation's attributes and determines if a variation is active.
9156 *
9157 * @param {Object} state Data state.
9158 * @param {string} blockName Name of block (example: “core/columns”).
9159 * @param {Object} attributes Block attributes used to determine active variation.
9160 * @param {WPBlockVariationScope} [scope] Block variation scope name.
9161 *
9162 * @example
9163 * ```js
9164 * import { __ } from '@wordpress/i18n';
9165 * import { store as blocksStore } from '@wordpress/blocks';
9166 * import { store as blockEditorStore } from '@wordpress/block-editor';
9167 * import { useSelect } from '@wordpress/data';
9168 *
9169 * const ExampleComponent = () => {
9170 * // This example assumes that a core/embed block is the first block in the Block Editor.
9171 * const activeBlockVariation = useSelect( ( select ) => {
9172 * // Retrieve the list of blocks.
9173 * const [ firstBlock ] = select( blockEditorStore ).getBlocks()
9174 *
9175 * // Return the active block variation for the first block.
9176 * return select( blocksStore ).getActiveBlockVariation(
9177 * firstBlock.name,
9178 * firstBlock.attributes
9179 * );
9180 * }, [] );
9181 *
9182 * return activeBlockVariation && activeBlockVariation.name === 'spotify' ? (
9183 * <p>{ __( 'Spotify variation' ) }</p>
9184 * ) : (
9185 * <p>{ __( 'Other variation' ) }</p>
9186 * );
9187 * };
9188 * ```
9189 *
9190 * @return {(WPBlockVariation|undefined)} Active block variation.
9191 */
9192 function getActiveBlockVariation(state, blockName, attributes, scope) {
9193 const variations = selectors_getBlockVariations(state, blockName, scope);
9194 const match = variations?.find(variation => {
9195 if (Array.isArray(variation.isActive)) {
9196 const blockType = selectors_getBlockType(state, blockName);
9197 const attributeKeys = Object.keys(blockType?.attributes || {});
9198 const definedAttributes = variation.isActive.filter(attribute => attributeKeys.includes(attribute));
9199 if (definedAttributes.length === 0) {
9200 return false;
9201 }
9202 return definedAttributes.every(attribute => attributes[attribute] === variation.attributes[attribute]);
9203 }
9204 return variation.isActive?.(attributes, variation.attributes);
9205 });
9206 return match;
9207 }
9208
9209 /**
9210 * Returns the default block variation for the given block type.
9211 * When there are multiple variations annotated as the default one,
9212 * the last added item is picked. This simplifies registering overrides.
9213 * When there is no default variation set, it returns the first item.
9214 *
9215 * @param {Object} state Data state.
9216 * @param {string} blockName Block type name.
9217 * @param {WPBlockVariationScope} [scope] Block variation scope name.
9218 *
9219 * @example
9220 * ```js
9221 * import { __, sprintf } from '@wordpress/i18n';
9222 * import { store as blocksStore } from '@wordpress/blocks';
9223 * import { useSelect } from '@wordpress/data';
9224 *
9225 * const ExampleComponent = () => {
9226 * const defaultEmbedBlockVariation = useSelect( ( select ) =>
9227 * select( blocksStore ).getDefaultBlockVariation( 'core/embed' ),
9228 * []
9229 * );
9230 *
9231 * return (
9232 * defaultEmbedBlockVariation && (
9233 * <p>
9234 * { sprintf(
9235 * __( 'core/embed default variation: %s' ),
9236 * defaultEmbedBlockVariation.title
9237 * ) }
9238 * </p>
9239 * )
9240 * );
9241 * };
9242 * ```
9243 *
9244 * @return {?WPBlockVariation} The default block variation.
9245 */
9246 function getDefaultBlockVariation(state, blockName, scope) {
9247 const variations = selectors_getBlockVariations(state, blockName, scope);
9248 const defaultVariation = [...variations].reverse().find(({
9249 isDefault
9250 }) => !!isDefault);
9251 return defaultVariation || variations[0];
9252 }
9253
9254 /**
9255 * Returns all the available block categories.
9256 *
9257 * @param {Object} state Data state.
9258 *
9259 * @example
9260 * ```js
9261 * import { store as blocksStore } from '@wordpress/blocks';
9262 * import { useSelect, } from '@wordpress/data';
9263 *
9264 * const ExampleComponent = () => {
9265 * const blockCategories = useSelect( ( select ) =>
9266 * select( blocksStore ).getCategories(),
9267 * []
9268 * );
9269 *
9270 * return (
9271 * <ul>
9272 * { blockCategories.map( ( category ) => (
9273 * <li key={ category.slug }>{ category.title }</li>
9274 * ) ) }
9275 * </ul>
9276 * );
9277 * };
9278 * ```
9279 *
9280 * @return {WPBlockCategory[]} Categories list.
9281 */
9282 function getCategories(state) {
9283 return state.categories;
9284 }
9285
9286 /**
9287 * Returns all the available collections.
9288 *
9289 * @param {Object} state Data state.
9290 *
9291 * @example
9292 * ```js
9293 * import { store as blocksStore } from '@wordpress/blocks';
9294 * import { useSelect } from '@wordpress/data';
9295 *
9296 * const ExampleComponent = () => {
9297 * const blockCollections = useSelect( ( select ) =>
9298 * select( blocksStore ).getCollections(),
9299 * []
9300 * );
9301 *
9302 * return (
9303 * <ul>
9304 * { Object.values( blockCollections ).length > 0 &&
9305 * Object.values( blockCollections ).map( ( collection ) => (
9306 * <li key={ collection.title }>{ collection.title }</li>
9307 * ) ) }
9308 * </ul>
9309 * );
9310 * };
9311 * ```
9312 *
9313 * @return {Object} Collections list.
9314 */
9315 function getCollections(state) {
9316 return state.collections;
9317 }
9318
9319 /**
9320 * Returns the name of the default block name.
9321 *
9322 * @param {Object} state Data state.
9323 *
9324 * @example
9325 * ```js
9326 * import { __, sprintf } from '@wordpress/i18n';
9327 * import { store as blocksStore } from '@wordpress/blocks';
9328 * import { useSelect } from '@wordpress/data';
9329 *
9330 * const ExampleComponent = () => {
9331 * const defaultBlockName = useSelect( ( select ) =>
9332 * select( blocksStore ).getDefaultBlockName(),
9333 * []
9334 * );
9335 *
9336 * return (
9337 * defaultBlockName && (
9338 * <p>
9339 * { sprintf( __( 'Default block name: %s' ), defaultBlockName ) }
9340 * </p>
9341 * )
9342 * );
9343 * };
9344 * ```
9345 *
9346 * @return {string?} Default block name.
9347 */
9348 function selectors_getDefaultBlockName(state) {
9349 return state.defaultBlockName;
9350 }
9351
9352 /**
9353 * Returns the name of the block for handling non-block content.
9354 *
9355 * @param {Object} state Data state.
9356 *
9357 * @example
9358 * ```js
9359 * import { __, sprintf } from '@wordpress/i18n';
9360 * import { store as blocksStore } from '@wordpress/blocks';
9361 * import { useSelect } from '@wordpress/data';
9362 *
9363 * const ExampleComponent = () => {
9364 * const freeformFallbackBlockName = useSelect( ( select ) =>
9365 * select( blocksStore ).getFreeformFallbackBlockName(),
9366 * []
9367 * );
9368 *
9369 * return (
9370 * freeformFallbackBlockName && (
9371 * <p>
9372 * { sprintf( __(
9373 * 'Freeform fallback block name: %s' ),
9374 * freeformFallbackBlockName
9375 * ) }
9376 * </p>
9377 * )
9378 * );
9379 * };
9380 * ```
9381 *
9382 * @return {string?} Name of the block for handling non-block content.
9383 */
9384 function getFreeformFallbackBlockName(state) {
9385 return state.freeformFallbackBlockName;
9386 }
9387
9388 /**
9389 * Returns the name of the block for handling unregistered blocks.
9390 *
9391 * @param {Object} state Data state.
9392 *
9393 * @example
9394 * ```js
9395 * import { __, sprintf } from '@wordpress/i18n';
9396 * import { store as blocksStore } from '@wordpress/blocks';
9397 * import { useSelect } from '@wordpress/data';
9398 *
9399 * const ExampleComponent = () => {
9400 * const unregisteredFallbackBlockName = useSelect( ( select ) =>
9401 * select( blocksStore ).getUnregisteredFallbackBlockName(),
9402 * []
9403 * );
9404 *
9405 * return (
9406 * unregisteredFallbackBlockName && (
9407 * <p>
9408 * { sprintf( __(
9409 * 'Unregistered fallback block name: %s' ),
9410 * unregisteredFallbackBlockName
9411 * ) }
9412 * </p>
9413 * )
9414 * );
9415 * };
9416 * ```
9417 *
9418 * @return {string?} Name of the block for handling unregistered blocks.
9419 */
9420 function getUnregisteredFallbackBlockName(state) {
9421 return state.unregisteredFallbackBlockName;
9422 }
9423
9424 /**
9425 * Returns the name of the block for handling the grouping of blocks.
9426 *
9427 * @param {Object} state Data state.
9428 *
9429 * @example
9430 * ```js
9431 * import { __, sprintf } from '@wordpress/i18n';
9432 * import { store as blocksStore } from '@wordpress/blocks';
9433 * import { useSelect } from '@wordpress/data';
9434 *
9435 * const ExampleComponent = () => {
9436 * const groupingBlockName = useSelect( ( select ) =>
9437 * select( blocksStore ).getGroupingBlockName(),
9438 * []
9439 * );
9440 *
9441 * return (
9442 * groupingBlockName && (
9443 * <p>
9444 * { sprintf(
9445 * __( 'Default grouping block name: %s' ),
9446 * groupingBlockName
9447 * ) }
9448 * </p>
9449 * )
9450 * );
9451 * };
9452 * ```
9453 *
9454 * @return {string?} Name of the block for handling the grouping of blocks.
9455 */
9456 function selectors_getGroupingBlockName(state) {
9457 return state.groupingBlockName;
9458 }
9459
9460 /**
9461 * Returns an array with the child blocks of a given block.
9462 *
9463 * @param {Object} state Data state.
9464 * @param {string} blockName Block type name.
9465 *
9466 * @example
9467 * ```js
9468 * import { store as blocksStore } from '@wordpress/blocks';
9469 * import { useSelect } from '@wordpress/data';
9470 *
9471 * const ExampleComponent = () => {
9472 * const childBlockNames = useSelect( ( select ) =>
9473 * select( blocksStore ).getChildBlockNames( 'core/navigation' ),
9474 * []
9475 * );
9476 *
9477 * return (
9478 * <ul>
9479 * { childBlockNames &&
9480 * childBlockNames.map( ( child ) => (
9481 * <li key={ child }>{ child }</li>
9482 * ) ) }
9483 * </ul>
9484 * );
9485 * };
9486 * ```
9487 *
9488 * @return {Array} Array of child block names.
9489 */
9490 const selectors_getChildBlockNames = rememo((state, blockName) => {
9491 return selectors_getBlockTypes(state).filter(blockType => {
9492 return blockType.parent?.includes(blockName);
9493 }).map(({
9494 name
9495 }) => name);
9496 }, state => [state.blockTypes]);
9497
9498 /**
9499 * Returns the block support value for a feature, if defined.
9500 *
9501 * @param {Object} state Data state.
9502 * @param {(string|Object)} nameOrType Block name or type object
9503 * @param {Array|string} feature Feature to retrieve
9504 * @param {*} defaultSupports Default value to return if not
9505 * explicitly defined
9506 *
9507 * @example
9508 * ```js
9509 * import { __, sprintf } from '@wordpress/i18n';
9510 * import { store as blocksStore } from '@wordpress/blocks';
9511 * import { useSelect } from '@wordpress/data';
9512 *
9513 * const ExampleComponent = () => {
9514 * const paragraphBlockSupportValue = useSelect( ( select ) =>
9515 * select( blocksStore ).getBlockSupport( 'core/paragraph', 'anchor' ),
9516 * []
9517 * );
9518 *
9519 * return (
9520 * <p>
9521 * { sprintf(
9522 * __( 'core/paragraph supports.anchor value: %s' ),
9523 * paragraphBlockSupportValue
9524 * ) }
9525 * </p>
9526 * );
9527 * };
9528 * ```
9529 *
9530 * @return {?*} Block support value
9531 */
9532 const selectors_getBlockSupport = (state, nameOrType, feature, defaultSupports) => {
9533 const blockType = getNormalizedBlockType(state, nameOrType);
9534 if (!blockType?.supports) {
9535 return defaultSupports;
9536 }
9537 return getValueFromObjectPath(blockType.supports, feature, defaultSupports);
9538 };
9539
9540 /**
9541 * Returns true if the block defines support for a feature, or false otherwise.
9542 *
9543 * @param {Object} state Data state.
9544 * @param {(string|Object)} nameOrType Block name or type object.
9545 * @param {string} feature Feature to test.
9546 * @param {boolean} defaultSupports Whether feature is supported by
9547 * default if not explicitly defined.
9548 *
9549 * @example
9550 * ```js
9551 * import { __, sprintf } from '@wordpress/i18n';
9552 * import { store as blocksStore } from '@wordpress/blocks';
9553 * import { useSelect } from '@wordpress/data';
9554 *
9555 * const ExampleComponent = () => {
9556 * const paragraphBlockSupportClassName = useSelect( ( select ) =>
9557 * select( blocksStore ).hasBlockSupport( 'core/paragraph', 'className' ),
9558 * []
9559 * );
9560 *
9561 * return (
9562 * <p>
9563 * { sprintf(
9564 * __( 'core/paragraph supports custom class name?: %s' ),
9565 * paragraphBlockSupportClassName
9566 * ) }
9567 * /p>
9568 * );
9569 * };
9570 * ```
9571 *
9572 * @return {boolean} Whether block supports feature.
9573 */
9574 function selectors_hasBlockSupport(state, nameOrType, feature, defaultSupports) {
9575 return !!selectors_getBlockSupport(state, nameOrType, feature, defaultSupports);
9576 }
9577
9578 /**
9579 * Returns true if the block type by the given name or object value matches a
9580 * search term, or false otherwise.
9581 *
9582 * @param {Object} state Blocks state.
9583 * @param {(string|Object)} nameOrType Block name or type object.
9584 * @param {string} searchTerm Search term by which to filter.
9585 *
9586 * @example
9587 * ```js
9588 * import { __, sprintf } from '@wordpress/i18n';
9589 * import { store as blocksStore } from '@wordpress/blocks';
9590 * import { useSelect } from '@wordpress/data';
9591 *
9592 * const ExampleComponent = () => {
9593 * const termFound = useSelect(
9594 * ( select ) =>
9595 * select( blocksStore ).isMatchingSearchTerm(
9596 * 'core/navigation',
9597 * 'theme'
9598 * ),
9599 * []
9600 * );
9601 *
9602 * return (
9603 * <p>
9604 * { sprintf(
9605 * __(
9606 * 'Search term was found in the title, keywords, category or description in block.json: %s'
9607 * ),
9608 * termFound
9609 * ) }
9610 * </p>
9611 * );
9612 * };
9613 * ```
9614 *
9615 * @return {Object[]} Whether block type matches search term.
9616 */
9617 function isMatchingSearchTerm(state, nameOrType, searchTerm) {
9618 const blockType = getNormalizedBlockType(state, nameOrType);
9619 const getNormalizedSearchTerm = (0,external_wp_compose_namespaceObject.pipe)([
9620 // Disregard diacritics.
9621 // Input: "média"
9622 term => remove_accents_default()(term !== null && term !== void 0 ? term : ''),
9623 // Lowercase.
9624 // Input: "MEDIA"
9625 term => term.toLowerCase(),
9626 // Strip leading and trailing whitespace.
9627 // Input: " media "
9628 term => term.trim()]);
9629 const normalizedSearchTerm = getNormalizedSearchTerm(searchTerm);
9630 const isSearchMatch = (0,external_wp_compose_namespaceObject.pipe)([getNormalizedSearchTerm, normalizedCandidate => normalizedCandidate.includes(normalizedSearchTerm)]);
9631 return isSearchMatch(blockType.title) || blockType.keywords?.some(isSearchMatch) || isSearchMatch(blockType.category) || typeof blockType.description === 'string' && isSearchMatch(blockType.description);
9632 }
9633
9634 /**
9635 * Returns a boolean indicating if a block has child blocks or not.
9636 *
9637 * @param {Object} state Data state.
9638 * @param {string} blockName Block type name.
9639 *
9640 * @example
9641 * ```js
9642 * import { __, sprintf } from '@wordpress/i18n';
9643 * import { store as blocksStore } from '@wordpress/blocks';
9644 * import { useSelect } from '@wordpress/data';
9645 *
9646 * const ExampleComponent = () => {
9647 * const navigationBlockHasChildBlocks = useSelect( ( select ) =>
9648 * select( blocksStore ).hasChildBlocks( 'core/navigation' ),
9649 * []
9650 * );
9651 *
9652 * return (
9653 * <p>
9654 * { sprintf(
9655 * __( 'core/navigation has child blocks: %s' ),
9656 * navigationBlockHasChildBlocks
9657 * ) }
9658 * </p>
9659 * );
9660 * };
9661 * ```
9662 *
9663 * @return {boolean} True if a block contains child blocks and false otherwise.
9664 */
9665 const selectors_hasChildBlocks = (state, blockName) => {
9666 return selectors_getChildBlockNames(state, blockName).length > 0;
9667 };
9668
9669 /**
9670 * Returns a boolean indicating if a block has at least one child block with inserter support.
9671 *
9672 * @param {Object} state Data state.
9673 * @param {string} blockName Block type name.
9674 *
9675 * @example
9676 * ```js
9677 * import { __, sprintf } from '@wordpress/i18n';
9678 * import { store as blocksStore } from '@wordpress/blocks';
9679 * import { useSelect } from '@wordpress/data';
9680 *
9681 * const ExampleComponent = () => {
9682 * const navigationBlockHasChildBlocksWithInserterSupport = useSelect( ( select ) =>
9683 * select( blocksStore ).hasChildBlocksWithInserterSupport(
9684 * 'core/navigation'
9685 * ),
9686 * []
9687 * );
9688 *
9689 * return (
9690 * <p>
9691 * { sprintf(
9692 * __( 'core/navigation has child blocks with inserter support: %s' ),
9693 * navigationBlockHasChildBlocksWithInserterSupport
9694 * ) }
9695 * </p>
9696 * );
9697 * };
9698 * ```
9699 *
9700 * @return {boolean} True if a block contains at least one child blocks with inserter support
9701 * and false otherwise.
9702 */
9703 const selectors_hasChildBlocksWithInserterSupport = (state, blockName) => {
9704 return selectors_getChildBlockNames(state, blockName).some(childBlockName => {
9705 return selectors_hasBlockSupport(state, childBlockName, 'inserter', true);
9706 });
9707 };
9708
9709 /**
9710 * DO-NOT-USE in production.
9711 * This selector is created for internal/experimental only usage and may be
9712 * removed anytime without any warning, causing breakage on any plugin or theme invoking it.
9713 */
9714 const __experimentalHasContentRoleAttribute = rememo((state, blockTypeName) => {
9715 const blockType = selectors_getBlockType(state, blockTypeName);
9716 if (!blockType) {
9717 return false;
9718 }
9719 return Object.entries(blockType.attributes).some(([, {
9720 __experimentalRole
9721 }]) => __experimentalRole === 'content');
9722 }, (state, blockTypeName) => [state.blockTypes[blockTypeName]?.attributes]);
9723
9724 ;// CONCATENATED MODULE: ./packages/blocks/build-module/store/private-selectors.js
9725 /**
9726 * External dependencies
9727 */
9728
9729
9730 /**
9731 * Internal dependencies
9732 */
9733
9734
9735
9736 const ROOT_BLOCK_SUPPORTS = ['background', 'backgroundColor', 'color', 'linkColor', 'captionColor', 'buttonColor', 'headingColor', 'fontFamily', 'fontSize', 'fontStyle', 'fontWeight', 'lineHeight', 'padding', 'contentSize', 'wideSize', 'blockGap', 'textDecoration', 'textTransform', 'letterSpacing'];
9737
9738 /**
9739 * Filters the list of supported styles for a given element.
9740 *
9741 * @param {string[]} blockSupports list of supported styles.
9742 * @param {string|undefined} name block name.
9743 * @param {string|undefined} element element name.
9744 *
9745 * @return {string[]} filtered list of supported styles.
9746 */
9747 function filterElementBlockSupports(blockSupports, name, element) {
9748 return blockSupports.filter(support => {
9749 if (support === 'fontSize' && element === 'heading') {
9750 return false;
9751 }
9752
9753 // This is only available for links
9754 if (support === 'textDecoration' && !name && element !== 'link') {
9755 return false;
9756 }
9757
9758 // This is only available for heading
9759 if (support === 'textTransform' && !name && !['heading', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(element)) {
9760 return false;
9761 }
9762
9763 // This is only available for headings
9764 if (support === 'letterSpacing' && !name && !['heading', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(element)) {
9765 return false;
9766 }
9767
9768 // Text columns is only available for blocks.
9769 if (support === 'textColumns' && !name) {
9770 return false;
9771 }
9772 return true;
9773 });
9774 }
9775
9776 /**
9777 * Returns the list of supported styles for a given block name and element.
9778 */
9779 const getSupportedStyles = rememo((state, name, element) => {
9780 if (!name) {
9781 return filterElementBlockSupports(ROOT_BLOCK_SUPPORTS, name, element);
9782 }
9783 const blockType = selectors_getBlockType(state, name);
9784 if (!blockType) {
9785 return [];
9786 }
9787 const supportKeys = [];
9788
9789 // Check for blockGap support.
9790 // Block spacing support doesn't map directly to a single style property, so needs to be handled separately.
9791 // Also, only allow `blockGap` support if serialization has not been skipped, to be sure global spacing can be applied.
9792 if (blockType?.supports?.spacing?.blockGap && blockType?.supports?.spacing?.__experimentalSkipSerialization !== true && !blockType?.supports?.spacing?.__experimentalSkipSerialization?.some?.(spacingType => spacingType === 'blockGap')) {
9793 supportKeys.push('blockGap');
9794 }
9795
9796 // check for shadow support
9797 if (blockType?.supports?.shadow) {
9798 supportKeys.push('shadow');
9799 }
9800 Object.keys(__EXPERIMENTAL_STYLE_PROPERTY).forEach(styleName => {
9801 if (!__EXPERIMENTAL_STYLE_PROPERTY[styleName].support) {
9802 return;
9803 }
9804
9805 // Opting out means that, for certain support keys like background color,
9806 // blocks have to explicitly set the support value false. If the key is
9807 // unset, we still enable it.
9808 if (__EXPERIMENTAL_STYLE_PROPERTY[styleName].requiresOptOut) {
9809 if (__EXPERIMENTAL_STYLE_PROPERTY[styleName].support[0] in blockType.supports && getValueFromObjectPath(blockType.supports, __EXPERIMENTAL_STYLE_PROPERTY[styleName].support) !== false) {
9810 supportKeys.push(styleName);
9811 return;
9812 }
9813 }
9814 if (getValueFromObjectPath(blockType.supports, __EXPERIMENTAL_STYLE_PROPERTY[styleName].support, false)) {
9815 supportKeys.push(styleName);
9816 }
9817 });
9818 return filterElementBlockSupports(supportKeys, name, element);
9819 }, (state, name) => [state.blockTypes[name]]);
9820
9821 ;// CONCATENATED MODULE: ./node_modules/is-plain-object/dist/is-plain-object.mjs
9822 /*!
9823 * is-plain-object <https://github.com/jonschlinkert/is-plain-object>
9824 *
9825 * Copyright (c) 2014-2017, Jon Schlinkert.
9826 * Released under the MIT License.
9827 */
9828
9829 function is_plain_object_isObject(o) {
9830 return Object.prototype.toString.call(o) === '[object Object]';
9831 }
9832
9833 function isPlainObject(o) {
9834 var ctor,prot;
9835
9836 if (is_plain_object_isObject(o) === false) return false;
9837
9838 // If has modified constructor
9839 ctor = o.constructor;
9840 if (ctor === undefined) return true;
9841
9842 // If has modified prototype
9843 prot = ctor.prototype;
9844 if (is_plain_object_isObject(prot) === false) return false;
9845
9846 // If constructor does not have an Object-specific method
9847 if (prot.hasOwnProperty('isPrototypeOf') === false) {
9848 return false;
9849 }
9850
9851 // Most likely a plain Object
9852 return true;
9853 }
9854
9855
9856
9857 ;// CONCATENATED MODULE: external ["wp","deprecated"]
9858 const external_wp_deprecated_namespaceObject = window["wp"]["deprecated"];
9859 var external_wp_deprecated_default = /*#__PURE__*/__webpack_require__.n(external_wp_deprecated_namespaceObject);
9860 ;// CONCATENATED MODULE: ./packages/blocks/build-module/store/actions.js
9861 /**
9862 * External dependencies
9863 */
9864
9865
9866 /**
9867 * WordPress dependencies
9868 */
9869
9870
9871
9872 /**
9873 * Internal dependencies
9874 */
9875
9876
9877
9878 /** @typedef {import('../api/registration').WPBlockVariation} WPBlockVariation */
9879 /** @typedef {import('../api/registration').WPBlockType} WPBlockType */
9880 /** @typedef {import('./reducer').WPBlockCategory} WPBlockCategory */
9881
9882 const {
9883 error,
9884 warn
9885 } = window.console;
9886
9887 /**
9888 * Mapping of legacy category slugs to their latest normal values, used to
9889 * accommodate updates of the default set of block categories.
9890 *
9891 * @type {Record<string,string>}
9892 */
9893 const LEGACY_CATEGORY_MAPPING = {
9894 common: 'text',
9895 formatting: 'text',
9896 layout: 'design'
9897 };
9898
9899 /**
9900 * Whether the argument is a function.
9901 *
9902 * @param {*} maybeFunc The argument to check.
9903 * @return {boolean} True if the argument is a function, false otherwise.
9904 */
9905 function isFunction(maybeFunc) {
9906 return typeof maybeFunc === 'function';
9907 }
9908
9909 /**
9910 * Takes the unprocessed block type data and applies all the existing filters for the registered block type.
9911 * Next, it validates all the settings and performs additional processing to the block type definition.
9912 *
9913 * @param {WPBlockType} blockType Unprocessed block type settings.
9914 * @param {Object} thunkArgs Argument object for the thunk middleware.
9915 * @param {Function} thunkArgs.select Function to select from the store.
9916 *
9917 * @return {WPBlockType | undefined} The block, if it has been successfully registered; otherwise `undefined`.
9918 */
9919 const processBlockType = (blockType, {
9920 select
9921 }) => {
9922 const {
9923 name
9924 } = blockType;
9925 const settings = (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.registerBlockType', {
9926 ...blockType
9927 }, name, null);
9928 if (settings.description && typeof settings.description !== 'string') {
9929 external_wp_deprecated_default()('Declaring non-string block descriptions', {
9930 since: '6.2'
9931 });
9932 }
9933 if (settings.deprecated) {
9934 settings.deprecated = settings.deprecated.map(deprecation => Object.fromEntries(Object.entries(
9935 // Only keep valid deprecation keys.
9936 (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.registerBlockType',
9937 // Merge deprecation keys with pre-filter settings
9938 // so that filters that depend on specific keys being
9939 // present don't fail.
9940 {
9941 // Omit deprecation keys here so that deprecations
9942 // can opt out of specific keys like "supports".
9943 ...omit(blockType, DEPRECATED_ENTRY_KEYS),
9944 ...deprecation
9945 }, name, deprecation)).filter(([key]) => DEPRECATED_ENTRY_KEYS.includes(key))));
9946 }
9947 if (!isPlainObject(settings)) {
9948 error('Block settings must be a valid object.');
9949 return;
9950 }
9951 if (!isFunction(settings.save)) {
9952 error('The "save" property must be a valid function.');
9953 return;
9954 }
9955 if ('edit' in settings && !isFunction(settings.edit)) {
9956 error('The "edit" property must be a valid function.');
9957 return;
9958 }
9959
9960 // Canonicalize legacy categories to equivalent fallback.
9961 if (LEGACY_CATEGORY_MAPPING.hasOwnProperty(settings.category)) {
9962 settings.category = LEGACY_CATEGORY_MAPPING[settings.category];
9963 }
9964 if ('category' in settings && !select.getCategories().some(({
9965 slug
9966 }) => slug === settings.category)) {
9967 warn('The block "' + name + '" is registered with an invalid category "' + settings.category + '".');
9968 delete settings.category;
9969 }
9970 if (!('title' in settings) || settings.title === '') {
9971 error('The block "' + name + '" must have a title.');
9972 return;
9973 }
9974 if (typeof settings.title !== 'string') {
9975 error('Block titles must be strings.');
9976 return;
9977 }
9978 settings.icon = normalizeIconObject(settings.icon);
9979 if (!isValidIcon(settings.icon.src)) {
9980 error('The icon passed is invalid. ' + 'The icon should be a string, an element, a function, or an object following the specifications documented in https://developer.wordpress.org/block-editor/developers/block-api/block-registration/#icon-optional');
9981 return;
9982 }
9983 return settings;
9984 };
9985
9986 /**
9987 * Returns an action object used in signalling that block types have been added.
9988 * Ignored from documentation as the recommended usage for this action through registerBlockType from @wordpress/blocks.
9989 *
9990 * @ignore
9991 *
9992 * @param {WPBlockType|WPBlockType[]} blockTypes Object or array of objects representing blocks to added.
9993 *
9994 *
9995 * @return {Object} Action object.
9996 */
9997 function addBlockTypes(blockTypes) {
9998 return {
9999 type: 'ADD_BLOCK_TYPES',
10000 blockTypes: Array.isArray(blockTypes) ? blockTypes : [blockTypes]
10001 };
10002 }
10003
10004 /**
10005 * Signals that the passed block type's settings should be stored in the state.
10006 *
10007 * @param {WPBlockType} blockType Unprocessed block type settings.
10008 */
10009 const __experimentalRegisterBlockType = blockType => ({
10010 dispatch,
10011 select
10012 }) => {
10013 dispatch({
10014 type: 'ADD_UNPROCESSED_BLOCK_TYPE',
10015 blockType
10016 });
10017 const processedBlockType = processBlockType(blockType, {
10018 select
10019 });
10020 if (!processedBlockType) {
10021 return;
10022 }
10023 dispatch.addBlockTypes(processedBlockType);
10024 };
10025
10026 /**
10027 * Signals that all block types should be computed again.
10028 * It uses stored unprocessed block types and all the most recent list of registered filters.
10029 *
10030 * It addresses the issue where third party block filters get registered after third party blocks. A sample sequence:
10031 * 1. Filter A.
10032 * 2. Block B.
10033 * 3. Block C.
10034 * 4. Filter D.
10035 * 5. Filter E.
10036 * 6. Block F.
10037 * 7. Filter G.
10038 * In this scenario some filters would not get applied for all blocks because they are registered too late.
10039 */
10040 const __experimentalReapplyBlockTypeFilters = () => ({
10041 dispatch,
10042 select
10043 }) => {
10044 const unprocessedBlockTypes = select.__experimentalGetUnprocessedBlockTypes();
10045 const processedBlockTypes = Object.keys(unprocessedBlockTypes).reduce((accumulator, blockName) => {
10046 const result = processBlockType(unprocessedBlockTypes[blockName], {
10047 select
10048 });
10049 if (result) {
10050 accumulator.push(result);
10051 }
10052 return accumulator;
10053 }, []);
10054 if (!processedBlockTypes.length) {
10055 return;
10056 }
10057 dispatch.addBlockTypes(processedBlockTypes);
10058 };
10059
10060 /**
10061 * Returns an action object used to remove a registered block type.
10062 * Ignored from documentation as the recommended usage for this action through unregisterBlockType from @wordpress/blocks.
10063 *
10064 * @ignore
10065 *
10066 * @param {string|string[]} names Block name or array of block names to be removed.
10067 *
10068 *
10069 * @return {Object} Action object.
10070 */
10071 function removeBlockTypes(names) {
10072 return {
10073 type: 'REMOVE_BLOCK_TYPES',
10074 names: Array.isArray(names) ? names : [names]
10075 };
10076 }
10077
10078 /**
10079 * Returns an action object used in signalling that new block styles have been added.
10080 * Ignored from documentation as the recommended usage for this action through registerBlockStyle from @wordpress/blocks.
10081 *
10082 * @param {string} blockName Block name.
10083 * @param {Array|Object} styles Block style object or array of block style objects.
10084 *
10085 * @ignore
10086 *
10087 * @return {Object} Action object.
10088 */
10089 function addBlockStyles(blockName, styles) {
10090 return {
10091 type: 'ADD_BLOCK_STYLES',
10092 styles: Array.isArray(styles) ? styles : [styles],
10093 blockName
10094 };
10095 }
10096
10097 /**
10098 * Returns an action object used in signalling that block styles have been removed.
10099 * Ignored from documentation as the recommended usage for this action through unregisterBlockStyle from @wordpress/blocks.
10100 *
10101 * @ignore
10102 *
10103 * @param {string} blockName Block name.
10104 * @param {Array|string} styleNames Block style names or array of block style names.
10105 *
10106 * @return {Object} Action object.
10107 */
10108 function removeBlockStyles(blockName, styleNames) {
10109 return {
10110 type: 'REMOVE_BLOCK_STYLES',
10111 styleNames: Array.isArray(styleNames) ? styleNames : [styleNames],
10112 blockName
10113 };
10114 }
10115
10116 /**
10117 * Returns an action object used in signalling that new block variations have been added.
10118 * Ignored from documentation as the recommended usage for this action through registerBlockVariation from @wordpress/blocks.
10119 *
10120 * @ignore
10121 *
10122 * @param {string} blockName Block name.
10123 * @param {WPBlockVariation|WPBlockVariation[]} variations Block variations.
10124 *
10125 * @return {Object} Action object.
10126 */
10127 function addBlockVariations(blockName, variations) {
10128 return {
10129 type: 'ADD_BLOCK_VARIATIONS',
10130 variations: Array.isArray(variations) ? variations : [variations],
10131 blockName
10132 };
10133 }
10134
10135 /**
10136 * Returns an action object used in signalling that block variations have been removed.
10137 * Ignored from documentation as the recommended usage for this action through unregisterBlockVariation from @wordpress/blocks.
10138 *
10139 * @ignore
10140 *
10141 * @param {string} blockName Block name.
10142 * @param {string|string[]} variationNames Block variation names.
10143 *
10144 * @return {Object} Action object.
10145 */
10146 function removeBlockVariations(blockName, variationNames) {
10147 return {
10148 type: 'REMOVE_BLOCK_VARIATIONS',
10149 variationNames: Array.isArray(variationNames) ? variationNames : [variationNames],
10150 blockName
10151 };
10152 }
10153
10154 /**
10155 * Returns an action object used to set the default block name.
10156 * Ignored from documentation as the recommended usage for this action through setDefaultBlockName from @wordpress/blocks.
10157 *
10158 * @ignore
10159 *
10160 * @param {string} name Block name.
10161 *
10162 * @return {Object} Action object.
10163 */
10164 function actions_setDefaultBlockName(name) {
10165 return {
10166 type: 'SET_DEFAULT_BLOCK_NAME',
10167 name
10168 };
10169 }
10170
10171 /**
10172 * Returns an action object used to set the name of the block used as a fallback
10173 * for non-block content.
10174 * Ignored from documentation as the recommended usage for this action through setFreeformContentHandlerName from @wordpress/blocks.
10175 *
10176 * @ignore
10177 *
10178 * @param {string} name Block name.
10179 *
10180 * @return {Object} Action object.
10181 */
10182 function setFreeformFallbackBlockName(name) {
10183 return {
10184 type: 'SET_FREEFORM_FALLBACK_BLOCK_NAME',
10185 name
10186 };
10187 }
10188
10189 /**
10190 * Returns an action object used to set the name of the block used as a fallback
10191 * for unregistered blocks.
10192 * Ignored from documentation as the recommended usage for this action through setUnregisteredTypeHandlerName from @wordpress/blocks.
10193 *
10194 * @ignore
10195 *
10196 * @param {string} name Block name.
10197 *
10198 * @return {Object} Action object.
10199 */
10200 function setUnregisteredFallbackBlockName(name) {
10201 return {
10202 type: 'SET_UNREGISTERED_FALLBACK_BLOCK_NAME',
10203 name
10204 };
10205 }
10206
10207 /**
10208 * Returns an action object used to set the name of the block used
10209 * when grouping other blocks
10210 * eg: in "Group/Ungroup" interactions
10211 * Ignored from documentation as the recommended usage for this action through setGroupingBlockName from @wordpress/blocks.
10212 *
10213 * @ignore
10214 *
10215 * @param {string} name Block name.
10216 *
10217 * @return {Object} Action object.
10218 */
10219 function actions_setGroupingBlockName(name) {
10220 return {
10221 type: 'SET_GROUPING_BLOCK_NAME',
10222 name
10223 };
10224 }
10225
10226 /**
10227 * Returns an action object used to set block categories.
10228 * Ignored from documentation as the recommended usage for this action through setCategories from @wordpress/blocks.
10229 *
10230 * @ignore
10231 *
10232 * @param {WPBlockCategory[]} categories Block categories.
10233 *
10234 * @return {Object} Action object.
10235 */
10236 function setCategories(categories) {
10237 return {
10238 type: 'SET_CATEGORIES',
10239 categories
10240 };
10241 }
10242
10243 /**
10244 * Returns an action object used to update a category.
10245 * Ignored from documentation as the recommended usage for this action through updateCategory from @wordpress/blocks.
10246 *
10247 * @ignore
10248 *
10249 * @param {string} slug Block category slug.
10250 * @param {Object} category Object containing the category properties that should be updated.
10251 *
10252 * @return {Object} Action object.
10253 */
10254 function updateCategory(slug, category) {
10255 return {
10256 type: 'UPDATE_CATEGORY',
10257 slug,
10258 category
10259 };
10260 }
10261
10262 /**
10263 * Returns an action object used to add block collections
10264 * Ignored from documentation as the recommended usage for this action through registerBlockCollection from @wordpress/blocks.
10265 *
10266 * @ignore
10267 *
10268 * @param {string} namespace The namespace of the blocks to put in the collection
10269 * @param {string} title The title to display in the block inserter
10270 * @param {Object} icon (optional) The icon to display in the block inserter
10271 *
10272 * @return {Object} Action object.
10273 */
10274 function addBlockCollection(namespace, title, icon) {
10275 return {
10276 type: 'ADD_BLOCK_COLLECTION',
10277 namespace,
10278 title,
10279 icon
10280 };
10281 }
10282
10283 /**
10284 * Returns an action object used to remove block collections
10285 * Ignored from documentation as the recommended usage for this action through unregisterBlockCollection from @wordpress/blocks.
10286 *
10287 * @ignore
10288 *
10289 * @param {string} namespace The namespace of the blocks to put in the collection
10290 *
10291 * @return {Object} Action object.
10292 */
10293 function removeBlockCollection(namespace) {
10294 return {
10295 type: 'REMOVE_BLOCK_COLLECTION',
10296 namespace
10297 };
10298 }
10299
10300 ;// CONCATENATED MODULE: ./packages/blocks/build-module/store/constants.js
10301 const STORE_NAME = 'core/blocks';
10302
10303 ;// CONCATENATED MODULE: external ["wp","privateApis"]
10304 const external_wp_privateApis_namespaceObject = window["wp"]["privateApis"];
10305 ;// CONCATENATED MODULE: ./packages/blocks/build-module/lock-unlock.js
10306 /**
10307 * WordPress dependencies
10308 */
10309
10310 const {
10311 lock,
10312 unlock
10313 } = (0,external_wp_privateApis_namespaceObject.__dangerousOptInToUnstableAPIsOnlyForCoreModules)('I know using unstable features means my plugin or theme will inevitably break on the next WordPress release.', '@wordpress/blocks');
10314
10315 ;// CONCATENATED MODULE: ./packages/blocks/build-module/store/index.js
10316 /**
10317 * WordPress dependencies
10318 */
10319
10320
10321 /**
10322 * Internal dependencies
10323 */
10324
10325
10326
10327
10328
10329
10330
10331 /**
10332 * Store definition for the blocks namespace.
10333 *
10334 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#createReduxStore
10335 *
10336 * @type {Object}
10337 */
10338 const store = (0,external_wp_data_namespaceObject.createReduxStore)(STORE_NAME, {
10339 reducer: reducer,
10340 selectors: selectors_namespaceObject,
10341 actions: actions_namespaceObject
10342 });
10343 (0,external_wp_data_namespaceObject.register)(store);
10344 unlock(store).registerPrivateSelectors(private_selectors_namespaceObject);
10345
10346 ;// CONCATENATED MODULE: external ["wp","blockSerializationDefaultParser"]
10347 const external_wp_blockSerializationDefaultParser_namespaceObject = window["wp"]["blockSerializationDefaultParser"];
10348 ;// CONCATENATED MODULE: external ["wp","autop"]
10349 const external_wp_autop_namespaceObject = window["wp"]["autop"];
10350 ;// CONCATENATED MODULE: external ["wp","isShallowEqual"]
10351 const external_wp_isShallowEqual_namespaceObject = window["wp"]["isShallowEqual"];
10352 var external_wp_isShallowEqual_default = /*#__PURE__*/__webpack_require__.n(external_wp_isShallowEqual_namespaceObject);
10353 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/parser/serialize-raw-block.js
10354 /**
10355 * Internal dependencies
10356 */
10357
10358
10359 /**
10360 * @typedef {Object} Options Serialization options.
10361 * @property {boolean} [isCommentDelimited=true] Whether to output HTML comments around blocks.
10362 */
10363
10364 /** @typedef {import("./").WPRawBlock} WPRawBlock */
10365
10366 /**
10367 * Serializes a block node into the native HTML-comment-powered block format.
10368 * CAVEAT: This function is intended for re-serializing blocks as parsed by
10369 * valid parsers and skips any validation steps. This is NOT a generic
10370 * serialization function for in-memory blocks. For most purposes, see the
10371 * following functions available in the `@wordpress/blocks` package:
10372 *
10373 * @see serializeBlock
10374 * @see serialize
10375 *
10376 * For more on the format of block nodes as returned by valid parsers:
10377 *
10378 * @see `@wordpress/block-serialization-default-parser` package
10379 * @see `@wordpress/block-serialization-spec-parser` package
10380 *
10381 * @param {WPRawBlock} rawBlock A block node as returned by a valid parser.
10382 * @param {Options} [options={}] Serialization options.
10383 *
10384 * @return {string} An HTML string representing a block.
10385 */
10386 function serializeRawBlock(rawBlock, options = {}) {
10387 const {
10388 isCommentDelimited = true
10389 } = options;
10390 const {
10391 blockName,
10392 attrs = {},
10393 innerBlocks = [],
10394 innerContent = []
10395 } = rawBlock;
10396 let childIndex = 0;
10397 const content = innerContent.map(item =>
10398 // `null` denotes a nested block, otherwise we have an HTML fragment.
10399 item !== null ? item : serializeRawBlock(innerBlocks[childIndex++], options)).join('\n').replace(/\n+/g, '\n').trim();
10400 return isCommentDelimited ? getCommentDelimitedContent(blockName, attrs, content) : content;
10401 }
10402
10403 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/serializer.js
10404
10405 /**
10406 * WordPress dependencies
10407 */
10408
10409
10410
10411
10412
10413 /**
10414 * Internal dependencies
10415 */
10416
10417
10418
10419
10420 /** @typedef {import('./parser').WPBlock} WPBlock */
10421
10422 /**
10423 * @typedef {Object} WPBlockSerializationOptions Serialization Options.
10424 *
10425 * @property {boolean} isInnerBlocks Whether we are serializing inner blocks.
10426 */
10427
10428 /**
10429 * Returns the block's default classname from its name.
10430 *
10431 * @param {string} blockName The block name.
10432 *
10433 * @return {string} The block's default class.
10434 */
10435 function getBlockDefaultClassName(blockName) {
10436 // Generated HTML classes for blocks follow the `wp-block-{name}` nomenclature.
10437 // Blocks provided by WordPress drop the prefixes 'core/' or 'core-' (historically used in 'core-embed/').
10438 const className = 'wp-block-' + blockName.replace(/\//, '-').replace(/^core-/, '');
10439 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getBlockDefaultClassName', className, blockName);
10440 }
10441
10442 /**
10443 * Returns the block's default menu item classname from its name.
10444 *
10445 * @param {string} blockName The block name.
10446 *
10447 * @return {string} The block's default menu item class.
10448 */
10449 function getBlockMenuDefaultClassName(blockName) {
10450 // Generated HTML classes for blocks follow the `editor-block-list-item-{name}` nomenclature.
10451 // Blocks provided by WordPress drop the prefixes 'core/' or 'core-' (historically used in 'core-embed/').
10452 const className = 'editor-block-list-item-' + blockName.replace(/\//, '-').replace(/^core-/, '');
10453 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getBlockMenuDefaultClassName', className, blockName);
10454 }
10455 const blockPropsProvider = {};
10456 const innerBlocksPropsProvider = {};
10457
10458 /**
10459 * Call within a save function to get the props for the block wrapper.
10460 *
10461 * @param {Object} props Optional. Props to pass to the element.
10462 */
10463 function getBlockProps(props = {}) {
10464 const {
10465 blockType,
10466 attributes
10467 } = blockPropsProvider;
10468 return getBlockProps.skipFilters ? props : (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getSaveContent.extraProps', {
10469 ...props
10470 }, blockType, attributes);
10471 }
10472
10473 /**
10474 * Call within a save function to get the props for the inner blocks wrapper.
10475 *
10476 * @param {Object} props Optional. Props to pass to the element.
10477 */
10478 function getInnerBlocksProps(props = {}) {
10479 const {
10480 innerBlocks
10481 } = innerBlocksPropsProvider;
10482 // Allow a different component to be passed to getSaveElement to handle
10483 // inner blocks, bypassing the default serialisation.
10484 if (!Array.isArray(innerBlocks)) {
10485 return {
10486 ...props,
10487 children: innerBlocks
10488 };
10489 }
10490 // Value is an array of blocks, so defer to block serializer.
10491 const html = serialize(innerBlocks, {
10492 isInnerBlocks: true
10493 });
10494 // Use special-cased raw HTML tag to avoid default escaping.
10495 const children = (0,external_wp_element_namespaceObject.createElement)(external_wp_element_namespaceObject.RawHTML, null, html);
10496 return {
10497 ...props,
10498 children
10499 };
10500 }
10501
10502 /**
10503 * Given a block type containing a save render implementation and attributes, returns the
10504 * enhanced element to be saved or string when raw HTML expected.
10505 *
10506 * @param {string|Object} blockTypeOrName Block type or name.
10507 * @param {Object} attributes Block attributes.
10508 * @param {?Array} innerBlocks Nested blocks.
10509 *
10510 * @return {Object|string} Save element or raw HTML string.
10511 */
10512 function getSaveElement(blockTypeOrName, attributes, innerBlocks = []) {
10513 const blockType = normalizeBlockType(blockTypeOrName);
10514 if (!blockType?.save) return null;
10515 let {
10516 save
10517 } = blockType;
10518
10519 // Component classes are unsupported for save since serialization must
10520 // occur synchronously. For improved interoperability with higher-order
10521 // components which often return component class, emulate basic support.
10522 if (save.prototype instanceof external_wp_element_namespaceObject.Component) {
10523 const instance = new save({
10524 attributes
10525 });
10526 save = instance.render.bind(instance);
10527 }
10528 blockPropsProvider.blockType = blockType;
10529 blockPropsProvider.attributes = attributes;
10530 innerBlocksPropsProvider.innerBlocks = innerBlocks;
10531 let element = save({
10532 attributes,
10533 innerBlocks
10534 });
10535 if (element !== null && typeof element === 'object' && (0,external_wp_hooks_namespaceObject.hasFilter)('blocks.getSaveContent.extraProps') && !(blockType.apiVersion > 1)) {
10536 /**
10537 * Filters the props applied to the block save result element.
10538 *
10539 * @param {Object} props Props applied to save element.
10540 * @param {WPBlock} blockType Block type definition.
10541 * @param {Object} attributes Block attributes.
10542 */
10543 const props = (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getSaveContent.extraProps', {
10544 ...element.props
10545 }, blockType, attributes);
10546 if (!external_wp_isShallowEqual_default()(props, element.props)) {
10547 element = (0,external_wp_element_namespaceObject.cloneElement)(element, props);
10548 }
10549 }
10550
10551 /**
10552 * Filters the save result of a block during serialization.
10553 *
10554 * @param {WPElement} element Block save result.
10555 * @param {WPBlock} blockType Block type definition.
10556 * @param {Object} attributes Block attributes.
10557 */
10558 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getSaveElement', element, blockType, attributes);
10559 }
10560
10561 /**
10562 * Given a block type containing a save render implementation and attributes, returns the
10563 * static markup to be saved.
10564 *
10565 * @param {string|Object} blockTypeOrName Block type or name.
10566 * @param {Object} attributes Block attributes.
10567 * @param {?Array} innerBlocks Nested blocks.
10568 *
10569 * @return {string} Save content.
10570 */
10571 function getSaveContent(blockTypeOrName, attributes, innerBlocks) {
10572 const blockType = normalizeBlockType(blockTypeOrName);
10573 return (0,external_wp_element_namespaceObject.renderToString)(getSaveElement(blockType, attributes, innerBlocks));
10574 }
10575
10576 /**
10577 * Returns attributes which are to be saved and serialized into the block
10578 * comment delimiter.
10579 *
10580 * When a block exists in memory it contains as its attributes both those
10581 * parsed the block comment delimiter _and_ those which matched from the
10582 * contents of the block.
10583 *
10584 * This function returns only those attributes which are needed to persist and
10585 * which cannot be matched from the block content.
10586 *
10587 * @param {Object<string,*>} blockType Block type.
10588 * @param {Object<string,*>} attributes Attributes from in-memory block data.
10589 *
10590 * @return {Object<string,*>} Subset of attributes for comment serialization.
10591 */
10592 function getCommentAttributes(blockType, attributes) {
10593 var _blockType$attributes;
10594 return Object.entries((_blockType$attributes = blockType.attributes) !== null && _blockType$attributes !== void 0 ? _blockType$attributes : {}).reduce((accumulator, [key, attributeSchema]) => {
10595 const value = attributes[key];
10596 // Ignore undefined values.
10597 if (undefined === value) {
10598 return accumulator;
10599 }
10600
10601 // Ignore all attributes but the ones with an "undefined" source
10602 // "undefined" source refers to attributes saved in the block comment.
10603 if (attributeSchema.source !== undefined) {
10604 return accumulator;
10605 }
10606
10607 // Ignore default value.
10608 if ('default' in attributeSchema && JSON.stringify(attributeSchema.default) === JSON.stringify(value)) {
10609 return accumulator;
10610 }
10611
10612 // Otherwise, include in comment set.
10613 accumulator[key] = value;
10614 return accumulator;
10615 }, {});
10616 }
10617
10618 /**
10619 * Given an attributes object, returns a string in the serialized attributes
10620 * format prepared for post content.
10621 *
10622 * @param {Object} attributes Attributes object.
10623 *
10624 * @return {string} Serialized attributes.
10625 */
10626 function serializeAttributes(attributes) {
10627 return JSON.stringify(attributes)
10628 // Don't break HTML comments.
10629 .replace(/--/g, '\\u002d\\u002d')
10630
10631 // Don't break non-standard-compliant tools.
10632 .replace(/</g, '\\u003c').replace(/>/g, '\\u003e').replace(/&/g, '\\u0026')
10633
10634 // Bypass server stripslashes behavior which would unescape stringify's
10635 // escaping of quotation mark.
10636 //
10637 // See: https://developer.wordpress.org/reference/functions/wp_kses_stripslashes/
10638 .replace(/\\"/g, '\\u0022');
10639 }
10640
10641 /**
10642 * Given a block object, returns the Block's Inner HTML markup.
10643 *
10644 * @param {Object} block Block instance.
10645 *
10646 * @return {string} HTML.
10647 */
10648 function getBlockInnerHTML(block) {
10649 // If block was parsed as invalid or encounters an error while generating
10650 // save content, use original content instead to avoid content loss. If a
10651 // block contains nested content, exempt it from this condition because we
10652 // otherwise have no access to its original content and content loss would
10653 // still occur.
10654 let saveContent = block.originalContent;
10655 if (block.isValid || block.innerBlocks.length) {
10656 try {
10657 saveContent = getSaveContent(block.name, block.attributes, block.innerBlocks);
10658 } catch (error) {}
10659 }
10660 return saveContent;
10661 }
10662
10663 /**
10664 * Returns the content of a block, including comment delimiters.
10665 *
10666 * @param {string} rawBlockName Block name.
10667 * @param {Object} attributes Block attributes.
10668 * @param {string} content Block save content.
10669 *
10670 * @return {string} Comment-delimited block content.
10671 */
10672 function getCommentDelimitedContent(rawBlockName, attributes, content) {
10673 const serializedAttributes = attributes && Object.entries(attributes).length ? serializeAttributes(attributes) + ' ' : '';
10674
10675 // Strip core blocks of their namespace prefix.
10676 const blockName = rawBlockName?.startsWith('core/') ? rawBlockName.slice(5) : rawBlockName;
10677
10678 // @todo make the `wp:` prefix potentially configurable.
10679
10680 if (!content) {
10681 return `<!-- wp:${blockName} ${serializedAttributes}/-->`;
10682 }
10683 return `<!-- wp:${blockName} ${serializedAttributes}-->\n` + content + `\n<!-- /wp:${blockName} -->`;
10684 }
10685
10686 /**
10687 * Returns the content of a block, including comment delimiters, determining
10688 * serialized attributes and content form from the current state of the block.
10689 *
10690 * @param {WPBlock} block Block instance.
10691 * @param {WPBlockSerializationOptions} options Serialization options.
10692 *
10693 * @return {string} Serialized block.
10694 */
10695 function serializeBlock(block, {
10696 isInnerBlocks = false
10697 } = {}) {
10698 if (!block.isValid && block.__unstableBlockSource) {
10699 return serializeRawBlock(block.__unstableBlockSource);
10700 }
10701 const blockName = block.name;
10702 const saveContent = getBlockInnerHTML(block);
10703 if (blockName === getUnregisteredTypeHandlerName() || !isInnerBlocks && blockName === getFreeformContentHandlerName()) {
10704 return saveContent;
10705 }
10706 const blockType = getBlockType(blockName);
10707 if (!blockType) {
10708 return saveContent;
10709 }
10710 const saveAttributes = getCommentAttributes(blockType, block.attributes);
10711 return getCommentDelimitedContent(blockName, saveAttributes, saveContent);
10712 }
10713 function __unstableSerializeAndClean(blocks) {
10714 // A single unmodified default block is assumed to
10715 // be equivalent to an empty post.
10716 if (blocks.length === 1 && isUnmodifiedDefaultBlock(blocks[0])) {
10717 blocks = [];
10718 }
10719 let content = serialize(blocks);
10720
10721 // For compatibility, treat a post consisting of a
10722 // single freeform block as legacy content and apply
10723 // pre-block-editor removep'd content formatting.
10724 if (blocks.length === 1 && blocks[0].name === getFreeformContentHandlerName() && blocks[0].name === 'core/freeform') {
10725 content = (0,external_wp_autop_namespaceObject.removep)(content);
10726 }
10727 return content;
10728 }
10729
10730 /**
10731 * Takes a block or set of blocks and returns the serialized post content.
10732 *
10733 * @param {Array} blocks Block(s) to serialize.
10734 * @param {WPBlockSerializationOptions} options Serialization options.
10735 *
10736 * @return {string} The post content.
10737 */
10738 function serialize(blocks, options) {
10739 const blocksArray = Array.isArray(blocks) ? blocks : [blocks];
10740 return blocksArray.map(block => serializeBlock(block, options)).join('\n\n');
10741 }
10742
10743 ;// CONCATENATED MODULE: ./node_modules/simple-html-tokenizer/dist/es6/index.js
10744 /**
10745 * generated from https://raw.githubusercontent.com/w3c/html/26b5126f96f736f796b9e29718138919dd513744/entities.json
10746 * do not edit
10747 */
10748 var namedCharRefs = {
10749 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"
10750 };
10751
10752 var HEXCHARCODE = /^#[xX]([A-Fa-f0-9]+)$/;
10753 var CHARCODE = /^#([0-9]+)$/;
10754 var NAMED = /^([A-Za-z0-9]+)$/;
10755 var EntityParser = /** @class */ (function () {
10756 function EntityParser(named) {
10757 this.named = named;
10758 }
10759 EntityParser.prototype.parse = function (entity) {
10760 if (!entity) {
10761 return;
10762 }
10763 var matches = entity.match(HEXCHARCODE);
10764 if (matches) {
10765 return String.fromCharCode(parseInt(matches[1], 16));
10766 }
10767 matches = entity.match(CHARCODE);
10768 if (matches) {
10769 return String.fromCharCode(parseInt(matches[1], 10));
10770 }
10771 matches = entity.match(NAMED);
10772 if (matches) {
10773 return this.named[matches[1]];
10774 }
10775 };
10776 return EntityParser;
10777 }());
10778
10779 var WSP = /[\t\n\f ]/;
10780 var ALPHA = /[A-Za-z]/;
10781 var CRLF = /\r\n?/g;
10782 function isSpace(char) {
10783 return WSP.test(char);
10784 }
10785 function isAlpha(char) {
10786 return ALPHA.test(char);
10787 }
10788 function preprocessInput(input) {
10789 return input.replace(CRLF, '\n');
10790 }
10791
10792 var EventedTokenizer = /** @class */ (function () {
10793 function EventedTokenizer(delegate, entityParser) {
10794 this.delegate = delegate;
10795 this.entityParser = entityParser;
10796 this.state = "beforeData" /* beforeData */;
10797 this.line = -1;
10798 this.column = -1;
10799 this.input = '';
10800 this.index = -1;
10801 this.tagNameBuffer = '';
10802 this.states = {
10803 beforeData: function () {
10804 var char = this.peek();
10805 if (char === '<') {
10806 this.transitionTo("tagOpen" /* tagOpen */);
10807 this.markTagStart();
10808 this.consume();
10809 }
10810 else {
10811 if (char === '\n') {
10812 var tag = this.tagNameBuffer.toLowerCase();
10813 if (tag === 'pre' || tag === 'textarea') {
10814 this.consume();
10815 }
10816 }
10817 this.transitionTo("data" /* data */);
10818 this.delegate.beginData();
10819 }
10820 },
10821 data: function () {
10822 var char = this.peek();
10823 if (char === '<') {
10824 this.delegate.finishData();
10825 this.transitionTo("tagOpen" /* tagOpen */);
10826 this.markTagStart();
10827 this.consume();
10828 }
10829 else if (char === '&') {
10830 this.consume();
10831 this.delegate.appendToData(this.consumeCharRef() || '&');
10832 }
10833 else {
10834 this.consume();
10835 this.delegate.appendToData(char);
10836 }
10837 },
10838 tagOpen: function () {
10839 var char = this.consume();
10840 if (char === '!') {
10841 this.transitionTo("markupDeclarationOpen" /* markupDeclarationOpen */);
10842 }
10843 else if (char === '/') {
10844 this.transitionTo("endTagOpen" /* endTagOpen */);
10845 }
10846 else if (char === '@' || char === ':' || isAlpha(char)) {
10847 this.transitionTo("tagName" /* tagName */);
10848 this.tagNameBuffer = '';
10849 this.delegate.beginStartTag();
10850 this.appendToTagName(char);
10851 }
10852 },
10853 markupDeclarationOpen: function () {
10854 var char = this.consume();
10855 if (char === '-' && this.input.charAt(this.index) === '-') {
10856 this.consume();
10857 this.transitionTo("commentStart" /* commentStart */);
10858 this.delegate.beginComment();
10859 }
10860 },
10861 commentStart: function () {
10862 var char = this.consume();
10863 if (char === '-') {
10864 this.transitionTo("commentStartDash" /* commentStartDash */);
10865 }
10866 else if (char === '>') {
10867 this.delegate.finishComment();
10868 this.transitionTo("beforeData" /* beforeData */);
10869 }
10870 else {
10871 this.delegate.appendToCommentData(char);
10872 this.transitionTo("comment" /* comment */);
10873 }
10874 },
10875 commentStartDash: function () {
10876 var char = this.consume();
10877 if (char === '-') {
10878 this.transitionTo("commentEnd" /* commentEnd */);
10879 }
10880 else if (char === '>') {
10881 this.delegate.finishComment();
10882 this.transitionTo("beforeData" /* beforeData */);
10883 }
10884 else {
10885 this.delegate.appendToCommentData('-');
10886 this.transitionTo("comment" /* comment */);
10887 }
10888 },
10889 comment: function () {
10890 var char = this.consume();
10891 if (char === '-') {
10892 this.transitionTo("commentEndDash" /* commentEndDash */);
10893 }
10894 else {
10895 this.delegate.appendToCommentData(char);
10896 }
10897 },
10898 commentEndDash: function () {
10899 var char = this.consume();
10900 if (char === '-') {
10901 this.transitionTo("commentEnd" /* commentEnd */);
10902 }
10903 else {
10904 this.delegate.appendToCommentData('-' + char);
10905 this.transitionTo("comment" /* comment */);
10906 }
10907 },
10908 commentEnd: function () {
10909 var char = this.consume();
10910 if (char === '>') {
10911 this.delegate.finishComment();
10912 this.transitionTo("beforeData" /* beforeData */);
10913 }
10914 else {
10915 this.delegate.appendToCommentData('--' + char);
10916 this.transitionTo("comment" /* comment */);
10917 }
10918 },
10919 tagName: function () {
10920 var char = this.consume();
10921 if (isSpace(char)) {
10922 this.transitionTo("beforeAttributeName" /* beforeAttributeName */);
10923 }
10924 else if (char === '/') {
10925 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */);
10926 }
10927 else if (char === '>') {
10928 this.delegate.finishTag();
10929 this.transitionTo("beforeData" /* beforeData */);
10930 }
10931 else {
10932 this.appendToTagName(char);
10933 }
10934 },
10935 beforeAttributeName: function () {
10936 var char = this.peek();
10937 if (isSpace(char)) {
10938 this.consume();
10939 return;
10940 }
10941 else if (char === '/') {
10942 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */);
10943 this.consume();
10944 }
10945 else if (char === '>') {
10946 this.consume();
10947 this.delegate.finishTag();
10948 this.transitionTo("beforeData" /* beforeData */);
10949 }
10950 else if (char === '=') {
10951 this.delegate.reportSyntaxError('attribute name cannot start with equals sign');
10952 this.transitionTo("attributeName" /* attributeName */);
10953 this.delegate.beginAttribute();
10954 this.consume();
10955 this.delegate.appendToAttributeName(char);
10956 }
10957 else {
10958 this.transitionTo("attributeName" /* attributeName */);
10959 this.delegate.beginAttribute();
10960 }
10961 },
10962 attributeName: function () {
10963 var char = this.peek();
10964 if (isSpace(char)) {
10965 this.transitionTo("afterAttributeName" /* afterAttributeName */);
10966 this.consume();
10967 }
10968 else if (char === '/') {
10969 this.delegate.beginAttributeValue(false);
10970 this.delegate.finishAttributeValue();
10971 this.consume();
10972 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */);
10973 }
10974 else if (char === '=') {
10975 this.transitionTo("beforeAttributeValue" /* beforeAttributeValue */);
10976 this.consume();
10977 }
10978 else if (char === '>') {
10979 this.delegate.beginAttributeValue(false);
10980 this.delegate.finishAttributeValue();
10981 this.consume();
10982 this.delegate.finishTag();
10983 this.transitionTo("beforeData" /* beforeData */);
10984 }
10985 else if (char === '"' || char === "'" || char === '<') {
10986 this.delegate.reportSyntaxError(char + ' is not a valid character within attribute names');
10987 this.consume();
10988 this.delegate.appendToAttributeName(char);
10989 }
10990 else {
10991 this.consume();
10992 this.delegate.appendToAttributeName(char);
10993 }
10994 },
10995 afterAttributeName: function () {
10996 var char = this.peek();
10997 if (isSpace(char)) {
10998 this.consume();
10999 return;
11000 }
11001 else if (char === '/') {
11002 this.delegate.beginAttributeValue(false);
11003 this.delegate.finishAttributeValue();
11004 this.consume();
11005 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */);
11006 }
11007 else if (char === '=') {
11008 this.consume();
11009 this.transitionTo("beforeAttributeValue" /* beforeAttributeValue */);
11010 }
11011 else if (char === '>') {
11012 this.delegate.beginAttributeValue(false);
11013 this.delegate.finishAttributeValue();
11014 this.consume();
11015 this.delegate.finishTag();
11016 this.transitionTo("beforeData" /* beforeData */);
11017 }
11018 else {
11019 this.delegate.beginAttributeValue(false);
11020 this.delegate.finishAttributeValue();
11021 this.transitionTo("attributeName" /* attributeName */);
11022 this.delegate.beginAttribute();
11023 this.consume();
11024 this.delegate.appendToAttributeName(char);
11025 }
11026 },
11027 beforeAttributeValue: function () {
11028 var char = this.peek();
11029 if (isSpace(char)) {
11030 this.consume();
11031 }
11032 else if (char === '"') {
11033 this.transitionTo("attributeValueDoubleQuoted" /* attributeValueDoubleQuoted */);
11034 this.delegate.beginAttributeValue(true);
11035 this.consume();
11036 }
11037 else if (char === "'") {
11038 this.transitionTo("attributeValueSingleQuoted" /* attributeValueSingleQuoted */);
11039 this.delegate.beginAttributeValue(true);
11040 this.consume();
11041 }
11042 else if (char === '>') {
11043 this.delegate.beginAttributeValue(false);
11044 this.delegate.finishAttributeValue();
11045 this.consume();
11046 this.delegate.finishTag();
11047 this.transitionTo("beforeData" /* beforeData */);
11048 }
11049 else {
11050 this.transitionTo("attributeValueUnquoted" /* attributeValueUnquoted */);
11051 this.delegate.beginAttributeValue(false);
11052 this.consume();
11053 this.delegate.appendToAttributeValue(char);
11054 }
11055 },
11056 attributeValueDoubleQuoted: function () {
11057 var char = this.consume();
11058 if (char === '"') {
11059 this.delegate.finishAttributeValue();
11060 this.transitionTo("afterAttributeValueQuoted" /* afterAttributeValueQuoted */);
11061 }
11062 else if (char === '&') {
11063 this.delegate.appendToAttributeValue(this.consumeCharRef() || '&');
11064 }
11065 else {
11066 this.delegate.appendToAttributeValue(char);
11067 }
11068 },
11069 attributeValueSingleQuoted: function () {
11070 var char = this.consume();
11071 if (char === "'") {
11072 this.delegate.finishAttributeValue();
11073 this.transitionTo("afterAttributeValueQuoted" /* afterAttributeValueQuoted */);
11074 }
11075 else if (char === '&') {
11076 this.delegate.appendToAttributeValue(this.consumeCharRef() || '&');
11077 }
11078 else {
11079 this.delegate.appendToAttributeValue(char);
11080 }
11081 },
11082 attributeValueUnquoted: function () {
11083 var char = this.peek();
11084 if (isSpace(char)) {
11085 this.delegate.finishAttributeValue();
11086 this.consume();
11087 this.transitionTo("beforeAttributeName" /* beforeAttributeName */);
11088 }
11089 else if (char === '/') {
11090 this.delegate.finishAttributeValue();
11091 this.consume();
11092 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */);
11093 }
11094 else if (char === '&') {
11095 this.consume();
11096 this.delegate.appendToAttributeValue(this.consumeCharRef() || '&');
11097 }
11098 else if (char === '>') {
11099 this.delegate.finishAttributeValue();
11100 this.consume();
11101 this.delegate.finishTag();
11102 this.transitionTo("beforeData" /* beforeData */);
11103 }
11104 else {
11105 this.consume();
11106 this.delegate.appendToAttributeValue(char);
11107 }
11108 },
11109 afterAttributeValueQuoted: function () {
11110 var char = this.peek();
11111 if (isSpace(char)) {
11112 this.consume();
11113 this.transitionTo("beforeAttributeName" /* beforeAttributeName */);
11114 }
11115 else if (char === '/') {
11116 this.consume();
11117 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */);
11118 }
11119 else if (char === '>') {
11120 this.consume();
11121 this.delegate.finishTag();
11122 this.transitionTo("beforeData" /* beforeData */);
11123 }
11124 else {
11125 this.transitionTo("beforeAttributeName" /* beforeAttributeName */);
11126 }
11127 },
11128 selfClosingStartTag: function () {
11129 var char = this.peek();
11130 if (char === '>') {
11131 this.consume();
11132 this.delegate.markTagAsSelfClosing();
11133 this.delegate.finishTag();
11134 this.transitionTo("beforeData" /* beforeData */);
11135 }
11136 else {
11137 this.transitionTo("beforeAttributeName" /* beforeAttributeName */);
11138 }
11139 },
11140 endTagOpen: function () {
11141 var char = this.consume();
11142 if (char === '@' || char === ':' || isAlpha(char)) {
11143 this.transitionTo("tagName" /* tagName */);
11144 this.tagNameBuffer = '';
11145 this.delegate.beginEndTag();
11146 this.appendToTagName(char);
11147 }
11148 }
11149 };
11150 this.reset();
11151 }
11152 EventedTokenizer.prototype.reset = function () {
11153 this.transitionTo("beforeData" /* beforeData */);
11154 this.input = '';
11155 this.index = 0;
11156 this.line = 1;
11157 this.column = 0;
11158 this.delegate.reset();
11159 };
11160 EventedTokenizer.prototype.transitionTo = function (state) {
11161 this.state = state;
11162 };
11163 EventedTokenizer.prototype.tokenize = function (input) {
11164 this.reset();
11165 this.tokenizePart(input);
11166 this.tokenizeEOF();
11167 };
11168 EventedTokenizer.prototype.tokenizePart = function (input) {
11169 this.input += preprocessInput(input);
11170 while (this.index < this.input.length) {
11171 var handler = this.states[this.state];
11172 if (handler !== undefined) {
11173 handler.call(this);
11174 }
11175 else {
11176 throw new Error("unhandled state " + this.state);
11177 }
11178 }
11179 };
11180 EventedTokenizer.prototype.tokenizeEOF = function () {
11181 this.flushData();
11182 };
11183 EventedTokenizer.prototype.flushData = function () {
11184 if (this.state === 'data') {
11185 this.delegate.finishData();
11186 this.transitionTo("beforeData" /* beforeData */);
11187 }
11188 };
11189 EventedTokenizer.prototype.peek = function () {
11190 return this.input.charAt(this.index);
11191 };
11192 EventedTokenizer.prototype.consume = function () {
11193 var char = this.peek();
11194 this.index++;
11195 if (char === '\n') {
11196 this.line++;
11197 this.column = 0;
11198 }
11199 else {
11200 this.column++;
11201 }
11202 return char;
11203 };
11204 EventedTokenizer.prototype.consumeCharRef = function () {
11205 var endIndex = this.input.indexOf(';', this.index);
11206 if (endIndex === -1) {
11207 return;
11208 }
11209 var entity = this.input.slice(this.index, endIndex);
11210 var chars = this.entityParser.parse(entity);
11211 if (chars) {
11212 var count = entity.length;
11213 // consume the entity chars
11214 while (count) {
11215 this.consume();
11216 count--;
11217 }
11218 // consume the `;`
11219 this.consume();
11220 return chars;
11221 }
11222 };
11223 EventedTokenizer.prototype.markTagStart = function () {
11224 this.delegate.tagOpen();
11225 };
11226 EventedTokenizer.prototype.appendToTagName = function (char) {
11227 this.tagNameBuffer += char;
11228 this.delegate.appendToTagName(char);
11229 };
11230 return EventedTokenizer;
11231 }());
11232
11233 var Tokenizer = /** @class */ (function () {
11234 function Tokenizer(entityParser, options) {
11235 if (options === void 0) { options = {}; }
11236 this.options = options;
11237 this.token = null;
11238 this.startLine = 1;
11239 this.startColumn = 0;
11240 this.tokens = [];
11241 this.tokenizer = new EventedTokenizer(this, entityParser);
11242 this._currentAttribute = undefined;
11243 }
11244 Tokenizer.prototype.tokenize = function (input) {
11245 this.tokens = [];
11246 this.tokenizer.tokenize(input);
11247 return this.tokens;
11248 };
11249 Tokenizer.prototype.tokenizePart = function (input) {
11250 this.tokens = [];
11251 this.tokenizer.tokenizePart(input);
11252 return this.tokens;
11253 };
11254 Tokenizer.prototype.tokenizeEOF = function () {
11255 this.tokens = [];
11256 this.tokenizer.tokenizeEOF();
11257 return this.tokens[0];
11258 };
11259 Tokenizer.prototype.reset = function () {
11260 this.token = null;
11261 this.startLine = 1;
11262 this.startColumn = 0;
11263 };
11264 Tokenizer.prototype.current = function () {
11265 var token = this.token;
11266 if (token === null) {
11267 throw new Error('token was unexpectedly null');
11268 }
11269 if (arguments.length === 0) {
11270 return token;
11271 }
11272 for (var i = 0; i < arguments.length; i++) {
11273 if (token.type === arguments[i]) {
11274 return token;
11275 }
11276 }
11277 throw new Error("token type was unexpectedly " + token.type);
11278 };
11279 Tokenizer.prototype.push = function (token) {
11280 this.token = token;
11281 this.tokens.push(token);
11282 };
11283 Tokenizer.prototype.currentAttribute = function () {
11284 return this._currentAttribute;
11285 };
11286 Tokenizer.prototype.addLocInfo = function () {
11287 if (this.options.loc) {
11288 this.current().loc = {
11289 start: {
11290 line: this.startLine,
11291 column: this.startColumn
11292 },
11293 end: {
11294 line: this.tokenizer.line,
11295 column: this.tokenizer.column
11296 }
11297 };
11298 }
11299 this.startLine = this.tokenizer.line;
11300 this.startColumn = this.tokenizer.column;
11301 };
11302 // Data
11303 Tokenizer.prototype.beginData = function () {
11304 this.push({
11305 type: "Chars" /* Chars */,
11306 chars: ''
11307 });
11308 };
11309 Tokenizer.prototype.appendToData = function (char) {
11310 this.current("Chars" /* Chars */).chars += char;
11311 };
11312 Tokenizer.prototype.finishData = function () {
11313 this.addLocInfo();
11314 };
11315 // Comment
11316 Tokenizer.prototype.beginComment = function () {
11317 this.push({
11318 type: "Comment" /* Comment */,
11319 chars: ''
11320 });
11321 };
11322 Tokenizer.prototype.appendToCommentData = function (char) {
11323 this.current("Comment" /* Comment */).chars += char;
11324 };
11325 Tokenizer.prototype.finishComment = function () {
11326 this.addLocInfo();
11327 };
11328 // Tags - basic
11329 Tokenizer.prototype.tagOpen = function () { };
11330 Tokenizer.prototype.beginStartTag = function () {
11331 this.push({
11332 type: "StartTag" /* StartTag */,
11333 tagName: '',
11334 attributes: [],
11335 selfClosing: false
11336 });
11337 };
11338 Tokenizer.prototype.beginEndTag = function () {
11339 this.push({
11340 type: "EndTag" /* EndTag */,
11341 tagName: ''
11342 });
11343 };
11344 Tokenizer.prototype.finishTag = function () {
11345 this.addLocInfo();
11346 };
11347 Tokenizer.prototype.markTagAsSelfClosing = function () {
11348 this.current("StartTag" /* StartTag */).selfClosing = true;
11349 };
11350 // Tags - name
11351 Tokenizer.prototype.appendToTagName = function (char) {
11352 this.current("StartTag" /* StartTag */, "EndTag" /* EndTag */).tagName += char;
11353 };
11354 // Tags - attributes
11355 Tokenizer.prototype.beginAttribute = function () {
11356 this._currentAttribute = ['', '', false];
11357 };
11358 Tokenizer.prototype.appendToAttributeName = function (char) {
11359 this.currentAttribute()[0] += char;
11360 };
11361 Tokenizer.prototype.beginAttributeValue = function (isQuoted) {
11362 this.currentAttribute()[2] = isQuoted;
11363 };
11364 Tokenizer.prototype.appendToAttributeValue = function (char) {
11365 this.currentAttribute()[1] += char;
11366 };
11367 Tokenizer.prototype.finishAttributeValue = function () {
11368 this.current("StartTag" /* StartTag */).attributes.push(this._currentAttribute);
11369 };
11370 Tokenizer.prototype.reportSyntaxError = function (message) {
11371 this.current().syntaxError = message;
11372 };
11373 return Tokenizer;
11374 }());
11375
11376 function tokenize(input, options) {
11377 var tokenizer = new Tokenizer(new EntityParser(namedCharRefs), options);
11378 return tokenizer.tokenize(input);
11379 }
11380
11381
11382
11383 // EXTERNAL MODULE: ./node_modules/fast-deep-equal/es6/index.js
11384 var es6 = __webpack_require__(5619);
11385 var es6_default = /*#__PURE__*/__webpack_require__.n(es6);
11386 ;// CONCATENATED MODULE: external ["wp","htmlEntities"]
11387 const external_wp_htmlEntities_namespaceObject = window["wp"]["htmlEntities"];
11388 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/validation/logger.js
11389 /**
11390 * @typedef LoggerItem
11391 * @property {Function} log Which logger recorded the message
11392 * @property {Array<any>} args White arguments were supplied to the logger
11393 */
11394
11395 function createLogger() {
11396 /**
11397 * Creates a log handler with block validation prefix.
11398 *
11399 * @param {Function} logger Original logger function.
11400 *
11401 * @return {Function} Augmented logger function.
11402 */
11403 function createLogHandler(logger) {
11404 let log = (message, ...args) => logger('Block validation: ' + message, ...args);
11405
11406 // In test environments, pre-process string substitutions to improve
11407 // readability of error messages. We'd prefer to avoid pulling in this
11408 // dependency in runtime environments, and it can be dropped by a combo
11409 // of Webpack env substitution + UglifyJS dead code elimination.
11410 if (false) {}
11411 return log;
11412 }
11413 return {
11414 // eslint-disable-next-line no-console
11415 error: createLogHandler(console.error),
11416 // eslint-disable-next-line no-console
11417 warning: createLogHandler(console.warn),
11418 getItems() {
11419 return [];
11420 }
11421 };
11422 }
11423 function createQueuedLogger() {
11424 /**
11425 * The list of enqueued log actions to print.
11426 *
11427 * @type {Array<LoggerItem>}
11428 */
11429 const queue = [];
11430 const logger = createLogger();
11431 return {
11432 error(...args) {
11433 queue.push({
11434 log: logger.error,
11435 args
11436 });
11437 },
11438 warning(...args) {
11439 queue.push({
11440 log: logger.warning,
11441 args
11442 });
11443 },
11444 getItems() {
11445 return queue;
11446 }
11447 };
11448 }
11449
11450 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/validation/index.js
11451 /**
11452 * External dependencies
11453 */
11454
11455
11456
11457 /**
11458 * WordPress dependencies
11459 */
11460
11461
11462
11463 /**
11464 * Internal dependencies
11465 */
11466
11467
11468
11469
11470
11471 /** @typedef {import('../parser').WPBlock} WPBlock */
11472 /** @typedef {import('../registration').WPBlockType} WPBlockType */
11473 /** @typedef {import('./logger').LoggerItem} LoggerItem */
11474
11475 const identity = x => x;
11476
11477 /**
11478 * Globally matches any consecutive whitespace
11479 *
11480 * @type {RegExp}
11481 */
11482 const REGEXP_WHITESPACE = /[\t\n\r\v\f ]+/g;
11483
11484 /**
11485 * Matches a string containing only whitespace
11486 *
11487 * @type {RegExp}
11488 */
11489 const REGEXP_ONLY_WHITESPACE = /^[\t\n\r\v\f ]*$/;
11490
11491 /**
11492 * Matches a CSS URL type value
11493 *
11494 * @type {RegExp}
11495 */
11496 const REGEXP_STYLE_URL_TYPE = /^url\s*\(['"\s]*(.*?)['"\s]*\)$/;
11497
11498 /**
11499 * Boolean attributes are attributes whose presence as being assigned is
11500 * meaningful, even if only empty.
11501 *
11502 * See: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#boolean-attributes
11503 * Extracted from: https://html.spec.whatwg.org/multipage/indices.html#attributes-3
11504 *
11505 * Object.keys( Array.from( document.querySelectorAll( '#attributes-1 > tbody > tr' ) )
11506 * .filter( ( tr ) => tr.lastChild.textContent.indexOf( 'Boolean attribute' ) !== -1 )
11507 * .reduce( ( result, tr ) => Object.assign( result, {
11508 * [ tr.firstChild.textContent.trim() ]: true
11509 * } ), {} ) ).sort();
11510 *
11511 * @type {Array}
11512 */
11513 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'];
11514
11515 /**
11516 * Enumerated attributes are attributes which must be of a specific value form.
11517 * Like boolean attributes, these are meaningful if specified, even if not of a
11518 * valid enumerated value.
11519 *
11520 * See: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#enumerated-attribute
11521 * Extracted from: https://html.spec.whatwg.org/multipage/indices.html#attributes-3
11522 *
11523 * Object.keys( Array.from( document.querySelectorAll( '#attributes-1 > tbody > tr' ) )
11524 * .filter( ( tr ) => /^("(.+?)";?\s*)+/.test( tr.lastChild.textContent.trim() ) )
11525 * .reduce( ( result, tr ) => Object.assign( result, {
11526 * [ tr.firstChild.textContent.trim() ]: true
11527 * } ), {} ) ).sort();
11528 *
11529 * @type {Array}
11530 */
11531 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'];
11532
11533 /**
11534 * Meaningful attributes are those who cannot be safely ignored when omitted in
11535 * one HTML markup string and not another.
11536 *
11537 * @type {Array}
11538 */
11539 const MEANINGFUL_ATTRIBUTES = [...BOOLEAN_ATTRIBUTES, ...ENUMERATED_ATTRIBUTES];
11540
11541 /**
11542 * Array of functions which receive a text string on which to apply normalizing
11543 * behavior for consideration in text token equivalence, carefully ordered from
11544 * least-to-most expensive operations.
11545 *
11546 * @type {Array}
11547 */
11548 const TEXT_NORMALIZATIONS = [identity, getTextWithCollapsedWhitespace];
11549
11550 /**
11551 * Regular expression matching a named character reference. In lieu of bundling
11552 * a full set of references, the pattern covers the minimal necessary to test
11553 * positively against the full set.
11554 *
11555 * "The ampersand must be followed by one of the names given in the named
11556 * character references section, using the same case."
11557 *
11558 * Tested aginst "12.5 Named character references":
11559 *
11560 * ```
11561 * const references = Array.from( document.querySelectorAll(
11562 * '#named-character-references-table tr[id^=entity-] td:first-child'
11563 * ) ).map( ( code ) => code.textContent )
11564 * references.every( ( reference ) => /^[\da-z]+$/i.test( reference ) )
11565 * ```
11566 *
11567 * @see https://html.spec.whatwg.org/multipage/syntax.html#character-references
11568 * @see https://html.spec.whatwg.org/multipage/named-characters.html#named-character-references
11569 *
11570 * @type {RegExp}
11571 */
11572 const REGEXP_NAMED_CHARACTER_REFERENCE = /^[\da-z]+$/i;
11573
11574 /**
11575 * Regular expression matching a decimal character reference.
11576 *
11577 * "The ampersand must be followed by a U+0023 NUMBER SIGN character (#),
11578 * followed by one or more ASCII digits, representing a base-ten integer"
11579 *
11580 * @see https://html.spec.whatwg.org/multipage/syntax.html#character-references
11581 *
11582 * @type {RegExp}
11583 */
11584 const REGEXP_DECIMAL_CHARACTER_REFERENCE = /^#\d+$/;
11585
11586 /**
11587 * Regular expression matching a hexadecimal character reference.
11588 *
11589 * "The ampersand must be followed by a U+0023 NUMBER SIGN character (#), which
11590 * must be followed by either a U+0078 LATIN SMALL LETTER X character (x) or a
11591 * U+0058 LATIN CAPITAL LETTER X character (X), which must then be followed by
11592 * one or more ASCII hex digits, representing a hexadecimal integer"
11593 *
11594 * @see https://html.spec.whatwg.org/multipage/syntax.html#character-references
11595 *
11596 * @type {RegExp}
11597 */
11598 const REGEXP_HEXADECIMAL_CHARACTER_REFERENCE = /^#x[\da-f]+$/i;
11599
11600 /**
11601 * Returns true if the given string is a valid character reference segment, or
11602 * false otherwise. The text should be stripped of `&` and `;` demarcations.
11603 *
11604 * @param {string} text Text to test.
11605 *
11606 * @return {boolean} Whether text is valid character reference.
11607 */
11608 function isValidCharacterReference(text) {
11609 return REGEXP_NAMED_CHARACTER_REFERENCE.test(text) || REGEXP_DECIMAL_CHARACTER_REFERENCE.test(text) || REGEXP_HEXADECIMAL_CHARACTER_REFERENCE.test(text);
11610 }
11611
11612 /**
11613 * Subsitute EntityParser class for `simple-html-tokenizer` which uses the
11614 * implementation of `decodeEntities` from `html-entities`, in order to avoid
11615 * bundling a massive named character reference.
11616 *
11617 * @see https://github.com/tildeio/simple-html-tokenizer/tree/HEAD/src/entity-parser.ts
11618 */
11619 class DecodeEntityParser {
11620 /**
11621 * Returns a substitute string for an entity string sequence between `&`
11622 * and `;`, or undefined if no substitution should occur.
11623 *
11624 * @param {string} entity Entity fragment discovered in HTML.
11625 *
11626 * @return {string | undefined} Entity substitute value.
11627 */
11628 parse(entity) {
11629 if (isValidCharacterReference(entity)) {
11630 return (0,external_wp_htmlEntities_namespaceObject.decodeEntities)('&' + entity + ';');
11631 }
11632 }
11633 }
11634
11635 /**
11636 * Given a specified string, returns an array of strings split by consecutive
11637 * whitespace, ignoring leading or trailing whitespace.
11638 *
11639 * @param {string} text Original text.
11640 *
11641 * @return {string[]} Text pieces split on whitespace.
11642 */
11643 function getTextPiecesSplitOnWhitespace(text) {
11644 return text.trim().split(REGEXP_WHITESPACE);
11645 }
11646
11647 /**
11648 * Given a specified string, returns a new trimmed string where all consecutive
11649 * whitespace is collapsed to a single space.
11650 *
11651 * @param {string} text Original text.
11652 *
11653 * @return {string} Trimmed text with consecutive whitespace collapsed.
11654 */
11655 function getTextWithCollapsedWhitespace(text) {
11656 // This is an overly simplified whitespace comparison. The specification is
11657 // more prescriptive of whitespace behavior in inline and block contexts.
11658 //
11659 // See: https://medium.com/@patrickbrosset/when-does-white-space-matter-in-html-b90e8a7cdd33
11660 return getTextPiecesSplitOnWhitespace(text).join(' ');
11661 }
11662
11663 /**
11664 * Returns attribute pairs of the given StartTag token, including only pairs
11665 * where the value is non-empty or the attribute is a boolean attribute, an
11666 * enumerated attribute, or a custom data- attribute.
11667 *
11668 * @see MEANINGFUL_ATTRIBUTES
11669 *
11670 * @param {Object} token StartTag token.
11671 *
11672 * @return {Array[]} Attribute pairs.
11673 */
11674 function getMeaningfulAttributePairs(token) {
11675 return token.attributes.filter(pair => {
11676 const [key, value] = pair;
11677 return value || key.indexOf('data-') === 0 || MEANINGFUL_ATTRIBUTES.includes(key);
11678 });
11679 }
11680
11681 /**
11682 * Returns true if two text tokens (with `chars` property) are equivalent, or
11683 * false otherwise.
11684 *
11685 * @param {Object} actual Actual token.
11686 * @param {Object} expected Expected token.
11687 * @param {Object} logger Validation logger object.
11688 *
11689 * @return {boolean} Whether two text tokens are equivalent.
11690 */
11691 function isEquivalentTextTokens(actual, expected, logger = createLogger()) {
11692 // This function is intentionally written as syntactically "ugly" as a hot
11693 // path optimization. Text is progressively normalized in order from least-
11694 // to-most operationally expensive, until the earliest point at which text
11695 // can be confidently inferred as being equal.
11696 let actualChars = actual.chars;
11697 let expectedChars = expected.chars;
11698 for (let i = 0; i < TEXT_NORMALIZATIONS.length; i++) {
11699 const normalize = TEXT_NORMALIZATIONS[i];
11700 actualChars = normalize(actualChars);
11701 expectedChars = normalize(expectedChars);
11702 if (actualChars === expectedChars) {
11703 return true;
11704 }
11705 }
11706 logger.warning('Expected text `%s`, saw `%s`.', expected.chars, actual.chars);
11707 return false;
11708 }
11709
11710 /**
11711 * Given a CSS length value, returns a normalized CSS length value for strict equality
11712 * comparison.
11713 *
11714 * @param {string} value CSS length value.
11715 *
11716 * @return {string} Normalized CSS length value.
11717 */
11718 function getNormalizedLength(value) {
11719 if (0 === parseFloat(value)) {
11720 return '0';
11721 }
11722 // Normalize strings with floats to always include a leading zero.
11723 if (value.indexOf('.') === 0) {
11724 return '0' + value;
11725 }
11726 return value;
11727 }
11728
11729 /**
11730 * Given a style value, returns a normalized style value for strict equality
11731 * comparison.
11732 *
11733 * @param {string} value Style value.
11734 *
11735 * @return {string} Normalized style value.
11736 */
11737 function getNormalizedStyleValue(value) {
11738 const textPieces = getTextPiecesSplitOnWhitespace(value);
11739 const normalizedPieces = textPieces.map(getNormalizedLength);
11740 const result = normalizedPieces.join(' ');
11741 return result
11742 // Normalize URL type to omit whitespace or quotes.
11743 .replace(REGEXP_STYLE_URL_TYPE, 'url($1)');
11744 }
11745
11746 /**
11747 * Given a style attribute string, returns an object of style properties.
11748 *
11749 * @param {string} text Style attribute.
11750 *
11751 * @return {Object} Style properties.
11752 */
11753 function getStyleProperties(text) {
11754 const pairs = text
11755 // Trim ending semicolon (avoid including in split)
11756 .replace(/;?\s*$/, '')
11757 // Split on property assignment.
11758 .split(';')
11759 // For each property assignment...
11760 .map(style => {
11761 // ...split further into key-value pairs.
11762 const [key, ...valueParts] = style.split(':');
11763 const value = valueParts.join(':');
11764 return [key.trim(), getNormalizedStyleValue(value.trim())];
11765 });
11766 return Object.fromEntries(pairs);
11767 }
11768
11769 /**
11770 * Attribute-specific equality handlers
11771 *
11772 * @type {Object}
11773 */
11774 const isEqualAttributesOfName = {
11775 class: (actual, expected) => {
11776 // Class matches if members are the same, even if out of order or
11777 // superfluous whitespace between.
11778 const [actualPieces, expectedPieces] = [actual, expected].map(getTextPiecesSplitOnWhitespace);
11779 const actualDiff = actualPieces.filter(c => !expectedPieces.includes(c));
11780 const expectedDiff = expectedPieces.filter(c => !actualPieces.includes(c));
11781 return actualDiff.length === 0 && expectedDiff.length === 0;
11782 },
11783 style: (actual, expected) => {
11784 return es6_default()(...[actual, expected].map(getStyleProperties));
11785 },
11786 // For each boolean attribute, mere presence of attribute in both is enough
11787 // to assume equivalence.
11788 ...Object.fromEntries(BOOLEAN_ATTRIBUTES.map(attribute => [attribute, () => true]))
11789 };
11790
11791 /**
11792 * Given two sets of attribute tuples, returns true if the attribute sets are
11793 * equivalent.
11794 *
11795 * @param {Array[]} actual Actual attributes tuples.
11796 * @param {Array[]} expected Expected attributes tuples.
11797 * @param {Object} logger Validation logger object.
11798 *
11799 * @return {boolean} Whether attributes are equivalent.
11800 */
11801 function isEqualTagAttributePairs(actual, expected, logger = createLogger()) {
11802 // Attributes is tokenized as tuples. Their lengths should match. This also
11803 // avoids us needing to check both attributes sets, since if A has any keys
11804 // which do not exist in B, we know the sets to be different.
11805 if (actual.length !== expected.length) {
11806 logger.warning('Expected attributes %o, instead saw %o.', expected, actual);
11807 return false;
11808 }
11809
11810 // Attributes are not guaranteed to occur in the same order. For validating
11811 // actual attributes, first convert the set of expected attribute values to
11812 // an object, for lookup by key.
11813 const expectedAttributes = {};
11814 for (let i = 0; i < expected.length; i++) {
11815 expectedAttributes[expected[i][0].toLowerCase()] = expected[i][1];
11816 }
11817 for (let i = 0; i < actual.length; i++) {
11818 const [name, actualValue] = actual[i];
11819 const nameLower = name.toLowerCase();
11820
11821 // As noted above, if missing member in B, assume different.
11822 if (!expectedAttributes.hasOwnProperty(nameLower)) {
11823 logger.warning('Encountered unexpected attribute `%s`.', name);
11824 return false;
11825 }
11826 const expectedValue = expectedAttributes[nameLower];
11827 const isEqualAttributes = isEqualAttributesOfName[nameLower];
11828 if (isEqualAttributes) {
11829 // Defer custom attribute equality handling.
11830 if (!isEqualAttributes(actualValue, expectedValue)) {
11831 logger.warning('Expected attribute `%s` of value `%s`, saw `%s`.', name, expectedValue, actualValue);
11832 return false;
11833 }
11834 } else if (actualValue !== expectedValue) {
11835 // Otherwise strict inequality should bail.
11836 logger.warning('Expected attribute `%s` of value `%s`, saw `%s`.', name, expectedValue, actualValue);
11837 return false;
11838 }
11839 }
11840 return true;
11841 }
11842
11843 /**
11844 * Token-type-specific equality handlers
11845 *
11846 * @type {Object}
11847 */
11848 const isEqualTokensOfType = {
11849 StartTag: (actual, expected, logger = createLogger()) => {
11850 if (actual.tagName !== expected.tagName &&
11851 // Optimization: Use short-circuit evaluation to defer case-
11852 // insensitive check on the assumption that the majority case will
11853 // have exactly equal tag names.
11854 actual.tagName.toLowerCase() !== expected.tagName.toLowerCase()) {
11855 logger.warning('Expected tag name `%s`, instead saw `%s`.', expected.tagName, actual.tagName);
11856 return false;
11857 }
11858 return isEqualTagAttributePairs(...[actual, expected].map(getMeaningfulAttributePairs), logger);
11859 },
11860 Chars: isEquivalentTextTokens,
11861 Comment: isEquivalentTextTokens
11862 };
11863
11864 /**
11865 * Given an array of tokens, returns the first token which is not purely
11866 * whitespace.
11867 *
11868 * Mutates the tokens array.
11869 *
11870 * @param {Object[]} tokens Set of tokens to search.
11871 *
11872 * @return {Object | undefined} Next non-whitespace token.
11873 */
11874 function getNextNonWhitespaceToken(tokens) {
11875 let token;
11876 while (token = tokens.shift()) {
11877 if (token.type !== 'Chars') {
11878 return token;
11879 }
11880 if (!REGEXP_ONLY_WHITESPACE.test(token.chars)) {
11881 return token;
11882 }
11883 }
11884 }
11885
11886 /**
11887 * Tokenize an HTML string, gracefully handling any errors thrown during
11888 * underlying tokenization.
11889 *
11890 * @param {string} html HTML string to tokenize.
11891 * @param {Object} logger Validation logger object.
11892 *
11893 * @return {Object[]|null} Array of valid tokenized HTML elements, or null on error
11894 */
11895 function getHTMLTokens(html, logger = createLogger()) {
11896 try {
11897 return new Tokenizer(new DecodeEntityParser()).tokenize(html);
11898 } catch (e) {
11899 logger.warning('Malformed HTML detected: %s', html);
11900 }
11901 return null;
11902 }
11903
11904 /**
11905 * Returns true if the next HTML token closes the current token.
11906 *
11907 * @param {Object} currentToken Current token to compare with.
11908 * @param {Object|undefined} nextToken Next token to compare against.
11909 *
11910 * @return {boolean} true if `nextToken` closes `currentToken`, false otherwise
11911 */
11912 function isClosedByToken(currentToken, nextToken) {
11913 // Ensure this is a self closed token.
11914 if (!currentToken.selfClosing) {
11915 return false;
11916 }
11917
11918 // Check token names and determine if nextToken is the closing tag for currentToken.
11919 if (nextToken && nextToken.tagName === currentToken.tagName && nextToken.type === 'EndTag') {
11920 return true;
11921 }
11922 return false;
11923 }
11924
11925 /**
11926 * Returns true if the given HTML strings are effectively equivalent, or
11927 * false otherwise. Invalid HTML is not considered equivalent, even if the
11928 * strings directly match.
11929 *
11930 * @param {string} actual Actual HTML string.
11931 * @param {string} expected Expected HTML string.
11932 * @param {Object} logger Validation logger object.
11933 *
11934 * @return {boolean} Whether HTML strings are equivalent.
11935 */
11936 function isEquivalentHTML(actual, expected, logger = createLogger()) {
11937 // Short-circuit if markup is identical.
11938 if (actual === expected) {
11939 return true;
11940 }
11941
11942 // Tokenize input content and reserialized save content.
11943 const [actualTokens, expectedTokens] = [actual, expected].map(html => getHTMLTokens(html, logger));
11944
11945 // If either is malformed then stop comparing - the strings are not equivalent.
11946 if (!actualTokens || !expectedTokens) {
11947 return false;
11948 }
11949 let actualToken, expectedToken;
11950 while (actualToken = getNextNonWhitespaceToken(actualTokens)) {
11951 expectedToken = getNextNonWhitespaceToken(expectedTokens);
11952
11953 // Inequal if exhausted all expected tokens.
11954 if (!expectedToken) {
11955 logger.warning('Expected end of content, instead saw %o.', actualToken);
11956 return false;
11957 }
11958
11959 // Inequal if next non-whitespace token of each set are not same type.
11960 if (actualToken.type !== expectedToken.type) {
11961 logger.warning('Expected token of type `%s` (%o), instead saw `%s` (%o).', expectedToken.type, expectedToken, actualToken.type, actualToken);
11962 return false;
11963 }
11964
11965 // Defer custom token type equality handling, otherwise continue and
11966 // assume as equal.
11967 const isEqualTokens = isEqualTokensOfType[actualToken.type];
11968 if (isEqualTokens && !isEqualTokens(actualToken, expectedToken, logger)) {
11969 return false;
11970 }
11971
11972 // Peek at the next tokens (actual and expected) to see if they close
11973 // a self-closing tag.
11974 if (isClosedByToken(actualToken, expectedTokens[0])) {
11975 // Consume the next expected token that closes the current actual
11976 // self-closing token.
11977 getNextNonWhitespaceToken(expectedTokens);
11978 } else if (isClosedByToken(expectedToken, actualTokens[0])) {
11979 // Consume the next actual token that closes the current expected
11980 // self-closing token.
11981 getNextNonWhitespaceToken(actualTokens);
11982 }
11983 }
11984 if (expectedToken = getNextNonWhitespaceToken(expectedTokens)) {
11985 // If any non-whitespace tokens remain in expected token set, this
11986 // indicates inequality.
11987 logger.warning('Expected %o, instead saw end of content.', expectedToken);
11988 return false;
11989 }
11990 return true;
11991 }
11992
11993 /**
11994 * Returns an object with `isValid` property set to `true` if the parsed block
11995 * is valid given the input content. A block is considered valid if, when serialized
11996 * with assumed attributes, the content matches the original value. If block is
11997 * invalid, this function returns all validations issues as well.
11998 *
11999 * @param {string|Object} blockTypeOrName Block type.
12000 * @param {Object} attributes Parsed block attributes.
12001 * @param {string} originalBlockContent Original block content.
12002 * @param {Object} logger Validation logger object.
12003 *
12004 * @return {Object} Whether block is valid and contains validation messages.
12005 */
12006
12007 /**
12008 * Returns an object with `isValid` property set to `true` if the parsed block
12009 * is valid given the input content. A block is considered valid if, when serialized
12010 * with assumed attributes, the content matches the original value. If block is
12011 * invalid, this function returns all validations issues as well.
12012 *
12013 * @param {WPBlock} block block object.
12014 * @param {WPBlockType|string} [blockTypeOrName = block.name] Block type or name, inferred from block if not given.
12015 *
12016 * @return {[boolean,Array<LoggerItem>]} validation results.
12017 */
12018 function validateBlock(block, blockTypeOrName = block.name) {
12019 const isFallbackBlock = block.name === getFreeformContentHandlerName() || block.name === getUnregisteredTypeHandlerName();
12020
12021 // Shortcut to avoid costly validation.
12022 if (isFallbackBlock) {
12023 return [true, []];
12024 }
12025 const logger = createQueuedLogger();
12026 const blockType = normalizeBlockType(blockTypeOrName);
12027 let generatedBlockContent;
12028 try {
12029 generatedBlockContent = getSaveContent(blockType, block.attributes);
12030 } catch (error) {
12031 logger.error('Block validation failed because an error occurred while generating block content:\n\n%s', error.toString());
12032 return [false, logger.getItems()];
12033 }
12034 const isValid = isEquivalentHTML(block.originalContent, generatedBlockContent, logger);
12035 if (!isValid) {
12036 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);
12037 }
12038 return [isValid, logger.getItems()];
12039 }
12040
12041 /**
12042 * Returns true if the parsed block is valid given the input content. A block
12043 * is considered valid if, when serialized with assumed attributes, the content
12044 * matches the original value.
12045 *
12046 * Logs to console in development environments when invalid.
12047 *
12048 * @deprecated Use validateBlock instead to avoid data loss.
12049 *
12050 * @param {string|Object} blockTypeOrName Block type.
12051 * @param {Object} attributes Parsed block attributes.
12052 * @param {string} originalBlockContent Original block content.
12053 *
12054 * @return {boolean} Whether block is valid.
12055 */
12056 function isValidBlockContent(blockTypeOrName, attributes, originalBlockContent) {
12057 external_wp_deprecated_default()('isValidBlockContent introduces opportunity for data loss', {
12058 since: '12.6',
12059 plugin: 'Gutenberg',
12060 alternative: 'validateBlock'
12061 });
12062 const blockType = normalizeBlockType(blockTypeOrName);
12063 const block = {
12064 name: blockType.name,
12065 attributes,
12066 innerBlocks: [],
12067 originalContent: originalBlockContent
12068 };
12069 const [isValid] = validateBlock(block, blockType);
12070 return isValid;
12071 }
12072
12073 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/parser/convert-legacy-block.js
12074 /**
12075 * Convert legacy blocks to their canonical form. This function is used
12076 * both in the parser level for previous content and to convert such blocks
12077 * used in Custom Post Types templates.
12078 *
12079 * @param {string} name The block's name
12080 * @param {Object} attributes The block's attributes
12081 *
12082 * @return {[string, Object]} The block's name and attributes, changed accordingly if a match was found
12083 */
12084 function convertLegacyBlockNameAndAttributes(name, attributes) {
12085 const newAttributes = {
12086 ...attributes
12087 };
12088 // Convert 'core/cover-image' block in existing content to 'core/cover'.
12089 if ('core/cover-image' === name) {
12090 name = 'core/cover';
12091 }
12092
12093 // Convert 'core/text' blocks in existing content to 'core/paragraph'.
12094 if ('core/text' === name || 'core/cover-text' === name) {
12095 name = 'core/paragraph';
12096 }
12097
12098 // Convert derivative blocks such as 'core/social-link-wordpress' to the
12099 // canonical form 'core/social-link'.
12100 if (name && name.indexOf('core/social-link-') === 0) {
12101 // Capture `social-link-wordpress` into `{"service":"wordpress"}`
12102 newAttributes.service = name.substring(17);
12103 name = 'core/social-link';
12104 }
12105
12106 // Convert derivative blocks such as 'core-embed/instagram' to the
12107 // canonical form 'core/embed'.
12108 if (name && name.indexOf('core-embed/') === 0) {
12109 // Capture `core-embed/instagram` into `{"providerNameSlug":"instagram"}`
12110 const providerSlug = name.substring(11);
12111 const deprecated = {
12112 speaker: 'speaker-deck',
12113 polldaddy: 'crowdsignal'
12114 };
12115 newAttributes.providerNameSlug = providerSlug in deprecated ? deprecated[providerSlug] : providerSlug;
12116 // This is needed as the `responsive` attribute was passed
12117 // in a different way before the refactoring to block variations.
12118 if (!['amazon-kindle', 'wordpress'].includes(providerSlug)) {
12119 newAttributes.responsive = true;
12120 }
12121 name = 'core/embed';
12122 }
12123
12124 // Convert Post Comment blocks in existing content to Comment blocks.
12125 // TODO: Remove these checks when WordPress 6.0 is released.
12126 if (name === 'core/post-comment-author') {
12127 name = 'core/comment-author-name';
12128 }
12129 if (name === 'core/post-comment-content') {
12130 name = 'core/comment-content';
12131 }
12132 if (name === 'core/post-comment-date') {
12133 name = 'core/comment-date';
12134 }
12135 if (name === 'core/comments-query-loop') {
12136 name = 'core/comments';
12137 const {
12138 className = ''
12139 } = newAttributes;
12140 if (!className.includes('wp-block-comments-query-loop')) {
12141 newAttributes.className = ['wp-block-comments-query-loop', className].join(' ');
12142 }
12143 // Note that we also had to add a deprecation to the block in order
12144 // for the ID change to work.
12145 }
12146
12147 if (name === 'core/post-comments') {
12148 name = 'core/comments';
12149 newAttributes.legacy = true;
12150 }
12151 return [name, newAttributes];
12152 }
12153
12154 ;// CONCATENATED MODULE: ./node_modules/hpq/es/get-path.js
12155 /**
12156 * Given object and string of dot-delimited path segments, returns value at
12157 * path or undefined if path cannot be resolved.
12158 *
12159 * @param {Object} object Lookup object
12160 * @param {string} path Path to resolve
12161 * @return {?*} Resolved value
12162 */
12163 function getPath(object, path) {
12164 var segments = path.split('.');
12165 var segment;
12166
12167 while (segment = segments.shift()) {
12168 if (!(segment in object)) {
12169 return;
12170 }
12171
12172 object = object[segment];
12173 }
12174
12175 return object;
12176 }
12177 ;// CONCATENATED MODULE: ./node_modules/hpq/es/index.js
12178 /**
12179 * Internal dependencies
12180 */
12181
12182 /**
12183 * Function returning a DOM document created by `createHTMLDocument`. The same
12184 * document is returned between invocations.
12185 *
12186 * @return {Document} DOM document.
12187 */
12188
12189 var getDocument = function () {
12190 var doc;
12191 return function () {
12192 if (!doc) {
12193 doc = document.implementation.createHTMLDocument('');
12194 }
12195
12196 return doc;
12197 };
12198 }();
12199 /**
12200 * Given a markup string or DOM element, creates an object aligning with the
12201 * shape of the matchers object, or the value returned by the matcher.
12202 *
12203 * @param {(string|Element)} source Source content
12204 * @param {(Object|Function)} matchers Matcher function or object of matchers
12205 * @return {(Object|*)} Matched value(s), shaped by object
12206 */
12207
12208
12209 function parse(source, matchers) {
12210 if (!matchers) {
12211 return;
12212 } // Coerce to element
12213
12214
12215 if ('string' === typeof source) {
12216 var doc = getDocument();
12217 doc.body.innerHTML = source;
12218 source = doc.body;
12219 } // Return singular value
12220
12221
12222 if ('function' === typeof matchers) {
12223 return matchers(source);
12224 } // Bail if we can't handle matchers
12225
12226
12227 if (Object !== matchers.constructor) {
12228 return;
12229 } // Shape result by matcher object
12230
12231
12232 return Object.keys(matchers).reduce(function (memo, key) {
12233 memo[key] = parse(source, matchers[key]);
12234 return memo;
12235 }, {});
12236 }
12237 /**
12238 * Generates a function which matches node of type selector, returning an
12239 * attribute by property if the attribute exists. If no selector is passed,
12240 * returns property of the query element.
12241 *
12242 * @param {?string} selector Optional selector
12243 * @param {string} name Property name
12244 * @return {*} Property value
12245 */
12246
12247 function prop(selector, name) {
12248 if (1 === arguments.length) {
12249 name = selector;
12250 selector = undefined;
12251 }
12252
12253 return function (node) {
12254 var match = node;
12255
12256 if (selector) {
12257 match = node.querySelector(selector);
12258 }
12259
12260 if (match) {
12261 return getPath(match, name);
12262 }
12263 };
12264 }
12265 /**
12266 * Generates a function which matches node of type selector, returning an
12267 * attribute by name if the attribute exists. If no selector is passed,
12268 * returns attribute of the query element.
12269 *
12270 * @param {?string} selector Optional selector
12271 * @param {string} name Attribute name
12272 * @return {?string} Attribute value
12273 */
12274
12275 function attr(selector, name) {
12276 if (1 === arguments.length) {
12277 name = selector;
12278 selector = undefined;
12279 }
12280
12281 return function (node) {
12282 var attributes = prop(selector, 'attributes')(node);
12283
12284 if (attributes && attributes.hasOwnProperty(name)) {
12285 return attributes[name].value;
12286 }
12287 };
12288 }
12289 /**
12290 * Convenience for `prop( selector, 'innerHTML' )`.
12291 *
12292 * @see prop()
12293 *
12294 * @param {?string} selector Optional selector
12295 * @return {string} Inner HTML
12296 */
12297
12298 function html(selector) {
12299 return prop(selector, 'innerHTML');
12300 }
12301 /**
12302 * Convenience for `prop( selector, 'textContent' )`.
12303 *
12304 * @see prop()
12305 *
12306 * @param {?string} selector Optional selector
12307 * @return {string} Text content
12308 */
12309
12310 function es_text(selector) {
12311 return prop(selector, 'textContent');
12312 }
12313 /**
12314 * Creates a new matching context by first finding elements matching selector
12315 * using querySelectorAll before then running another `parse` on `matchers`
12316 * scoped to the matched elements.
12317 *
12318 * @see parse()
12319 *
12320 * @param {string} selector Selector to match
12321 * @param {(Object|Function)} matchers Matcher function or object of matchers
12322 * @return {Array.<*,Object>} Array of matched value(s)
12323 */
12324
12325 function query(selector, matchers) {
12326 return function (node) {
12327 var matches = node.querySelectorAll(selector);
12328 return [].map.call(matches, function (match) {
12329 return parse(match, matchers);
12330 });
12331 };
12332 }
12333 ;// CONCATENATED MODULE: ./node_modules/memize/dist/index.js
12334 /**
12335 * Memize options object.
12336 *
12337 * @typedef MemizeOptions
12338 *
12339 * @property {number} [maxSize] Maximum size of the cache.
12340 */
12341
12342 /**
12343 * Internal cache entry.
12344 *
12345 * @typedef MemizeCacheNode
12346 *
12347 * @property {?MemizeCacheNode|undefined} [prev] Previous node.
12348 * @property {?MemizeCacheNode|undefined} [next] Next node.
12349 * @property {Array<*>} args Function arguments for cache
12350 * entry.
12351 * @property {*} val Function result.
12352 */
12353
12354 /**
12355 * Properties of the enhanced function for controlling cache.
12356 *
12357 * @typedef MemizeMemoizedFunction
12358 *
12359 * @property {()=>void} clear Clear the cache.
12360 */
12361
12362 /**
12363 * Accepts a function to be memoized, and returns a new memoized function, with
12364 * optional options.
12365 *
12366 * @template {(...args: any[]) => any} F
12367 *
12368 * @param {F} fn Function to memoize.
12369 * @param {MemizeOptions} [options] Options object.
12370 *
12371 * @return {((...args: Parameters<F>) => ReturnType<F>) & MemizeMemoizedFunction} Memoized function.
12372 */
12373 function memize(fn, options) {
12374 var size = 0;
12375
12376 /** @type {?MemizeCacheNode|undefined} */
12377 var head;
12378
12379 /** @type {?MemizeCacheNode|undefined} */
12380 var tail;
12381
12382 options = options || {};
12383
12384 function memoized(/* ...args */) {
12385 var node = head,
12386 len = arguments.length,
12387 args,
12388 i;
12389
12390 searchCache: while (node) {
12391 // Perform a shallow equality test to confirm that whether the node
12392 // under test is a candidate for the arguments passed. Two arrays
12393 // are shallowly equal if their length matches and each entry is
12394 // strictly equal between the two sets. Avoid abstracting to a
12395 // function which could incur an arguments leaking deoptimization.
12396
12397 // Check whether node arguments match arguments length
12398 if (node.args.length !== arguments.length) {
12399 node = node.next;
12400 continue;
12401 }
12402
12403 // Check whether node arguments match arguments values
12404 for (i = 0; i < len; i++) {
12405 if (node.args[i] !== arguments[i]) {
12406 node = node.next;
12407 continue searchCache;
12408 }
12409 }
12410
12411 // At this point we can assume we've found a match
12412
12413 // Surface matched node to head if not already
12414 if (node !== head) {
12415 // As tail, shift to previous. Must only shift if not also
12416 // head, since if both head and tail, there is no previous.
12417 if (node === tail) {
12418 tail = node.prev;
12419 }
12420
12421 // Adjust siblings to point to each other. If node was tail,
12422 // this also handles new tail's empty `next` assignment.
12423 /** @type {MemizeCacheNode} */ (node.prev).next = node.next;
12424 if (node.next) {
12425 node.next.prev = node.prev;
12426 }
12427
12428 node.next = head;
12429 node.prev = null;
12430 /** @type {MemizeCacheNode} */ (head).prev = node;
12431 head = node;
12432 }
12433
12434 // Return immediately
12435 return node.val;
12436 }
12437
12438 // No cached value found. Continue to insertion phase:
12439
12440 // Create a copy of arguments (avoid leaking deoptimization)
12441 args = new Array(len);
12442 for (i = 0; i < len; i++) {
12443 args[i] = arguments[i];
12444 }
12445
12446 node = {
12447 args: args,
12448
12449 // Generate the result from original function
12450 val: fn.apply(null, args),
12451 };
12452
12453 // Don't need to check whether node is already head, since it would
12454 // have been returned above already if it was
12455
12456 // Shift existing head down list
12457 if (head) {
12458 head.prev = node;
12459 node.next = head;
12460 } else {
12461 // If no head, follows that there's no tail (at initial or reset)
12462 tail = node;
12463 }
12464
12465 // Trim tail if we're reached max size and are pending cache insertion
12466 if (size === /** @type {MemizeOptions} */ (options).maxSize) {
12467 tail = /** @type {MemizeCacheNode} */ (tail).prev;
12468 /** @type {MemizeCacheNode} */ (tail).next = null;
12469 } else {
12470 size++;
12471 }
12472
12473 head = node;
12474
12475 return node.val;
12476 }
12477
12478 memoized.clear = function () {
12479 head = null;
12480 tail = null;
12481 size = 0;
12482 };
12483
12484 // Ignore reason: There's not a clear solution to create an intersection of
12485 // the function with additional properties, where the goal is to retain the
12486 // function signature of the incoming argument and add control properties
12487 // on the return value.
12488
12489 // @ts-ignore
12490 return memoized;
12491 }
12492
12493
12494
12495 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/matchers.js
12496 /**
12497 * External dependencies
12498 */
12499
12500
12501 /**
12502 * Internal dependencies
12503 */
12504
12505
12506 function matchers_html(selector, multilineTag) {
12507 return domNode => {
12508 let match = domNode;
12509 if (selector) {
12510 match = domNode.querySelector(selector);
12511 }
12512 if (!match) {
12513 return '';
12514 }
12515 if (multilineTag) {
12516 let value = '';
12517 const length = match.children.length;
12518 for (let index = 0; index < length; index++) {
12519 const child = match.children[index];
12520 if (child.nodeName.toLowerCase() !== multilineTag) {
12521 continue;
12522 }
12523 value += child.outerHTML;
12524 }
12525 return value;
12526 }
12527 return match.innerHTML;
12528 };
12529 }
12530
12531 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/node.js
12532 /**
12533 * WordPress dependencies
12534 */
12535
12536
12537 /**
12538 * Internal dependencies
12539 */
12540
12541
12542 /**
12543 * A representation of a single node within a block's rich text value. If
12544 * representing a text node, the value is simply a string of the node value.
12545 * As representing an element node, it is an object of:
12546 *
12547 * 1. `type` (string): Tag name.
12548 * 2. `props` (object): Attributes and children array of WPBlockNode.
12549 *
12550 * @typedef {string|Object} WPBlockNode
12551 */
12552
12553 /**
12554 * Given a single node and a node type (e.g. `'br'`), returns true if the node
12555 * corresponds to that type, false otherwise.
12556 *
12557 * @param {WPBlockNode} node Block node to test
12558 * @param {string} type Node to type to test against.
12559 *
12560 * @return {boolean} Whether node is of intended type.
12561 */
12562 function isNodeOfType(node, type) {
12563 external_wp_deprecated_default()('wp.blocks.node.isNodeOfType', {
12564 since: '6.1',
12565 version: '6.3',
12566 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/'
12567 });
12568 return node && node.type === type;
12569 }
12570
12571 /**
12572 * Given an object implementing the NamedNodeMap interface, returns a plain
12573 * object equivalent value of name, value key-value pairs.
12574 *
12575 * @see https://dom.spec.whatwg.org/#interface-namednodemap
12576 *
12577 * @param {NamedNodeMap} nodeMap NamedNodeMap to convert to object.
12578 *
12579 * @return {Object} Object equivalent value of NamedNodeMap.
12580 */
12581 function getNamedNodeMapAsObject(nodeMap) {
12582 const result = {};
12583 for (let i = 0; i < nodeMap.length; i++) {
12584 const {
12585 name,
12586 value
12587 } = nodeMap[i];
12588 result[name] = value;
12589 }
12590 return result;
12591 }
12592
12593 /**
12594 * Given a DOM Element or Text node, returns an equivalent block node. Throws
12595 * if passed any node type other than element or text.
12596 *
12597 * @throws {TypeError} If non-element/text node is passed.
12598 *
12599 * @param {Node} domNode DOM node to convert.
12600 *
12601 * @return {WPBlockNode} Block node equivalent to DOM node.
12602 */
12603 function fromDOM(domNode) {
12604 external_wp_deprecated_default()('wp.blocks.node.fromDOM', {
12605 since: '6.1',
12606 version: '6.3',
12607 alternative: 'wp.richText.create',
12608 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/'
12609 });
12610 if (domNode.nodeType === domNode.TEXT_NODE) {
12611 return domNode.nodeValue;
12612 }
12613 if (domNode.nodeType !== domNode.ELEMENT_NODE) {
12614 throw new TypeError('A block node can only be created from a node of type text or ' + 'element.');
12615 }
12616 return {
12617 type: domNode.nodeName.toLowerCase(),
12618 props: {
12619 ...getNamedNodeMapAsObject(domNode.attributes),
12620 children: children_fromDOM(domNode.childNodes)
12621 }
12622 };
12623 }
12624
12625 /**
12626 * Given a block node, returns its HTML string representation.
12627 *
12628 * @param {WPBlockNode} node Block node to convert to string.
12629 *
12630 * @return {string} String HTML representation of block node.
12631 */
12632 function toHTML(node) {
12633 external_wp_deprecated_default()('wp.blocks.node.toHTML', {
12634 since: '6.1',
12635 version: '6.3',
12636 alternative: 'wp.richText.toHTMLString',
12637 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/'
12638 });
12639 return children_toHTML([node]);
12640 }
12641
12642 /**
12643 * Given a selector, returns an hpq matcher generating a WPBlockNode value
12644 * matching the selector result.
12645 *
12646 * @param {string} selector DOM selector.
12647 *
12648 * @return {Function} hpq matcher.
12649 */
12650 function node_matcher(selector) {
12651 external_wp_deprecated_default()('wp.blocks.node.matcher', {
12652 since: '6.1',
12653 version: '6.3',
12654 alternative: 'html source',
12655 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/'
12656 });
12657 return domNode => {
12658 let match = domNode;
12659 if (selector) {
12660 match = domNode.querySelector(selector);
12661 }
12662 try {
12663 return fromDOM(match);
12664 } catch (error) {
12665 return null;
12666 }
12667 };
12668 }
12669
12670 /**
12671 * Object of utility functions used in managing block attribute values of
12672 * source `node`.
12673 *
12674 * @see https://github.com/WordPress/gutenberg/pull/10439
12675 *
12676 * @deprecated since 4.0. The `node` source should not be used, and can be
12677 * replaced by the `html` source.
12678 *
12679 * @private
12680 */
12681 /* harmony default export */ const node = ({
12682 isNodeOfType,
12683 fromDOM,
12684 toHTML,
12685 matcher: node_matcher
12686 });
12687
12688 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/children.js
12689 /**
12690 * WordPress dependencies
12691 */
12692
12693
12694
12695 /**
12696 * Internal dependencies
12697 */
12698
12699
12700 /**
12701 * A representation of a block's rich text value.
12702 *
12703 * @typedef {WPBlockNode[]} WPBlockChildren
12704 */
12705
12706 /**
12707 * Given block children, returns a serialize-capable WordPress element.
12708 *
12709 * @param {WPBlockChildren} children Block children object to convert.
12710 *
12711 * @return {WPElement} A serialize-capable element.
12712 */
12713 function getSerializeCapableElement(children) {
12714 // The fact that block children are compatible with the element serializer is
12715 // merely an implementation detail that currently serves to be true, but
12716 // should not be mistaken as being a guarantee on the external API. The
12717 // public API only offers guarantees to work with strings (toHTML) and DOM
12718 // elements (fromDOM), and should provide utilities to manipulate the value
12719 // rather than expect consumers to inspect or construct its shape (concat).
12720 return children;
12721 }
12722
12723 /**
12724 * Given block children, returns an array of block nodes.
12725 *
12726 * @param {WPBlockChildren} children Block children object to convert.
12727 *
12728 * @return {Array<WPBlockNode>} An array of individual block nodes.
12729 */
12730 function getChildrenArray(children) {
12731 external_wp_deprecated_default()('wp.blocks.children.getChildrenArray', {
12732 since: '6.1',
12733 version: '6.3',
12734 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/'
12735 });
12736
12737 // The fact that block children are compatible with the element serializer
12738 // is merely an implementation detail that currently serves to be true, but
12739 // should not be mistaken as being a guarantee on the external API.
12740 return children;
12741 }
12742
12743 /**
12744 * Given two or more block nodes, returns a new block node representing a
12745 * concatenation of its values.
12746 *
12747 * @param {...WPBlockChildren} blockNodes Block nodes to concatenate.
12748 *
12749 * @return {WPBlockChildren} Concatenated block node.
12750 */
12751 function concat(...blockNodes) {
12752 external_wp_deprecated_default()('wp.blocks.children.concat', {
12753 since: '6.1',
12754 version: '6.3',
12755 alternative: 'wp.richText.concat',
12756 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/'
12757 });
12758 const result = [];
12759 for (let i = 0; i < blockNodes.length; i++) {
12760 const blockNode = Array.isArray(blockNodes[i]) ? blockNodes[i] : [blockNodes[i]];
12761 for (let j = 0; j < blockNode.length; j++) {
12762 const child = blockNode[j];
12763 const canConcatToPreviousString = typeof child === 'string' && typeof result[result.length - 1] === 'string';
12764 if (canConcatToPreviousString) {
12765 result[result.length - 1] += child;
12766 } else {
12767 result.push(child);
12768 }
12769 }
12770 }
12771 return result;
12772 }
12773
12774 /**
12775 * Given an iterable set of DOM nodes, returns equivalent block children.
12776 * Ignores any non-element/text nodes included in set.
12777 *
12778 * @param {Iterable.<Node>} domNodes Iterable set of DOM nodes to convert.
12779 *
12780 * @return {WPBlockChildren} Block children equivalent to DOM nodes.
12781 */
12782 function children_fromDOM(domNodes) {
12783 external_wp_deprecated_default()('wp.blocks.children.fromDOM', {
12784 since: '6.1',
12785 version: '6.3',
12786 alternative: 'wp.richText.create',
12787 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/'
12788 });
12789 const result = [];
12790 for (let i = 0; i < domNodes.length; i++) {
12791 try {
12792 result.push(fromDOM(domNodes[i]));
12793 } catch (error) {
12794 // Simply ignore if DOM node could not be converted.
12795 }
12796 }
12797 return result;
12798 }
12799
12800 /**
12801 * Given a block node, returns its HTML string representation.
12802 *
12803 * @param {WPBlockChildren} children Block node(s) to convert to string.
12804 *
12805 * @return {string} String HTML representation of block node.
12806 */
12807 function children_toHTML(children) {
12808 external_wp_deprecated_default()('wp.blocks.children.toHTML', {
12809 since: '6.1',
12810 version: '6.3',
12811 alternative: 'wp.richText.toHTMLString',
12812 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/'
12813 });
12814 const element = getSerializeCapableElement(children);
12815 return (0,external_wp_element_namespaceObject.renderToString)(element);
12816 }
12817
12818 /**
12819 * Given a selector, returns an hpq matcher generating a WPBlockChildren value
12820 * matching the selector result.
12821 *
12822 * @param {string} selector DOM selector.
12823 *
12824 * @return {Function} hpq matcher.
12825 */
12826 function children_matcher(selector) {
12827 external_wp_deprecated_default()('wp.blocks.children.matcher', {
12828 since: '6.1',
12829 version: '6.3',
12830 alternative: 'html source',
12831 link: 'https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/introducing-attributes-and-editable-fields/'
12832 });
12833 return domNode => {
12834 let match = domNode;
12835 if (selector) {
12836 match = domNode.querySelector(selector);
12837 }
12838 if (match) {
12839 return children_fromDOM(match.childNodes);
12840 }
12841 return [];
12842 };
12843 }
12844
12845 /**
12846 * Object of utility functions used in managing block attribute values of
12847 * source `children`.
12848 *
12849 * @see https://github.com/WordPress/gutenberg/pull/10439
12850 *
12851 * @deprecated since 4.0. The `children` source should not be used, and can be
12852 * replaced by the `html` source.
12853 *
12854 * @private
12855 */
12856 /* harmony default export */ const children = ({
12857 concat,
12858 getChildrenArray,
12859 fromDOM: children_fromDOM,
12860 toHTML: children_toHTML,
12861 matcher: children_matcher
12862 });
12863
12864 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/parser/get-block-attributes.js
12865 /**
12866 * External dependencies
12867 */
12868
12869
12870
12871 /**
12872 * WordPress dependencies
12873 */
12874
12875
12876
12877 /**
12878 * Internal dependencies
12879 */
12880
12881
12882
12883 /**
12884 * Higher-order hpq matcher which enhances an attribute matcher to return true
12885 * or false depending on whether the original matcher returns undefined. This
12886 * is useful for boolean attributes (e.g. disabled) whose attribute values may
12887 * be technically falsey (empty string), though their mere presence should be
12888 * enough to infer as true.
12889 *
12890 * @param {Function} matcher Original hpq matcher.
12891 *
12892 * @return {Function} Enhanced hpq matcher.
12893 */
12894 const toBooleanAttributeMatcher = matcher => (0,external_wp_compose_namespaceObject.pipe)([matcher,
12895 // Expected values from `attr( 'disabled' )`:
12896 //
12897 // <input>
12898 // - Value: `undefined`
12899 // - Transformed: `false`
12900 //
12901 // <input disabled>
12902 // - Value: `''`
12903 // - Transformed: `true`
12904 //
12905 // <input disabled="disabled">
12906 // - Value: `'disabled'`
12907 // - Transformed: `true`
12908 value => value !== undefined]);
12909
12910 /**
12911 * Returns true if value is of the given JSON schema type, or false otherwise.
12912 *
12913 * @see http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.25
12914 *
12915 * @param {*} value Value to test.
12916 * @param {string} type Type to test.
12917 *
12918 * @return {boolean} Whether value is of type.
12919 */
12920 function isOfType(value, type) {
12921 switch (type) {
12922 case 'string':
12923 return typeof value === 'string';
12924 case 'boolean':
12925 return typeof value === 'boolean';
12926 case 'object':
12927 return !!value && value.constructor === Object;
12928 case 'null':
12929 return value === null;
12930 case 'array':
12931 return Array.isArray(value);
12932 case 'integer':
12933 case 'number':
12934 return typeof value === 'number';
12935 }
12936 return true;
12937 }
12938
12939 /**
12940 * Returns true if value is of an array of given JSON schema types, or false
12941 * otherwise.
12942 *
12943 * @see http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.25
12944 *
12945 * @param {*} value Value to test.
12946 * @param {string[]} types Types to test.
12947 *
12948 * @return {boolean} Whether value is of types.
12949 */
12950 function isOfTypes(value, types) {
12951 return types.some(type => isOfType(value, type));
12952 }
12953
12954 /**
12955 * Given an attribute key, an attribute's schema, a block's raw content and the
12956 * commentAttributes returns the attribute value depending on its source
12957 * definition of the given attribute key.
12958 *
12959 * @param {string} attributeKey Attribute key.
12960 * @param {Object} attributeSchema Attribute's schema.
12961 * @param {Node} innerDOM Parsed DOM of block's inner HTML.
12962 * @param {Object} commentAttributes Block's comment attributes.
12963 * @param {string} innerHTML Raw HTML from block node's innerHTML property.
12964 *
12965 * @return {*} Attribute value.
12966 */
12967 function getBlockAttribute(attributeKey, attributeSchema, innerDOM, commentAttributes, innerHTML) {
12968 let value;
12969 switch (attributeSchema.source) {
12970 // An undefined source means that it's an attribute serialized to the
12971 // block's "comment".
12972 case undefined:
12973 value = commentAttributes ? commentAttributes[attributeKey] : undefined;
12974 break;
12975 // raw source means that it's the original raw block content.
12976 case 'raw':
12977 value = innerHTML;
12978 break;
12979 case 'attribute':
12980 case 'property':
12981 case 'html':
12982 case 'text':
12983 case 'children':
12984 case 'node':
12985 case 'query':
12986 case 'tag':
12987 value = parseWithAttributeSchema(innerDOM, attributeSchema);
12988 break;
12989 }
12990 if (!isValidByType(value, attributeSchema.type) || !isValidByEnum(value, attributeSchema.enum)) {
12991 // Reject the value if it is not valid. Reverting to the undefined
12992 // value ensures the default is respected, if applicable.
12993 value = undefined;
12994 }
12995 if (value === undefined) {
12996 value = attributeSchema.default;
12997 }
12998 return value;
12999 }
13000
13001 /**
13002 * Returns true if value is valid per the given block attribute schema type
13003 * definition, or false otherwise.
13004 *
13005 * @see https://json-schema.org/latest/json-schema-validation.html#rfc.section.6.1.1
13006 *
13007 * @param {*} value Value to test.
13008 * @param {?(Array<string>|string)} type Block attribute schema type.
13009 *
13010 * @return {boolean} Whether value is valid.
13011 */
13012 function isValidByType(value, type) {
13013 return type === undefined || isOfTypes(value, Array.isArray(type) ? type : [type]);
13014 }
13015
13016 /**
13017 * Returns true if value is valid per the given block attribute schema enum
13018 * definition, or false otherwise.
13019 *
13020 * @see https://json-schema.org/latest/json-schema-validation.html#rfc.section.6.1.2
13021 *
13022 * @param {*} value Value to test.
13023 * @param {?Array} enumSet Block attribute schema enum.
13024 *
13025 * @return {boolean} Whether value is valid.
13026 */
13027 function isValidByEnum(value, enumSet) {
13028 return !Array.isArray(enumSet) || enumSet.includes(value);
13029 }
13030
13031 /**
13032 * Returns an hpq matcher given a source object.
13033 *
13034 * @param {Object} sourceConfig Attribute Source object.
13035 *
13036 * @return {Function} A hpq Matcher.
13037 */
13038 const matcherFromSource = memize(sourceConfig => {
13039 switch (sourceConfig.source) {
13040 case 'attribute':
13041 let matcher = attr(sourceConfig.selector, sourceConfig.attribute);
13042 if (sourceConfig.type === 'boolean') {
13043 matcher = toBooleanAttributeMatcher(matcher);
13044 }
13045 return matcher;
13046 case 'html':
13047 return matchers_html(sourceConfig.selector, sourceConfig.multiline);
13048 case 'text':
13049 return es_text(sourceConfig.selector);
13050 case 'children':
13051 return children_matcher(sourceConfig.selector);
13052 case 'node':
13053 return node_matcher(sourceConfig.selector);
13054 case 'query':
13055 const subMatchers = Object.fromEntries(Object.entries(sourceConfig.query).map(([key, subSourceConfig]) => [key, matcherFromSource(subSourceConfig)]));
13056 return query(sourceConfig.selector, subMatchers);
13057 case 'tag':
13058 return (0,external_wp_compose_namespaceObject.pipe)([prop(sourceConfig.selector, 'nodeName'), nodeName => nodeName ? nodeName.toLowerCase() : undefined]);
13059 default:
13060 // eslint-disable-next-line no-console
13061 console.error(`Unknown source type "${sourceConfig.source}"`);
13062 }
13063 });
13064
13065 /**
13066 * Parse a HTML string into DOM tree.
13067 *
13068 * @param {string|Node} innerHTML HTML string or already parsed DOM node.
13069 *
13070 * @return {Node} Parsed DOM node.
13071 */
13072 function parseHtml(innerHTML) {
13073 return parse(innerHTML, h => h);
13074 }
13075
13076 /**
13077 * Given a block's raw content and an attribute's schema returns the attribute's
13078 * value depending on its source.
13079 *
13080 * @param {string|Node} innerHTML Block's raw content.
13081 * @param {Object} attributeSchema Attribute's schema.
13082 *
13083 * @return {*} Attribute value.
13084 */
13085 function parseWithAttributeSchema(innerHTML, attributeSchema) {
13086 return matcherFromSource(attributeSchema)(parseHtml(innerHTML));
13087 }
13088
13089 /**
13090 * Returns the block attributes of a registered block node given its type.
13091 *
13092 * @param {string|Object} blockTypeOrName Block type or name.
13093 * @param {string|Node} innerHTML Raw block content.
13094 * @param {?Object} attributes Known block attributes (from delimiters).
13095 *
13096 * @return {Object} All block attributes.
13097 */
13098 function getBlockAttributes(blockTypeOrName, innerHTML, attributes = {}) {
13099 var _blockType$attributes;
13100 const doc = parseHtml(innerHTML);
13101 const blockType = normalizeBlockType(blockTypeOrName);
13102 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)]));
13103 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getBlockAttributes', blockAttributes, blockType, innerHTML, attributes);
13104 }
13105
13106 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/parser/fix-custom-classname.js
13107 /**
13108 * Internal dependencies
13109 */
13110
13111
13112
13113 const CLASS_ATTR_SCHEMA = {
13114 type: 'string',
13115 source: 'attribute',
13116 selector: '[data-custom-class-name] > *',
13117 attribute: 'class'
13118 };
13119
13120 /**
13121 * Given an HTML string, returns an array of class names assigned to the root
13122 * element in the markup.
13123 *
13124 * @param {string} innerHTML Markup string from which to extract classes.
13125 *
13126 * @return {string[]} Array of class names assigned to the root element.
13127 */
13128 function getHTMLRootElementClasses(innerHTML) {
13129 const parsed = parseWithAttributeSchema(`<div data-custom-class-name>${innerHTML}</div>`, CLASS_ATTR_SCHEMA);
13130 return parsed ? parsed.trim().split(/\s+/) : [];
13131 }
13132
13133 /**
13134 * Given a parsed set of block attributes, if the block supports custom class
13135 * names and an unknown class (per the block's serialization behavior) is
13136 * found, the unknown classes are treated as custom classes. This prevents the
13137 * block from being considered as invalid.
13138 *
13139 * @param {Object} blockAttributes Original block attributes.
13140 * @param {Object} blockType Block type settings.
13141 * @param {string} innerHTML Original block markup.
13142 *
13143 * @return {Object} Filtered block attributes.
13144 */
13145 function fixCustomClassname(blockAttributes, blockType, innerHTML) {
13146 if (hasBlockSupport(blockType, 'customClassName', true)) {
13147 // To determine difference, serialize block given the known set of
13148 // attributes, with the exception of `className`. This will determine
13149 // the default set of classes. From there, any difference in innerHTML
13150 // can be considered as custom classes.
13151 const {
13152 className: omittedClassName,
13153 ...attributesSansClassName
13154 } = blockAttributes;
13155 const serialized = getSaveContent(blockType, attributesSansClassName);
13156 const defaultClasses = getHTMLRootElementClasses(serialized);
13157 const actualClasses = getHTMLRootElementClasses(innerHTML);
13158 const customClasses = actualClasses.filter(className => !defaultClasses.includes(className));
13159 if (customClasses.length) {
13160 blockAttributes.className = customClasses.join(' ');
13161 } else if (serialized) {
13162 delete blockAttributes.className;
13163 }
13164 }
13165 return blockAttributes;
13166 }
13167
13168 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/parser/apply-built-in-validation-fixes.js
13169 /**
13170 * Internal dependencies
13171 */
13172
13173
13174 /**
13175 * Attempts to fix block invalidation by applying build-in validation fixes
13176 * like moving all extra classNames to the className attribute.
13177 *
13178 * @param {WPBlock} block block object.
13179 * @param {import('../registration').WPBlockType} blockType Block type. This is normalize not necessary and
13180 * can be inferred from the block name,
13181 * but it's here for performance reasons.
13182 *
13183 * @return {WPBlock} Fixed block object
13184 */
13185 function applyBuiltInValidationFixes(block, blockType) {
13186 const updatedBlockAttributes = fixCustomClassname(block.attributes, blockType, block.originalContent);
13187 return {
13188 ...block,
13189 attributes: updatedBlockAttributes
13190 };
13191 }
13192
13193 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/parser/apply-block-deprecated-versions.js
13194 /**
13195 * Internal dependencies
13196 */
13197
13198
13199
13200
13201
13202
13203 /**
13204 * Function that takes no arguments and always returns false.
13205 *
13206 * @return {boolean} Always returns false.
13207 */
13208 function stubFalse() {
13209 return false;
13210 }
13211
13212 /**
13213 * Given a block object, returns a new copy of the block with any applicable
13214 * deprecated migrations applied, or the original block if it was both valid
13215 * and no eligible migrations exist.
13216 *
13217 * @param {import(".").WPBlock} block Parsed and invalid block object.
13218 * @param {import(".").WPRawBlock} rawBlock Raw block object.
13219 * @param {import('../registration').WPBlockType} blockType Block type. This is normalize not necessary and
13220 * can be inferred from the block name,
13221 * but it's here for performance reasons.
13222 *
13223 * @return {import(".").WPBlock} Migrated block object.
13224 */
13225 function applyBlockDeprecatedVersions(block, rawBlock, blockType) {
13226 const parsedAttributes = rawBlock.attrs;
13227 const {
13228 deprecated: deprecatedDefinitions
13229 } = blockType;
13230 // Bail early if there are no registered deprecations to be handled.
13231 if (!deprecatedDefinitions || !deprecatedDefinitions.length) {
13232 return block;
13233 }
13234
13235 // By design, blocks lack any sort of version tracking. Instead, to process
13236 // outdated content the system operates a queue out of all the defined
13237 // attribute shapes and tries each definition until the input produces a
13238 // valid result. This mechanism seeks to avoid polluting the user-space with
13239 // machine-specific code. An invalid block is thus a block that could not be
13240 // matched successfully with any of the registered deprecation definitions.
13241 for (let i = 0; i < deprecatedDefinitions.length; i++) {
13242 // A block can opt into a migration even if the block is valid by
13243 // defining `isEligible` on its deprecation. If the block is both valid
13244 // and does not opt to migrate, skip.
13245 const {
13246 isEligible = stubFalse
13247 } = deprecatedDefinitions[i];
13248 if (block.isValid && !isEligible(parsedAttributes, block.innerBlocks, {
13249 blockNode: rawBlock,
13250 block
13251 })) {
13252 continue;
13253 }
13254
13255 // Block type properties which could impact either serialization or
13256 // parsing are not considered in the deprecated block type by default,
13257 // and must be explicitly provided.
13258 const deprecatedBlockType = Object.assign(omit(blockType, DEPRECATED_ENTRY_KEYS), deprecatedDefinitions[i]);
13259 let migratedBlock = {
13260 ...block,
13261 attributes: getBlockAttributes(deprecatedBlockType, block.originalContent, parsedAttributes)
13262 };
13263
13264 // Ignore the deprecation if it produces a block which is not valid.
13265 let [isValid] = validateBlock(migratedBlock, deprecatedBlockType);
13266
13267 // If the migrated block is not valid initially, try the built-in fixes.
13268 if (!isValid) {
13269 migratedBlock = applyBuiltInValidationFixes(migratedBlock, deprecatedBlockType);
13270 [isValid] = validateBlock(migratedBlock, deprecatedBlockType);
13271 }
13272
13273 // An invalid block does not imply incorrect HTML but the fact block
13274 // source information could be lost on re-serialization.
13275 if (!isValid) {
13276 continue;
13277 }
13278 let migratedInnerBlocks = migratedBlock.innerBlocks;
13279 let migratedAttributes = migratedBlock.attributes;
13280
13281 // A block may provide custom behavior to assign new attributes and/or
13282 // inner blocks.
13283 const {
13284 migrate
13285 } = deprecatedBlockType;
13286 if (migrate) {
13287 let migrated = migrate(migratedAttributes, block.innerBlocks);
13288 if (!Array.isArray(migrated)) {
13289 migrated = [migrated];
13290 }
13291 [migratedAttributes = parsedAttributes, migratedInnerBlocks = block.innerBlocks] = migrated;
13292 }
13293 block = {
13294 ...block,
13295 attributes: migratedAttributes,
13296 innerBlocks: migratedInnerBlocks,
13297 isValid: true,
13298 validationIssues: []
13299 };
13300 }
13301 return block;
13302 }
13303
13304 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/parser/index.js
13305 /**
13306 * WordPress dependencies
13307 */
13308
13309
13310
13311 /**
13312 * Internal dependencies
13313 */
13314
13315
13316
13317
13318
13319
13320
13321
13322
13323
13324 /**
13325 * The raw structure of a block includes its attributes, inner
13326 * blocks, and inner HTML. It is important to distinguish inner blocks from
13327 * the HTML content of the block as only the latter is relevant for block
13328 * validation and edit operations.
13329 *
13330 * @typedef WPRawBlock
13331 *
13332 * @property {string=} blockName Block name
13333 * @property {Object=} attrs Block raw or comment attributes.
13334 * @property {string} innerHTML HTML content of the block.
13335 * @property {(string|null)[]} innerContent Content without inner blocks.
13336 * @property {WPRawBlock[]} innerBlocks Inner Blocks.
13337 */
13338
13339 /**
13340 * Fully parsed block object.
13341 *
13342 * @typedef WPBlock
13343 *
13344 * @property {string} name Block name
13345 * @property {Object} attributes Block raw or comment attributes.
13346 * @property {WPBlock[]} innerBlocks Inner Blocks.
13347 * @property {string} originalContent Original content of the block before validation fixes.
13348 * @property {boolean} isValid Whether the block is valid.
13349 * @property {Object[]} validationIssues Validation issues.
13350 * @property {WPRawBlock} [__unstableBlockSource] Un-processed original copy of block if created through parser.
13351 */
13352
13353 /**
13354 * @typedef {Object} ParseOptions
13355 * @property {boolean?} __unstableSkipMigrationLogs If a block is migrated from a deprecated version, skip logging the migration details.
13356 * @property {boolean?} __unstableSkipAutop Whether to skip autop when processing freeform content.
13357 */
13358
13359 /**
13360 * Convert legacy blocks to their canonical form. This function is used
13361 * both in the parser level for previous content and to convert such blocks
13362 * used in Custom Post Types templates.
13363 *
13364 * @param {WPRawBlock} rawBlock
13365 *
13366 * @return {WPRawBlock} The block's name and attributes, changed accordingly if a match was found
13367 */
13368 function convertLegacyBlocks(rawBlock) {
13369 const [correctName, correctedAttributes] = convertLegacyBlockNameAndAttributes(rawBlock.blockName, rawBlock.attrs);
13370 return {
13371 ...rawBlock,
13372 blockName: correctName,
13373 attrs: correctedAttributes
13374 };
13375 }
13376
13377 /**
13378 * Normalize the raw block by applying the fallback block name if none given,
13379 * sanitize the parsed HTML...
13380 *
13381 * @param {WPRawBlock} rawBlock The raw block object.
13382 * @param {ParseOptions?} options Extra options for handling block parsing.
13383 *
13384 * @return {WPRawBlock} The normalized block object.
13385 */
13386 function normalizeRawBlock(rawBlock, options) {
13387 const fallbackBlockName = getFreeformContentHandlerName();
13388
13389 // If the grammar parsing don't produce any block name, use the freeform block.
13390 const rawBlockName = rawBlock.blockName || getFreeformContentHandlerName();
13391 const rawAttributes = rawBlock.attrs || {};
13392 const rawInnerBlocks = rawBlock.innerBlocks || [];
13393 let rawInnerHTML = rawBlock.innerHTML.trim();
13394
13395 // Fallback content may be upgraded from classic content expecting implicit
13396 // automatic paragraphs, so preserve them. Assumes wpautop is idempotent,
13397 // meaning there are no negative consequences to repeated autop calls.
13398 if (rawBlockName === fallbackBlockName && rawBlockName === 'core/freeform' && !options?.__unstableSkipAutop) {
13399 rawInnerHTML = (0,external_wp_autop_namespaceObject.autop)(rawInnerHTML).trim();
13400 }
13401 return {
13402 ...rawBlock,
13403 blockName: rawBlockName,
13404 attrs: rawAttributes,
13405 innerHTML: rawInnerHTML,
13406 innerBlocks: rawInnerBlocks
13407 };
13408 }
13409
13410 /**
13411 * Uses the "unregistered blockType" to create a block object.
13412 *
13413 * @param {WPRawBlock} rawBlock block.
13414 *
13415 * @return {WPRawBlock} The unregistered block object.
13416 */
13417 function createMissingBlockType(rawBlock) {
13418 const unregisteredFallbackBlock = getUnregisteredTypeHandlerName() || getFreeformContentHandlerName();
13419
13420 // Preserve undelimited content for use by the unregistered type
13421 // handler. A block node's `innerHTML` isn't enough, as that field only
13422 // carries the block's own HTML and not its nested blocks.
13423 const originalUndelimitedContent = serializeRawBlock(rawBlock, {
13424 isCommentDelimited: false
13425 });
13426
13427 // Preserve full block content for use by the unregistered type
13428 // handler, block boundaries included.
13429 const originalContent = serializeRawBlock(rawBlock, {
13430 isCommentDelimited: true
13431 });
13432 return {
13433 blockName: unregisteredFallbackBlock,
13434 attrs: {
13435 originalName: rawBlock.blockName,
13436 originalContent,
13437 originalUndelimitedContent
13438 },
13439 innerHTML: rawBlock.blockName ? originalContent : rawBlock.innerHTML,
13440 innerBlocks: rawBlock.innerBlocks,
13441 innerContent: rawBlock.innerContent
13442 };
13443 }
13444
13445 /**
13446 * Validates a block and wraps with validation meta.
13447 *
13448 * The name here is regrettable but `validateBlock` is already taken.
13449 *
13450 * @param {WPBlock} unvalidatedBlock
13451 * @param {import('../registration').WPBlockType} blockType
13452 * @return {WPBlock} validated block, with auto-fixes if initially invalid
13453 */
13454 function applyBlockValidation(unvalidatedBlock, blockType) {
13455 // Attempt to validate the block.
13456 const [isValid] = validateBlock(unvalidatedBlock, blockType);
13457 if (isValid) {
13458 return {
13459 ...unvalidatedBlock,
13460 isValid,
13461 validationIssues: []
13462 };
13463 }
13464
13465 // If the block is invalid, attempt some built-in fixes
13466 // like custom classNames handling.
13467 const fixedBlock = applyBuiltInValidationFixes(unvalidatedBlock, blockType);
13468 // Attempt to validate the block once again after the built-in fixes.
13469 const [isFixedValid, validationIssues] = validateBlock(unvalidatedBlock, blockType);
13470 return {
13471 ...fixedBlock,
13472 isValid: isFixedValid,
13473 validationIssues
13474 };
13475 }
13476
13477 /**
13478 * Given a raw block returned by grammar parsing, returns a fully parsed block.
13479 *
13480 * @param {WPRawBlock} rawBlock The raw block object.
13481 * @param {ParseOptions} options Extra options for handling block parsing.
13482 *
13483 * @return {WPBlock | undefined} Fully parsed block.
13484 */
13485 function parseRawBlock(rawBlock, options) {
13486 let normalizedBlock = normalizeRawBlock(rawBlock, options);
13487
13488 // During the lifecycle of the project, we renamed some old blocks
13489 // and transformed others to new blocks. To avoid breaking existing content,
13490 // we added this function to properly parse the old content.
13491 normalizedBlock = convertLegacyBlocks(normalizedBlock);
13492
13493 // Try finding the type for known block name.
13494 let blockType = getBlockType(normalizedBlock.blockName);
13495
13496 // If not blockType is found for the specified name, fallback to the "unregistedBlockType".
13497 if (!blockType) {
13498 normalizedBlock = createMissingBlockType(normalizedBlock);
13499 blockType = getBlockType(normalizedBlock.blockName);
13500 }
13501
13502 // If it's an empty freeform block or there's no blockType (no missing block handler)
13503 // Then, just ignore the block.
13504 // It might be a good idea to throw a warning here.
13505 // TODO: I'm unsure about the unregisteredFallbackBlock check,
13506 // it might ignore some dynamic unregistered third party blocks wrongly.
13507 const isFallbackBlock = normalizedBlock.blockName === getFreeformContentHandlerName() || normalizedBlock.blockName === getUnregisteredTypeHandlerName();
13508 if (!blockType || !normalizedBlock.innerHTML && isFallbackBlock) {
13509 return;
13510 }
13511
13512 // Parse inner blocks recursively.
13513 const parsedInnerBlocks = normalizedBlock.innerBlocks.map(innerBlock => parseRawBlock(innerBlock, options))
13514 // See https://github.com/WordPress/gutenberg/pull/17164.
13515 .filter(innerBlock => !!innerBlock);
13516
13517 // Get the fully parsed block.
13518 const parsedBlock = createBlock(normalizedBlock.blockName, getBlockAttributes(blockType, normalizedBlock.innerHTML, normalizedBlock.attrs), parsedInnerBlocks);
13519 parsedBlock.originalContent = normalizedBlock.innerHTML;
13520 const validatedBlock = applyBlockValidation(parsedBlock, blockType);
13521 const {
13522 validationIssues
13523 } = validatedBlock;
13524
13525 // Run the block deprecation and migrations.
13526 // This is performed on both invalid and valid blocks because
13527 // migration using the `migrate` functions should run even
13528 // if the output is deemed valid.
13529 const updatedBlock = applyBlockDeprecatedVersions(validatedBlock, normalizedBlock, blockType);
13530 if (!updatedBlock.isValid) {
13531 // Preserve the original unprocessed version of the block
13532 // that we received (no fixes, no deprecations) so that
13533 // we can save it as close to exactly the same way as
13534 // we loaded it. This is important to avoid corruption
13535 // and data loss caused by block implementations trying
13536 // to process data that isn't fully recognized.
13537 updatedBlock.__unstableBlockSource = rawBlock;
13538 }
13539 if (!validatedBlock.isValid && updatedBlock.isValid && !options?.__unstableSkipMigrationLogs) {
13540 /* eslint-disable no-console */
13541 console.groupCollapsed('Updated Block: %s', blockType.name);
13542 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);
13543 console.groupEnd();
13544 /* eslint-enable no-console */
13545 } else if (!validatedBlock.isValid && !updatedBlock.isValid) {
13546 validationIssues.forEach(({
13547 log,
13548 args
13549 }) => log(...args));
13550 }
13551 return updatedBlock;
13552 }
13553
13554 /**
13555 * Utilizes an optimized token-driven parser based on the Gutenberg grammar spec
13556 * defined through a parsing expression grammar to take advantage of the regular
13557 * cadence provided by block delimiters -- composed syntactically through HTML
13558 * comments -- which, given a general HTML document as an input, returns a block
13559 * list array representation.
13560 *
13561 * This is a recursive-descent parser that scans linearly once through the input
13562 * document. Instead of directly recursing it utilizes a trampoline mechanism to
13563 * prevent stack overflow. This initial pass is mainly interested in separating
13564 * and isolating the blocks serialized in the document and manifestly not in the
13565 * content within the blocks.
13566 *
13567 * @see
13568 * https://developer.wordpress.org/block-editor/packages/packages-block-serialization-default-parser/
13569 *
13570 * @param {string} content The post content.
13571 * @param {ParseOptions} options Extra options for handling block parsing.
13572 *
13573 * @return {Array} Block list.
13574 */
13575 function parser_parse(content, options) {
13576 return (0,external_wp_blockSerializationDefaultParser_namespaceObject.parse)(content).reduce((accumulator, rawBlock) => {
13577 const block = parseRawBlock(rawBlock, options);
13578 if (block) {
13579 accumulator.push(block);
13580 }
13581 return accumulator;
13582 }, []);
13583 }
13584
13585 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/get-raw-transforms.js
13586 /**
13587 * Internal dependencies
13588 */
13589
13590 function getRawTransforms() {
13591 return getBlockTransforms('from').filter(({
13592 type
13593 }) => type === 'raw').map(transform => {
13594 return transform.isMatch ? transform : {
13595 ...transform,
13596 isMatch: node => transform.selector && node.matches(transform.selector)
13597 };
13598 });
13599 }
13600
13601 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/html-to-blocks.js
13602 /**
13603 * Internal dependencies
13604 */
13605
13606
13607
13608
13609 /**
13610 * Converts HTML directly to blocks. Looks for a matching transform for each
13611 * top-level tag. The HTML should be filtered to not have any text between
13612 * top-level tags and formatted in a way that blocks can handle the HTML.
13613 *
13614 * @param {string} html HTML to convert.
13615 * @param {Function} handler The handler calling htmlToBlocks: either rawHandler
13616 * or pasteHandler.
13617 *
13618 * @return {Array} An array of blocks.
13619 */
13620 function htmlToBlocks(html, handler) {
13621 const doc = document.implementation.createHTMLDocument('');
13622 doc.body.innerHTML = html;
13623 return Array.from(doc.body.children).flatMap(node => {
13624 const rawTransform = findTransform(getRawTransforms(), ({
13625 isMatch
13626 }) => isMatch(node));
13627 if (!rawTransform) {
13628 return createBlock(
13629 // Should not be hardcoded.
13630 'core/html', getBlockAttributes('core/html', node.outerHTML));
13631 }
13632 const {
13633 transform,
13634 blockName
13635 } = rawTransform;
13636 if (transform) {
13637 return transform(node, handler);
13638 }
13639 return createBlock(blockName, getBlockAttributes(blockName, node.outerHTML));
13640 });
13641 }
13642
13643 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/normalise-blocks.js
13644 /**
13645 * WordPress dependencies
13646 */
13647
13648 function normaliseBlocks(HTML) {
13649 const decuDoc = document.implementation.createHTMLDocument('');
13650 const accuDoc = document.implementation.createHTMLDocument('');
13651 const decu = decuDoc.body;
13652 const accu = accuDoc.body;
13653 decu.innerHTML = HTML;
13654 while (decu.firstChild) {
13655 const node = decu.firstChild;
13656
13657 // Text nodes: wrap in a paragraph, or append to previous.
13658 if (node.nodeType === node.TEXT_NODE) {
13659 if ((0,external_wp_dom_namespaceObject.isEmpty)(node)) {
13660 decu.removeChild(node);
13661 } else {
13662 if (!accu.lastChild || accu.lastChild.nodeName !== 'P') {
13663 accu.appendChild(accuDoc.createElement('P'));
13664 }
13665 accu.lastChild.appendChild(node);
13666 }
13667 // Element nodes.
13668 } else if (node.nodeType === node.ELEMENT_NODE) {
13669 // BR nodes: create a new paragraph on double, or append to previous.
13670 if (node.nodeName === 'BR') {
13671 if (node.nextSibling && node.nextSibling.nodeName === 'BR') {
13672 accu.appendChild(accuDoc.createElement('P'));
13673 decu.removeChild(node.nextSibling);
13674 }
13675
13676 // Don't append to an empty paragraph.
13677 if (accu.lastChild && accu.lastChild.nodeName === 'P' && accu.lastChild.hasChildNodes()) {
13678 accu.lastChild.appendChild(node);
13679 } else {
13680 decu.removeChild(node);
13681 }
13682 } else if (node.nodeName === 'P') {
13683 // Only append non-empty paragraph nodes.
13684 if ((0,external_wp_dom_namespaceObject.isEmpty)(node)) {
13685 decu.removeChild(node);
13686 } else {
13687 accu.appendChild(node);
13688 }
13689 } else if ((0,external_wp_dom_namespaceObject.isPhrasingContent)(node)) {
13690 if (!accu.lastChild || accu.lastChild.nodeName !== 'P') {
13691 accu.appendChild(accuDoc.createElement('P'));
13692 }
13693 accu.lastChild.appendChild(node);
13694 } else {
13695 accu.appendChild(node);
13696 }
13697 } else {
13698 decu.removeChild(node);
13699 }
13700 }
13701 return accu.innerHTML;
13702 }
13703
13704 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/special-comment-converter.js
13705 /**
13706 * WordPress dependencies
13707 */
13708
13709
13710 /**
13711 * Looks for `<!--nextpage-->` and `<!--more-->` comments and
13712 * replaces them with a custom element representing a future block.
13713 *
13714 * The custom element is a way to bypass the rest of the `raw-handling`
13715 * transforms, which would eliminate other kinds of node with which to carry
13716 * `<!--more-->`'s data: nodes with `data` attributes, empty paragraphs, etc.
13717 *
13718 * The custom element is then expected to be recognized by any registered
13719 * block's `raw` transform.
13720 *
13721 * @param {Node} node The node to be processed.
13722 * @param {Document} doc The document of the node.
13723 * @return {void}
13724 */
13725 function specialCommentConverter(node, doc) {
13726 if (node.nodeType !== node.COMMENT_NODE) {
13727 return;
13728 }
13729 if (node.nodeValue === 'nextpage') {
13730 (0,external_wp_dom_namespaceObject.replace)(node, createNextpage(doc));
13731 return;
13732 }
13733 if (node.nodeValue.indexOf('more') === 0) {
13734 moreCommentConverter(node, doc);
13735 }
13736 }
13737
13738 /**
13739 * Convert `<!--more-->` as well as the `<!--more Some text-->` variant
13740 * and its `<!--noteaser-->` companion into the custom element
13741 * described in `specialCommentConverter()`.
13742 *
13743 * @param {Node} node The node to be processed.
13744 * @param {Document} doc The document of the node.
13745 * @return {void}
13746 */
13747 function moreCommentConverter(node, doc) {
13748 // Grab any custom text in the comment.
13749 const customText = node.nodeValue.slice(4).trim();
13750
13751 /*
13752 * When a `<!--more-->` comment is found, we need to look for any
13753 * `<!--noteaser-->` sibling, but it may not be a direct sibling
13754 * (whitespace typically lies in between)
13755 */
13756 let sibling = node;
13757 let noTeaser = false;
13758 while (sibling = sibling.nextSibling) {
13759 if (sibling.nodeType === sibling.COMMENT_NODE && sibling.nodeValue === 'noteaser') {
13760 noTeaser = true;
13761 (0,external_wp_dom_namespaceObject.remove)(sibling);
13762 break;
13763 }
13764 }
13765 const moreBlock = createMore(customText, noTeaser, doc);
13766
13767 // If our `<!--more-->` comment is in the middle of a paragraph, we should
13768 // split the paragraph in two and insert the more block in between. If not,
13769 // the more block will eventually end up being inserted after the paragraph.
13770 if (!node.parentNode || node.parentNode.nodeName !== 'P' || node.parentNode.childNodes.length === 1) {
13771 (0,external_wp_dom_namespaceObject.replace)(node, moreBlock);
13772 } else {
13773 const childNodes = Array.from(node.parentNode.childNodes);
13774 const nodeIndex = childNodes.indexOf(node);
13775 const wrapperNode = node.parentNode.parentNode || doc.body;
13776 const paragraphBuilder = (acc, child) => {
13777 if (!acc) {
13778 acc = doc.createElement('p');
13779 }
13780 acc.appendChild(child);
13781 return acc;
13782 };
13783
13784 // Split the original parent node and insert our more block
13785 [childNodes.slice(0, nodeIndex).reduce(paragraphBuilder, null), moreBlock, childNodes.slice(nodeIndex + 1).reduce(paragraphBuilder, null)].forEach(element => element && wrapperNode.insertBefore(element, node.parentNode));
13786
13787 // Remove the old parent paragraph
13788 (0,external_wp_dom_namespaceObject.remove)(node.parentNode);
13789 }
13790 }
13791 function createMore(customText, noTeaser, doc) {
13792 const node = doc.createElement('wp-block');
13793 node.dataset.block = 'core/more';
13794 if (customText) {
13795 node.dataset.customText = customText;
13796 }
13797 if (noTeaser) {
13798 // "Boolean" data attribute.
13799 node.dataset.noTeaser = '';
13800 }
13801 return node;
13802 }
13803 function createNextpage(doc) {
13804 const node = doc.createElement('wp-block');
13805 node.dataset.block = 'core/nextpage';
13806 return node;
13807 }
13808
13809 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/list-reducer.js
13810 /**
13811 * WordPress dependencies
13812 */
13813
13814 function isList(node) {
13815 return node.nodeName === 'OL' || node.nodeName === 'UL';
13816 }
13817 function shallowTextContent(element) {
13818 return Array.from(element.childNodes).map(({
13819 nodeValue = ''
13820 }) => nodeValue).join('');
13821 }
13822 function listReducer(node) {
13823 if (!isList(node)) {
13824 return;
13825 }
13826 const list = node;
13827 const prevElement = node.previousElementSibling;
13828
13829 // Merge with previous list if:
13830 // * There is a previous list of the same type.
13831 // * There is only one list item.
13832 if (prevElement && prevElement.nodeName === node.nodeName && list.children.length === 1) {
13833 // Move all child nodes, including any text nodes, if any.
13834 while (list.firstChild) {
13835 prevElement.appendChild(list.firstChild);
13836 }
13837 list.parentNode.removeChild(list);
13838 }
13839 const parentElement = node.parentNode;
13840
13841 // Nested list with empty parent item.
13842 if (parentElement && parentElement.nodeName === 'LI' && parentElement.children.length === 1 && !/\S/.test(shallowTextContent(parentElement))) {
13843 const parentListItem = parentElement;
13844 const prevListItem = parentListItem.previousElementSibling;
13845 const parentList = parentListItem.parentNode;
13846 if (prevListItem) {
13847 prevListItem.appendChild(list);
13848 parentList.removeChild(parentListItem);
13849 } else {
13850 parentList.parentNode.insertBefore(list, parentList);
13851 parentList.parentNode.removeChild(parentList);
13852 }
13853 }
13854
13855 // Invalid: OL/UL > OL/UL.
13856 if (parentElement && isList(parentElement)) {
13857 const prevListItem = node.previousElementSibling;
13858 if (prevListItem) {
13859 prevListItem.appendChild(node);
13860 } else {
13861 (0,external_wp_dom_namespaceObject.unwrap)(node);
13862 }
13863 }
13864 }
13865
13866 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/blockquote-normaliser.js
13867 /**
13868 * Internal dependencies
13869 */
13870
13871 function blockquoteNormaliser(node) {
13872 if (node.nodeName !== 'BLOCKQUOTE') {
13873 return;
13874 }
13875 node.innerHTML = normaliseBlocks(node.innerHTML);
13876 }
13877
13878 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/figure-content-reducer.js
13879 /**
13880 * WordPress dependencies
13881 */
13882
13883
13884 /**
13885 * Whether or not the given node is figure content.
13886 *
13887 * @param {Node} node The node to check.
13888 * @param {Object} schema The schema to use.
13889 *
13890 * @return {boolean} True if figure content, false if not.
13891 */
13892 function isFigureContent(node, schema) {
13893 var _schema$figure$childr;
13894 const tag = node.nodeName.toLowerCase();
13895
13896 // We are looking for tags that can be a child of the figure tag, excluding
13897 // `figcaption` and any phrasing content.
13898 if (tag === 'figcaption' || (0,external_wp_dom_namespaceObject.isTextContent)(node)) {
13899 return false;
13900 }
13901 return tag in ((_schema$figure$childr = schema?.figure?.children) !== null && _schema$figure$childr !== void 0 ? _schema$figure$childr : {});
13902 }
13903
13904 /**
13905 * Whether or not the given node can have an anchor.
13906 *
13907 * @param {Node} node The node to check.
13908 * @param {Object} schema The schema to use.
13909 *
13910 * @return {boolean} True if it can, false if not.
13911 */
13912 function canHaveAnchor(node, schema) {
13913 var _schema$figure$childr2;
13914 const tag = node.nodeName.toLowerCase();
13915 return tag in ((_schema$figure$childr2 = schema?.figure?.children?.a?.children) !== null && _schema$figure$childr2 !== void 0 ? _schema$figure$childr2 : {});
13916 }
13917
13918 /**
13919 * Wraps the given element in a figure element.
13920 *
13921 * @param {Element} element The element to wrap.
13922 * @param {Element} beforeElement The element before which to place the figure.
13923 */
13924 function wrapFigureContent(element, beforeElement = element) {
13925 const figure = element.ownerDocument.createElement('figure');
13926 beforeElement.parentNode.insertBefore(figure, beforeElement);
13927 figure.appendChild(element);
13928 }
13929
13930 /**
13931 * This filter takes figure content out of paragraphs, wraps it in a figure
13932 * element, and moves any anchors with it if needed.
13933 *
13934 * @param {Node} node The node to filter.
13935 * @param {Document} doc The document of the node.
13936 * @param {Object} schema The schema to use.
13937 *
13938 * @return {void}
13939 */
13940 function figureContentReducer(node, doc, schema) {
13941 if (!isFigureContent(node, schema)) {
13942 return;
13943 }
13944 let nodeToInsert = node;
13945 const parentNode = node.parentNode;
13946
13947 // If the figure content can have an anchor and its parent is an anchor with
13948 // only the figure content, take the anchor out instead of just the content.
13949 if (canHaveAnchor(node, schema) && parentNode.nodeName === 'A' && parentNode.childNodes.length === 1) {
13950 nodeToInsert = node.parentNode;
13951 }
13952 const wrapper = nodeToInsert.closest('p,div');
13953
13954 // If wrapped in a paragraph or div, only extract if it's aligned or if
13955 // there is no text content.
13956 // Otherwise, if directly at the root, wrap in a figure element.
13957 if (wrapper) {
13958 // In jsdom-jscore, 'node.classList' can be undefined.
13959 // In this case, default to extract as it offers a better UI experience on mobile.
13960 if (!node.classList) {
13961 wrapFigureContent(nodeToInsert, wrapper);
13962 } else if (node.classList.contains('alignright') || node.classList.contains('alignleft') || node.classList.contains('aligncenter') || !wrapper.textContent.trim()) {
13963 wrapFigureContent(nodeToInsert, wrapper);
13964 }
13965 } else if (nodeToInsert.parentNode.nodeName === 'BODY') {
13966 wrapFigureContent(nodeToInsert);
13967 }
13968 }
13969
13970 ;// CONCATENATED MODULE: external ["wp","shortcode"]
13971 const external_wp_shortcode_namespaceObject = window["wp"]["shortcode"];
13972 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/shortcode-converter.js
13973 /**
13974 * WordPress dependencies
13975 */
13976
13977
13978 /**
13979 * Internal dependencies
13980 */
13981
13982
13983
13984
13985 const castArray = maybeArray => Array.isArray(maybeArray) ? maybeArray : [maybeArray];
13986 function segmentHTMLToShortcodeBlock(HTML, lastIndex = 0, excludedBlockNames = []) {
13987 // Get all matches.
13988 const transformsFrom = getBlockTransforms('from');
13989 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)));
13990 if (!transformation) {
13991 return [HTML];
13992 }
13993 const transformTags = castArray(transformation.tag);
13994 const transformTag = transformTags.find(tag => (0,external_wp_shortcode_namespaceObject.regexp)(tag).test(HTML));
13995 let match;
13996 const previousIndex = lastIndex;
13997 if (match = (0,external_wp_shortcode_namespaceObject.next)(transformTag, HTML, lastIndex)) {
13998 lastIndex = match.index + match.content.length;
13999 const beforeHTML = HTML.substr(0, match.index);
14000 const afterHTML = HTML.substr(lastIndex);
14001
14002 // If the shortcode content does not contain HTML and the shortcode is
14003 // not on a new line (or in paragraph from Markdown converter),
14004 // consider the shortcode as inline text, and thus skip conversion for
14005 // this segment.
14006 if (!match.shortcode.content?.includes('<') && !(/(\n|<p>)\s*$/.test(beforeHTML) && /^\s*(\n|<\/p>)/.test(afterHTML))) {
14007 return segmentHTMLToShortcodeBlock(HTML, lastIndex);
14008 }
14009
14010 // If a transformation's `isMatch` predicate fails for the inbound
14011 // shortcode, try again by excluding the current block type.
14012 //
14013 // This is the only call to `segmentHTMLToShortcodeBlock` that should
14014 // ever carry over `excludedBlockNames`. Other calls in the module
14015 // should skip that argument as a way to reset the exclusion state, so
14016 // that one `isMatch` fail in an HTML fragment doesn't prevent any
14017 // valid matches in subsequent fragments.
14018 if (transformation.isMatch && !transformation.isMatch(match.shortcode.attrs)) {
14019 return segmentHTMLToShortcodeBlock(HTML, previousIndex, [...excludedBlockNames, transformation.blockName]);
14020 }
14021 let blocks = [];
14022 if (typeof transformation.transform === 'function') {
14023 // Passing all of `match` as second argument is intentionally broad
14024 // but shouldn't be too relied upon.
14025 //
14026 // See: https://github.com/WordPress/gutenberg/pull/3610#discussion_r152546926
14027 blocks = [].concat(transformation.transform(match.shortcode.attrs, match));
14028
14029 // Applying the built-in fixes can enhance the attributes with missing content like "className".
14030 blocks = blocks.map(block => {
14031 block.originalContent = match.shortcode.content;
14032 return applyBuiltInValidationFixes(block, getBlockType(block.name));
14033 });
14034 } else {
14035 const attributes = Object.fromEntries(Object.entries(transformation.attributes).filter(([, schema]) => schema.shortcode)
14036 // Passing all of `match` as second argument is intentionally broad
14037 // but shouldn't be too relied upon.
14038 //
14039 // See: https://github.com/WordPress/gutenberg/pull/3610#discussion_r152546926
14040 .map(([key, schema]) => [key, schema.shortcode(match.shortcode.attrs, match)]));
14041 const blockType = getBlockType(transformation.blockName);
14042 if (!blockType) {
14043 return [HTML];
14044 }
14045 const transformationBlockType = {
14046 ...blockType,
14047 attributes: transformation.attributes
14048 };
14049 let block = createBlock(transformation.blockName, getBlockAttributes(transformationBlockType, match.shortcode.content, attributes));
14050
14051 // Applying the built-in fixes can enhance the attributes with missing content like "className".
14052 block.originalContent = match.shortcode.content;
14053 block = applyBuiltInValidationFixes(block, transformationBlockType);
14054 blocks = [block];
14055 }
14056 return [...segmentHTMLToShortcodeBlock(beforeHTML), ...blocks, ...segmentHTMLToShortcodeBlock(afterHTML)];
14057 }
14058 return [HTML];
14059 }
14060 /* harmony default export */ const shortcode_converter = (segmentHTMLToShortcodeBlock);
14061
14062 // EXTERNAL MODULE: ./node_modules/deepmerge/dist/cjs.js
14063 var cjs = __webpack_require__(1919);
14064 var cjs_default = /*#__PURE__*/__webpack_require__.n(cjs);
14065 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/utils.js
14066 /**
14067 * External dependencies
14068 */
14069
14070
14071 /**
14072 * WordPress dependencies
14073 */
14074
14075
14076 /**
14077 * Internal dependencies
14078 */
14079
14080
14081 const customMerge = key => {
14082 return (srcValue, objValue) => {
14083 switch (key) {
14084 case 'children':
14085 {
14086 if (objValue === '*' || srcValue === '*') {
14087 return '*';
14088 }
14089 return {
14090 ...objValue,
14091 ...srcValue
14092 };
14093 }
14094 case 'attributes':
14095 case 'require':
14096 {
14097 return [...(objValue || []), ...(srcValue || [])];
14098 }
14099 case 'isMatch':
14100 {
14101 // If one of the values being merge is undefined (matches everything),
14102 // the result of the merge will be undefined.
14103 if (!objValue || !srcValue) {
14104 return undefined;
14105 }
14106 // When merging two isMatch functions, the result is a new function
14107 // that returns if one of the source functions returns true.
14108 return (...args) => {
14109 return objValue(...args) || srcValue(...args);
14110 };
14111 }
14112 }
14113 return cjs_default()(objValue, srcValue, {
14114 customMerge,
14115 clone: false
14116 });
14117 };
14118 };
14119 function getBlockContentSchemaFromTransforms(transforms, context) {
14120 const phrasingContentSchema = (0,external_wp_dom_namespaceObject.getPhrasingContentSchema)(context);
14121 const schemaArgs = {
14122 phrasingContentSchema,
14123 isPaste: context === 'paste'
14124 };
14125 const schemas = transforms.map(({
14126 isMatch,
14127 blockName,
14128 schema
14129 }) => {
14130 const hasAnchorSupport = hasBlockSupport(blockName, 'anchor');
14131 schema = typeof schema === 'function' ? schema(schemaArgs) : schema;
14132
14133 // If the block does not has anchor support and the transform does not
14134 // provides an isMatch we can return the schema right away.
14135 if (!hasAnchorSupport && !isMatch) {
14136 return schema;
14137 }
14138 if (!schema) {
14139 return {};
14140 }
14141 return Object.fromEntries(Object.entries(schema).map(([key, value]) => {
14142 let attributes = value.attributes || [];
14143 // If the block supports the "anchor" functionality, it needs to keep its ID attribute.
14144 if (hasAnchorSupport) {
14145 attributes = [...attributes, 'id'];
14146 }
14147 return [key, {
14148 ...value,
14149 attributes,
14150 isMatch: isMatch ? isMatch : undefined
14151 }];
14152 }));
14153 });
14154 return cjs_default().all(schemas, {
14155 customMerge,
14156 clone: false
14157 });
14158 }
14159
14160 /**
14161 * Gets the block content schema, which is extracted and merged from all
14162 * registered blocks with raw transfroms.
14163 *
14164 * @param {string} context Set to "paste" when in paste context, where the
14165 * schema is more strict.
14166 *
14167 * @return {Object} A complete block content schema.
14168 */
14169 function getBlockContentSchema(context) {
14170 return getBlockContentSchemaFromTransforms(getRawTransforms(), context);
14171 }
14172
14173 /**
14174 * Checks whether HTML can be considered plain text. That is, it does not contain
14175 * any elements that are not line breaks.
14176 *
14177 * @param {string} HTML The HTML to check.
14178 *
14179 * @return {boolean} Whether the HTML can be considered plain text.
14180 */
14181 function isPlain(HTML) {
14182 return !/<(?!br[ />])/i.test(HTML);
14183 }
14184
14185 /**
14186 * Given node filters, deeply filters and mutates a NodeList.
14187 *
14188 * @param {NodeList} nodeList The nodeList to filter.
14189 * @param {Array} filters An array of functions that can mutate with the provided node.
14190 * @param {Document} doc The document of the nodeList.
14191 * @param {Object} schema The schema to use.
14192 */
14193 function deepFilterNodeList(nodeList, filters, doc, schema) {
14194 Array.from(nodeList).forEach(node => {
14195 deepFilterNodeList(node.childNodes, filters, doc, schema);
14196 filters.forEach(item => {
14197 // Make sure the node is still attached to the document.
14198 if (!doc.contains(node)) {
14199 return;
14200 }
14201 item(node, doc, schema);
14202 });
14203 });
14204 }
14205
14206 /**
14207 * Given node filters, deeply filters HTML tags.
14208 * Filters from the deepest nodes to the top.
14209 *
14210 * @param {string} HTML The HTML to filter.
14211 * @param {Array} filters An array of functions that can mutate with the provided node.
14212 * @param {Object} schema The schema to use.
14213 *
14214 * @return {string} The filtered HTML.
14215 */
14216 function deepFilterHTML(HTML, filters = [], schema) {
14217 const doc = document.implementation.createHTMLDocument('');
14218 doc.body.innerHTML = HTML;
14219 deepFilterNodeList(doc.body.childNodes, filters, doc, schema);
14220 return doc.body.innerHTML;
14221 }
14222
14223 /**
14224 * Gets a sibling within text-level context.
14225 *
14226 * @param {Element} node The subject node.
14227 * @param {string} which "next" or "previous".
14228 */
14229 function getSibling(node, which) {
14230 const sibling = node[`${which}Sibling`];
14231 if (sibling && (0,external_wp_dom_namespaceObject.isPhrasingContent)(sibling)) {
14232 return sibling;
14233 }
14234 const {
14235 parentNode
14236 } = node;
14237 if (!parentNode || !(0,external_wp_dom_namespaceObject.isPhrasingContent)(parentNode)) {
14238 return;
14239 }
14240 return getSibling(parentNode, which);
14241 }
14242
14243 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/index.js
14244 /**
14245 * WordPress dependencies
14246 */
14247
14248
14249
14250 /**
14251 * Internal dependencies
14252 */
14253
14254
14255
14256
14257
14258
14259
14260
14261
14262
14263 function deprecatedGetPhrasingContentSchema(context) {
14264 external_wp_deprecated_default()('wp.blocks.getPhrasingContentSchema', {
14265 since: '5.6',
14266 alternative: 'wp.dom.getPhrasingContentSchema'
14267 });
14268 return (0,external_wp_dom_namespaceObject.getPhrasingContentSchema)(context);
14269 }
14270
14271 /**
14272 * Converts an HTML string to known blocks.
14273 *
14274 * @param {Object} $1
14275 * @param {string} $1.HTML The HTML to convert.
14276 *
14277 * @return {Array} A list of blocks.
14278 */
14279 function rawHandler({
14280 HTML = ''
14281 }) {
14282 // If we detect block delimiters, parse entirely as blocks.
14283 if (HTML.indexOf('<!-- wp:') !== -1) {
14284 return parser_parse(HTML);
14285 }
14286
14287 // An array of HTML strings and block objects. The blocks replace matched
14288 // shortcodes.
14289 const pieces = shortcode_converter(HTML);
14290 const blockContentSchema = getBlockContentSchema();
14291 return pieces.map(piece => {
14292 // Already a block from shortcode.
14293 if (typeof piece !== 'string') {
14294 return piece;
14295 }
14296
14297 // These filters are essential for some blocks to be able to transform
14298 // from raw HTML. These filters move around some content or add
14299 // additional tags, they do not remove any content.
14300 const filters = [
14301 // Needed to adjust invalid lists.
14302 listReducer,
14303 // Needed to create more and nextpage blocks.
14304 specialCommentConverter,
14305 // Needed to create media blocks.
14306 figureContentReducer,
14307 // Needed to create the quote block, which cannot handle text
14308 // without wrapper paragraphs.
14309 blockquoteNormaliser];
14310 piece = deepFilterHTML(piece, filters, blockContentSchema);
14311 piece = normaliseBlocks(piece);
14312 return htmlToBlocks(piece, rawHandler);
14313 }).flat().filter(Boolean);
14314 }
14315
14316 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/comment-remover.js
14317 /**
14318 * WordPress dependencies
14319 */
14320
14321
14322 /**
14323 * Looks for comments, and removes them.
14324 *
14325 * @param {Node} node The node to be processed.
14326 * @return {void}
14327 */
14328 function commentRemover(node) {
14329 if (node.nodeType === node.COMMENT_NODE) {
14330 (0,external_wp_dom_namespaceObject.remove)(node);
14331 }
14332 }
14333
14334 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/is-inline-content.js
14335 /**
14336 * WordPress dependencies
14337 */
14338
14339
14340 /**
14341 * Checks if the given node should be considered inline content, optionally
14342 * depending on a context tag.
14343 *
14344 * @param {Node} node Node name.
14345 * @param {string} contextTag Tag name.
14346 *
14347 * @return {boolean} True if the node is inline content, false if nohe.
14348 */
14349 function isInline(node, contextTag) {
14350 if ((0,external_wp_dom_namespaceObject.isTextContent)(node)) {
14351 return true;
14352 }
14353 if (!contextTag) {
14354 return false;
14355 }
14356 const tag = node.nodeName.toLowerCase();
14357 const inlineAllowedTagGroups = [['ul', 'li', 'ol'], ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']];
14358 return inlineAllowedTagGroups.some(tagGroup => [tag, contextTag].filter(t => !tagGroup.includes(t)).length === 0);
14359 }
14360 function deepCheck(nodes, contextTag) {
14361 return nodes.every(node => isInline(node, contextTag) && deepCheck(Array.from(node.children), contextTag));
14362 }
14363 function isDoubleBR(node) {
14364 return node.nodeName === 'BR' && node.previousSibling && node.previousSibling.nodeName === 'BR';
14365 }
14366 function isInlineContent(HTML, contextTag) {
14367 const doc = document.implementation.createHTMLDocument('');
14368 doc.body.innerHTML = HTML;
14369 const nodes = Array.from(doc.body.children);
14370 return !nodes.some(isDoubleBR) && deepCheck(nodes, contextTag);
14371 }
14372
14373 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/phrasing-content-reducer.js
14374 /**
14375 * WordPress dependencies
14376 */
14377
14378 function phrasingContentReducer(node, doc) {
14379 // In jsdom-jscore, 'node.style' can be null.
14380 // TODO: Explore fixing this by patching jsdom-jscore.
14381 if (node.nodeName === 'SPAN' && node.style) {
14382 const {
14383 fontWeight,
14384 fontStyle,
14385 textDecorationLine,
14386 textDecoration,
14387 verticalAlign
14388 } = node.style;
14389 if (fontWeight === 'bold' || fontWeight === '700') {
14390 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('strong'), node);
14391 }
14392 if (fontStyle === 'italic') {
14393 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('em'), node);
14394 }
14395
14396 // Some DOM implementations (Safari, JSDom) don't support
14397 // style.textDecorationLine, so we check style.textDecoration as a
14398 // fallback.
14399 if (textDecorationLine === 'line-through' || textDecoration.includes('line-through')) {
14400 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('s'), node);
14401 }
14402 if (verticalAlign === 'super') {
14403 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('sup'), node);
14404 } else if (verticalAlign === 'sub') {
14405 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('sub'), node);
14406 }
14407 } else if (node.nodeName === 'B') {
14408 node = (0,external_wp_dom_namespaceObject.replaceTag)(node, 'strong');
14409 } else if (node.nodeName === 'I') {
14410 node = (0,external_wp_dom_namespaceObject.replaceTag)(node, 'em');
14411 } else if (node.nodeName === 'A') {
14412 // In jsdom-jscore, 'node.target' can be null.
14413 // TODO: Explore fixing this by patching jsdom-jscore.
14414 if (node.target && node.target.toLowerCase() === '_blank') {
14415 node.rel = 'noreferrer noopener';
14416 } else {
14417 node.removeAttribute('target');
14418 node.removeAttribute('rel');
14419 }
14420
14421 // Saves anchor elements name attribute as id
14422 if (node.name && !node.id) {
14423 node.id = node.name;
14424 }
14425
14426 // Keeps id only if there is an internal link pointing to it
14427 if (node.id && !node.ownerDocument.querySelector(`[href="#${node.id}"]`)) {
14428 node.removeAttribute('id');
14429 }
14430 }
14431 }
14432
14433 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/head-remover.js
14434 function headRemover(node) {
14435 if (node.nodeName !== 'SCRIPT' && node.nodeName !== 'NOSCRIPT' && node.nodeName !== 'TEMPLATE' && node.nodeName !== 'STYLE') {
14436 return;
14437 }
14438 node.parentNode.removeChild(node);
14439 }
14440
14441 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/ms-list-converter.js
14442 /**
14443 * Browser dependencies
14444 */
14445 const {
14446 parseInt: ms_list_converter_parseInt
14447 } = window;
14448 function ms_list_converter_isList(node) {
14449 return node.nodeName === 'OL' || node.nodeName === 'UL';
14450 }
14451 function msListConverter(node, doc) {
14452 if (node.nodeName !== 'P') {
14453 return;
14454 }
14455 const style = node.getAttribute('style');
14456 if (!style) {
14457 return;
14458 }
14459
14460 // Quick check.
14461 if (style.indexOf('mso-list') === -1) {
14462 return;
14463 }
14464 const matches = /mso-list\s*:[^;]+level([0-9]+)/i.exec(style);
14465 if (!matches) {
14466 return;
14467 }
14468 let level = ms_list_converter_parseInt(matches[1], 10) - 1 || 0;
14469 const prevNode = node.previousElementSibling;
14470
14471 // Add new list if no previous.
14472 if (!prevNode || !ms_list_converter_isList(prevNode)) {
14473 // See https://html.spec.whatwg.org/multipage/grouping-content.html#attr-ol-type.
14474 const type = node.textContent.trim().slice(0, 1);
14475 const isNumeric = /[1iIaA]/.test(type);
14476 const newListNode = doc.createElement(isNumeric ? 'ol' : 'ul');
14477 if (isNumeric) {
14478 newListNode.setAttribute('type', type);
14479 }
14480 node.parentNode.insertBefore(newListNode, node);
14481 }
14482 const listNode = node.previousElementSibling;
14483 const listType = listNode.nodeName;
14484 const listItem = doc.createElement('li');
14485 let receivingNode = listNode;
14486
14487 // Remove the first span with list info.
14488 node.removeChild(node.firstChild);
14489
14490 // Add content.
14491 while (node.firstChild) {
14492 listItem.appendChild(node.firstChild);
14493 }
14494
14495 // Change pointer depending on indentation level.
14496 while (level--) {
14497 receivingNode = receivingNode.lastChild || receivingNode;
14498
14499 // If it's a list, move pointer to the last item.
14500 if (ms_list_converter_isList(receivingNode)) {
14501 receivingNode = receivingNode.lastChild || receivingNode;
14502 }
14503 }
14504
14505 // Make sure we append to a list.
14506 if (!ms_list_converter_isList(receivingNode)) {
14507 receivingNode = receivingNode.appendChild(doc.createElement(listType));
14508 }
14509
14510 // Append the list item to the list.
14511 receivingNode.appendChild(listItem);
14512
14513 // Remove the wrapper paragraph.
14514 node.parentNode.removeChild(node);
14515 }
14516
14517 ;// CONCATENATED MODULE: external ["wp","blob"]
14518 const external_wp_blob_namespaceObject = window["wp"]["blob"];
14519 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/image-corrector.js
14520 /**
14521 * WordPress dependencies
14522 */
14523
14524
14525 /**
14526 * Browser dependencies
14527 */
14528 const {
14529 atob,
14530 File
14531 } = window;
14532 function imageCorrector(node) {
14533 if (node.nodeName !== 'IMG') {
14534 return;
14535 }
14536 if (node.src.indexOf('file:') === 0) {
14537 node.src = '';
14538 }
14539
14540 // This piece cannot be tested outside a browser env.
14541 if (node.src.indexOf('data:') === 0) {
14542 const [properties, data] = node.src.split(',');
14543 const [type] = properties.slice(5).split(';');
14544 if (!data || !type) {
14545 node.src = '';
14546 return;
14547 }
14548 let decoded;
14549
14550 // Can throw DOMException!
14551 try {
14552 decoded = atob(data);
14553 } catch (e) {
14554 node.src = '';
14555 return;
14556 }
14557 const uint8Array = new Uint8Array(decoded.length);
14558 for (let i = 0; i < uint8Array.length; i++) {
14559 uint8Array[i] = decoded.charCodeAt(i);
14560 }
14561 const name = type.replace('/', '.');
14562 const file = new File([uint8Array], name, {
14563 type
14564 });
14565 node.src = (0,external_wp_blob_namespaceObject.createBlobURL)(file);
14566 }
14567
14568 // Remove trackers and hardly visible images.
14569 if (node.height === 1 || node.width === 1) {
14570 node.parentNode.removeChild(node);
14571 }
14572 }
14573
14574 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/div-normaliser.js
14575 /**
14576 * Internal dependencies
14577 */
14578
14579 function divNormaliser(node) {
14580 if (node.nodeName !== 'DIV') {
14581 return;
14582 }
14583 node.innerHTML = normaliseBlocks(node.innerHTML);
14584 }
14585
14586 // EXTERNAL MODULE: ./node_modules/showdown/dist/showdown.js
14587 var showdown = __webpack_require__(7308);
14588 var showdown_default = /*#__PURE__*/__webpack_require__.n(showdown);
14589 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/markdown-converter.js
14590 /**
14591 * External dependencies
14592 */
14593
14594
14595 // Reuse the same showdown converter.
14596 const converter = new (showdown_default()).Converter({
14597 noHeaderId: true,
14598 tables: true,
14599 literalMidWordUnderscores: true,
14600 omitExtraWLInCodeBlocks: true,
14601 simpleLineBreaks: true,
14602 strikethrough: true
14603 });
14604
14605 /**
14606 * Corrects the Slack Markdown variant of the code block.
14607 * If uncorrected, it will be converted to inline code.
14608 *
14609 * @see https://get.slack.help/hc/en-us/articles/202288908-how-can-i-add-formatting-to-my-messages-#code-blocks
14610 *
14611 * @param {string} text The potential Markdown text to correct.
14612 *
14613 * @return {string} The corrected Markdown.
14614 */
14615 function slackMarkdownVariantCorrector(text) {
14616 return text.replace(/((?:^|\n)```)([^\n`]+)(```(?:$|\n))/, (match, p1, p2, p3) => `${p1}\n${p2}\n${p3}`);
14617 }
14618 function bulletsToAsterisks(text) {
14619 return text.replace(/(^|\n)•( +)/g, '$1*$2');
14620 }
14621
14622 /**
14623 * Converts a piece of text into HTML based on any Markdown present.
14624 * Also decodes any encoded HTML.
14625 *
14626 * @param {string} text The plain text to convert.
14627 *
14628 * @return {string} HTML.
14629 */
14630 function markdownConverter(text) {
14631 return converter.makeHtml(slackMarkdownVariantCorrector(bulletsToAsterisks(text)));
14632 }
14633
14634 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/iframe-remover.js
14635 /**
14636 * Removes iframes.
14637 *
14638 * @param {Node} node The node to check.
14639 *
14640 * @return {void}
14641 */
14642 function iframeRemover(node) {
14643 if (node.nodeName === 'IFRAME') {
14644 const text = node.ownerDocument.createTextNode(node.src);
14645 node.parentNode.replaceChild(text, node);
14646 }
14647 }
14648
14649 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/google-docs-uid-remover.js
14650 /**
14651 * WordPress dependencies
14652 */
14653
14654 function googleDocsUIdRemover(node) {
14655 if (!node.id || node.id.indexOf('docs-internal-guid-') !== 0) {
14656 return;
14657 }
14658
14659 // Google Docs sometimes wraps the content in a B tag. We don't want to keep
14660 // this.
14661 if (node.tagName === 'B') {
14662 (0,external_wp_dom_namespaceObject.unwrap)(node);
14663 } else {
14664 node.removeAttribute('id');
14665 }
14666 }
14667
14668 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/html-formatting-remover.js
14669 /**
14670 * Internal dependencies
14671 */
14672
14673 function isFormattingSpace(character) {
14674 return character === ' ' || character === '\r' || character === '\n' || character === '\t';
14675 }
14676
14677 /**
14678 * Removes spacing that formats HTML.
14679 *
14680 * @see https://www.w3.org/TR/css-text-3/#white-space-processing
14681 *
14682 * @param {Node} node The node to be processed.
14683 * @return {void}
14684 */
14685 function htmlFormattingRemover(node) {
14686 if (node.nodeType !== node.TEXT_NODE) {
14687 return;
14688 }
14689
14690 // Ignore pre content. Note that this does not use Element#closest due to
14691 // a combination of (a) node may not be Element and (b) node.parentElement
14692 // does not have full support in all browsers (Internet Exporer).
14693 //
14694 // See: https://developer.mozilla.org/en-US/docs/Web/API/Node/parentElement#Browser_compatibility
14695
14696 /** @type {Node?} */
14697 let parent = node;
14698 while (parent = parent.parentNode) {
14699 if (parent.nodeType === parent.ELEMENT_NODE && parent.nodeName === 'PRE') {
14700 return;
14701 }
14702 }
14703
14704 // First, replace any sequence of HTML formatting space with a single space.
14705 let newData = node.data.replace(/[ \r\n\t]+/g, ' ');
14706
14707 // Remove the leading space if the text element is at the start of a block,
14708 // is preceded by a line break element, or has a space in the previous
14709 // node.
14710 if (newData[0] === ' ') {
14711 const previousSibling = getSibling(node, 'previous');
14712 if (!previousSibling || previousSibling.nodeName === 'BR' || previousSibling.textContent.slice(-1) === ' ') {
14713 newData = newData.slice(1);
14714 }
14715 }
14716
14717 // Remove the trailing space if the text element is at the end of a block,
14718 // is succeded by a line break element, or has a space in the next text
14719 // node.
14720 if (newData[newData.length - 1] === ' ') {
14721 const nextSibling = getSibling(node, 'next');
14722 if (!nextSibling || nextSibling.nodeName === 'BR' || nextSibling.nodeType === nextSibling.TEXT_NODE && isFormattingSpace(nextSibling.textContent[0])) {
14723 newData = newData.slice(0, -1);
14724 }
14725 }
14726
14727 // If there's no data left, remove the node, so `previousSibling` stays
14728 // accurate. Otherwise, update the node data.
14729 if (!newData) {
14730 node.parentNode.removeChild(node);
14731 } else {
14732 node.data = newData;
14733 }
14734 }
14735
14736 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/br-remover.js
14737 /**
14738 * Internal dependencies
14739 */
14740
14741
14742 /**
14743 * Removes trailing br elements from text-level content.
14744 *
14745 * @param {Element} node Node to check.
14746 */
14747 function brRemover(node) {
14748 if (node.nodeName !== 'BR') {
14749 return;
14750 }
14751 if (getSibling(node, 'next')) {
14752 return;
14753 }
14754 node.parentNode.removeChild(node);
14755 }
14756
14757 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/empty-paragraph-remover.js
14758 /**
14759 * Removes empty paragraph elements.
14760 *
14761 * @param {Element} node Node to check.
14762 */
14763 function emptyParagraphRemover(node) {
14764 if (node.nodeName !== 'P') {
14765 return;
14766 }
14767 if (node.hasChildNodes()) {
14768 return;
14769 }
14770 node.parentNode.removeChild(node);
14771 }
14772
14773 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/slack-paragraph-corrector.js
14774 /**
14775 * Replaces Slack paragraph markup with a double line break (later converted to
14776 * a proper paragraph).
14777 *
14778 * @param {Element} node Node to check.
14779 */
14780 function slackParagraphCorrector(node) {
14781 if (node.nodeName !== 'SPAN') {
14782 return;
14783 }
14784 if (node.getAttribute('data-stringify-type') !== 'paragraph-break') {
14785 return;
14786 }
14787 const {
14788 parentNode
14789 } = node;
14790 parentNode.insertBefore(node.ownerDocument.createElement('br'), node);
14791 parentNode.insertBefore(node.ownerDocument.createElement('br'), node);
14792 parentNode.removeChild(node);
14793 }
14794
14795 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/paste-handler.js
14796 /**
14797 * WordPress dependencies
14798 */
14799
14800
14801 /**
14802 * Internal dependencies
14803 */
14804
14805
14806
14807
14808
14809
14810
14811
14812
14813
14814
14815
14816
14817
14818
14819
14820
14821
14822
14823
14824
14825
14826
14827
14828
14829 /**
14830 * Browser dependencies
14831 */
14832 const {
14833 console: paste_handler_console
14834 } = window;
14835
14836 /**
14837 * Filters HTML to only contain phrasing content.
14838 *
14839 * @param {string} HTML The HTML to filter.
14840 * @param {boolean} preserveWhiteSpace Whether or not to preserve consequent white space.
14841 *
14842 * @return {string} HTML only containing phrasing content.
14843 */
14844 function filterInlineHTML(HTML, preserveWhiteSpace) {
14845 HTML = deepFilterHTML(HTML, [headRemover, googleDocsUIdRemover, phrasingContentReducer, commentRemover]);
14846 HTML = (0,external_wp_dom_namespaceObject.removeInvalidHTML)(HTML, (0,external_wp_dom_namespaceObject.getPhrasingContentSchema)('paste'), {
14847 inline: true
14848 });
14849 if (!preserveWhiteSpace) {
14850 HTML = deepFilterHTML(HTML, [htmlFormattingRemover, brRemover]);
14851 }
14852
14853 // Allows us to ask for this information when we get a report.
14854 paste_handler_console.log('Processed inline HTML:\n\n', HTML);
14855 return HTML;
14856 }
14857
14858 /**
14859 * If we're allowed to return inline content, and there is only one inlineable
14860 * block, and the original plain text content does not have any line breaks,
14861 * then treat it as inline paste.
14862 *
14863 * @param {Object} options
14864 * @param {Array} options.blocks
14865 * @param {string} options.plainText
14866 * @param {string} options.mode
14867 */
14868 function maybeConvertToInline({
14869 blocks,
14870 plainText,
14871 mode
14872 }) {
14873 if (mode === 'AUTO' && blocks.length === 1 && hasBlockSupport(blocks[0].name, '__unstablePasteTextInline', false)) {
14874 const trimRegex = /^[\n]+|[\n]+$/g;
14875 // Don't catch line breaks at the start or end.
14876 const trimmedPlainText = plainText.replace(trimRegex, '');
14877 if (trimmedPlainText !== '' && trimmedPlainText.indexOf('\n') === -1) {
14878 const target = blocks[0].innerBlocks.length ? blocks[0].innerBlocks[0] : blocks[0];
14879 return target.attributes.content;
14880 }
14881 }
14882 return blocks;
14883 }
14884
14885 /**
14886 * Converts an HTML string to known blocks. Strips everything else.
14887 *
14888 * @param {Object} options
14889 * @param {string} [options.HTML] The HTML to convert.
14890 * @param {string} [options.plainText] Plain text version.
14891 * @param {string} [options.mode] Handle content as blocks or inline content.
14892 * * 'AUTO': Decide based on the content passed.
14893 * * 'INLINE': Always handle as inline content, and return string.
14894 * * 'BLOCKS': Always handle as blocks, and return array of blocks.
14895 * @param {Array} [options.tagName] The tag into which content will be inserted.
14896 * @param {boolean} [options.preserveWhiteSpace] Whether or not to preserve consequent white space.
14897 *
14898 * @param {boolean} [options.disableFilters] Whether or not to filter non semantic content.
14899 * @return {Array|string} A list of blocks or a string, depending on `handlerMode`.
14900 */
14901 function pasteHandler({
14902 HTML = '',
14903 plainText = '',
14904 mode = 'AUTO',
14905 tagName,
14906 preserveWhiteSpace,
14907 disableFilters
14908 }) {
14909 // First of all, strip any meta tags.
14910 HTML = HTML.replace(/<meta[^>]+>/g, '');
14911 // Strip Windows markers.
14912 HTML = HTML.replace(/^\s*<html[^>]*>\s*<body[^>]*>(?:\s*<!--\s*StartFragment\s*-->)?/i, '');
14913 HTML = HTML.replace(/(?:<!--\s*EndFragment\s*-->\s*)?<\/body>\s*<\/html>\s*$/i, '');
14914
14915 // If we detect block delimiters in HTML, parse entirely as blocks.
14916 if (mode !== 'INLINE') {
14917 // Check plain text if there is no HTML.
14918 const content = HTML ? HTML : plainText;
14919 if (content.indexOf('<!-- wp:') !== -1) {
14920 return parser_parse(content);
14921 }
14922 }
14923
14924 // Normalize unicode to use composed characters.
14925 // This is unsupported in IE 11 but it's a nice-to-have feature, not mandatory.
14926 // Not normalizing the content will only affect older browsers and won't
14927 // entirely break the app.
14928 // See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize
14929 // See: https://core.trac.wordpress.org/ticket/30130
14930 // See: https://github.com/WordPress/gutenberg/pull/6983#pullrequestreview-125151075
14931 if (String.prototype.normalize) {
14932 HTML = HTML.normalize();
14933 }
14934 if (disableFilters) {
14935 return maybeConvertToInline({
14936 blocks: htmlToBlocks(normaliseBlocks(HTML), pasteHandler),
14937 plainText,
14938 mode
14939 });
14940 }
14941
14942 // Parse Markdown (and encoded HTML) if:
14943 // * There is a plain text version.
14944 // * There is no HTML version, or it has no formatting.
14945 if (plainText && (!HTML || isPlain(HTML))) {
14946 HTML = plainText;
14947
14948 // The markdown converter (Showdown) trims whitespace.
14949 if (!/^\s+$/.test(plainText)) {
14950 HTML = markdownConverter(HTML);
14951 }
14952
14953 // Switch to inline mode if:
14954 // * The current mode is AUTO.
14955 // * The original plain text had no line breaks.
14956 // * The original plain text was not an HTML paragraph.
14957 // * The converted text is just a paragraph.
14958 if (mode === 'AUTO' && plainText.indexOf('\n') === -1 && plainText.indexOf('<p>') !== 0 && HTML.indexOf('<p>') === 0) {
14959 mode = 'INLINE';
14960 }
14961 }
14962 if (mode === 'INLINE') {
14963 return filterInlineHTML(HTML, preserveWhiteSpace);
14964 }
14965
14966 // Must be run before checking if it's inline content.
14967 HTML = deepFilterHTML(HTML, [slackParagraphCorrector]);
14968
14969 // An array of HTML strings and block objects. The blocks replace matched
14970 // shortcodes.
14971 const pieces = shortcode_converter(HTML);
14972
14973 // The call to shortcodeConverter will always return more than one element
14974 // if shortcodes are matched. The reason is when shortcodes are matched
14975 // empty HTML strings are included.
14976 const hasShortcodes = pieces.length > 1;
14977 if (mode === 'AUTO' && !hasShortcodes && isInlineContent(HTML, tagName)) {
14978 return filterInlineHTML(HTML, preserveWhiteSpace);
14979 }
14980 const phrasingContentSchema = (0,external_wp_dom_namespaceObject.getPhrasingContentSchema)('paste');
14981 const blockContentSchema = getBlockContentSchema('paste');
14982 const blocks = pieces.map(piece => {
14983 // Already a block from shortcode.
14984 if (typeof piece !== 'string') {
14985 return piece;
14986 }
14987 const filters = [googleDocsUIdRemover, msListConverter, headRemover, listReducer, imageCorrector, phrasingContentReducer, specialCommentConverter, commentRemover, iframeRemover, figureContentReducer, blockquoteNormaliser, divNormaliser];
14988 const schema = {
14989 ...blockContentSchema,
14990 // Keep top-level phrasing content, normalised by `normaliseBlocks`.
14991 ...phrasingContentSchema
14992 };
14993 piece = deepFilterHTML(piece, filters, blockContentSchema);
14994 piece = (0,external_wp_dom_namespaceObject.removeInvalidHTML)(piece, schema);
14995 piece = normaliseBlocks(piece);
14996 piece = deepFilterHTML(piece, [htmlFormattingRemover, brRemover, emptyParagraphRemover], blockContentSchema);
14997
14998 // Allows us to ask for this information when we get a report.
14999 paste_handler_console.log('Processed HTML piece:\n\n', piece);
15000 return htmlToBlocks(piece, pasteHandler);
15001 }).flat().filter(Boolean);
15002 return maybeConvertToInline({
15003 blocks,
15004 plainText,
15005 mode
15006 });
15007 }
15008
15009 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/categories.js
15010 /**
15011 * WordPress dependencies
15012 */
15013
15014
15015 /**
15016 * Internal dependencies
15017 */
15018
15019
15020 /** @typedef {import('../store/reducer').WPBlockCategory} WPBlockCategory */
15021
15022 /**
15023 * Returns all the block categories.
15024 * Ignored from documentation as the recommended usage is via useSelect from @wordpress/data.
15025 *
15026 * @ignore
15027 *
15028 * @return {WPBlockCategory[]} Block categories.
15029 */
15030 function categories_getCategories() {
15031 return (0,external_wp_data_namespaceObject.select)(store).getCategories();
15032 }
15033
15034 /**
15035 * Sets the block categories.
15036 *
15037 * @param {WPBlockCategory[]} categories Block categories.
15038 *
15039 * @example
15040 * ```js
15041 * import { __ } from '@wordpress/i18n';
15042 * import { store as blocksStore, setCategories } from '@wordpress/blocks';
15043 * import { useSelect } from '@wordpress/data';
15044 * import { Button } from '@wordpress/components';
15045 *
15046 * const ExampleComponent = () => {
15047 * // Retrieve the list of current categories.
15048 * const blockCategories = useSelect(
15049 * ( select ) => select( blocksStore ).getCategories(),
15050 * []
15051 * );
15052 *
15053 * return (
15054 * <Button
15055 * onClick={ () => {
15056 * // Add a custom category to the existing list.
15057 * setCategories( [
15058 * ...blockCategories,
15059 * { title: 'Custom Category', slug: 'custom-category' },
15060 * ] );
15061 * } }
15062 * >
15063 * { __( 'Add a new custom block category' ) }
15064 * </Button>
15065 * );
15066 * };
15067 * ```
15068 */
15069 function categories_setCategories(categories) {
15070 (0,external_wp_data_namespaceObject.dispatch)(store).setCategories(categories);
15071 }
15072
15073 /**
15074 * Updates a category.
15075 *
15076 * @param {string} slug Block category slug.
15077 * @param {WPBlockCategory} category Object containing the category properties
15078 * that should be updated.
15079 *
15080 * @example
15081 * ```js
15082 * import { __ } from '@wordpress/i18n';
15083 * import { updateCategory } from '@wordpress/blocks';
15084 * import { Button } from '@wordpress/components';
15085 *
15086 * const ExampleComponent = () => {
15087 * return (
15088 * <Button
15089 * onClick={ () => {
15090 * updateCategory( 'text', { title: __( 'Written Word' ) } );
15091 * } }
15092 * >
15093 * { __( 'Update Text category title' ) }
15094 * </Button>
15095 * ) ;
15096 * };
15097 * ```
15098 */
15099 function categories_updateCategory(slug, category) {
15100 (0,external_wp_data_namespaceObject.dispatch)(store).updateCategory(slug, category);
15101 }
15102
15103 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/templates.js
15104 /**
15105 * WordPress dependencies
15106 */
15107
15108
15109 /**
15110 * Internal dependencies
15111 */
15112
15113
15114
15115
15116 /**
15117 * Checks whether a list of blocks matches a template by comparing the block names.
15118 *
15119 * @param {Array} blocks Block list.
15120 * @param {Array} template Block template.
15121 *
15122 * @return {boolean} Whether the list of blocks matches a templates.
15123 */
15124 function doBlocksMatchTemplate(blocks = [], template = []) {
15125 return blocks.length === template.length && template.every(([name,, innerBlocksTemplate], index) => {
15126 const block = blocks[index];
15127 return name === block.name && doBlocksMatchTemplate(block.innerBlocks, innerBlocksTemplate);
15128 });
15129 }
15130
15131 /**
15132 * Synchronize a block list with a block template.
15133 *
15134 * Synchronizing a block list with a block template means that we loop over the blocks
15135 * keep the block as is if it matches the block at the same position in the template
15136 * (If it has the same name) and if doesn't match, we create a new block based on the template.
15137 * Extra blocks not present in the template are removed.
15138 *
15139 * @param {Array} blocks Block list.
15140 * @param {Array} template Block template.
15141 *
15142 * @return {Array} Updated Block list.
15143 */
15144 function synchronizeBlocksWithTemplate(blocks = [], template) {
15145 // If no template is provided, return blocks unmodified.
15146 if (!template) {
15147 return blocks;
15148 }
15149 return template.map(([name, attributes, innerBlocksTemplate], index) => {
15150 var _blockType$attributes;
15151 const block = blocks[index];
15152 if (block && block.name === name) {
15153 const innerBlocks = synchronizeBlocksWithTemplate(block.innerBlocks, innerBlocksTemplate);
15154 return {
15155 ...block,
15156 innerBlocks
15157 };
15158 }
15159
15160 // To support old templates that were using the "children" format
15161 // for the attributes using "html" strings now, we normalize the template attributes
15162 // before creating the blocks.
15163
15164 const blockType = getBlockType(name);
15165 const isHTMLAttribute = attributeDefinition => attributeDefinition?.source === 'html';
15166 const isQueryAttribute = attributeDefinition => attributeDefinition?.source === 'query';
15167 const normalizeAttributes = (schema, values) => {
15168 if (!values) {
15169 return {};
15170 }
15171 return Object.fromEntries(Object.entries(values).map(([key, value]) => [key, normalizeAttribute(schema[key], value)]));
15172 };
15173 const normalizeAttribute = (definition, value) => {
15174 if (isHTMLAttribute(definition) && Array.isArray(value)) {
15175 // Introduce a deprecated call at this point
15176 // When we're confident that "children" format should be removed from the templates.
15177
15178 return (0,external_wp_element_namespaceObject.renderToString)(value);
15179 }
15180 if (isQueryAttribute(definition) && value) {
15181 return value.map(subValues => {
15182 return normalizeAttributes(definition.query, subValues);
15183 });
15184 }
15185 return value;
15186 };
15187 const normalizedAttributes = normalizeAttributes((_blockType$attributes = blockType?.attributes) !== null && _blockType$attributes !== void 0 ? _blockType$attributes : {}, attributes);
15188 let [blockName, blockAttributes] = convertLegacyBlockNameAndAttributes(name, normalizedAttributes);
15189
15190 // If a Block is undefined at this point, use the core/missing block as
15191 // a placeholder for a better user experience.
15192 if (undefined === getBlockType(blockName)) {
15193 blockAttributes = {
15194 originalName: name,
15195 originalContent: '',
15196 originalUndelimitedContent: ''
15197 };
15198 blockName = 'core/missing';
15199 }
15200 return createBlock(blockName, blockAttributes, synchronizeBlocksWithTemplate([], innerBlocksTemplate));
15201 });
15202 }
15203
15204 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/index.js
15205 // The blocktype is the most important concept within the block API. It defines
15206 // all aspects of the block configuration and its interfaces, including `edit`
15207 // and `save`. The transforms specification allows converting one blocktype to
15208 // another through formulas defined by either the source or the destination.
15209 // Switching a blocktype is to be considered a one-way operation implying a
15210 // transformation in the opposite way has to be handled explicitly.
15211
15212
15213 // The block tree is composed of a collection of block nodes. Blocks contained
15214 // within other blocks are called inner blocks. An important design
15215 // consideration is that inner blocks are -- conceptually -- not part of the
15216 // territory established by the parent block that contains them.
15217 //
15218 // This has multiple practical implications: when parsing, we can safely dispose
15219 // of any block boundary found within a block from the innerHTML property when
15220 // transfering to state. Not doing so would have a compounding effect on memory
15221 // and uncertainty over the source of truth. This can be illustrated in how,
15222 // given a tree of `n` nested blocks, the entry node would have to contain the
15223 // actual content of each block while each subsequent block node in the state
15224 // tree would replicate the entire chain `n-1`, meaning the extreme end node
15225 // would have been replicated `n` times as the tree is traversed and would
15226 // generate uncertainty as to which one is to hold the current value of the
15227 // block. For composition, it also means inner blocks can effectively be child
15228 // components whose mechanisms can be shielded from the `edit` implementation
15229 // and just passed along.
15230
15231
15232
15233
15234 // While block transformations account for a specific surface of the API, there
15235 // are also raw transformations which handle arbitrary sources not made out of
15236 // blocks but producing block basaed on various heursitics. This includes
15237 // pasting rich text or HTML data.
15238
15239
15240 // The process of serialization aims to deflate the internal memory of the block
15241 // editor and its state representation back into an HTML valid string. This
15242 // process restores the document integrity and inserts invisible delimiters
15243 // around each block with HTML comment boundaries which can contain any extra
15244 // attributes needed to operate with the block later on.
15245
15246
15247 // Validation is the process of comparing a block source with its output before
15248 // there is any user input or interaction with a block. When this operation
15249 // fails -- for whatever reason -- the block is to be considered invalid. As
15250 // part of validating a block the system will attempt to run the source against
15251 // any provided deprecation definitions.
15252 //
15253 // Worth emphasizing that validation is not a case of whether the markup is
15254 // merely HTML spec-compliant but about how the editor knows to create such
15255 // markup and that its inability to create an identical result can be a strong
15256 // indicator of potential data loss (the invalidation is then a protective
15257 // measure).
15258 //
15259 // The invalidation process can also be deconstructed in phases: 1) validate the
15260 // block exists; 2) validate the source matches the output; 3) validate the
15261 // source matches deprecated outputs; 4) work through the significance of
15262 // differences. These are stacked in a way that favors performance and optimizes
15263 // for the majority of cases. That is to say, the evaluation logic can become
15264 // more sophisticated the further down it goes in the process as the cost is
15265 // accounted for. The first logic checks have to be extremely efficient since
15266 // they will be run for all valid and invalid blocks alike. However, once a
15267 // block is detected as invalid -- failing the three first steps -- it is
15268 // adequate to spend more time determining validity before throwing a conflict.
15269
15270
15271
15272 // Blocks are inherently indifferent about where the data they operate with ends
15273 // up being saved. For example, all blocks can have a static and dynamic aspect
15274 // to them depending on the needs. The static nature of a block is the `save()`
15275 // definition that is meant to be serialized into HTML and which can be left
15276 // void. Any block can also register a `render_callback` on the server, which
15277 // makes its output dynamic either in part or in its totality.
15278 //
15279 // Child blocks are defined as a relationship that builds on top of the inner
15280 // blocks mechanism. A child block is a block node of a particular type that can
15281 // only exist within the inner block boundaries of a specific parent type. This
15282 // allows block authors to compose specific blocks that are not meant to be used
15283 // outside of a specified parent block context. Thus, child blocks extend the
15284 // concept of inner blocks to support a more direct relationship between sets of
15285 // blocks. The addition of parent–child would be a subset of the inner block
15286 // functionality under the premise that certain blocks only make sense as
15287 // children of another block.
15288
15289
15290
15291 // Templates are, in a general sense, a basic collection of block nodes with any
15292 // given set of predefined attributes that are supplied as the initial state of
15293 // an inner blocks group. These nodes can, in turn, contain any number of nested
15294 // blocks within their definition. Templates allow both to specify a default
15295 // state for an editor session or a default set of blocks for any inner block
15296 // implementation within a specific block.
15297
15298
15299
15300
15301
15302 ;// CONCATENATED MODULE: ./packages/blocks/build-module/deprecated.js
15303 /**
15304 * WordPress dependencies
15305 */
15306
15307
15308 /**
15309 * A Higher Order Component used to inject BlockContent using context to the
15310 * wrapped component.
15311 *
15312 * @deprecated
15313 *
15314 * @param {WPComponent} OriginalComponent The component to enhance.
15315 * @return {WPComponent} The same component.
15316 */
15317 function withBlockContentContext(OriginalComponent) {
15318 external_wp_deprecated_default()('wp.blocks.withBlockContentContext', {
15319 since: '6.1'
15320 });
15321 return OriginalComponent;
15322 }
15323
15324 ;// CONCATENATED MODULE: ./packages/blocks/build-module/index.js
15325 // A "block" is the abstract term used to describe units of markup that,
15326 // when composed together, form the content or layout of a page.
15327 // The API for blocks is exposed via `wp.blocks`.
15328 //
15329 // Supported blocks are registered by calling `registerBlockType`. Once registered,
15330 // the block is made available as an option to the editor interface.
15331 //
15332 // Blocks are inferred from the HTML source of a post through a parsing mechanism
15333 // and then stored as objects in state, from which it is then rendered for editing.
15334
15335
15336
15337
15338
15339 })();
15340
15341 (window.wp = window.wp || {}).blocks = __webpack_exports__;
15342 /******/ })()
15343 ;