PluginProbe
Gutenberg / 11.6.0
Gutenberg v11.6.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 11.6.0, at build/blocks/index.js

13,825 lines 472.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /******/ (function() { // webpackBootstrap
2 /******/ var __webpack_modules__ = ({
3
4 /***/ 3787:
5 /***/ (function(module, exports, __webpack_require__) {
6
7 var __WEBPACK_AMD_DEFINE_RESULT__;;/*! showdown v 1.9.1 - 02-11-2019 */
8 (function(){
9 /**
10 * Created by Tivie on 13-07-2015.
11 */
12
13 function getDefaultOpts (simple) {
14 'use strict';
15
16 var defaultOptions = {
17 omitExtraWLInCodeBlocks: {
18 defaultValue: false,
19 describe: 'Omit the default extra whiteline added to code blocks',
20 type: 'boolean'
21 },
22 noHeaderId: {
23 defaultValue: false,
24 describe: 'Turn on/off generated header id',
25 type: 'boolean'
26 },
27 prefixHeaderId: {
28 defaultValue: false,
29 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',
30 type: 'string'
31 },
32 rawPrefixHeaderId: {
33 defaultValue: false,
34 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)',
35 type: 'boolean'
36 },
37 ghCompatibleHeaderId: {
38 defaultValue: false,
39 describe: 'Generate header ids compatible with github style (spaces are replaced with dashes, a bunch of non alphanumeric chars are removed)',
40 type: 'boolean'
41 },
42 rawHeaderId: {
43 defaultValue: false,
44 describe: 'Remove only spaces, \' and " from generated header ids (including prefixes), replacing them with dashes (-). WARNING: This might result in malformed ids',
45 type: 'boolean'
46 },
47 headerLevelStart: {
48 defaultValue: false,
49 describe: 'The header blocks level start',
50 type: 'integer'
51 },
52 parseImgDimensions: {
53 defaultValue: false,
54 describe: 'Turn on/off image dimension parsing',
55 type: 'boolean'
56 },
57 simplifiedAutoLink: {
58 defaultValue: false,
59 describe: 'Turn on/off GFM autolink style',
60 type: 'boolean'
61 },
62 excludeTrailingPunctuationFromURLs: {
63 defaultValue: false,
64 describe: 'Excludes trailing punctuation from links generated with autoLinking',
65 type: 'boolean'
66 },
67 literalMidWordUnderscores: {
68 defaultValue: false,
69 describe: 'Parse midword underscores as literal underscores',
70 type: 'boolean'
71 },
72 literalMidWordAsterisks: {
73 defaultValue: false,
74 describe: 'Parse midword asterisks as literal asterisks',
75 type: 'boolean'
76 },
77 strikethrough: {
78 defaultValue: false,
79 describe: 'Turn on/off strikethrough support',
80 type: 'boolean'
81 },
82 tables: {
83 defaultValue: false,
84 describe: 'Turn on/off tables support',
85 type: 'boolean'
86 },
87 tablesHeaderId: {
88 defaultValue: false,
89 describe: 'Add an id to table headers',
90 type: 'boolean'
91 },
92 ghCodeBlocks: {
93 defaultValue: true,
94 describe: 'Turn on/off GFM fenced code blocks support',
95 type: 'boolean'
96 },
97 tasklists: {
98 defaultValue: false,
99 describe: 'Turn on/off GFM tasklist support',
100 type: 'boolean'
101 },
102 smoothLivePreview: {
103 defaultValue: false,
104 describe: 'Prevents weird effects in live previews due to incomplete input',
105 type: 'boolean'
106 },
107 smartIndentationFix: {
108 defaultValue: false,
109 description: 'Tries to smartly fix indentation in es6 strings',
110 type: 'boolean'
111 },
112 disableForced4SpacesIndentedSublists: {
113 defaultValue: false,
114 description: 'Disables the requirement of indenting nested sublists by 4 spaces',
115 type: 'boolean'
116 },
117 simpleLineBreaks: {
118 defaultValue: false,
119 description: 'Parses simple line breaks as <br> (GFM Style)',
120 type: 'boolean'
121 },
122 requireSpaceBeforeHeadingText: {
123 defaultValue: false,
124 description: 'Makes adding a space between `#` and the header text mandatory (GFM Style)',
125 type: 'boolean'
126 },
127 ghMentions: {
128 defaultValue: false,
129 description: 'Enables github @mentions',
130 type: 'boolean'
131 },
132 ghMentionsLink: {
133 defaultValue: 'https://github.com/{u}',
134 description: 'Changes the link generated by @mentions. Only applies if ghMentions option is enabled.',
135 type: 'string'
136 },
137 encodeEmails: {
138 defaultValue: true,
139 description: 'Encode e-mail addresses through the use of Character Entities, transforming ASCII e-mail addresses into its equivalent decimal entities',
140 type: 'boolean'
141 },
142 openLinksInNewWindow: {
143 defaultValue: false,
144 description: 'Open all links in new windows',
145 type: 'boolean'
146 },
147 backslashEscapesHTMLTags: {
148 defaultValue: false,
149 description: 'Support for HTML Tag escaping. ex: \<div>foo\</div>',
150 type: 'boolean'
151 },
152 emoji: {
153 defaultValue: false,
154 description: 'Enable emoji support. Ex: `this is a :smile: emoji`',
155 type: 'boolean'
156 },
157 underline: {
158 defaultValue: false,
159 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>`',
160 type: 'boolean'
161 },
162 completeHTMLDocument: {
163 defaultValue: false,
164 description: 'Outputs a complete html document, including `<html>`, `<head>` and `<body>` tags',
165 type: 'boolean'
166 },
167 metadata: {
168 defaultValue: false,
169 description: 'Enable support for document metadata (defined at the top of the document between `«««` and `»»»` or between `---` and `---`).',
170 type: 'boolean'
171 },
172 splitAdjacentBlockquotes: {
173 defaultValue: false,
174 description: 'Split adjacent blockquote blocks',
175 type: 'boolean'
176 }
177 };
178 if (simple === false) {
179 return JSON.parse(JSON.stringify(defaultOptions));
180 }
181 var ret = {};
182 for (var opt in defaultOptions) {
183 if (defaultOptions.hasOwnProperty(opt)) {
184 ret[opt] = defaultOptions[opt].defaultValue;
185 }
186 }
187 return ret;
188 }
189
190 function allOptionsOn () {
191 'use strict';
192 var options = getDefaultOpts(true),
193 ret = {};
194 for (var opt in options) {
195 if (options.hasOwnProperty(opt)) {
196 ret[opt] = true;
197 }
198 }
199 return ret;
200 }
201
202 /**
203 * Created by Tivie on 06-01-2015.
204 */
205
206 // Private properties
207 var showdown = {},
208 parsers = {},
209 extensions = {},
210 globalOptions = getDefaultOpts(true),
211 setFlavor = 'vanilla',
212 flavor = {
213 github: {
214 omitExtraWLInCodeBlocks: true,
215 simplifiedAutoLink: true,
216 excludeTrailingPunctuationFromURLs: true,
217 literalMidWordUnderscores: true,
218 strikethrough: true,
219 tables: true,
220 tablesHeaderId: true,
221 ghCodeBlocks: true,
222 tasklists: true,
223 disableForced4SpacesIndentedSublists: true,
224 simpleLineBreaks: true,
225 requireSpaceBeforeHeadingText: true,
226 ghCompatibleHeaderId: true,
227 ghMentions: true,
228 backslashEscapesHTMLTags: true,
229 emoji: true,
230 splitAdjacentBlockquotes: true
231 },
232 original: {
233 noHeaderId: true,
234 ghCodeBlocks: false
235 },
236 ghost: {
237 omitExtraWLInCodeBlocks: true,
238 parseImgDimensions: true,
239 simplifiedAutoLink: true,
240 excludeTrailingPunctuationFromURLs: true,
241 literalMidWordUnderscores: true,
242 strikethrough: true,
243 tables: true,
244 tablesHeaderId: true,
245 ghCodeBlocks: true,
246 tasklists: true,
247 smoothLivePreview: true,
248 simpleLineBreaks: true,
249 requireSpaceBeforeHeadingText: true,
250 ghMentions: false,
251 encodeEmails: true
252 },
253 vanilla: getDefaultOpts(true),
254 allOn: allOptionsOn()
255 };
256
257 /**
258 * helper namespace
259 * @type {{}}
260 */
261 showdown.helper = {};
262
263 /**
264 * TODO LEGACY SUPPORT CODE
265 * @type {{}}
266 */
267 showdown.extensions = {};
268
269 /**
270 * Set a global option
271 * @static
272 * @param {string} key
273 * @param {*} value
274 * @returns {showdown}
275 */
276 showdown.setOption = function (key, value) {
277 'use strict';
278 globalOptions[key] = value;
279 return this;
280 };
281
282 /**
283 * Get a global option
284 * @static
285 * @param {string} key
286 * @returns {*}
287 */
288 showdown.getOption = function (key) {
289 'use strict';
290 return globalOptions[key];
291 };
292
293 /**
294 * Get the global options
295 * @static
296 * @returns {{}}
297 */
298 showdown.getOptions = function () {
299 'use strict';
300 return globalOptions;
301 };
302
303 /**
304 * Reset global options to the default values
305 * @static
306 */
307 showdown.resetOptions = function () {
308 'use strict';
309 globalOptions = getDefaultOpts(true);
310 };
311
312 /**
313 * Set the flavor showdown should use as default
314 * @param {string} name
315 */
316 showdown.setFlavor = function (name) {
317 'use strict';
318 if (!flavor.hasOwnProperty(name)) {
319 throw Error(name + ' flavor was not found');
320 }
321 showdown.resetOptions();
322 var preset = flavor[name];
323 setFlavor = name;
324 for (var option in preset) {
325 if (preset.hasOwnProperty(option)) {
326 globalOptions[option] = preset[option];
327 }
328 }
329 };
330
331 /**
332 * Get the currently set flavor
333 * @returns {string}
334 */
335 showdown.getFlavor = function () {
336 'use strict';
337 return setFlavor;
338 };
339
340 /**
341 * Get the options of a specified flavor. Returns undefined if the flavor was not found
342 * @param {string} name Name of the flavor
343 * @returns {{}|undefined}
344 */
345 showdown.getFlavorOptions = function (name) {
346 'use strict';
347 if (flavor.hasOwnProperty(name)) {
348 return flavor[name];
349 }
350 };
351
352 /**
353 * Get the default options
354 * @static
355 * @param {boolean} [simple=true]
356 * @returns {{}}
357 */
358 showdown.getDefaultOptions = function (simple) {
359 'use strict';
360 return getDefaultOpts(simple);
361 };
362
363 /**
364 * Get or set a subParser
365 *
366 * subParser(name) - Get a registered subParser
367 * subParser(name, func) - Register a subParser
368 * @static
369 * @param {string} name
370 * @param {function} [func]
371 * @returns {*}
372 */
373 showdown.subParser = function (name, func) {
374 'use strict';
375 if (showdown.helper.isString(name)) {
376 if (typeof func !== 'undefined') {
377 parsers[name] = func;
378 } else {
379 if (parsers.hasOwnProperty(name)) {
380 return parsers[name];
381 } else {
382 throw Error('SubParser named ' + name + ' not registered!');
383 }
384 }
385 }
386 };
387
388 /**
389 * Gets or registers an extension
390 * @static
391 * @param {string} name
392 * @param {object|function=} ext
393 * @returns {*}
394 */
395 showdown.extension = function (name, ext) {
396 'use strict';
397
398 if (!showdown.helper.isString(name)) {
399 throw Error('Extension \'name\' must be a string');
400 }
401
402 name = showdown.helper.stdExtName(name);
403
404 // Getter
405 if (showdown.helper.isUndefined(ext)) {
406 if (!extensions.hasOwnProperty(name)) {
407 throw Error('Extension named ' + name + ' is not registered!');
408 }
409 return extensions[name];
410
411 // Setter
412 } else {
413 // Expand extension if it's wrapped in a function
414 if (typeof ext === 'function') {
415 ext = ext();
416 }
417
418 // Ensure extension is an array
419 if (!showdown.helper.isArray(ext)) {
420 ext = [ext];
421 }
422
423 var validExtension = validate(ext, name);
424
425 if (validExtension.valid) {
426 extensions[name] = ext;
427 } else {
428 throw Error(validExtension.error);
429 }
430 }
431 };
432
433 /**
434 * Gets all extensions registered
435 * @returns {{}}
436 */
437 showdown.getAllExtensions = function () {
438 'use strict';
439 return extensions;
440 };
441
442 /**
443 * Remove an extension
444 * @param {string} name
445 */
446 showdown.removeExtension = function (name) {
447 'use strict';
448 delete extensions[name];
449 };
450
451 /**
452 * Removes all extensions
453 */
454 showdown.resetExtensions = function () {
455 'use strict';
456 extensions = {};
457 };
458
459 /**
460 * Validate extension
461 * @param {array} extension
462 * @param {string} name
463 * @returns {{valid: boolean, error: string}}
464 */
465 function validate (extension, name) {
466 'use strict';
467
468 var errMsg = (name) ? 'Error in ' + name + ' extension->' : 'Error in unnamed extension',
469 ret = {
470 valid: true,
471 error: ''
472 };
473
474 if (!showdown.helper.isArray(extension)) {
475 extension = [extension];
476 }
477
478 for (var i = 0; i < extension.length; ++i) {
479 var baseMsg = errMsg + ' sub-extension ' + i + ': ',
480 ext = extension[i];
481 if (typeof ext !== 'object') {
482 ret.valid = false;
483 ret.error = baseMsg + 'must be an object, but ' + typeof ext + ' given';
484 return ret;
485 }
486
487 if (!showdown.helper.isString(ext.type)) {
488 ret.valid = false;
489 ret.error = baseMsg + 'property "type" must be a string, but ' + typeof ext.type + ' given';
490 return ret;
491 }
492
493 var type = ext.type = ext.type.toLowerCase();
494
495 // normalize extension type
496 if (type === 'language') {
497 type = ext.type = 'lang';
498 }
499
500 if (type === 'html') {
501 type = ext.type = 'output';
502 }
503
504 if (type !== 'lang' && type !== 'output' && type !== 'listener') {
505 ret.valid = false;
506 ret.error = baseMsg + 'type ' + type + ' is not recognized. Valid values: "lang/language", "output/html" or "listener"';
507 return ret;
508 }
509
510 if (type === 'listener') {
511 if (showdown.helper.isUndefined(ext.listeners)) {
512 ret.valid = false;
513 ret.error = baseMsg + '. Extensions of type "listener" must have a property called "listeners"';
514 return ret;
515 }
516 } else {
517 if (showdown.helper.isUndefined(ext.filter) && showdown.helper.isUndefined(ext.regex)) {
518 ret.valid = false;
519 ret.error = baseMsg + type + ' extensions must define either a "regex" property or a "filter" method';
520 return ret;
521 }
522 }
523
524 if (ext.listeners) {
525 if (typeof ext.listeners !== 'object') {
526 ret.valid = false;
527 ret.error = baseMsg + '"listeners" property must be an object but ' + typeof ext.listeners + ' given';
528 return ret;
529 }
530 for (var ln in ext.listeners) {
531 if (ext.listeners.hasOwnProperty(ln)) {
532 if (typeof ext.listeners[ln] !== 'function') {
533 ret.valid = false;
534 ret.error = baseMsg + '"listeners" property must be an hash of [event name]: [callback]. listeners.' + ln +
535 ' must be a function but ' + typeof ext.listeners[ln] + ' given';
536 return ret;
537 }
538 }
539 }
540 }
541
542 if (ext.filter) {
543 if (typeof ext.filter !== 'function') {
544 ret.valid = false;
545 ret.error = baseMsg + '"filter" must be a function, but ' + typeof ext.filter + ' given';
546 return ret;
547 }
548 } else if (ext.regex) {
549 if (showdown.helper.isString(ext.regex)) {
550 ext.regex = new RegExp(ext.regex, 'g');
551 }
552 if (!(ext.regex instanceof RegExp)) {
553 ret.valid = false;
554 ret.error = baseMsg + '"regex" property must either be a string or a RegExp object, but ' + typeof ext.regex + ' given';
555 return ret;
556 }
557 if (showdown.helper.isUndefined(ext.replace)) {
558 ret.valid = false;
559 ret.error = baseMsg + '"regex" extensions must implement a replace string or function';
560 return ret;
561 }
562 }
563 }
564 return ret;
565 }
566
567 /**
568 * Validate extension
569 * @param {object} ext
570 * @returns {boolean}
571 */
572 showdown.validateExtension = function (ext) {
573 'use strict';
574
575 var validateExtension = validate(ext, null);
576 if (!validateExtension.valid) {
577 console.warn(validateExtension.error);
578 return false;
579 }
580 return true;
581 };
582
583 /**
584 * showdownjs helper functions
585 */
586
587 if (!showdown.hasOwnProperty('helper')) {
588 showdown.helper = {};
589 }
590
591 /**
592 * Check if var is string
593 * @static
594 * @param {string} a
595 * @returns {boolean}
596 */
597 showdown.helper.isString = function (a) {
598 'use strict';
599 return (typeof a === 'string' || a instanceof String);
600 };
601
602 /**
603 * Check if var is a function
604 * @static
605 * @param {*} a
606 * @returns {boolean}
607 */
608 showdown.helper.isFunction = function (a) {
609 'use strict';
610 var getType = {};
611 return a && getType.toString.call(a) === '[object Function]';
612 };
613
614 /**
615 * isArray helper function
616 * @static
617 * @param {*} a
618 * @returns {boolean}
619 */
620 showdown.helper.isArray = function (a) {
621 'use strict';
622 return Array.isArray(a);
623 };
624
625 /**
626 * Check if value is undefined
627 * @static
628 * @param {*} value The value to check.
629 * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
630 */
631 showdown.helper.isUndefined = function (value) {
632 'use strict';
633 return typeof value === 'undefined';
634 };
635
636 /**
637 * ForEach helper function
638 * Iterates over Arrays and Objects (own properties only)
639 * @static
640 * @param {*} obj
641 * @param {function} callback Accepts 3 params: 1. value, 2. key, 3. the original array/object
642 */
643 showdown.helper.forEach = function (obj, callback) {
644 'use strict';
645 // check if obj is defined
646 if (showdown.helper.isUndefined(obj)) {
647 throw new Error('obj param is required');
648 }
649
650 if (showdown.helper.isUndefined(callback)) {
651 throw new Error('callback param is required');
652 }
653
654 if (!showdown.helper.isFunction(callback)) {
655 throw new Error('callback param must be a function/closure');
656 }
657
658 if (typeof obj.forEach === 'function') {
659 obj.forEach(callback);
660 } else if (showdown.helper.isArray(obj)) {
661 for (var i = 0; i < obj.length; i++) {
662 callback(obj[i], i, obj);
663 }
664 } else if (typeof (obj) === 'object') {
665 for (var prop in obj) {
666 if (obj.hasOwnProperty(prop)) {
667 callback(obj[prop], prop, obj);
668 }
669 }
670 } else {
671 throw new Error('obj does not seem to be an array or an iterable object');
672 }
673 };
674
675 /**
676 * Standardidize extension name
677 * @static
678 * @param {string} s extension name
679 * @returns {string}
680 */
681 showdown.helper.stdExtName = function (s) {
682 'use strict';
683 return s.replace(/[_?*+\/\\.^-]/g, '').replace(/\s/g, '').toLowerCase();
684 };
685
686 function escapeCharactersCallback (wholeMatch, m1) {
687 'use strict';
688 var charCodeToEscape = m1.charCodeAt(0);
689 return '¨E' + charCodeToEscape + 'E';
690 }
691
692 /**
693 * Callback used to escape characters when passing through String.replace
694 * @static
695 * @param {string} wholeMatch
696 * @param {string} m1
697 * @returns {string}
698 */
699 showdown.helper.escapeCharactersCallback = escapeCharactersCallback;
700
701 /**
702 * Escape characters in a string
703 * @static
704 * @param {string} text
705 * @param {string} charsToEscape
706 * @param {boolean} afterBackslash
707 * @returns {XML|string|void|*}
708 */
709 showdown.helper.escapeCharacters = function (text, charsToEscape, afterBackslash) {
710 'use strict';
711 // First we have to escape the escape characters so that
712 // we can build a character class out of them
713 var regexString = '([' + charsToEscape.replace(/([\[\]\\])/g, '\\$1') + '])';
714
715 if (afterBackslash) {
716 regexString = '\\\\' + regexString;
717 }
718
719 var regex = new RegExp(regexString, 'g');
720 text = text.replace(regex, escapeCharactersCallback);
721
722 return text;
723 };
724
725 /**
726 * Unescape HTML entities
727 * @param txt
728 * @returns {string}
729 */
730 showdown.helper.unescapeHTMLEntities = function (txt) {
731 'use strict';
732
733 return txt
734 .replace(/&quot;/g, '"')
735 .replace(/&lt;/g, '<')
736 .replace(/&gt;/g, '>')
737 .replace(/&amp;/g, '&');
738 };
739
740 var rgxFindMatchPos = function (str, left, right, flags) {
741 'use strict';
742 var f = flags || '',
743 g = f.indexOf('g') > -1,
744 x = new RegExp(left + '|' + right, 'g' + f.replace(/g/g, '')),
745 l = new RegExp(left, f.replace(/g/g, '')),
746 pos = [],
747 t, s, m, start, end;
748
749 do {
750 t = 0;
751 while ((m = x.exec(str))) {
752 if (l.test(m[0])) {
753 if (!(t++)) {
754 s = x.lastIndex;
755 start = s - m[0].length;
756 }
757 } else if (t) {
758 if (!--t) {
759 end = m.index + m[0].length;
760 var obj = {
761 left: {start: start, end: s},
762 match: {start: s, end: m.index},
763 right: {start: m.index, end: end},
764 wholeMatch: {start: start, end: end}
765 };
766 pos.push(obj);
767 if (!g) {
768 return pos;
769 }
770 }
771 }
772 }
773 } while (t && (x.lastIndex = s));
774
775 return pos;
776 };
777
778 /**
779 * matchRecursiveRegExp
780 *
781 * (c) 2007 Steven Levithan <stevenlevithan.com>
782 * MIT License
783 *
784 * Accepts a string to search, a left and right format delimiter
785 * as regex patterns, and optional regex flags. Returns an array
786 * of matches, allowing nested instances of left/right delimiters.
787 * Use the "g" flag to return all matches, otherwise only the
788 * first is returned. Be careful to ensure that the left and
789 * right format delimiters produce mutually exclusive matches.
790 * Backreferences are not supported within the right delimiter
791 * due to how it is internally combined with the left delimiter.
792 * When matching strings whose format delimiters are unbalanced
793 * to the left or right, the output is intentionally as a
794 * conventional regex library with recursion support would
795 * produce, e.g. "<<x>" and "<x>>" both produce ["x"] when using
796 * "<" and ">" as the delimiters (both strings contain a single,
797 * balanced instance of "<x>").
798 *
799 * examples:
800 * matchRecursiveRegExp("test", "\\(", "\\)")
801 * returns: []
802 * matchRecursiveRegExp("<t<<e>><s>>t<>", "<", ">", "g")
803 * returns: ["t<<e>><s>", ""]
804 * matchRecursiveRegExp("<div id=\"x\">test</div>", "<div\\b[^>]*>", "</div>", "gi")
805 * returns: ["test"]
806 */
807 showdown.helper.matchRecursiveRegExp = function (str, left, right, flags) {
808 'use strict';
809
810 var matchPos = rgxFindMatchPos (str, left, right, flags),
811 results = [];
812
813 for (var i = 0; i < matchPos.length; ++i) {
814 results.push([
815 str.slice(matchPos[i].wholeMatch.start, matchPos[i].wholeMatch.end),
816 str.slice(matchPos[i].match.start, matchPos[i].match.end),
817 str.slice(matchPos[i].left.start, matchPos[i].left.end),
818 str.slice(matchPos[i].right.start, matchPos[i].right.end)
819 ]);
820 }
821 return results;
822 };
823
824 /**
825 *
826 * @param {string} str
827 * @param {string|function} replacement
828 * @param {string} left
829 * @param {string} right
830 * @param {string} flags
831 * @returns {string}
832 */
833 showdown.helper.replaceRecursiveRegExp = function (str, replacement, left, right, flags) {
834 'use strict';
835
836 if (!showdown.helper.isFunction(replacement)) {
837 var repStr = replacement;
838 replacement = function () {
839 return repStr;
840 };
841 }
842
843 var matchPos = rgxFindMatchPos(str, left, right, flags),
844 finalStr = str,
845 lng = matchPos.length;
846
847 if (lng > 0) {
848 var bits = [];
849 if (matchPos[0].wholeMatch.start !== 0) {
850 bits.push(str.slice(0, matchPos[0].wholeMatch.start));
851 }
852 for (var i = 0; i < lng; ++i) {
853 bits.push(
854 replacement(
855 str.slice(matchPos[i].wholeMatch.start, matchPos[i].wholeMatch.end),
856 str.slice(matchPos[i].match.start, matchPos[i].match.end),
857 str.slice(matchPos[i].left.start, matchPos[i].left.end),
858 str.slice(matchPos[i].right.start, matchPos[i].right.end)
859 )
860 );
861 if (i < lng - 1) {
862 bits.push(str.slice(matchPos[i].wholeMatch.end, matchPos[i + 1].wholeMatch.start));
863 }
864 }
865 if (matchPos[lng - 1].wholeMatch.end < str.length) {
866 bits.push(str.slice(matchPos[lng - 1].wholeMatch.end));
867 }
868 finalStr = bits.join('');
869 }
870 return finalStr;
871 };
872
873 /**
874 * Returns the index within the passed String object of the first occurrence of the specified regex,
875 * starting the search at fromIndex. Returns -1 if the value is not found.
876 *
877 * @param {string} str string to search
878 * @param {RegExp} regex Regular expression to search
879 * @param {int} [fromIndex = 0] Index to start the search
880 * @returns {Number}
881 * @throws InvalidArgumentError
882 */
883 showdown.helper.regexIndexOf = function (str, regex, fromIndex) {
884 'use strict';
885 if (!showdown.helper.isString(str)) {
886 throw 'InvalidArgumentError: first parameter of showdown.helper.regexIndexOf function must be a string';
887 }
888 if (regex instanceof RegExp === false) {
889 throw 'InvalidArgumentError: second parameter of showdown.helper.regexIndexOf function must be an instance of RegExp';
890 }
891 var indexOf = str.substring(fromIndex || 0).search(regex);
892 return (indexOf >= 0) ? (indexOf + (fromIndex || 0)) : indexOf;
893 };
894
895 /**
896 * Splits the passed string object at the defined index, and returns an array composed of the two substrings
897 * @param {string} str string to split
898 * @param {int} index index to split string at
899 * @returns {[string,string]}
900 * @throws InvalidArgumentError
901 */
902 showdown.helper.splitAtIndex = function (str, index) {
903 'use strict';
904 if (!showdown.helper.isString(str)) {
905 throw 'InvalidArgumentError: first parameter of showdown.helper.regexIndexOf function must be a string';
906 }
907 return [str.substring(0, index), str.substring(index)];
908 };
909
910 /**
911 * Obfuscate an e-mail address through the use of Character Entities,
912 * transforming ASCII characters into their equivalent decimal or hex entities.
913 *
914 * Since it has a random component, subsequent calls to this function produce different results
915 *
916 * @param {string} mail
917 * @returns {string}
918 */
919 showdown.helper.encodeEmailAddress = function (mail) {
920 'use strict';
921 var encode = [
922 function (ch) {
923 return '&#' + ch.charCodeAt(0) + ';';
924 },
925 function (ch) {
926 return '&#x' + ch.charCodeAt(0).toString(16) + ';';
927 },
928 function (ch) {
929 return ch;
930 }
931 ];
932
933 mail = mail.replace(/./g, function (ch) {
934 if (ch === '@') {
935 // this *must* be encoded. I insist.
936 ch = encode[Math.floor(Math.random() * 2)](ch);
937 } else {
938 var r = Math.random();
939 // roughly 10% raw, 45% hex, 45% dec
940 ch = (
941 r > 0.9 ? encode[2](ch) : r > 0.45 ? encode[1](ch) : encode[0](ch)
942 );
943 }
944 return ch;
945 });
946
947 return mail;
948 };
949
950 /**
951 *
952 * @param str
953 * @param targetLength
954 * @param padString
955 * @returns {string}
956 */
957 showdown.helper.padEnd = function padEnd (str, targetLength, padString) {
958 'use strict';
959 /*jshint bitwise: false*/
960 // eslint-disable-next-line space-infix-ops
961 targetLength = targetLength>>0; //floor if number or convert non-number to 0;
962 /*jshint bitwise: true*/
963 padString = String(padString || ' ');
964 if (str.length > targetLength) {
965 return String(str);
966 } else {
967 targetLength = targetLength - str.length;
968 if (targetLength > padString.length) {
969 padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed
970 }
971 return String(str) + padString.slice(0,targetLength);
972 }
973 };
974
975 /**
976 * POLYFILLS
977 */
978 // use this instead of builtin is undefined for IE8 compatibility
979 if (typeof console === 'undefined') {
980 console = {
981 warn: function (msg) {
982 'use strict';
983 alert(msg);
984 },
985 log: function (msg) {
986 'use strict';
987 alert(msg);
988 },
989 error: function (msg) {
990 'use strict';
991 throw msg;
992 }
993 };
994 }
995
996 /**
997 * Common regexes.
998 * We declare some common regexes to improve performance
999 */
1000 showdown.helper.regexes = {
1001 asteriskDashAndColon: /([*_:~])/g
1002 };
1003
1004 /**
1005 * EMOJIS LIST
1006 */
1007 showdown.helper.emojis = {
1008 '+1':'\ud83d\udc4d',
1009 '-1':'\ud83d\udc4e',
1010 '100':'\ud83d\udcaf',
1011 '1234':'\ud83d\udd22',
1012 '1st_place_medal':'\ud83e\udd47',
1013 '2nd_place_medal':'\ud83e\udd48',
1014 '3rd_place_medal':'\ud83e\udd49',
1015 '8ball':'\ud83c\udfb1',
1016 'a':'\ud83c\udd70\ufe0f',
1017 'ab':'\ud83c\udd8e',
1018 'abc':'\ud83d\udd24',
1019 'abcd':'\ud83d\udd21',
1020 'accept':'\ud83c\ude51',
1021 'aerial_tramway':'\ud83d\udea1',
1022 'airplane':'\u2708\ufe0f',
1023 'alarm_clock':'\u23f0',
1024 'alembic':'\u2697\ufe0f',
1025 'alien':'\ud83d\udc7d',
1026 'ambulance':'\ud83d\ude91',
1027 'amphora':'\ud83c\udffa',
1028 'anchor':'\u2693\ufe0f',
1029 'angel':'\ud83d\udc7c',
1030 'anger':'\ud83d\udca2',
1031 'angry':'\ud83d\ude20',
1032 'anguished':'\ud83d\ude27',
1033 'ant':'\ud83d\udc1c',
1034 'apple':'\ud83c\udf4e',
1035 'aquarius':'\u2652\ufe0f',
1036 'aries':'\u2648\ufe0f',
1037 'arrow_backward':'\u25c0\ufe0f',
1038 'arrow_double_down':'\u23ec',
1039 'arrow_double_up':'\u23eb',
1040 'arrow_down':'\u2b07\ufe0f',
1041 'arrow_down_small':'\ud83d\udd3d',
1042 'arrow_forward':'\u25b6\ufe0f',
1043 'arrow_heading_down':'\u2935\ufe0f',
1044 'arrow_heading_up':'\u2934\ufe0f',
1045 'arrow_left':'\u2b05\ufe0f',
1046 'arrow_lower_left':'\u2199\ufe0f',
1047 'arrow_lower_right':'\u2198\ufe0f',
1048 'arrow_right':'\u27a1\ufe0f',
1049 'arrow_right_hook':'\u21aa\ufe0f',
1050 'arrow_up':'\u2b06\ufe0f',
1051 'arrow_up_down':'\u2195\ufe0f',
1052 'arrow_up_small':'\ud83d\udd3c',
1053 'arrow_upper_left':'\u2196\ufe0f',
1054 'arrow_upper_right':'\u2197\ufe0f',
1055 'arrows_clockwise':'\ud83d\udd03',
1056 'arrows_counterclockwise':'\ud83d\udd04',
1057 'art':'\ud83c\udfa8',
1058 'articulated_lorry':'\ud83d\ude9b',
1059 'artificial_satellite':'\ud83d\udef0',
1060 'astonished':'\ud83d\ude32',
1061 'athletic_shoe':'\ud83d\udc5f',
1062 'atm':'\ud83c\udfe7',
1063 'atom_symbol':'\u269b\ufe0f',
1064 'avocado':'\ud83e\udd51',
1065 'b':'\ud83c\udd71\ufe0f',
1066 'baby':'\ud83d\udc76',
1067 'baby_bottle':'\ud83c\udf7c',
1068 'baby_chick':'\ud83d\udc24',
1069 'baby_symbol':'\ud83d\udebc',
1070 'back':'\ud83d\udd19',
1071 'bacon':'\ud83e\udd53',
1072 'badminton':'\ud83c\udff8',
1073 'baggage_claim':'\ud83d\udec4',
1074 'baguette_bread':'\ud83e\udd56',
1075 'balance_scale':'\u2696\ufe0f',
1076 'balloon':'\ud83c\udf88',
1077 'ballot_box':'\ud83d\uddf3',
1078 'ballot_box_with_check':'\u2611\ufe0f',
1079 'bamboo':'\ud83c\udf8d',
1080 'banana':'\ud83c\udf4c',
1081 'bangbang':'\u203c\ufe0f',
1082 'bank':'\ud83c\udfe6',
1083 'bar_chart':'\ud83d\udcca',
1084 'barber':'\ud83d\udc88',
1085 'baseball':'\u26be\ufe0f',
1086 'basketball':'\ud83c\udfc0',
1087 'basketball_man':'\u26f9\ufe0f',
1088 'basketball_woman':'\u26f9\ufe0f&zwj;\u2640\ufe0f',
1089 'bat':'\ud83e\udd87',
1090 'bath':'\ud83d\udec0',
1091 'bathtub':'\ud83d\udec1',
1092 'battery':'\ud83d\udd0b',
1093 'beach_umbrella':'\ud83c\udfd6',
1094 'bear':'\ud83d\udc3b',
1095 'bed':'\ud83d\udecf',
1096 'bee':'\ud83d\udc1d',
1097 'beer':'\ud83c\udf7a',
1098 'beers':'\ud83c\udf7b',
1099 'beetle':'\ud83d\udc1e',
1100 'beginner':'\ud83d\udd30',
1101 'bell':'\ud83d\udd14',
1102 'bellhop_bell':'\ud83d\udece',
1103 'bento':'\ud83c\udf71',
1104 'biking_man':'\ud83d\udeb4',
1105 'bike':'\ud83d\udeb2',
1106 'biking_woman':'\ud83d\udeb4&zwj;\u2640\ufe0f',
1107 'bikini':'\ud83d\udc59',
1108 'biohazard':'\u2623\ufe0f',
1109 'bird':'\ud83d\udc26',
1110 'birthday':'\ud83c\udf82',
1111 'black_circle':'\u26ab\ufe0f',
1112 'black_flag':'\ud83c\udff4',
1113 'black_heart':'\ud83d\udda4',
1114 'black_joker':'\ud83c\udccf',
1115 'black_large_square':'\u2b1b\ufe0f',
1116 'black_medium_small_square':'\u25fe\ufe0f',
1117 'black_medium_square':'\u25fc\ufe0f',
1118 'black_nib':'\u2712\ufe0f',
1119 'black_small_square':'\u25aa\ufe0f',
1120 'black_square_button':'\ud83d\udd32',
1121 'blonde_man':'\ud83d\udc71',
1122 'blonde_woman':'\ud83d\udc71&zwj;\u2640\ufe0f',
1123 'blossom':'\ud83c\udf3c',
1124 'blowfish':'\ud83d\udc21',
1125 'blue_book':'\ud83d\udcd8',
1126 'blue_car':'\ud83d\ude99',
1127 'blue_heart':'\ud83d\udc99',
1128 'blush':'\ud83d\ude0a',
1129 'boar':'\ud83d\udc17',
1130 'boat':'\u26f5\ufe0f',
1131 'bomb':'\ud83d\udca3',
1132 'book':'\ud83d\udcd6',
1133 'bookmark':'\ud83d\udd16',
1134 'bookmark_tabs':'\ud83d\udcd1',
1135 'books':'\ud83d\udcda',
1136 'boom':'\ud83d\udca5',
1137 'boot':'\ud83d\udc62',
1138 'bouquet':'\ud83d\udc90',
1139 'bowing_man':'\ud83d\ude47',
1140 'bow_and_arrow':'\ud83c\udff9',
1141 'bowing_woman':'\ud83d\ude47&zwj;\u2640\ufe0f',
1142 'bowling':'\ud83c\udfb3',
1143 'boxing_glove':'\ud83e\udd4a',
1144 'boy':'\ud83d\udc66',
1145 'bread':'\ud83c\udf5e',
1146 'bride_with_veil':'\ud83d\udc70',
1147 'bridge_at_night':'\ud83c\udf09',
1148 'briefcase':'\ud83d\udcbc',
1149 'broken_heart':'\ud83d\udc94',
1150 'bug':'\ud83d\udc1b',
1151 'building_construction':'\ud83c\udfd7',
1152 'bulb':'\ud83d\udca1',
1153 'bullettrain_front':'\ud83d\ude85',
1154 'bullettrain_side':'\ud83d\ude84',
1155 'burrito':'\ud83c\udf2f',
1156 'bus':'\ud83d\ude8c',
1157 'business_suit_levitating':'\ud83d\udd74',
1158 'busstop':'\ud83d\ude8f',
1159 'bust_in_silhouette':'\ud83d\udc64',
1160 'busts_in_silhouette':'\ud83d\udc65',
1161 'butterfly':'\ud83e\udd8b',
1162 'cactus':'\ud83c\udf35',
1163 'cake':'\ud83c\udf70',
1164 'calendar':'\ud83d\udcc6',
1165 'call_me_hand':'\ud83e\udd19',
1166 'calling':'\ud83d\udcf2',
1167 'camel':'\ud83d\udc2b',
1168 'camera':'\ud83d\udcf7',
1169 'camera_flash':'\ud83d\udcf8',
1170 'camping':'\ud83c\udfd5',
1171 'cancer':'\u264b\ufe0f',
1172 'candle':'\ud83d\udd6f',
1173 'candy':'\ud83c\udf6c',
1174 'canoe':'\ud83d\udef6',
1175 'capital_abcd':'\ud83d\udd20',
1176 'capricorn':'\u2651\ufe0f',
1177 'car':'\ud83d\ude97',
1178 'card_file_box':'\ud83d\uddc3',
1179 'card_index':'\ud83d\udcc7',
1180 'card_index_dividers':'\ud83d\uddc2',
1181 'carousel_horse':'\ud83c\udfa0',
1182 'carrot':'\ud83e\udd55',
1183 'cat':'\ud83d\udc31',
1184 'cat2':'\ud83d\udc08',
1185 'cd':'\ud83d\udcbf',
1186 'chains':'\u26d3',
1187 'champagne':'\ud83c\udf7e',
1188 'chart':'\ud83d\udcb9',
1189 'chart_with_downwards_trend':'\ud83d\udcc9',
1190 'chart_with_upwards_trend':'\ud83d\udcc8',
1191 'checkered_flag':'\ud83c\udfc1',
1192 'cheese':'\ud83e\uddc0',
1193 'cherries':'\ud83c\udf52',
1194 'cherry_blossom':'\ud83c\udf38',
1195 'chestnut':'\ud83c\udf30',
1196 'chicken':'\ud83d\udc14',
1197 'children_crossing':'\ud83d\udeb8',
1198 'chipmunk':'\ud83d\udc3f',
1199 'chocolate_bar':'\ud83c\udf6b',
1200 'christmas_tree':'\ud83c\udf84',
1201 'church':'\u26ea\ufe0f',
1202 'cinema':'\ud83c\udfa6',
1203 'circus_tent':'\ud83c\udfaa',
1204 'city_sunrise':'\ud83c\udf07',
1205 'city_sunset':'\ud83c\udf06',
1206 'cityscape':'\ud83c\udfd9',
1207 'cl':'\ud83c\udd91',
1208 'clamp':'\ud83d\udddc',
1209 'clap':'\ud83d\udc4f',
1210 'clapper':'\ud83c\udfac',
1211 'classical_building':'\ud83c\udfdb',
1212 'clinking_glasses':'\ud83e\udd42',
1213 'clipboard':'\ud83d\udccb',
1214 'clock1':'\ud83d\udd50',
1215 'clock10':'\ud83d\udd59',
1216 'clock1030':'\ud83d\udd65',
1217 'clock11':'\ud83d\udd5a',
1218 'clock1130':'\ud83d\udd66',
1219 'clock12':'\ud83d\udd5b',
1220 'clock1230':'\ud83d\udd67',
1221 'clock130':'\ud83d\udd5c',
1222 'clock2':'\ud83d\udd51',
1223 'clock230':'\ud83d\udd5d',
1224 'clock3':'\ud83d\udd52',
1225 'clock330':'\ud83d\udd5e',
1226 'clock4':'\ud83d\udd53',
1227 'clock430':'\ud83d\udd5f',
1228 'clock5':'\ud83d\udd54',
1229 'clock530':'\ud83d\udd60',
1230 'clock6':'\ud83d\udd55',
1231 'clock630':'\ud83d\udd61',
1232 'clock7':'\ud83d\udd56',
1233 'clock730':'\ud83d\udd62',
1234 'clock8':'\ud83d\udd57',
1235 'clock830':'\ud83d\udd63',
1236 'clock9':'\ud83d\udd58',
1237 'clock930':'\ud83d\udd64',
1238 'closed_book':'\ud83d\udcd5',
1239 'closed_lock_with_key':'\ud83d\udd10',
1240 'closed_umbrella':'\ud83c\udf02',
1241 'cloud':'\u2601\ufe0f',
1242 'cloud_with_lightning':'\ud83c\udf29',
1243 'cloud_with_lightning_and_rain':'\u26c8',
1244 'cloud_with_rain':'\ud83c\udf27',
1245 'cloud_with_snow':'\ud83c\udf28',
1246 'clown_face':'\ud83e\udd21',
1247 'clubs':'\u2663\ufe0f',
1248 'cocktail':'\ud83c\udf78',
1249 'coffee':'\u2615\ufe0f',
1250 'coffin':'\u26b0\ufe0f',
1251 'cold_sweat':'\ud83d\ude30',
1252 'comet':'\u2604\ufe0f',
1253 'computer':'\ud83d\udcbb',
1254 'computer_mouse':'\ud83d\uddb1',
1255 'confetti_ball':'\ud83c\udf8a',
1256 'confounded':'\ud83d\ude16',
1257 'confused':'\ud83d\ude15',
1258 'congratulations':'\u3297\ufe0f',
1259 'construction':'\ud83d\udea7',
1260 'construction_worker_man':'\ud83d\udc77',
1261 'construction_worker_woman':'\ud83d\udc77&zwj;\u2640\ufe0f',
1262 'control_knobs':'\ud83c\udf9b',
1263 'convenience_store':'\ud83c\udfea',
1264 'cookie':'\ud83c\udf6a',
1265 'cool':'\ud83c\udd92',
1266 'policeman':'\ud83d\udc6e',
1267 'copyright':'\u00a9\ufe0f',
1268 'corn':'\ud83c\udf3d',
1269 'couch_and_lamp':'\ud83d\udecb',
1270 'couple':'\ud83d\udc6b',
1271 'couple_with_heart_woman_man':'\ud83d\udc91',
1272 'couple_with_heart_man_man':'\ud83d\udc68&zwj;\u2764\ufe0f&zwj;\ud83d\udc68',
1273 'couple_with_heart_woman_woman':'\ud83d\udc69&zwj;\u2764\ufe0f&zwj;\ud83d\udc69',
1274 'couplekiss_man_man':'\ud83d\udc68&zwj;\u2764\ufe0f&zwj;\ud83d\udc8b&zwj;\ud83d\udc68',
1275 'couplekiss_man_woman':'\ud83d\udc8f',
1276 'couplekiss_woman_woman':'\ud83d\udc69&zwj;\u2764\ufe0f&zwj;\ud83d\udc8b&zwj;\ud83d\udc69',
1277 'cow':'\ud83d\udc2e',
1278 'cow2':'\ud83d\udc04',
1279 'cowboy_hat_face':'\ud83e\udd20',
1280 'crab':'\ud83e\udd80',
1281 'crayon':'\ud83d\udd8d',
1282 'credit_card':'\ud83d\udcb3',
1283 'crescent_moon':'\ud83c\udf19',
1284 'cricket':'\ud83c\udfcf',
1285 'crocodile':'\ud83d\udc0a',
1286 'croissant':'\ud83e\udd50',
1287 'crossed_fingers':'\ud83e\udd1e',
1288 'crossed_flags':'\ud83c\udf8c',
1289 'crossed_swords':'\u2694\ufe0f',
1290 'crown':'\ud83d\udc51',
1291 'cry':'\ud83d\ude22',
1292 'crying_cat_face':'\ud83d\ude3f',
1293 'crystal_ball':'\ud83d\udd2e',
1294 'cucumber':'\ud83e\udd52',
1295 'cupid':'\ud83d\udc98',
1296 'curly_loop':'\u27b0',
1297 'currency_exchange':'\ud83d\udcb1',
1298 'curry':'\ud83c\udf5b',
1299 'custard':'\ud83c\udf6e',
1300 'customs':'\ud83d\udec3',
1301 'cyclone':'\ud83c\udf00',
1302 'dagger':'\ud83d\udde1',
1303 'dancer':'\ud83d\udc83',
1304 'dancing_women':'\ud83d\udc6f',
1305 'dancing_men':'\ud83d\udc6f&zwj;\u2642\ufe0f',
1306 'dango':'\ud83c\udf61',
1307 'dark_sunglasses':'\ud83d\udd76',
1308 'dart':'\ud83c\udfaf',
1309 'dash':'\ud83d\udca8',
1310 'date':'\ud83d\udcc5',
1311 'deciduous_tree':'\ud83c\udf33',
1312 'deer':'\ud83e\udd8c',
1313 'department_store':'\ud83c\udfec',
1314 'derelict_house':'\ud83c\udfda',
1315 'desert':'\ud83c\udfdc',
1316 'desert_island':'\ud83c\udfdd',
1317 'desktop_computer':'\ud83d\udda5',
1318 'male_detective':'\ud83d\udd75\ufe0f',
1319 'diamond_shape_with_a_dot_inside':'\ud83d\udca0',
1320 'diamonds':'\u2666\ufe0f',
1321 'disappointed':'\ud83d\ude1e',
1322 'disappointed_relieved':'\ud83d\ude25',
1323 'dizzy':'\ud83d\udcab',
1324 'dizzy_face':'\ud83d\ude35',
1325 'do_not_litter':'\ud83d\udeaf',
1326 'dog':'\ud83d\udc36',
1327 'dog2':'\ud83d\udc15',
1328 'dollar':'\ud83d\udcb5',
1329 'dolls':'\ud83c\udf8e',
1330 'dolphin':'\ud83d\udc2c',
1331 'door':'\ud83d\udeaa',
1332 'doughnut':'\ud83c\udf69',
1333 'dove':'\ud83d\udd4a',
1334 'dragon':'\ud83d\udc09',
1335 'dragon_face':'\ud83d\udc32',
1336 'dress':'\ud83d\udc57',
1337 'dromedary_camel':'\ud83d\udc2a',
1338 'drooling_face':'\ud83e\udd24',
1339 'droplet':'\ud83d\udca7',
1340 'drum':'\ud83e\udd41',
1341 'duck':'\ud83e\udd86',
1342 'dvd':'\ud83d\udcc0',
1343 'e-mail':'\ud83d\udce7',
1344 'eagle':'\ud83e\udd85',
1345 'ear':'\ud83d\udc42',
1346 'ear_of_rice':'\ud83c\udf3e',
1347 'earth_africa':'\ud83c\udf0d',
1348 'earth_americas':'\ud83c\udf0e',
1349 'earth_asia':'\ud83c\udf0f',
1350 'egg':'\ud83e\udd5a',
1351 'eggplant':'\ud83c\udf46',
1352 'eight_pointed_black_star':'\u2734\ufe0f',
1353 'eight_spoked_asterisk':'\u2733\ufe0f',
1354 'electric_plug':'\ud83d\udd0c',
1355 'elephant':'\ud83d\udc18',
1356 'email':'\u2709\ufe0f',
1357 'end':'\ud83d\udd1a',
1358 'envelope_with_arrow':'\ud83d\udce9',
1359 'euro':'\ud83d\udcb6',
1360 'european_castle':'\ud83c\udff0',
1361 'european_post_office':'\ud83c\udfe4',
1362 'evergreen_tree':'\ud83c\udf32',
1363 'exclamation':'\u2757\ufe0f',
1364 'expressionless':'\ud83d\ude11',
1365 'eye':'\ud83d\udc41',
1366 'eye_speech_bubble':'\ud83d\udc41&zwj;\ud83d\udde8',
1367 'eyeglasses':'\ud83d\udc53',
1368 'eyes':'\ud83d\udc40',
1369 'face_with_head_bandage':'\ud83e\udd15',
1370 'face_with_thermometer':'\ud83e\udd12',
1371 'fist_oncoming':'\ud83d\udc4a',
1372 'factory':'\ud83c\udfed',
1373 'fallen_leaf':'\ud83c\udf42',
1374 'family_man_woman_boy':'\ud83d\udc6a',
1375 'family_man_boy':'\ud83d\udc68&zwj;\ud83d\udc66',
1376 'family_man_boy_boy':'\ud83d\udc68&zwj;\ud83d\udc66&zwj;\ud83d\udc66',
1377 'family_man_girl':'\ud83d\udc68&zwj;\ud83d\udc67',
1378 'family_man_girl_boy':'\ud83d\udc68&zwj;\ud83d\udc67&zwj;\ud83d\udc66',
1379 'family_man_girl_girl':'\ud83d\udc68&zwj;\ud83d\udc67&zwj;\ud83d\udc67',
1380 'family_man_man_boy':'\ud83d\udc68&zwj;\ud83d\udc68&zwj;\ud83d\udc66',
1381 'family_man_man_boy_boy':'\ud83d\udc68&zwj;\ud83d\udc68&zwj;\ud83d\udc66&zwj;\ud83d\udc66',
1382 'family_man_man_girl':'\ud83d\udc68&zwj;\ud83d\udc68&zwj;\ud83d\udc67',
1383 'family_man_man_girl_boy':'\ud83d\udc68&zwj;\ud83d\udc68&zwj;\ud83d\udc67&zwj;\ud83d\udc66',
1384 'family_man_man_girl_girl':'\ud83d\udc68&zwj;\ud83d\udc68&zwj;\ud83d\udc67&zwj;\ud83d\udc67',
1385 'family_man_woman_boy_boy':'\ud83d\udc68&zwj;\ud83d\udc69&zwj;\ud83d\udc66&zwj;\ud83d\udc66',
1386 'family_man_woman_girl':'\ud83d\udc68&zwj;\ud83d\udc69&zwj;\ud83d\udc67',
1387 'family_man_woman_girl_boy':'\ud83d\udc68&zwj;\ud83d\udc69&zwj;\ud83d\udc67&zwj;\ud83d\udc66',
1388 'family_man_woman_girl_girl':'\ud83d\udc68&zwj;\ud83d\udc69&zwj;\ud83d\udc67&zwj;\ud83d\udc67',
1389 'family_woman_boy':'\ud83d\udc69&zwj;\ud83d\udc66',
1390 'family_woman_boy_boy':'\ud83d\udc69&zwj;\ud83d\udc66&zwj;\ud83d\udc66',
1391 'family_woman_girl':'\ud83d\udc69&zwj;\ud83d\udc67',
1392 'family_woman_girl_boy':'\ud83d\udc69&zwj;\ud83d\udc67&zwj;\ud83d\udc66',
1393 'family_woman_girl_girl':'\ud83d\udc69&zwj;\ud83d\udc67&zwj;\ud83d\udc67',
1394 'family_woman_woman_boy':'\ud83d\udc69&zwj;\ud83d\udc69&zwj;\ud83d\udc66',
1395 'family_woman_woman_boy_boy':'\ud83d\udc69&zwj;\ud83d\udc69&zwj;\ud83d\udc66&zwj;\ud83d\udc66',
1396 'family_woman_woman_girl':'\ud83d\udc69&zwj;\ud83d\udc69&zwj;\ud83d\udc67',
1397 'family_woman_woman_girl_boy':'\ud83d\udc69&zwj;\ud83d\udc69&zwj;\ud83d\udc67&zwj;\ud83d\udc66',
1398 'family_woman_woman_girl_girl':'\ud83d\udc69&zwj;\ud83d\udc69&zwj;\ud83d\udc67&zwj;\ud83d\udc67',
1399 'fast_forward':'\u23e9',
1400 'fax':'\ud83d\udce0',
1401 'fearful':'\ud83d\ude28',
1402 'feet':'\ud83d\udc3e',
1403 'female_detective':'\ud83d\udd75\ufe0f&zwj;\u2640\ufe0f',
1404 'ferris_wheel':'\ud83c\udfa1',
1405 'ferry':'\u26f4',
1406 'field_hockey':'\ud83c\udfd1',
1407 'file_cabinet':'\ud83d\uddc4',
1408 'file_folder':'\ud83d\udcc1',
1409 'film_projector':'\ud83d\udcfd',
1410 'film_strip':'\ud83c\udf9e',
1411 'fire':'\ud83d\udd25',
1412 'fire_engine':'\ud83d\ude92',
1413 'fireworks':'\ud83c\udf86',
1414 'first_quarter_moon':'\ud83c\udf13',
1415 'first_quarter_moon_with_face':'\ud83c\udf1b',
1416 'fish':'\ud83d\udc1f',
1417 'fish_cake':'\ud83c\udf65',
1418 'fishing_pole_and_fish':'\ud83c\udfa3',
1419 'fist_raised':'\u270a',
1420 'fist_left':'\ud83e\udd1b',
1421 'fist_right':'\ud83e\udd1c',
1422 'flags':'\ud83c\udf8f',
1423 'flashlight':'\ud83d\udd26',
1424 'fleur_de_lis':'\u269c\ufe0f',
1425 'flight_arrival':'\ud83d\udeec',
1426 'flight_departure':'\ud83d\udeeb',
1427 'floppy_disk':'\ud83d\udcbe',
1428 'flower_playing_cards':'\ud83c\udfb4',
1429 'flushed':'\ud83d\ude33',
1430 'fog':'\ud83c\udf2b',
1431 'foggy':'\ud83c\udf01',
1432 'football':'\ud83c\udfc8',
1433 'footprints':'\ud83d\udc63',
1434 'fork_and_knife':'\ud83c\udf74',
1435 'fountain':'\u26f2\ufe0f',
1436 'fountain_pen':'\ud83d\udd8b',
1437 'four_leaf_clover':'\ud83c\udf40',
1438 'fox_face':'\ud83e\udd8a',
1439 'framed_picture':'\ud83d\uddbc',
1440 'free':'\ud83c\udd93',
1441 'fried_egg':'\ud83c\udf73',
1442 'fried_shrimp':'\ud83c\udf64',
1443 'fries':'\ud83c\udf5f',
1444 'frog':'\ud83d\udc38',
1445 'frowning':'\ud83d\ude26',
1446 'frowning_face':'\u2639\ufe0f',
1447 'frowning_man':'\ud83d\ude4d&zwj;\u2642\ufe0f',
1448 'frowning_woman':'\ud83d\ude4d',
1449 'middle_finger':'\ud83d\udd95',
1450 'fuelpump':'\u26fd\ufe0f',
1451 'full_moon':'\ud83c\udf15',
1452 'full_moon_with_face':'\ud83c\udf1d',
1453 'funeral_urn':'\u26b1\ufe0f',
1454 'game_die':'\ud83c\udfb2',
1455 'gear':'\u2699\ufe0f',
1456 'gem':'\ud83d\udc8e',
1457 'gemini':'\u264a\ufe0f',
1458 'ghost':'\ud83d\udc7b',
1459 'gift':'\ud83c\udf81',
1460 'gift_heart':'\ud83d\udc9d',
1461 'girl':'\ud83d\udc67',
1462 'globe_with_meridians':'\ud83c\udf10',
1463 'goal_net':'\ud83e\udd45',
1464 'goat':'\ud83d\udc10',
1465 'golf':'\u26f3\ufe0f',
1466 'golfing_man':'\ud83c\udfcc\ufe0f',
1467 'golfing_woman':'\ud83c\udfcc\ufe0f&zwj;\u2640\ufe0f',
1468 'gorilla':'\ud83e\udd8d',
1469 'grapes':'\ud83c\udf47',
1470 'green_apple':'\ud83c\udf4f',
1471 'green_book':'\ud83d\udcd7',
1472 'green_heart':'\ud83d\udc9a',
1473 'green_salad':'\ud83e\udd57',
1474 'grey_exclamation':'\u2755',
1475 'grey_question':'\u2754',
1476 'grimacing':'\ud83d\ude2c',
1477 'grin':'\ud83d\ude01',
1478 'grinning':'\ud83d\ude00',
1479 'guardsman':'\ud83d\udc82',
1480 'guardswoman':'\ud83d\udc82&zwj;\u2640\ufe0f',
1481 'guitar':'\ud83c\udfb8',
1482 'gun':'\ud83d\udd2b',
1483 'haircut_woman':'\ud83d\udc87',
1484 'haircut_man':'\ud83d\udc87&zwj;\u2642\ufe0f',
1485 'hamburger':'\ud83c\udf54',
1486 'hammer':'\ud83d\udd28',
1487 'hammer_and_pick':'\u2692',
1488 'hammer_and_wrench':'\ud83d\udee0',
1489 'hamster':'\ud83d\udc39',
1490 'hand':'\u270b',
1491 'handbag':'\ud83d\udc5c',
1492 'handshake':'\ud83e\udd1d',
1493 'hankey':'\ud83d\udca9',
1494 'hatched_chick':'\ud83d\udc25',
1495 'hatching_chick':'\ud83d\udc23',
1496 'headphones':'\ud83c\udfa7',
1497 'hear_no_evil':'\ud83d\ude49',
1498 'heart':'\u2764\ufe0f',
1499 'heart_decoration':'\ud83d\udc9f',
1500 'heart_eyes':'\ud83d\ude0d',
1501 'heart_eyes_cat':'\ud83d\ude3b',
1502 'heartbeat':'\ud83d\udc93',
1503 'heartpulse':'\ud83d\udc97',
1504 'hearts':'\u2665\ufe0f',
1505 'heavy_check_mark':'\u2714\ufe0f',
1506 'heavy_division_sign':'\u2797',
1507 'heavy_dollar_sign':'\ud83d\udcb2',
1508 'heavy_heart_exclamation':'\u2763\ufe0f',
1509 'heavy_minus_sign':'\u2796',
1510 'heavy_multiplication_x':'\u2716\ufe0f',
1511 'heavy_plus_sign':'\u2795',
1512 'helicopter':'\ud83d\ude81',
1513 'herb':'\ud83c\udf3f',
1514 'hibiscus':'\ud83c\udf3a',
1515 'high_brightness':'\ud83d\udd06',
1516 'high_heel':'\ud83d\udc60',
1517 'hocho':'\ud83d\udd2a',
1518 'hole':'\ud83d\udd73',
1519 'honey_pot':'\ud83c\udf6f',
1520 'horse':'\ud83d\udc34',
1521 'horse_racing':'\ud83c\udfc7',
1522 'hospital':'\ud83c\udfe5',
1523 'hot_pepper':'\ud83c\udf36',
1524 'hotdog':'\ud83c\udf2d',
1525 'hotel':'\ud83c\udfe8',
1526 'hotsprings':'\u2668\ufe0f',
1527 'hourglass':'\u231b\ufe0f',
1528 'hourglass_flowing_sand':'\u23f3',
1529 'house':'\ud83c\udfe0',
1530 'house_with_garden':'\ud83c\udfe1',
1531 'houses':'\ud83c\udfd8',
1532 'hugs':'\ud83e\udd17',
1533 'hushed':'\ud83d\ude2f',
1534 'ice_cream':'\ud83c\udf68',
1535 'ice_hockey':'\ud83c\udfd2',
1536 'ice_skate':'\u26f8',
1537 'icecream':'\ud83c\udf66',
1538 'id':'\ud83c\udd94',
1539 'ideograph_advantage':'\ud83c\ude50',
1540 'imp':'\ud83d\udc7f',
1541 'inbox_tray':'\ud83d\udce5',
1542 'incoming_envelope':'\ud83d\udce8',
1543 'tipping_hand_woman':'\ud83d\udc81',
1544 'information_source':'\u2139\ufe0f',
1545 'innocent':'\ud83d\ude07',
1546 'interrobang':'\u2049\ufe0f',
1547 'iphone':'\ud83d\udcf1',
1548 'izakaya_lantern':'\ud83c\udfee',
1549 'jack_o_lantern':'\ud83c\udf83',
1550 'japan':'\ud83d\uddfe',
1551 'japanese_castle':'\ud83c\udfef',
1552 'japanese_goblin':'\ud83d\udc7a',
1553 'japanese_ogre':'\ud83d\udc79',
1554 'jeans':'\ud83d\udc56',
1555 'joy':'\ud83d\ude02',
1556 'joy_cat':'\ud83d\ude39',
1557 'joystick':'\ud83d\udd79',
1558 'kaaba':'\ud83d\udd4b',
1559 'key':'\ud83d\udd11',
1560 'keyboard':'\u2328\ufe0f',
1561 'keycap_ten':'\ud83d\udd1f',
1562 'kick_scooter':'\ud83d\udef4',
1563 'kimono':'\ud83d\udc58',
1564 'kiss':'\ud83d\udc8b',
1565 'kissing':'\ud83d\ude17',
1566 'kissing_cat':'\ud83d\ude3d',
1567 'kissing_closed_eyes':'\ud83d\ude1a',
1568 'kissing_heart':'\ud83d\ude18',
1569 'kissing_smiling_eyes':'\ud83d\ude19',
1570 'kiwi_fruit':'\ud83e\udd5d',
1571 'koala':'\ud83d\udc28',
1572 'koko':'\ud83c\ude01',
1573 'label':'\ud83c\udff7',
1574 'large_blue_circle':'\ud83d\udd35',
1575 'large_blue_diamond':'\ud83d\udd37',
1576 'large_orange_diamond':'\ud83d\udd36',
1577 'last_quarter_moon':'\ud83c\udf17',
1578 'last_quarter_moon_with_face':'\ud83c\udf1c',
1579 'latin_cross':'\u271d\ufe0f',
1580 'laughing':'\ud83d\ude06',
1581 'leaves':'\ud83c\udf43',
1582 'ledger':'\ud83d\udcd2',
1583 'left_luggage':'\ud83d\udec5',
1584 'left_right_arrow':'\u2194\ufe0f',
1585 'leftwards_arrow_with_hook':'\u21a9\ufe0f',
1586 'lemon':'\ud83c\udf4b',
1587 'leo':'\u264c\ufe0f',
1588 'leopard':'\ud83d\udc06',
1589 'level_slider':'\ud83c\udf9a',
1590 'libra':'\u264e\ufe0f',
1591 'light_rail':'\ud83d\ude88',
1592 'link':'\ud83d\udd17',
1593 'lion':'\ud83e\udd81',
1594 'lips':'\ud83d\udc44',
1595 'lipstick':'\ud83d\udc84',
1596 'lizard':'\ud83e\udd8e',
1597 'lock':'\ud83d\udd12',
1598 'lock_with_ink_pen':'\ud83d\udd0f',
1599 'lollipop':'\ud83c\udf6d',
1600 'loop':'\u27bf',
1601 'loud_sound':'\ud83d\udd0a',
1602 'loudspeaker':'\ud83d\udce2',
1603 'love_hotel':'\ud83c\udfe9',
1604 'love_letter':'\ud83d\udc8c',
1605 'low_brightness':'\ud83d\udd05',
1606 'lying_face':'\ud83e\udd25',
1607 'm':'\u24c2\ufe0f',
1608 'mag':'\ud83d\udd0d',
1609 'mag_right':'\ud83d\udd0e',
1610 'mahjong':'\ud83c\udc04\ufe0f',
1611 'mailbox':'\ud83d\udceb',
1612 'mailbox_closed':'\ud83d\udcea',
1613 'mailbox_with_mail':'\ud83d\udcec',
1614 'mailbox_with_no_mail':'\ud83d\udced',
1615 'man':'\ud83d\udc68',
1616 'man_artist':'\ud83d\udc68&zwj;\ud83c\udfa8',
1617 'man_astronaut':'\ud83d\udc68&zwj;\ud83d\ude80',
1618 'man_cartwheeling':'\ud83e\udd38&zwj;\u2642\ufe0f',
1619 'man_cook':'\ud83d\udc68&zwj;\ud83c\udf73',
1620 'man_dancing':'\ud83d\udd7a',
1621 'man_facepalming':'\ud83e\udd26&zwj;\u2642\ufe0f',
1622 'man_factory_worker':'\ud83d\udc68&zwj;\ud83c\udfed',
1623 'man_farmer':'\ud83d\udc68&zwj;\ud83c\udf3e',
1624 'man_firefighter':'\ud83d\udc68&zwj;\ud83d\ude92',
1625 'man_health_worker':'\ud83d\udc68&zwj;\u2695\ufe0f',
1626 'man_in_tuxedo':'\ud83e\udd35',
1627 'man_judge':'\ud83d\udc68&zwj;\u2696\ufe0f',
1628 'man_juggling':'\ud83e\udd39&zwj;\u2642\ufe0f',
1629 'man_mechanic':'\ud83d\udc68&zwj;\ud83d\udd27',
1630 'man_office_worker':'\ud83d\udc68&zwj;\ud83d\udcbc',
1631 'man_pilot':'\ud83d\udc68&zwj;\u2708\ufe0f',
1632 'man_playing_handball':'\ud83e\udd3e&zwj;\u2642\ufe0f',
1633 'man_playing_water_polo':'\ud83e\udd3d&zwj;\u2642\ufe0f',
1634 'man_scientist':'\ud83d\udc68&zwj;\ud83d\udd2c',
1635 'man_shrugging':'\ud83e\udd37&zwj;\u2642\ufe0f',
1636 'man_singer':'\ud83d\udc68&zwj;\ud83c\udfa4',
1637 'man_student':'\ud83d\udc68&zwj;\ud83c\udf93',
1638 'man_teacher':'\ud83d\udc68&zwj;\ud83c\udfeb',
1639 'man_technologist':'\ud83d\udc68&zwj;\ud83d\udcbb',
1640 'man_with_gua_pi_mao':'\ud83d\udc72',
1641 'man_with_turban':'\ud83d\udc73',
1642 'tangerine':'\ud83c\udf4a',
1643 'mans_shoe':'\ud83d\udc5e',
1644 'mantelpiece_clock':'\ud83d\udd70',
1645 'maple_leaf':'\ud83c\udf41',
1646 'martial_arts_uniform':'\ud83e\udd4b',
1647 'mask':'\ud83d\ude37',
1648 'massage_woman':'\ud83d\udc86',
1649 'massage_man':'\ud83d\udc86&zwj;\u2642\ufe0f',
1650 'meat_on_bone':'\ud83c\udf56',
1651 'medal_military':'\ud83c\udf96',
1652 'medal_sports':'\ud83c\udfc5',
1653 'mega':'\ud83d\udce3',
1654 'melon':'\ud83c\udf48',
1655 'memo':'\ud83d\udcdd',
1656 'men_wrestling':'\ud83e\udd3c&zwj;\u2642\ufe0f',
1657 'menorah':'\ud83d\udd4e',
1658 'mens':'\ud83d\udeb9',
1659 'metal':'\ud83e\udd18',
1660 'metro':'\ud83d\ude87',
1661 'microphone':'\ud83c\udfa4',
1662 'microscope':'\ud83d\udd2c',
1663 'milk_glass':'\ud83e\udd5b',
1664 'milky_way':'\ud83c\udf0c',
1665 'minibus':'\ud83d\ude90',
1666 'minidisc':'\ud83d\udcbd',
1667 'mobile_phone_off':'\ud83d\udcf4',
1668 'money_mouth_face':'\ud83e\udd11',
1669 'money_with_wings':'\ud83d\udcb8',
1670 'moneybag':'\ud83d\udcb0',
1671 'monkey':'\ud83d\udc12',
1672 'monkey_face':'\ud83d\udc35',
1673 'monorail':'\ud83d\ude9d',
1674 'moon':'\ud83c\udf14',
1675 'mortar_board':'\ud83c\udf93',
1676 'mosque':'\ud83d\udd4c',
1677 'motor_boat':'\ud83d\udee5',
1678 'motor_scooter':'\ud83d\udef5',
1679 'motorcycle':'\ud83c\udfcd',
1680 'motorway':'\ud83d\udee3',
1681 'mount_fuji':'\ud83d\uddfb',
1682 'mountain':'\u26f0',
1683 'mountain_biking_man':'\ud83d\udeb5',
1684 'mountain_biking_woman':'\ud83d\udeb5&zwj;\u2640\ufe0f',
1685 'mountain_cableway':'\ud83d\udea0',
1686 'mountain_railway':'\ud83d\ude9e',
1687 'mountain_snow':'\ud83c\udfd4',
1688 'mouse':'\ud83d\udc2d',
1689 'mouse2':'\ud83d\udc01',
1690 'movie_camera':'\ud83c\udfa5',
1691 'moyai':'\ud83d\uddff',
1692 'mrs_claus':'\ud83e\udd36',
1693 'muscle':'\ud83d\udcaa',
1694 'mushroom':'\ud83c\udf44',
1695 'musical_keyboard':'\ud83c\udfb9',
1696 'musical_note':'\ud83c\udfb5',
1697 'musical_score':'\ud83c\udfbc',
1698 'mute':'\ud83d\udd07',
1699 'nail_care':'\ud83d\udc85',
1700 'name_badge':'\ud83d\udcdb',
1701 'national_park':'\ud83c\udfde',
1702 'nauseated_face':'\ud83e\udd22',
1703 'necktie':'\ud83d\udc54',
1704 'negative_squared_cross_mark':'\u274e',
1705 'nerd_face':'\ud83e\udd13',
1706 'neutral_face':'\ud83d\ude10',
1707 'new':'\ud83c\udd95',
1708 'new_moon':'\ud83c\udf11',
1709 'new_moon_with_face':'\ud83c\udf1a',
1710 'newspaper':'\ud83d\udcf0',
1711 'newspaper_roll':'\ud83d\uddde',
1712 'next_track_button':'\u23ed',
1713 'ng':'\ud83c\udd96',
1714 'no_good_man':'\ud83d\ude45&zwj;\u2642\ufe0f',
1715 'no_good_woman':'\ud83d\ude45',
1716 'night_with_stars':'\ud83c\udf03',
1717 'no_bell':'\ud83d\udd15',
1718 'no_bicycles':'\ud83d\udeb3',
1719 'no_entry':'\u26d4\ufe0f',
1720 'no_entry_sign':'\ud83d\udeab',
1721 'no_mobile_phones':'\ud83d\udcf5',
1722 'no_mouth':'\ud83d\ude36',
1723 'no_pedestrians':'\ud83d\udeb7',
1724 'no_smoking':'\ud83d\udead',
1725 'non-potable_water':'\ud83d\udeb1',
1726 'nose':'\ud83d\udc43',
1727 'notebook':'\ud83d\udcd3',
1728 'notebook_with_decorative_cover':'\ud83d\udcd4',
1729 'notes':'\ud83c\udfb6',
1730 'nut_and_bolt':'\ud83d\udd29',
1731 'o':'\u2b55\ufe0f',
1732 'o2':'\ud83c\udd7e\ufe0f',
1733 'ocean':'\ud83c\udf0a',
1734 'octopus':'\ud83d\udc19',
1735 'oden':'\ud83c\udf62',
1736 'office':'\ud83c\udfe2',
1737 'oil_drum':'\ud83d\udee2',
1738 'ok':'\ud83c\udd97',
1739 'ok_hand':'\ud83d\udc4c',
1740 'ok_man':'\ud83d\ude46&zwj;\u2642\ufe0f',
1741 'ok_woman':'\ud83d\ude46',
1742 'old_key':'\ud83d\udddd',
1743 'older_man':'\ud83d\udc74',
1744 'older_woman':'\ud83d\udc75',
1745 'om':'\ud83d\udd49',
1746 'on':'\ud83d\udd1b',
1747 'oncoming_automobile':'\ud83d\ude98',
1748 'oncoming_bus':'\ud83d\ude8d',
1749 'oncoming_police_car':'\ud83d\ude94',
1750 'oncoming_taxi':'\ud83d\ude96',
1751 'open_file_folder':'\ud83d\udcc2',
1752 'open_hands':'\ud83d\udc50',
1753 'open_mouth':'\ud83d\ude2e',
1754 'open_umbrella':'\u2602\ufe0f',
1755 'ophiuchus':'\u26ce',
1756 'orange_book':'\ud83d\udcd9',
1757 'orthodox_cross':'\u2626\ufe0f',
1758 'outbox_tray':'\ud83d\udce4',
1759 'owl':'\ud83e\udd89',
1760 'ox':'\ud83d\udc02',
1761 'package':'\ud83d\udce6',
1762 'page_facing_up':'\ud83d\udcc4',
1763 'page_with_curl':'\ud83d\udcc3',
1764 'pager':'\ud83d\udcdf',
1765 'paintbrush':'\ud83d\udd8c',
1766 'palm_tree':'\ud83c\udf34',
1767 'pancakes':'\ud83e\udd5e',
1768 'panda_face':'\ud83d\udc3c',
1769 'paperclip':'\ud83d\udcce',
1770 'paperclips':'\ud83d\udd87',
1771 'parasol_on_ground':'\u26f1',
1772 'parking':'\ud83c\udd7f\ufe0f',
1773 'part_alternation_mark':'\u303d\ufe0f',
1774 'partly_sunny':'\u26c5\ufe0f',
1775 'passenger_ship':'\ud83d\udef3',
1776 'passport_control':'\ud83d\udec2',
1777 'pause_button':'\u23f8',
1778 'peace_symbol':'\u262e\ufe0f',
1779 'peach':'\ud83c\udf51',
1780 'peanuts':'\ud83e\udd5c',
1781 'pear':'\ud83c\udf50',
1782 'pen':'\ud83d\udd8a',
1783 'pencil2':'\u270f\ufe0f',
1784 'penguin':'\ud83d\udc27',
1785 'pensive':'\ud83d\ude14',
1786 'performing_arts':'\ud83c\udfad',
1787 'persevere':'\ud83d\ude23',
1788 'person_fencing':'\ud83e\udd3a',
1789 'pouting_woman':'\ud83d\ude4e',
1790 'phone':'\u260e\ufe0f',
1791 'pick':'\u26cf',
1792 'pig':'\ud83d\udc37',
1793 'pig2':'\ud83d\udc16',
1794 'pig_nose':'\ud83d\udc3d',
1795 'pill':'\ud83d\udc8a',
1796 'pineapple':'\ud83c\udf4d',
1797 'ping_pong':'\ud83c\udfd3',
1798 'pisces':'\u2653\ufe0f',
1799 'pizza':'\ud83c\udf55',
1800 'place_of_worship':'\ud83d\uded0',
1801 'plate_with_cutlery':'\ud83c\udf7d',
1802 'play_or_pause_button':'\u23ef',
1803 'point_down':'\ud83d\udc47',
1804 'point_left':'\ud83d\udc48',
1805 'point_right':'\ud83d\udc49',
1806 'point_up':'\u261d\ufe0f',
1807 'point_up_2':'\ud83d\udc46',
1808 'police_car':'\ud83d\ude93',
1809 'policewoman':'\ud83d\udc6e&zwj;\u2640\ufe0f',
1810 'poodle':'\ud83d\udc29',
1811 'popcorn':'\ud83c\udf7f',
1812 'post_office':'\ud83c\udfe3',
1813 'postal_horn':'\ud83d\udcef',
1814 'postbox':'\ud83d\udcee',
1815 'potable_water':'\ud83d\udeb0',
1816 'potato':'\ud83e\udd54',
1817 'pouch':'\ud83d\udc5d',
1818 'poultry_leg':'\ud83c\udf57',
1819 'pound':'\ud83d\udcb7',
1820 'rage':'\ud83d\ude21',
1821 'pouting_cat':'\ud83d\ude3e',
1822 'pouting_man':'\ud83d\ude4e&zwj;\u2642\ufe0f',
1823 'pray':'\ud83d\ude4f',
1824 'prayer_beads':'\ud83d\udcff',
1825 'pregnant_woman':'\ud83e\udd30',
1826 'previous_track_button':'\u23ee',
1827 'prince':'\ud83e\udd34',
1828 'princess':'\ud83d\udc78',
1829 'printer':'\ud83d\udda8',
1830 'purple_heart':'\ud83d\udc9c',
1831 'purse':'\ud83d\udc5b',
1832 'pushpin':'\ud83d\udccc',
1833 'put_litter_in_its_place':'\ud83d\udeae',
1834 'question':'\u2753',
1835 'rabbit':'\ud83d\udc30',
1836 'rabbit2':'\ud83d\udc07',
1837 'racehorse':'\ud83d\udc0e',
1838 'racing_car':'\ud83c\udfce',
1839 'radio':'\ud83d\udcfb',
1840 'radio_button':'\ud83d\udd18',
1841 'radioactive':'\u2622\ufe0f',
1842 'railway_car':'\ud83d\ude83',
1843 'railway_track':'\ud83d\udee4',
1844 'rainbow':'\ud83c\udf08',
1845 'rainbow_flag':'\ud83c\udff3\ufe0f&zwj;\ud83c\udf08',
1846 'raised_back_of_hand':'\ud83e\udd1a',
1847 'raised_hand_with_fingers_splayed':'\ud83d\udd90',
1848 'raised_hands':'\ud83d\ude4c',
1849 'raising_hand_woman':'\ud83d\ude4b',
1850 'raising_hand_man':'\ud83d\ude4b&zwj;\u2642\ufe0f',
1851 'ram':'\ud83d\udc0f',
1852 'ramen':'\ud83c\udf5c',
1853 'rat':'\ud83d\udc00',
1854 'record_button':'\u23fa',
1855 'recycle':'\u267b\ufe0f',
1856 'red_circle':'\ud83d\udd34',
1857 'registered':'\u00ae\ufe0f',
1858 'relaxed':'\u263a\ufe0f',
1859 'relieved':'\ud83d\ude0c',
1860 'reminder_ribbon':'\ud83c\udf97',
1861 'repeat':'\ud83d\udd01',
1862 'repeat_one':'\ud83d\udd02',
1863 'rescue_worker_helmet':'\u26d1',
1864 'restroom':'\ud83d\udebb',
1865 'revolving_hearts':'\ud83d\udc9e',
1866 'rewind':'\u23ea',
1867 'rhinoceros':'\ud83e\udd8f',
1868 'ribbon':'\ud83c\udf80',
1869 'rice':'\ud83c\udf5a',
1870 'rice_ball':'\ud83c\udf59',
1871 'rice_cracker':'\ud83c\udf58',
1872 'rice_scene':'\ud83c\udf91',
1873 'right_anger_bubble':'\ud83d\uddef',
1874 'ring':'\ud83d\udc8d',
1875 'robot':'\ud83e\udd16',
1876 'rocket':'\ud83d\ude80',
1877 'rofl':'\ud83e\udd23',
1878 'roll_eyes':'\ud83d\ude44',
1879 'roller_coaster':'\ud83c\udfa2',
1880 'rooster':'\ud83d\udc13',
1881 'rose':'\ud83c\udf39',
1882 'rosette':'\ud83c\udff5',
1883 'rotating_light':'\ud83d\udea8',
1884 'round_pushpin':'\ud83d\udccd',
1885 'rowing_man':'\ud83d\udea3',
1886 'rowing_woman':'\ud83d\udea3&zwj;\u2640\ufe0f',
1887 'rugby_football':'\ud83c\udfc9',
1888 'running_man':'\ud83c\udfc3',
1889 'running_shirt_with_sash':'\ud83c\udfbd',
1890 'running_woman':'\ud83c\udfc3&zwj;\u2640\ufe0f',
1891 'sa':'\ud83c\ude02\ufe0f',
1892 'sagittarius':'\u2650\ufe0f',
1893 'sake':'\ud83c\udf76',
1894 'sandal':'\ud83d\udc61',
1895 'santa':'\ud83c\udf85',
1896 'satellite':'\ud83d\udce1',
1897 'saxophone':'\ud83c\udfb7',
1898 'school':'\ud83c\udfeb',
1899 'school_satchel':'\ud83c\udf92',
1900 'scissors':'\u2702\ufe0f',
1901 'scorpion':'\ud83e\udd82',
1902 'scorpius':'\u264f\ufe0f',
1903 'scream':'\ud83d\ude31',
1904 'scream_cat':'\ud83d\ude40',
1905 'scroll':'\ud83d\udcdc',
1906 'seat':'\ud83d\udcba',
1907 'secret':'\u3299\ufe0f',
1908 'see_no_evil':'\ud83d\ude48',
1909 'seedling':'\ud83c\udf31',
1910 'selfie':'\ud83e\udd33',
1911 'shallow_pan_of_food':'\ud83e\udd58',
1912 'shamrock':'\u2618\ufe0f',
1913 'shark':'\ud83e\udd88',
1914 'shaved_ice':'\ud83c\udf67',
1915 'sheep':'\ud83d\udc11',
1916 'shell':'\ud83d\udc1a',
1917 'shield':'\ud83d\udee1',
1918 'shinto_shrine':'\u26e9',
1919 'ship':'\ud83d\udea2',
1920 'shirt':'\ud83d\udc55',
1921 'shopping':'\ud83d\udecd',
1922 'shopping_cart':'\ud83d\uded2',
1923 'shower':'\ud83d\udebf',
1924 'shrimp':'\ud83e\udd90',
1925 'signal_strength':'\ud83d\udcf6',
1926 'six_pointed_star':'\ud83d\udd2f',
1927 'ski':'\ud83c\udfbf',
1928 'skier':'\u26f7',
1929 'skull':'\ud83d\udc80',
1930 'skull_and_crossbones':'\u2620\ufe0f',
1931 'sleeping':'\ud83d\ude34',
1932 'sleeping_bed':'\ud83d\udecc',
1933 'sleepy':'\ud83d\ude2a',
1934 'slightly_frowning_face':'\ud83d\ude41',
1935 'slightly_smiling_face':'\ud83d\ude42',
1936 'slot_machine':'\ud83c\udfb0',
1937 'small_airplane':'\ud83d\udee9',
1938 'small_blue_diamond':'\ud83d\udd39',
1939 'small_orange_diamond':'\ud83d\udd38',
1940 'small_red_triangle':'\ud83d\udd3a',
1941 'small_red_triangle_down':'\ud83d\udd3b',
1942 'smile':'\ud83d\ude04',
1943 'smile_cat':'\ud83d\ude38',
1944 'smiley':'\ud83d\ude03',
1945 'smiley_cat':'\ud83d\ude3a',
1946 'smiling_imp':'\ud83d\ude08',
1947 'smirk':'\ud83d\ude0f',
1948 'smirk_cat':'\ud83d\ude3c',
1949 'smoking':'\ud83d\udeac',
1950 'snail':'\ud83d\udc0c',
1951 'snake':'\ud83d\udc0d',
1952 'sneezing_face':'\ud83e\udd27',
1953 'snowboarder':'\ud83c\udfc2',
1954 'snowflake':'\u2744\ufe0f',
1955 'snowman':'\u26c4\ufe0f',
1956 'snowman_with_snow':'\u2603\ufe0f',
1957 'sob':'\ud83d\ude2d',
1958 'soccer':'\u26bd\ufe0f',
1959 'soon':'\ud83d\udd1c',
1960 'sos':'\ud83c\udd98',
1961 'sound':'\ud83d\udd09',
1962 'space_invader':'\ud83d\udc7e',
1963 'spades':'\u2660\ufe0f',
1964 'spaghetti':'\ud83c\udf5d',
1965 'sparkle':'\u2747\ufe0f',
1966 'sparkler':'\ud83c\udf87',
1967 'sparkles':'\u2728',
1968 'sparkling_heart':'\ud83d\udc96',
1969 'speak_no_evil':'\ud83d\ude4a',
1970 'speaker':'\ud83d\udd08',
1971 'speaking_head':'\ud83d\udde3',
1972 'speech_balloon':'\ud83d\udcac',
1973 'speedboat':'\ud83d\udea4',
1974 'spider':'\ud83d\udd77',
1975 'spider_web':'\ud83d\udd78',
1976 'spiral_calendar':'\ud83d\uddd3',
1977 'spiral_notepad':'\ud83d\uddd2',
1978 'spoon':'\ud83e\udd44',
1979 'squid':'\ud83e\udd91',
1980 'stadium':'\ud83c\udfdf',
1981 'star':'\u2b50\ufe0f',
1982 'star2':'\ud83c\udf1f',
1983 'star_and_crescent':'\u262a\ufe0f',
1984 'star_of_david':'\u2721\ufe0f',
1985 'stars':'\ud83c\udf20',
1986 'station':'\ud83d\ude89',
1987 'statue_of_liberty':'\ud83d\uddfd',
1988 'steam_locomotive':'\ud83d\ude82',
1989 'stew':'\ud83c\udf72',
1990 'stop_button':'\u23f9',
1991 'stop_sign':'\ud83d\uded1',
1992 'stopwatch':'\u23f1',
1993 'straight_ruler':'\ud83d\udccf',
1994 'strawberry':'\ud83c\udf53',
1995 'stuck_out_tongue':'\ud83d\ude1b',
1996 'stuck_out_tongue_closed_eyes':'\ud83d\ude1d',
1997 'stuck_out_tongue_winking_eye':'\ud83d\ude1c',
1998 'studio_microphone':'\ud83c\udf99',
1999 'stuffed_flatbread':'\ud83e\udd59',
2000 'sun_behind_large_cloud':'\ud83c\udf25',
2001 'sun_behind_rain_cloud':'\ud83c\udf26',
2002 'sun_behind_small_cloud':'\ud83c\udf24',
2003 'sun_with_face':'\ud83c\udf1e',
2004 'sunflower':'\ud83c\udf3b',
2005 'sunglasses':'\ud83d\ude0e',
2006 'sunny':'\u2600\ufe0f',
2007 'sunrise':'\ud83c\udf05',
2008 'sunrise_over_mountains':'\ud83c\udf04',
2009 'surfing_man':'\ud83c\udfc4',
2010 'surfing_woman':'\ud83c\udfc4&zwj;\u2640\ufe0f',
2011 'sushi':'\ud83c\udf63',
2012 'suspension_railway':'\ud83d\ude9f',
2013 'sweat':'\ud83d\ude13',
2014 'sweat_drops':'\ud83d\udca6',
2015 'sweat_smile':'\ud83d\ude05',
2016 'sweet_potato':'\ud83c\udf60',
2017 'swimming_man':'\ud83c\udfca',
2018 'swimming_woman':'\ud83c\udfca&zwj;\u2640\ufe0f',
2019 'symbols':'\ud83d\udd23',
2020 'synagogue':'\ud83d\udd4d',
2021 'syringe':'\ud83d\udc89',
2022 'taco':'\ud83c\udf2e',
2023 'tada':'\ud83c\udf89',
2024 'tanabata_tree':'\ud83c\udf8b',
2025 'taurus':'\u2649\ufe0f',
2026 'taxi':'\ud83d\ude95',
2027 'tea':'\ud83c\udf75',
2028 'telephone_receiver':'\ud83d\udcde',
2029 'telescope':'\ud83d\udd2d',
2030 'tennis':'\ud83c\udfbe',
2031 'tent':'\u26fa\ufe0f',
2032 'thermometer':'\ud83c\udf21',
2033 'thinking':'\ud83e\udd14',
2034 'thought_balloon':'\ud83d\udcad',
2035 'ticket':'\ud83c\udfab',
2036 'tickets':'\ud83c\udf9f',
2037 'tiger':'\ud83d\udc2f',
2038 'tiger2':'\ud83d\udc05',
2039 'timer_clock':'\u23f2',
2040 'tipping_hand_man':'\ud83d\udc81&zwj;\u2642\ufe0f',
2041 'tired_face':'\ud83d\ude2b',
2042 'tm':'\u2122\ufe0f',
2043 'toilet':'\ud83d\udebd',
2044 'tokyo_tower':'\ud83d\uddfc',
2045 'tomato':'\ud83c\udf45',
2046 'tongue':'\ud83d\udc45',
2047 'top':'\ud83d\udd1d',
2048 'tophat':'\ud83c\udfa9',
2049 'tornado':'\ud83c\udf2a',
2050 'trackball':'\ud83d\uddb2',
2051 'tractor':'\ud83d\ude9c',
2052 'traffic_light':'\ud83d\udea5',
2053 'train':'\ud83d\ude8b',
2054 'train2':'\ud83d\ude86',
2055 'tram':'\ud83d\ude8a',
2056 'triangular_flag_on_post':'\ud83d\udea9',
2057 'triangular_ruler':'\ud83d\udcd0',
2058 'trident':'\ud83d\udd31',
2059 'triumph':'\ud83d\ude24',
2060 'trolleybus':'\ud83d\ude8e',
2061 'trophy':'\ud83c\udfc6',
2062 'tropical_drink':'\ud83c\udf79',
2063 'tropical_fish':'\ud83d\udc20',
2064 'truck':'\ud83d\ude9a',
2065 'trumpet':'\ud83c\udfba',
2066 'tulip':'\ud83c\udf37',
2067 'tumbler_glass':'\ud83e\udd43',
2068 'turkey':'\ud83e\udd83',
2069 'turtle':'\ud83d\udc22',
2070 'tv':'\ud83d\udcfa',
2071 'twisted_rightwards_arrows':'\ud83d\udd00',
2072 'two_hearts':'\ud83d\udc95',
2073 'two_men_holding_hands':'\ud83d\udc6c',
2074 'two_women_holding_hands':'\ud83d\udc6d',
2075 'u5272':'\ud83c\ude39',
2076 'u5408':'\ud83c\ude34',
2077 'u55b6':'\ud83c\ude3a',
2078 'u6307':'\ud83c\ude2f\ufe0f',
2079 'u6708':'\ud83c\ude37\ufe0f',
2080 'u6709':'\ud83c\ude36',
2081 'u6e80':'\ud83c\ude35',
2082 'u7121':'\ud83c\ude1a\ufe0f',
2083 'u7533':'\ud83c\ude38',
2084 'u7981':'\ud83c\ude32',
2085 'u7a7a':'\ud83c\ude33',
2086 'umbrella':'\u2614\ufe0f',
2087 'unamused':'\ud83d\ude12',
2088 'underage':'\ud83d\udd1e',
2089 'unicorn':'\ud83e\udd84',
2090 'unlock':'\ud83d\udd13',
2091 'up':'\ud83c\udd99',
2092 'upside_down_face':'\ud83d\ude43',
2093 'v':'\u270c\ufe0f',
2094 'vertical_traffic_light':'\ud83d\udea6',
2095 'vhs':'\ud83d\udcfc',
2096 'vibration_mode':'\ud83d\udcf3',
2097 'video_camera':'\ud83d\udcf9',
2098 'video_game':'\ud83c\udfae',
2099 'violin':'\ud83c\udfbb',
2100 'virgo':'\u264d\ufe0f',
2101 'volcano':'\ud83c\udf0b',
2102 'volleyball':'\ud83c\udfd0',
2103 'vs':'\ud83c\udd9a',
2104 'vulcan_salute':'\ud83d\udd96',
2105 'walking_man':'\ud83d\udeb6',
2106 'walking_woman':'\ud83d\udeb6&zwj;\u2640\ufe0f',
2107 'waning_crescent_moon':'\ud83c\udf18',
2108 'waning_gibbous_moon':'\ud83c\udf16',
2109 'warning':'\u26a0\ufe0f',
2110 'wastebasket':'\ud83d\uddd1',
2111 'watch':'\u231a\ufe0f',
2112 'water_buffalo':'\ud83d\udc03',
2113 'watermelon':'\ud83c\udf49',
2114 'wave':'\ud83d\udc4b',
2115 'wavy_dash':'\u3030\ufe0f',
2116 'waxing_crescent_moon':'\ud83c\udf12',
2117 'wc':'\ud83d\udebe',
2118 'weary':'\ud83d\ude29',
2119 'wedding':'\ud83d\udc92',
2120 'weight_lifting_man':'\ud83c\udfcb\ufe0f',
2121 'weight_lifting_woman':'\ud83c\udfcb\ufe0f&zwj;\u2640\ufe0f',
2122 'whale':'\ud83d\udc33',
2123 'whale2':'\ud83d\udc0b',
2124 'wheel_of_dharma':'\u2638\ufe0f',
2125 'wheelchair':'\u267f\ufe0f',
2126 'white_check_mark':'\u2705',
2127 'white_circle':'\u26aa\ufe0f',
2128 'white_flag':'\ud83c\udff3\ufe0f',
2129 'white_flower':'\ud83d\udcae',
2130 'white_large_square':'\u2b1c\ufe0f',
2131 'white_medium_small_square':'\u25fd\ufe0f',
2132 'white_medium_square':'\u25fb\ufe0f',
2133 'white_small_square':'\u25ab\ufe0f',
2134 'white_square_button':'\ud83d\udd33',
2135 'wilted_flower':'\ud83e\udd40',
2136 'wind_chime':'\ud83c\udf90',
2137 'wind_face':'\ud83c\udf2c',
2138 'wine_glass':'\ud83c\udf77',
2139 'wink':'\ud83d\ude09',
2140 'wolf':'\ud83d\udc3a',
2141 'woman':'\ud83d\udc69',
2142 'woman_artist':'\ud83d\udc69&zwj;\ud83c\udfa8',
2143 'woman_astronaut':'\ud83d\udc69&zwj;\ud83d\ude80',
2144 'woman_cartwheeling':'\ud83e\udd38&zwj;\u2640\ufe0f',
2145 'woman_cook':'\ud83d\udc69&zwj;\ud83c\udf73',
2146 'woman_facepalming':'\ud83e\udd26&zwj;\u2640\ufe0f',
2147 'woman_factory_worker':'\ud83d\udc69&zwj;\ud83c\udfed',
2148 'woman_farmer':'\ud83d\udc69&zwj;\ud83c\udf3e',
2149 'woman_firefighter':'\ud83d\udc69&zwj;\ud83d\ude92',
2150 'woman_health_worker':'\ud83d\udc69&zwj;\u2695\ufe0f',
2151 'woman_judge':'\ud83d\udc69&zwj;\u2696\ufe0f',
2152 'woman_juggling':'\ud83e\udd39&zwj;\u2640\ufe0f',
2153 'woman_mechanic':'\ud83d\udc69&zwj;\ud83d\udd27',
2154 'woman_office_worker':'\ud83d\udc69&zwj;\ud83d\udcbc',
2155 'woman_pilot':'\ud83d\udc69&zwj;\u2708\ufe0f',
2156 'woman_playing_handball':'\ud83e\udd3e&zwj;\u2640\ufe0f',
2157 'woman_playing_water_polo':'\ud83e\udd3d&zwj;\u2640\ufe0f',
2158 'woman_scientist':'\ud83d\udc69&zwj;\ud83d\udd2c',
2159 'woman_shrugging':'\ud83e\udd37&zwj;\u2640\ufe0f',
2160 'woman_singer':'\ud83d\udc69&zwj;\ud83c\udfa4',
2161 'woman_student':'\ud83d\udc69&zwj;\ud83c\udf93',
2162 'woman_teacher':'\ud83d\udc69&zwj;\ud83c\udfeb',
2163 'woman_technologist':'\ud83d\udc69&zwj;\ud83d\udcbb',
2164 'woman_with_turban':'\ud83d\udc73&zwj;\u2640\ufe0f',
2165 'womans_clothes':'\ud83d\udc5a',
2166 'womans_hat':'\ud83d\udc52',
2167 'women_wrestling':'\ud83e\udd3c&zwj;\u2640\ufe0f',
2168 'womens':'\ud83d\udeba',
2169 'world_map':'\ud83d\uddfa',
2170 'worried':'\ud83d\ude1f',
2171 'wrench':'\ud83d\udd27',
2172 'writing_hand':'\u270d\ufe0f',
2173 'x':'\u274c',
2174 'yellow_heart':'\ud83d\udc9b',
2175 'yen':'\ud83d\udcb4',
2176 'yin_yang':'\u262f\ufe0f',
2177 'yum':'\ud83d\ude0b',
2178 'zap':'\u26a1\ufe0f',
2179 'zipper_mouth_face':'\ud83e\udd10',
2180 'zzz':'\ud83d\udca4',
2181
2182 /* special emojis :P */
2183 'octocat': '<img alt=":octocat:" height="20" width="20" align="absmiddle" src="https://assets-cdn.github.com/images/icons/emoji/octocat.png">',
2184 '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>'
2185 };
2186
2187 /**
2188 * Created by Estevao on 31-05-2015.
2189 */
2190
2191 /**
2192 * Showdown Converter class
2193 * @class
2194 * @param {object} [converterOptions]
2195 * @returns {Converter}
2196 */
2197 showdown.Converter = function (converterOptions) {
2198 'use strict';
2199
2200 var
2201 /**
2202 * Options used by this converter
2203 * @private
2204 * @type {{}}
2205 */
2206 options = {},
2207
2208 /**
2209 * Language extensions used by this converter
2210 * @private
2211 * @type {Array}
2212 */
2213 langExtensions = [],
2214
2215 /**
2216 * Output modifiers extensions used by this converter
2217 * @private
2218 * @type {Array}
2219 */
2220 outputModifiers = [],
2221
2222 /**
2223 * Event listeners
2224 * @private
2225 * @type {{}}
2226 */
2227 listeners = {},
2228
2229 /**
2230 * The flavor set in this converter
2231 */
2232 setConvFlavor = setFlavor,
2233
2234 /**
2235 * Metadata of the document
2236 * @type {{parsed: {}, raw: string, format: string}}
2237 */
2238 metadata = {
2239 parsed: {},
2240 raw: '',
2241 format: ''
2242 };
2243
2244 _constructor();
2245
2246 /**
2247 * Converter constructor
2248 * @private
2249 */
2250 function _constructor () {
2251 converterOptions = converterOptions || {};
2252
2253 for (var gOpt in globalOptions) {
2254 if (globalOptions.hasOwnProperty(gOpt)) {
2255 options[gOpt] = globalOptions[gOpt];
2256 }
2257 }
2258
2259 // Merge options
2260 if (typeof converterOptions === 'object') {
2261 for (var opt in converterOptions) {
2262 if (converterOptions.hasOwnProperty(opt)) {
2263 options[opt] = converterOptions[opt];
2264 }
2265 }
2266 } else {
2267 throw Error('Converter expects the passed parameter to be an object, but ' + typeof converterOptions +
2268 ' was passed instead.');
2269 }
2270
2271 if (options.extensions) {
2272 showdown.helper.forEach(options.extensions, _parseExtension);
2273 }
2274 }
2275
2276 /**
2277 * Parse extension
2278 * @param {*} ext
2279 * @param {string} [name='']
2280 * @private
2281 */
2282 function _parseExtension (ext, name) {
2283
2284 name = name || null;
2285 // If it's a string, the extension was previously loaded
2286 if (showdown.helper.isString(ext)) {
2287 ext = showdown.helper.stdExtName(ext);
2288 name = ext;
2289
2290 // LEGACY_SUPPORT CODE
2291 if (showdown.extensions[ext]) {
2292 console.warn('DEPRECATION WARNING: ' + ext + ' is an old extension that uses a deprecated loading method.' +
2293 'Please inform the developer that the extension should be updated!');
2294 legacyExtensionLoading(showdown.extensions[ext], ext);
2295 return;
2296 // END LEGACY SUPPORT CODE
2297
2298 } else if (!showdown.helper.isUndefined(extensions[ext])) {
2299 ext = extensions[ext];
2300
2301 } else {
2302 throw Error('Extension "' + ext + '" could not be loaded. It was either not found or is not a valid extension.');
2303 }
2304 }
2305
2306 if (typeof ext === 'function') {
2307 ext = ext();
2308 }
2309
2310 if (!showdown.helper.isArray(ext)) {
2311 ext = [ext];
2312 }
2313
2314 var validExt = validate(ext, name);
2315 if (!validExt.valid) {
2316 throw Error(validExt.error);
2317 }
2318
2319 for (var i = 0; i < ext.length; ++i) {
2320 switch (ext[i].type) {
2321
2322 case 'lang':
2323 langExtensions.push(ext[i]);
2324 break;
2325
2326 case 'output':
2327 outputModifiers.push(ext[i]);
2328 break;
2329 }
2330 if (ext[i].hasOwnProperty('listeners')) {
2331 for (var ln in ext[i].listeners) {
2332 if (ext[i].listeners.hasOwnProperty(ln)) {
2333 listen(ln, ext[i].listeners[ln]);
2334 }
2335 }
2336 }
2337 }
2338
2339 }
2340
2341 /**
2342 * LEGACY_SUPPORT
2343 * @param {*} ext
2344 * @param {string} name
2345 */
2346 function legacyExtensionLoading (ext, name) {
2347 if (typeof ext === 'function') {
2348 ext = ext(new showdown.Converter());
2349 }
2350 if (!showdown.helper.isArray(ext)) {
2351 ext = [ext];
2352 }
2353 var valid = validate(ext, name);
2354
2355 if (!valid.valid) {
2356 throw Error(valid.error);
2357 }
2358
2359 for (var i = 0; i < ext.length; ++i) {
2360 switch (ext[i].type) {
2361 case 'lang':
2362 langExtensions.push(ext[i]);
2363 break;
2364 case 'output':
2365 outputModifiers.push(ext[i]);
2366 break;
2367 default:// should never reach here
2368 throw Error('Extension loader error: Type unrecognized!!!');
2369 }
2370 }
2371 }
2372
2373 /**
2374 * Listen to an event
2375 * @param {string} name
2376 * @param {function} callback
2377 */
2378 function listen (name, callback) {
2379 if (!showdown.helper.isString(name)) {
2380 throw Error('Invalid argument in converter.listen() method: name must be a string, but ' + typeof name + ' given');
2381 }
2382
2383 if (typeof callback !== 'function') {
2384 throw Error('Invalid argument in converter.listen() method: callback must be a function, but ' + typeof callback + ' given');
2385 }
2386
2387 if (!listeners.hasOwnProperty(name)) {
2388 listeners[name] = [];
2389 }
2390 listeners[name].push(callback);
2391 }
2392
2393 function rTrimInputText (text) {
2394 var rsp = text.match(/^\s*/)[0].length,
2395 rgx = new RegExp('^\\s{0,' + rsp + '}', 'gm');
2396 return text.replace(rgx, '');
2397 }
2398
2399 /**
2400 * Dispatch an event
2401 * @private
2402 * @param {string} evtName Event name
2403 * @param {string} text Text
2404 * @param {{}} options Converter Options
2405 * @param {{}} globals
2406 * @returns {string}
2407 */
2408 this._dispatch = function dispatch (evtName, text, options, globals) {
2409 if (listeners.hasOwnProperty(evtName)) {
2410 for (var ei = 0; ei < listeners[evtName].length; ++ei) {
2411 var nText = listeners[evtName][ei](evtName, text, this, options, globals);
2412 if (nText && typeof nText !== 'undefined') {
2413 text = nText;
2414 }
2415 }
2416 }
2417 return text;
2418 };
2419
2420 /**
2421 * Listen to an event
2422 * @param {string} name
2423 * @param {function} callback
2424 * @returns {showdown.Converter}
2425 */
2426 this.listen = function (name, callback) {
2427 listen(name, callback);
2428 return this;
2429 };
2430
2431 /**
2432 * Converts a markdown string into HTML
2433 * @param {string} text
2434 * @returns {*}
2435 */
2436 this.makeHtml = function (text) {
2437 //check if text is not falsy
2438 if (!text) {
2439 return text;
2440 }
2441
2442 var globals = {
2443 gHtmlBlocks: [],
2444 gHtmlMdBlocks: [],
2445 gHtmlSpans: [],
2446 gUrls: {},
2447 gTitles: {},
2448 gDimensions: {},
2449 gListLevel: 0,
2450 hashLinkCounts: {},
2451 langExtensions: langExtensions,
2452 outputModifiers: outputModifiers,
2453 converter: this,
2454 ghCodeBlocks: [],
2455 metadata: {
2456 parsed: {},
2457 raw: '',
2458 format: ''
2459 }
2460 };
2461
2462 // This lets us use ¨ trema as an escape char to avoid md5 hashes
2463 // The choice of character is arbitrary; anything that isn't
2464 // magic in Markdown will work.
2465 text = text.replace(/¨/g, '¨T');
2466
2467 // Replace $ with ¨D
2468 // RegExp interprets $ as a special character
2469 // when it's in a replacement string
2470 text = text.replace(/\$/g, '¨D');
2471
2472 // Standardize line endings
2473 text = text.replace(/\r\n/g, '\n'); // DOS to Unix
2474 text = text.replace(/\r/g, '\n'); // Mac to Unix
2475
2476 // Stardardize line spaces
2477 text = text.replace(/\u00A0/g, '&nbsp;');
2478
2479 if (options.smartIndentationFix) {
2480 text = rTrimInputText(text);
2481 }
2482
2483 // Make sure text begins and ends with a couple of newlines:
2484 text = '\n\n' + text + '\n\n';
2485
2486 // detab
2487 text = showdown.subParser('detab')(text, options, globals);
2488
2489 /**
2490 * Strip any lines consisting only of spaces and tabs.
2491 * This makes subsequent regexs easier to write, because we can
2492 * match consecutive blank lines with /\n+/ instead of something
2493 * contorted like /[ \t]*\n+/
2494 */
2495 text = text.replace(/^[ \t]+$/mg, '');
2496
2497 //run languageExtensions
2498 showdown.helper.forEach(langExtensions, function (ext) {
2499 text = showdown.subParser('runExtension')(ext, text, options, globals);
2500 });
2501
2502 // run the sub parsers
2503 text = showdown.subParser('metadata')(text, options, globals);
2504 text = showdown.subParser('hashPreCodeTags')(text, options, globals);
2505 text = showdown.subParser('githubCodeBlocks')(text, options, globals);
2506 text = showdown.subParser('hashHTMLBlocks')(text, options, globals);
2507 text = showdown.subParser('hashCodeTags')(text, options, globals);
2508 text = showdown.subParser('stripLinkDefinitions')(text, options, globals);
2509 text = showdown.subParser('blockGamut')(text, options, globals);
2510 text = showdown.subParser('unhashHTMLSpans')(text, options, globals);
2511 text = showdown.subParser('unescapeSpecialChars')(text, options, globals);
2512
2513 // attacklab: Restore dollar signs
2514 text = text.replace(/¨D/g, '$$');
2515
2516 // attacklab: Restore tremas
2517 text = text.replace(/¨T/g, '¨');
2518
2519 // render a complete html document instead of a partial if the option is enabled
2520 text = showdown.subParser('completeHTMLDocument')(text, options, globals);
2521
2522 // Run output modifiers
2523 showdown.helper.forEach(outputModifiers, function (ext) {
2524 text = showdown.subParser('runExtension')(ext, text, options, globals);
2525 });
2526
2527 // update metadata
2528 metadata = globals.metadata;
2529 return text;
2530 };
2531
2532 /**
2533 * Converts an HTML string into a markdown string
2534 * @param src
2535 * @param [HTMLParser] A WHATWG DOM and HTML parser, such as JSDOM. If none is supplied, window.document will be used.
2536 * @returns {string}
2537 */
2538 this.makeMarkdown = this.makeMd = function (src, HTMLParser) {
2539
2540 // replace \r\n with \n
2541 src = src.replace(/\r\n/g, '\n');
2542 src = src.replace(/\r/g, '\n'); // old macs
2543
2544 // due to an edge case, we need to find this: > <
2545 // to prevent removing of non silent white spaces
2546 // ex: <em>this is</em> <strong>sparta</strong>
2547 src = src.replace(/>[ \t]+</, '>¨NBSP;<');
2548
2549 if (!HTMLParser) {
2550 if (window && window.document) {
2551 HTMLParser = window.document;
2552 } else {
2553 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');
2554 }
2555 }
2556
2557 var doc = HTMLParser.createElement('div');
2558 doc.innerHTML = src;
2559
2560 var globals = {
2561 preList: substitutePreCodeTags(doc)
2562 };
2563
2564 // remove all newlines and collapse spaces
2565 clean(doc);
2566
2567 // some stuff, like accidental reference links must now be escaped
2568 // TODO
2569 // doc.innerHTML = doc.innerHTML.replace(/\[[\S\t ]]/);
2570
2571 var nodes = doc.childNodes,
2572 mdDoc = '';
2573
2574 for (var i = 0; i < nodes.length; i++) {
2575 mdDoc += showdown.subParser('makeMarkdown.node')(nodes[i], globals);
2576 }
2577
2578 function clean (node) {
2579 for (var n = 0; n < node.childNodes.length; ++n) {
2580 var child = node.childNodes[n];
2581 if (child.nodeType === 3) {
2582 if (!/\S/.test(child.nodeValue)) {
2583 node.removeChild(child);
2584 --n;
2585 } else {
2586 child.nodeValue = child.nodeValue.split('\n').join(' ');
2587 child.nodeValue = child.nodeValue.replace(/(\s)+/g, '$1');
2588 }
2589 } else if (child.nodeType === 1) {
2590 clean(child);
2591 }
2592 }
2593 }
2594
2595 // find all pre tags and replace contents with placeholder
2596 // we need this so that we can remove all indentation from html
2597 // to ease up parsing
2598 function substitutePreCodeTags (doc) {
2599
2600 var pres = doc.querySelectorAll('pre'),
2601 presPH = [];
2602
2603 for (var i = 0; i < pres.length; ++i) {
2604
2605 if (pres[i].childElementCount === 1 && pres[i].firstChild.tagName.toLowerCase() === 'code') {
2606 var content = pres[i].firstChild.innerHTML.trim(),
2607 language = pres[i].firstChild.getAttribute('data-language') || '';
2608
2609 // if data-language attribute is not defined, then we look for class language-*
2610 if (language === '') {
2611 var classes = pres[i].firstChild.className.split(' ');
2612 for (var c = 0; c < classes.length; ++c) {
2613 var matches = classes[c].match(/^language-(.+)$/);
2614 if (matches !== null) {
2615 language = matches[1];
2616 break;
2617 }
2618 }
2619 }
2620
2621 // unescape html entities in content
2622 content = showdown.helper.unescapeHTMLEntities(content);
2623
2624 presPH.push(content);
2625 pres[i].outerHTML = '<precode language="' + language + '" precodenum="' + i.toString() + '"></precode>';
2626 } else {
2627 presPH.push(pres[i].innerHTML);
2628 pres[i].innerHTML = '';
2629 pres[i].setAttribute('prenum', i.toString());
2630 }
2631 }
2632 return presPH;
2633 }
2634
2635 return mdDoc;
2636 };
2637
2638 /**
2639 * Set an option of this Converter instance
2640 * @param {string} key
2641 * @param {*} value
2642 */
2643 this.setOption = function (key, value) {
2644 options[key] = value;
2645 };
2646
2647 /**
2648 * Get the option of this Converter instance
2649 * @param {string} key
2650 * @returns {*}
2651 */
2652 this.getOption = function (key) {
2653 return options[key];
2654 };
2655
2656 /**
2657 * Get the options of this Converter instance
2658 * @returns {{}}
2659 */
2660 this.getOptions = function () {
2661 return options;
2662 };
2663
2664 /**
2665 * Add extension to THIS converter
2666 * @param {{}} extension
2667 * @param {string} [name=null]
2668 */
2669 this.addExtension = function (extension, name) {
2670 name = name || null;
2671 _parseExtension(extension, name);
2672 };
2673
2674 /**
2675 * Use a global registered extension with THIS converter
2676 * @param {string} extensionName Name of the previously registered extension
2677 */
2678 this.useExtension = function (extensionName) {
2679 _parseExtension(extensionName);
2680 };
2681
2682 /**
2683 * Set the flavor THIS converter should use
2684 * @param {string} name
2685 */
2686 this.setFlavor = function (name) {
2687 if (!flavor.hasOwnProperty(name)) {
2688 throw Error(name + ' flavor was not found');
2689 }
2690 var preset = flavor[name];
2691 setConvFlavor = name;
2692 for (var option in preset) {
2693 if (preset.hasOwnProperty(option)) {
2694 options[option] = preset[option];
2695 }
2696 }
2697 };
2698
2699 /**
2700 * Get the currently set flavor of this converter
2701 * @returns {string}
2702 */
2703 this.getFlavor = function () {
2704 return setConvFlavor;
2705 };
2706
2707 /**
2708 * Remove an extension from THIS converter.
2709 * Note: This is a costly operation. It's better to initialize a new converter
2710 * and specify the extensions you wish to use
2711 * @param {Array} extension
2712 */
2713 this.removeExtension = function (extension) {
2714 if (!showdown.helper.isArray(extension)) {
2715 extension = [extension];
2716 }
2717 for (var a = 0; a < extension.length; ++a) {
2718 var ext = extension[a];
2719 for (var i = 0; i < langExtensions.length; ++i) {
2720 if (langExtensions[i] === ext) {
2721 langExtensions[i].splice(i, 1);
2722 }
2723 }
2724 for (var ii = 0; ii < outputModifiers.length; ++i) {
2725 if (outputModifiers[ii] === ext) {
2726 outputModifiers[ii].splice(i, 1);
2727 }
2728 }
2729 }
2730 };
2731
2732 /**
2733 * Get all extension of THIS converter
2734 * @returns {{language: Array, output: Array}}
2735 */
2736 this.getAllExtensions = function () {
2737 return {
2738 language: langExtensions,
2739 output: outputModifiers
2740 };
2741 };
2742
2743 /**
2744 * Get the metadata of the previously parsed document
2745 * @param raw
2746 * @returns {string|{}}
2747 */
2748 this.getMetadata = function (raw) {
2749 if (raw) {
2750 return metadata.raw;
2751 } else {
2752 return metadata.parsed;
2753 }
2754 };
2755
2756 /**
2757 * Get the metadata format of the previously parsed document
2758 * @returns {string}
2759 */
2760 this.getMetadataFormat = function () {
2761 return metadata.format;
2762 };
2763
2764 /**
2765 * Private: set a single key, value metadata pair
2766 * @param {string} key
2767 * @param {string} value
2768 */
2769 this._setMetadataPair = function (key, value) {
2770 metadata.parsed[key] = value;
2771 };
2772
2773 /**
2774 * Private: set metadata format
2775 * @param {string} format
2776 */
2777 this._setMetadataFormat = function (format) {
2778 metadata.format = format;
2779 };
2780
2781 /**
2782 * Private: set metadata raw text
2783 * @param {string} raw
2784 */
2785 this._setMetadataRaw = function (raw) {
2786 metadata.raw = raw;
2787 };
2788 };
2789
2790 /**
2791 * Turn Markdown link shortcuts into XHTML <a> tags.
2792 */
2793 showdown.subParser('anchors', function (text, options, globals) {
2794 'use strict';
2795
2796 text = globals.converter._dispatch('anchors.before', text, options, globals);
2797
2798 var writeAnchorTag = function (wholeMatch, linkText, linkId, url, m5, m6, title) {
2799 if (showdown.helper.isUndefined(title)) {
2800 title = '';
2801 }
2802 linkId = linkId.toLowerCase();
2803
2804 // Special case for explicit empty url
2805 if (wholeMatch.search(/\(<?\s*>? ?(['"].*['"])?\)$/m) > -1) {
2806 url = '';
2807 } else if (!url) {
2808 if (!linkId) {
2809 // lower-case and turn embedded newlines into spaces
2810 linkId = linkText.toLowerCase().replace(/ ?\n/g, ' ');
2811 }
2812 url = '#' + linkId;
2813
2814 if (!showdown.helper.isUndefined(globals.gUrls[linkId])) {
2815 url = globals.gUrls[linkId];
2816 if (!showdown.helper.isUndefined(globals.gTitles[linkId])) {
2817 title = globals.gTitles[linkId];
2818 }
2819 } else {
2820 return wholeMatch;
2821 }
2822 }
2823
2824 //url = showdown.helper.escapeCharacters(url, '*_', false); // replaced line to improve performance
2825 url = url.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback);
2826
2827 var result = '<a href="' + url + '"';
2828
2829 if (title !== '' && title !== null) {
2830 title = title.replace(/"/g, '&quot;');
2831 //title = showdown.helper.escapeCharacters(title, '*_', false); // replaced line to improve performance
2832 title = title.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback);
2833 result += ' title="' + title + '"';
2834 }
2835
2836 // optionLinksInNewWindow only applies
2837 // to external links. Hash links (#) open in same page
2838 if (options.openLinksInNewWindow && !/^#/.test(url)) {
2839 // escaped _
2840 result += ' rel="noopener noreferrer" target="¨E95Eblank"';
2841 }
2842
2843 result += '>' + linkText + '</a>';
2844
2845 return result;
2846 };
2847
2848 // First, handle reference-style links: [link text] [id]
2849 text = text.replace(/\[((?:\[[^\]]*]|[^\[\]])*)] ?(?:\n *)?\[(.*?)]()()()()/g, writeAnchorTag);
2850
2851 // Next, inline-style links: [link text](url "optional title")
2852 // cases with crazy urls like ./image/cat1).png
2853 text = text.replace(/\[((?:\[[^\]]*]|[^\[\]])*)]()[ \t]*\([ \t]?<([^>]*)>(?:[ \t]*((["'])([^"]*?)\5))?[ \t]?\)/g,
2854 writeAnchorTag);
2855
2856 // normal cases
2857 text = text.replace(/\[((?:\[[^\]]*]|[^\[\]])*)]()[ \t]*\([ \t]?<?([\S]+?(?:\([\S]*?\)[\S]*?)?)>?(?:[ \t]*((["'])([^"]*?)\5))?[ \t]?\)/g,
2858 writeAnchorTag);
2859
2860 // handle reference-style shortcuts: [link text]
2861 // These must come last in case you've also got [link test][1]
2862 // or [link test](/foo)
2863 text = text.replace(/\[([^\[\]]+)]()()()()()/g, writeAnchorTag);
2864
2865 // Lastly handle GithubMentions if option is enabled
2866 if (options.ghMentions) {
2867 text = text.replace(/(^|\s)(\\)?(@([a-z\d]+(?:[a-z\d.-]+?[a-z\d]+)*))/gmi, function (wm, st, escape, mentions, username) {
2868 if (escape === '\\') {
2869 return st + mentions;
2870 }
2871
2872 //check if options.ghMentionsLink is a string
2873 if (!showdown.helper.isString(options.ghMentionsLink)) {
2874 throw new Error('ghMentionsLink option must be a string');
2875 }
2876 var lnk = options.ghMentionsLink.replace(/\{u}/g, username),
2877 target = '';
2878 if (options.openLinksInNewWindow) {
2879 target = ' rel="noopener noreferrer" target="¨E95Eblank"';
2880 }
2881 return st + '<a href="' + lnk + '"' + target + '>' + mentions + '</a>';
2882 });
2883 }
2884
2885 text = globals.converter._dispatch('anchors.after', text, options, globals);
2886 return text;
2887 });
2888
2889 // url allowed chars [a-z\d_.~:/?#[]@!$&'()*+,;=-]
2890
2891 var simpleURLRegex = /([*~_]+|\b)(((https?|ftp|dict):\/\/|www\.)[^'">\s]+?\.[^'">\s]+?)()(\1)?(?=\s|$)(?!["<>])/gi,
2892 simpleURLRegex2 = /([*~_]+|\b)(((https?|ftp|dict):\/\/|www\.)[^'">\s]+\.[^'">\s]+?)([.!?,()\[\]])?(\1)?(?=\s|$)(?!["<>])/gi,
2893 delimUrlRegex = /()<(((https?|ftp|dict):\/\/|www\.)[^'">\s]+)()>()/gi,
2894 simpleMailRegex = /(^|\s)(?:mailto:)?([A-Za-z0-9!#$%&'*+-/=?^_`{|}~.]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)(?=$|\s)/gmi,
2895 delimMailRegex = /<()(?:mailto:)?([-.\w]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi,
2896
2897 replaceLink = function (options) {
2898 'use strict';
2899 return function (wm, leadingMagicChars, link, m2, m3, trailingPunctuation, trailingMagicChars) {
2900 link = link.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback);
2901 var lnkTxt = link,
2902 append = '',
2903 target = '',
2904 lmc = leadingMagicChars || '',
2905 tmc = trailingMagicChars || '';
2906 if (/^www\./i.test(link)) {
2907 link = link.replace(/^www\./i, 'http://www.');
2908 }
2909 if (options.excludeTrailingPunctuationFromURLs && trailingPunctuation) {
2910 append = trailingPunctuation;
2911 }
2912 if (options.openLinksInNewWindow) {
2913 target = ' rel="noopener noreferrer" target="¨E95Eblank"';
2914 }
2915 return lmc + '<a href="' + link + '"' + target + '>' + lnkTxt + '</a>' + append + tmc;
2916 };
2917 },
2918
2919 replaceMail = function (options, globals) {
2920 'use strict';
2921 return function (wholeMatch, b, mail) {
2922 var href = 'mailto:';
2923 b = b || '';
2924 mail = showdown.subParser('unescapeSpecialChars')(mail, options, globals);
2925 if (options.encodeEmails) {
2926 href = showdown.helper.encodeEmailAddress(href + mail);
2927 mail = showdown.helper.encodeEmailAddress(mail);
2928 } else {
2929 href = href + mail;
2930 }
2931 return b + '<a href="' + href + '">' + mail + '</a>';
2932 };
2933 };
2934
2935 showdown.subParser('autoLinks', function (text, options, globals) {
2936 'use strict';
2937
2938 text = globals.converter._dispatch('autoLinks.before', text, options, globals);
2939
2940 text = text.replace(delimUrlRegex, replaceLink(options));
2941 text = text.replace(delimMailRegex, replaceMail(options, globals));
2942
2943 text = globals.converter._dispatch('autoLinks.after', text, options, globals);
2944
2945 return text;
2946 });
2947
2948 showdown.subParser('simplifiedAutoLinks', function (text, options, globals) {
2949 'use strict';
2950
2951 if (!options.simplifiedAutoLink) {
2952 return text;
2953 }
2954
2955 text = globals.converter._dispatch('simplifiedAutoLinks.before', text, options, globals);
2956
2957 if (options.excludeTrailingPunctuationFromURLs) {
2958 text = text.replace(simpleURLRegex2, replaceLink(options));
2959 } else {
2960 text = text.replace(simpleURLRegex, replaceLink(options));
2961 }
2962 text = text.replace(simpleMailRegex, replaceMail(options, globals));
2963
2964 text = globals.converter._dispatch('simplifiedAutoLinks.after', text, options, globals);
2965
2966 return text;
2967 });
2968
2969 /**
2970 * These are all the transformations that form block-level
2971 * tags like paragraphs, headers, and list items.
2972 */
2973 showdown.subParser('blockGamut', function (text, options, globals) {
2974 'use strict';
2975
2976 text = globals.converter._dispatch('blockGamut.before', text, options, globals);
2977
2978 // we parse blockquotes first so that we can have headings and hrs
2979 // inside blockquotes
2980 text = showdown.subParser('blockQuotes')(text, options, globals);
2981 text = showdown.subParser('headers')(text, options, globals);
2982
2983 // Do Horizontal Rules:
2984 text = showdown.subParser('horizontalRule')(text, options, globals);
2985
2986 text = showdown.subParser('lists')(text, options, globals);
2987 text = showdown.subParser('codeBlocks')(text, options, globals);
2988 text = showdown.subParser('tables')(text, options, globals);
2989
2990 // We already ran _HashHTMLBlocks() before, in Markdown(), but that
2991 // was to escape raw HTML in the original Markdown source. This time,
2992 // we're escaping the markup we've just created, so that we don't wrap
2993 // <p> tags around block-level tags.
2994 text = showdown.subParser('hashHTMLBlocks')(text, options, globals);
2995 text = showdown.subParser('paragraphs')(text, options, globals);
2996
2997 text = globals.converter._dispatch('blockGamut.after', text, options, globals);
2998
2999 return text;
3000 });
3001
3002 showdown.subParser('blockQuotes', function (text, options, globals) {
3003 'use strict';
3004
3005 text = globals.converter._dispatch('blockQuotes.before', text, options, globals);
3006
3007 // add a couple extra lines after the text and endtext mark
3008 text = text + '\n\n';
3009
3010 var rgx = /(^ {0,3}>[ \t]?.+\n(.+\n)*\n*)+/gm;
3011
3012 if (options.splitAdjacentBlockquotes) {
3013 rgx = /^ {0,3}>[\s\S]*?(?:\n\n)/gm;
3014 }
3015
3016 text = text.replace(rgx, function (bq) {
3017 // attacklab: hack around Konqueror 3.5.4 bug:
3018 // "----------bug".replace(/^-/g,"") == "bug"
3019 bq = bq.replace(/^[ \t]*>[ \t]?/gm, ''); // trim one level of quoting
3020
3021 // attacklab: clean up hack
3022 bq = bq.replace(/¨0/g, '');
3023
3024 bq = bq.replace(/^[ \t]+$/gm, ''); // trim whitespace-only lines
3025 bq = showdown.subParser('githubCodeBlocks')(bq, options, globals);
3026 bq = showdown.subParser('blockGamut')(bq, options, globals); // recurse
3027
3028 bq = bq.replace(/(^|\n)/g, '$1 ');
3029 // These leading spaces screw with <pre> content, so we need to fix that:
3030 bq = bq.replace(/(\s*<pre>[^\r]+?<\/pre>)/gm, function (wholeMatch, m1) {
3031 var pre = m1;
3032 // attacklab: hack around Konqueror 3.5.4 bug:
3033 pre = pre.replace(/^ /mg, '¨0');
3034 pre = pre.replace(/¨0/g, '');
3035 return pre;
3036 });
3037
3038 return showdown.subParser('hashBlock')('<blockquote>\n' + bq + '\n</blockquote>', options, globals);
3039 });
3040
3041 text = globals.converter._dispatch('blockQuotes.after', text, options, globals);
3042 return text;
3043 });
3044
3045 /**
3046 * Process Markdown `<pre><code>` blocks.
3047 */
3048 showdown.subParser('codeBlocks', function (text, options, globals) {
3049 'use strict';
3050
3051 text = globals.converter._dispatch('codeBlocks.before', text, options, globals);
3052
3053 // sentinel workarounds for lack of \A and \Z, safari\khtml bug
3054 text += '¨0';
3055
3056 var pattern = /(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=¨0))/g;
3057 text = text.replace(pattern, function (wholeMatch, m1, m2) {
3058 var codeblock = m1,
3059 nextChar = m2,
3060 end = '\n';
3061
3062 codeblock = showdown.subParser('outdent')(codeblock, options, globals);
3063 codeblock = showdown.subParser('encodeCode')(codeblock, options, globals);
3064 codeblock = showdown.subParser('detab')(codeblock, options, globals);
3065 codeblock = codeblock.replace(/^\n+/g, ''); // trim leading newlines
3066 codeblock = codeblock.replace(/\n+$/g, ''); // trim trailing newlines
3067
3068 if (options.omitExtraWLInCodeBlocks) {
3069 end = '';
3070 }
3071
3072 codeblock = '<pre><code>' + codeblock + end + '</code></pre>';
3073
3074 return showdown.subParser('hashBlock')(codeblock, options, globals) + nextChar;
3075 });
3076
3077 // strip sentinel
3078 text = text.replace(/¨0/, '');
3079
3080 text = globals.converter._dispatch('codeBlocks.after', text, options, globals);
3081 return text;
3082 });
3083
3084 /**
3085 *
3086 * * Backtick quotes are used for <code></code> spans.
3087 *
3088 * * You can use multiple backticks as the delimiters if you want to
3089 * include literal backticks in the code span. So, this input:
3090 *
3091 * Just type ``foo `bar` baz`` at the prompt.
3092 *
3093 * Will translate to:
3094 *
3095 * <p>Just type <code>foo `bar` baz</code> at the prompt.</p>
3096 *
3097 * There's no arbitrary limit to the number of backticks you
3098 * can use as delimters. If you need three consecutive backticks
3099 * in your code, use four for delimiters, etc.
3100 *
3101 * * You can use spaces to get literal backticks at the edges:
3102 *
3103 * ... type `` `bar` `` ...
3104 *
3105 * Turns to:
3106 *
3107 * ... type <code>`bar`</code> ...
3108 */
3109 showdown.subParser('codeSpans', function (text, options, globals) {
3110 'use strict';
3111
3112 text = globals.converter._dispatch('codeSpans.before', text, options, globals);
3113
3114 if (typeof text === 'undefined') {
3115 text = '';
3116 }
3117 text = text.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm,
3118 function (wholeMatch, m1, m2, m3) {
3119 var c = m3;
3120 c = c.replace(/^([ \t]*)/g, ''); // leading whitespace
3121 c = c.replace(/[ \t]*$/g, ''); // trailing whitespace
3122 c = showdown.subParser('encodeCode')(c, options, globals);
3123 c = m1 + '<code>' + c + '</code>';
3124 c = showdown.subParser('hashHTMLSpans')(c, options, globals);
3125 return c;
3126 }
3127 );
3128
3129 text = globals.converter._dispatch('codeSpans.after', text, options, globals);
3130 return text;
3131 });
3132
3133 /**
3134 * Create a full HTML document from the processed markdown
3135 */
3136 showdown.subParser('completeHTMLDocument', function (text, options, globals) {
3137 'use strict';
3138
3139 if (!options.completeHTMLDocument) {
3140 return text;
3141 }
3142
3143 text = globals.converter._dispatch('completeHTMLDocument.before', text, options, globals);
3144
3145 var doctype = 'html',
3146 doctypeParsed = '<!DOCTYPE HTML>\n',
3147 title = '',
3148 charset = '<meta charset="utf-8">\n',
3149 lang = '',
3150 metadata = '';
3151
3152 if (typeof globals.metadata.parsed.doctype !== 'undefined') {
3153 doctypeParsed = '<!DOCTYPE ' + globals.metadata.parsed.doctype + '>\n';
3154 doctype = globals.metadata.parsed.doctype.toString().toLowerCase();
3155 if (doctype === 'html' || doctype === 'html5') {
3156 charset = '<meta charset="utf-8">';
3157 }
3158 }
3159
3160 for (var meta in globals.metadata.parsed) {
3161 if (globals.metadata.parsed.hasOwnProperty(meta)) {
3162 switch (meta.toLowerCase()) {
3163 case 'doctype':
3164 break;
3165
3166 case 'title':
3167 title = '<title>' + globals.metadata.parsed.title + '</title>\n';
3168 break;
3169
3170 case 'charset':
3171 if (doctype === 'html' || doctype === 'html5') {
3172 charset = '<meta charset="' + globals.metadata.parsed.charset + '">\n';
3173 } else {
3174 charset = '<meta name="charset" content="' + globals.metadata.parsed.charset + '">\n';
3175 }
3176 break;
3177
3178 case 'language':
3179 case 'lang':
3180 lang = ' lang="' + globals.metadata.parsed[meta] + '"';
3181 metadata += '<meta name="' + meta + '" content="' + globals.metadata.parsed[meta] + '">\n';
3182 break;
3183
3184 default:
3185 metadata += '<meta name="' + meta + '" content="' + globals.metadata.parsed[meta] + '">\n';
3186 }
3187 }
3188 }
3189
3190 text = doctypeParsed + '<html' + lang + '>\n<head>\n' + title + charset + metadata + '</head>\n<body>\n' + text.trim() + '\n</body>\n</html>';
3191
3192 text = globals.converter._dispatch('completeHTMLDocument.after', text, options, globals);
3193 return text;
3194 });
3195
3196 /**
3197 * Convert all tabs to spaces
3198 */
3199 showdown.subParser('detab', function (text, options, globals) {
3200 'use strict';
3201 text = globals.converter._dispatch('detab.before', text, options, globals);
3202
3203 // expand first n-1 tabs
3204 text = text.replace(/\t(?=\t)/g, ' '); // g_tab_width
3205
3206 // replace the nth with two sentinels
3207 text = text.replace(/\t/g, '¨A¨B');
3208
3209 // use the sentinel to anchor our regex so it doesn't explode
3210 text = text.replace(/¨B(.+?)¨A/g, function (wholeMatch, m1) {
3211 var leadingText = m1,
3212 numSpaces = 4 - leadingText.length % 4; // g_tab_width
3213
3214 // there *must* be a better way to do this:
3215 for (var i = 0; i < numSpaces; i++) {
3216 leadingText += ' ';
3217 }
3218
3219 return leadingText;
3220 });
3221
3222 // clean up sentinels
3223 text = text.replace(/¨A/g, ' '); // g_tab_width
3224 text = text.replace(/¨B/g, '');
3225
3226 text = globals.converter._dispatch('detab.after', text, options, globals);
3227 return text;
3228 });
3229
3230 showdown.subParser('ellipsis', function (text, options, globals) {
3231 'use strict';
3232
3233 text = globals.converter._dispatch('ellipsis.before', text, options, globals);
3234
3235 text = text.replace(/\.\.\./g, '…');
3236
3237 text = globals.converter._dispatch('ellipsis.after', text, options, globals);
3238
3239 return text;
3240 });
3241
3242 /**
3243 * Turn emoji codes into emojis
3244 *
3245 * List of supported emojis: https://github.com/showdownjs/showdown/wiki/Emojis
3246 */
3247 showdown.subParser('emoji', function (text, options, globals) {
3248 'use strict';
3249
3250 if (!options.emoji) {
3251 return text;
3252 }
3253
3254 text = globals.converter._dispatch('emoji.before', text, options, globals);
3255
3256 var emojiRgx = /:([\S]+?):/g;
3257
3258 text = text.replace(emojiRgx, function (wm, emojiCode) {
3259 if (showdown.helper.emojis.hasOwnProperty(emojiCode)) {
3260 return showdown.helper.emojis[emojiCode];
3261 }
3262 return wm;
3263 });
3264
3265 text = globals.converter._dispatch('emoji.after', text, options, globals);
3266
3267 return text;
3268 });
3269
3270 /**
3271 * Smart processing for ampersands and angle brackets that need to be encoded.
3272 */
3273 showdown.subParser('encodeAmpsAndAngles', function (text, options, globals) {
3274 'use strict';
3275 text = globals.converter._dispatch('encodeAmpsAndAngles.before', text, options, globals);
3276
3277 // Ampersand-encoding based entirely on Nat Irons's Amputator MT plugin:
3278 // http://bumppo.net/projects/amputator/
3279 text = text.replace(/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/g, '&amp;');
3280
3281 // Encode naked <'s
3282 text = text.replace(/<(?![a-z\/?$!])/gi, '&lt;');
3283
3284 // Encode <
3285 text = text.replace(/</g, '&lt;');
3286
3287 // Encode >
3288 text = text.replace(/>/g, '&gt;');
3289
3290 text = globals.converter._dispatch('encodeAmpsAndAngles.after', text, options, globals);
3291 return text;
3292 });
3293
3294 /**
3295 * Returns the string, with after processing the following backslash escape sequences.
3296 *
3297 * attacklab: The polite way to do this is with the new escapeCharacters() function:
3298 *
3299 * text = escapeCharacters(text,"\\",true);
3300 * text = escapeCharacters(text,"`*_{}[]()>#+-.!",true);
3301 *
3302 * ...but we're sidestepping its use of the (slow) RegExp constructor
3303 * as an optimization for Firefox. This function gets called a LOT.
3304 */
3305 showdown.subParser('encodeBackslashEscapes', function (text, options, globals) {
3306 'use strict';
3307 text = globals.converter._dispatch('encodeBackslashEscapes.before', text, options, globals);
3308
3309 text = text.replace(/\\(\\)/g, showdown.helper.escapeCharactersCallback);
3310 text = text.replace(/\\([`*_{}\[\]()>#+.!~=|-])/g, showdown.helper.escapeCharactersCallback);
3311
3312 text = globals.converter._dispatch('encodeBackslashEscapes.after', text, options, globals);
3313 return text;
3314 });
3315
3316 /**
3317 * Encode/escape certain characters inside Markdown code runs.
3318 * The point is that in code, these characters are literals,
3319 * and lose their special Markdown meanings.
3320 */
3321 showdown.subParser('encodeCode', function (text, options, globals) {
3322 'use strict';
3323
3324 text = globals.converter._dispatch('encodeCode.before', text, options, globals);
3325
3326 // Encode all ampersands; HTML entities are not
3327 // entities within a Markdown code span.
3328 text = text
3329 .replace(/&/g, '&amp;')
3330 // Do the angle bracket song and dance:
3331 .replace(/</g, '&lt;')
3332 .replace(/>/g, '&gt;')
3333 // Now, escape characters that are magic in Markdown:
3334 .replace(/([*_{}\[\]\\=~-])/g, showdown.helper.escapeCharactersCallback);
3335
3336 text = globals.converter._dispatch('encodeCode.after', text, options, globals);
3337 return text;
3338 });
3339
3340 /**
3341 * Within tags -- meaning between < and > -- encode [\ ` * _ ~ =] so they
3342 * don't conflict with their use in Markdown for code, italics and strong.
3343 */
3344 showdown.subParser('escapeSpecialCharsWithinTagAttributes', function (text, options, globals) {
3345 'use strict';
3346 text = globals.converter._dispatch('escapeSpecialCharsWithinTagAttributes.before', text, options, globals);
3347
3348 // Build a regex to find HTML tags.
3349 var tags = /<\/?[a-z\d_:-]+(?:[\s]+[\s\S]+?)?>/gi,
3350 comments = /<!(--(?:(?:[^>-]|-[^>])(?:[^-]|-[^-])*)--)>/gi;
3351
3352 text = text.replace(tags, function (wholeMatch) {
3353 return wholeMatch
3354 .replace(/(.)<\/?code>(?=.)/g, '$1`')
3355 .replace(/([\\`*_~=|])/g, showdown.helper.escapeCharactersCallback);
3356 });
3357
3358 text = text.replace(comments, function (wholeMatch) {
3359 return wholeMatch
3360 .replace(/([\\`*_~=|])/g, showdown.helper.escapeCharactersCallback);
3361 });
3362
3363 text = globals.converter._dispatch('escapeSpecialCharsWithinTagAttributes.after', text, options, globals);
3364 return text;
3365 });
3366
3367 /**
3368 * Handle github codeblocks prior to running HashHTML so that
3369 * HTML contained within the codeblock gets escaped properly
3370 * Example:
3371 * ```ruby
3372 * def hello_world(x)
3373 * puts "Hello, #{x}"
3374 * end
3375 * ```
3376 */
3377 showdown.subParser('githubCodeBlocks', function (text, options, globals) {
3378 'use strict';
3379
3380 // early exit if option is not enabled
3381 if (!options.ghCodeBlocks) {
3382 return text;
3383 }
3384
3385 text = globals.converter._dispatch('githubCodeBlocks.before', text, options, globals);
3386
3387 text += '¨0';
3388
3389 text = text.replace(/(?:^|\n)(?: {0,3})(```+|~~~+)(?: *)([^\s`~]*)\n([\s\S]*?)\n(?: {0,3})\1/g, function (wholeMatch, delim, language, codeblock) {
3390 var end = (options.omitExtraWLInCodeBlocks) ? '' : '\n';
3391
3392 // First parse the github code block
3393 codeblock = showdown.subParser('encodeCode')(codeblock, options, globals);
3394 codeblock = showdown.subParser('detab')(codeblock, options, globals);
3395 codeblock = codeblock.replace(/^\n+/g, ''); // trim leading newlines
3396 codeblock = codeblock.replace(/\n+$/g, ''); // trim trailing whitespace
3397
3398 codeblock = '<pre><code' + (language ? ' class="' + language + ' language-' + language + '"' : '') + '>' + codeblock + end + '</code></pre>';
3399
3400 codeblock = showdown.subParser('hashBlock')(codeblock, options, globals);
3401
3402 // Since GHCodeblocks can be false positives, we need to
3403 // store the primitive text and the parsed text in a global var,
3404 // and then return a token
3405 return '\n\n¨G' + (globals.ghCodeBlocks.push({text: wholeMatch, codeblock: codeblock}) - 1) + 'G\n\n';
3406 });
3407
3408 // attacklab: strip sentinel
3409 text = text.replace(/¨0/, '');
3410
3411 return globals.converter._dispatch('githubCodeBlocks.after', text, options, globals);
3412 });
3413
3414 showdown.subParser('hashBlock', function (text, options, globals) {
3415 'use strict';
3416 text = globals.converter._dispatch('hashBlock.before', text, options, globals);
3417 text = text.replace(/(^\n+|\n+$)/g, '');
3418 text = '\n\n¨K' + (globals.gHtmlBlocks.push(text) - 1) + 'K\n\n';
3419 text = globals.converter._dispatch('hashBlock.after', text, options, globals);
3420 return text;
3421 });
3422
3423 /**
3424 * Hash and escape <code> elements that should not be parsed as markdown
3425 */
3426 showdown.subParser('hashCodeTags', function (text, options, globals) {
3427 'use strict';
3428 text = globals.converter._dispatch('hashCodeTags.before', text, options, globals);
3429
3430 var repFunc = function (wholeMatch, match, left, right) {
3431 var codeblock = left + showdown.subParser('encodeCode')(match, options, globals) + right;
3432 return '¨C' + (globals.gHtmlSpans.push(codeblock) - 1) + 'C';
3433 };
3434
3435 // Hash naked <code>
3436 text = showdown.helper.replaceRecursiveRegExp(text, repFunc, '<code\\b[^>]*>', '</code>', 'gim');
3437
3438 text = globals.converter._dispatch('hashCodeTags.after', text, options, globals);
3439 return text;
3440 });
3441
3442 showdown.subParser('hashElement', function (text, options, globals) {
3443 'use strict';
3444
3445 return function (wholeMatch, m1) {
3446 var blockText = m1;
3447
3448 // Undo double lines
3449 blockText = blockText.replace(/\n\n/g, '\n');
3450 blockText = blockText.replace(/^\n/, '');
3451
3452 // strip trailing blank lines
3453 blockText = blockText.replace(/\n+$/g, '');
3454
3455 // Replace the element text with a marker ("¨KxK" where x is its key)
3456 blockText = '\n\n¨K' + (globals.gHtmlBlocks.push(blockText) - 1) + 'K\n\n';
3457
3458 return blockText;
3459 };
3460 });
3461
3462 showdown.subParser('hashHTMLBlocks', function (text, options, globals) {
3463 'use strict';
3464 text = globals.converter._dispatch('hashHTMLBlocks.before', text, options, globals);
3465
3466 var blockTags = [
3467 'pre',
3468 'div',
3469 'h1',
3470 'h2',
3471 'h3',
3472 'h4',
3473 'h5',
3474 'h6',
3475 'blockquote',
3476 'table',
3477 'dl',
3478 'ol',
3479 'ul',
3480 'script',
3481 'noscript',
3482 'form',
3483 'fieldset',
3484 'iframe',
3485 'math',
3486 'style',
3487 'section',
3488 'header',
3489 'footer',
3490 'nav',
3491 'article',
3492 'aside',
3493 'address',
3494 'audio',
3495 'canvas',
3496 'figure',
3497 'hgroup',
3498 'output',
3499 'video',
3500 'p'
3501 ],
3502 repFunc = function (wholeMatch, match, left, right) {
3503 var txt = wholeMatch;
3504 // check if this html element is marked as markdown
3505 // if so, it's contents should be parsed as markdown
3506 if (left.search(/\bmarkdown\b/) !== -1) {
3507 txt = left + globals.converter.makeHtml(match) + right;
3508 }
3509 return '\n\n¨K' + (globals.gHtmlBlocks.push(txt) - 1) + 'K\n\n';
3510 };
3511
3512 if (options.backslashEscapesHTMLTags) {
3513 // encode backslash escaped HTML tags
3514 text = text.replace(/\\<(\/?[^>]+?)>/g, function (wm, inside) {
3515 return '&lt;' + inside + '&gt;';
3516 });
3517 }
3518
3519 // hash HTML Blocks
3520 for (var i = 0; i < blockTags.length; ++i) {
3521
3522 var opTagPos,
3523 rgx1 = new RegExp('^ {0,3}(<' + blockTags[i] + '\\b[^>]*>)', 'im'),
3524 patLeft = '<' + blockTags[i] + '\\b[^>]*>',
3525 patRight = '</' + blockTags[i] + '>';
3526 // 1. Look for the first position of the first opening HTML tag in the text
3527 while ((opTagPos = showdown.helper.regexIndexOf(text, rgx1)) !== -1) {
3528
3529 // if the HTML tag is \ escaped, we need to escape it and break
3530
3531
3532 //2. Split the text in that position
3533 var subTexts = showdown.helper.splitAtIndex(text, opTagPos),
3534 //3. Match recursively
3535 newSubText1 = showdown.helper.replaceRecursiveRegExp(subTexts[1], repFunc, patLeft, patRight, 'im');
3536
3537 // prevent an infinite loop
3538 if (newSubText1 === subTexts[1]) {
3539 break;
3540 }
3541 text = subTexts[0].concat(newSubText1);
3542 }
3543 }
3544 // HR SPECIAL CASE
3545 text = text.replace(/(\n {0,3}(<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g,
3546 showdown.subParser('hashElement')(text, options, globals));
3547
3548 // Special case for standalone HTML comments
3549 text = showdown.helper.replaceRecursiveRegExp(text, function (txt) {
3550 return '\n\n¨K' + (globals.gHtmlBlocks.push(txt) - 1) + 'K\n\n';
3551 }, '^ {0,3}<!--', '-->', 'gm');
3552
3553 // PHP and ASP-style processor instructions (<?...?> and <%...%>)
3554 text = text.replace(/(?:\n\n)( {0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g,
3555 showdown.subParser('hashElement')(text, options, globals));
3556
3557 text = globals.converter._dispatch('hashHTMLBlocks.after', text, options, globals);
3558 return text;
3559 });
3560
3561 /**
3562 * Hash span elements that should not be parsed as markdown
3563 */
3564 showdown.subParser('hashHTMLSpans', function (text, options, globals) {
3565 'use strict';
3566 text = globals.converter._dispatch('hashHTMLSpans.before', text, options, globals);
3567
3568 function hashHTMLSpan (html) {
3569 return '¨C' + (globals.gHtmlSpans.push(html) - 1) + 'C';
3570 }
3571
3572 // Hash Self Closing tags
3573 text = text.replace(/<[^>]+?\/>/gi, function (wm) {
3574 return hashHTMLSpan(wm);
3575 });
3576
3577 // Hash tags without properties
3578 text = text.replace(/<([^>]+?)>[\s\S]*?<\/\1>/g, function (wm) {
3579 return hashHTMLSpan(wm);
3580 });
3581
3582 // Hash tags with properties
3583 text = text.replace(/<([^>]+?)\s[^>]+?>[\s\S]*?<\/\1>/g, function (wm) {
3584 return hashHTMLSpan(wm);
3585 });
3586
3587 // Hash self closing tags without />
3588 text = text.replace(/<[^>]+?>/gi, function (wm) {
3589 return hashHTMLSpan(wm);
3590 });
3591
3592 /*showdown.helper.matchRecursiveRegExp(text, '<code\\b[^>]*>', '</code>', 'gi');*/
3593
3594 text = globals.converter._dispatch('hashHTMLSpans.after', text, options, globals);
3595 return text;
3596 });
3597
3598 /**
3599 * Unhash HTML spans
3600 */
3601 showdown.subParser('unhashHTMLSpans', function (text, options, globals) {
3602 'use strict';
3603 text = globals.converter._dispatch('unhashHTMLSpans.before', text, options, globals);
3604
3605 for (var i = 0; i < globals.gHtmlSpans.length; ++i) {
3606 var repText = globals.gHtmlSpans[i],
3607 // limiter to prevent infinite loop (assume 10 as limit for recurse)
3608 limit = 0;
3609
3610 while (/¨C(\d+)C/.test(repText)) {
3611 var num = RegExp.$1;
3612 repText = repText.replace('¨C' + num + 'C', globals.gHtmlSpans[num]);
3613 if (limit === 10) {
3614 console.error('maximum nesting of 10 spans reached!!!');
3615 break;
3616 }
3617 ++limit;
3618 }
3619 text = text.replace('¨C' + i + 'C', repText);
3620 }
3621
3622 text = globals.converter._dispatch('unhashHTMLSpans.after', text, options, globals);
3623 return text;
3624 });
3625
3626 /**
3627 * Hash and escape <pre><code> elements that should not be parsed as markdown
3628 */
3629 showdown.subParser('hashPreCodeTags', function (text, options, globals) {
3630 'use strict';
3631 text = globals.converter._dispatch('hashPreCodeTags.before', text, options, globals);
3632
3633 var repFunc = function (wholeMatch, match, left, right) {
3634 // encode html entities
3635 var codeblock = left + showdown.subParser('encodeCode')(match, options, globals) + right;
3636 return '\n\n¨G' + (globals.ghCodeBlocks.push({text: wholeMatch, codeblock: codeblock}) - 1) + 'G\n\n';
3637 };
3638
3639 // Hash <pre><code>
3640 text = showdown.helper.replaceRecursiveRegExp(text, repFunc, '^ {0,3}<pre\\b[^>]*>\\s*<code\\b[^>]*>', '^ {0,3}</code>\\s*</pre>', 'gim');
3641
3642 text = globals.converter._dispatch('hashPreCodeTags.after', text, options, globals);
3643 return text;
3644 });
3645
3646 showdown.subParser('headers', function (text, options, globals) {
3647 'use strict';
3648
3649 text = globals.converter._dispatch('headers.before', text, options, globals);
3650
3651 var headerLevelStart = (isNaN(parseInt(options.headerLevelStart))) ? 1 : parseInt(options.headerLevelStart),
3652
3653 // Set text-style headers:
3654 // Header 1
3655 // ========
3656 //
3657 // Header 2
3658 // --------
3659 //
3660 setextRegexH1 = (options.smoothLivePreview) ? /^(.+)[ \t]*\n={2,}[ \t]*\n+/gm : /^(.+)[ \t]*\n=+[ \t]*\n+/gm,
3661 setextRegexH2 = (options.smoothLivePreview) ? /^(.+)[ \t]*\n-{2,}[ \t]*\n+/gm : /^(.+)[ \t]*\n-+[ \t]*\n+/gm;
3662
3663 text = text.replace(setextRegexH1, function (wholeMatch, m1) {
3664
3665 var spanGamut = showdown.subParser('spanGamut')(m1, options, globals),
3666 hID = (options.noHeaderId) ? '' : ' id="' + headerId(m1) + '"',
3667 hLevel = headerLevelStart,
3668 hashBlock = '<h' + hLevel + hID + '>' + spanGamut + '</h' + hLevel + '>';
3669 return showdown.subParser('hashBlock')(hashBlock, options, globals);
3670 });
3671
3672 text = text.replace(setextRegexH2, function (matchFound, m1) {
3673 var spanGamut = showdown.subParser('spanGamut')(m1, options, globals),
3674 hID = (options.noHeaderId) ? '' : ' id="' + headerId(m1) + '"',
3675 hLevel = headerLevelStart + 1,
3676 hashBlock = '<h' + hLevel + hID + '>' + spanGamut + '</h' + hLevel + '>';
3677 return showdown.subParser('hashBlock')(hashBlock, options, globals);
3678 });
3679
3680 // atx-style headers:
3681 // # Header 1
3682 // ## Header 2
3683 // ## Header 2 with closing hashes ##
3684 // ...
3685 // ###### Header 6
3686 //
3687 var atxStyle = (options.requireSpaceBeforeHeadingText) ? /^(#{1,6})[ \t]+(.+?)[ \t]*#*\n+/gm : /^(#{1,6})[ \t]*(.+?)[ \t]*#*\n+/gm;
3688
3689 text = text.replace(atxStyle, function (wholeMatch, m1, m2) {
3690 var hText = m2;
3691 if (options.customizedHeaderId) {
3692 hText = m2.replace(/\s?\{([^{]+?)}\s*$/, '');
3693 }
3694
3695 var span = showdown.subParser('spanGamut')(hText, options, globals),
3696 hID = (options.noHeaderId) ? '' : ' id="' + headerId(m2) + '"',
3697 hLevel = headerLevelStart - 1 + m1.length,
3698 header = '<h' + hLevel + hID + '>' + span + '</h' + hLevel + '>';
3699
3700 return showdown.subParser('hashBlock')(header, options, globals);
3701 });
3702
3703 function headerId (m) {
3704 var title,
3705 prefix;
3706
3707 // It is separate from other options to allow combining prefix and customized
3708 if (options.customizedHeaderId) {
3709 var match = m.match(/\{([^{]+?)}\s*$/);
3710 if (match && match[1]) {
3711 m = match[1];
3712 }
3713 }
3714
3715 title = m;
3716
3717 // Prefix id to prevent causing inadvertent pre-existing style matches.
3718 if (showdown.helper.isString(options.prefixHeaderId)) {
3719 prefix = options.prefixHeaderId;
3720 } else if (options.prefixHeaderId === true) {
3721 prefix = 'section-';
3722 } else {
3723 prefix = '';
3724 }
3725
3726 if (!options.rawPrefixHeaderId) {
3727 title = prefix + title;
3728 }
3729
3730 if (options.ghCompatibleHeaderId) {
3731 title = title
3732 .replace(/ /g, '-')
3733 // replace previously escaped chars (&, ¨ and $)
3734 .replace(/&amp;/g, '')
3735 .replace(/¨T/g, '')
3736 .replace(/¨D/g, '')
3737 // replace rest of the chars (&~$ are repeated as they might have been escaped)
3738 // borrowed from github's redcarpet (some they should produce similar results)
3739 .replace(/[&+$,\/:;=?@"#{}|^¨~\[\]`\\*)(%.!'<>]/g, '')
3740 .toLowerCase();
3741 } else if (options.rawHeaderId) {
3742 title = title
3743 .replace(/ /g, '-')
3744 // replace previously escaped chars (&, ¨ and $)
3745 .replace(/&amp;/g, '&')
3746 .replace(/¨T/g, '¨')
3747 .replace(/¨D/g, '$')
3748 // replace " and '
3749 .replace(/["']/g, '-')
3750 .toLowerCase();
3751 } else {
3752 title = title
3753 .replace(/[^\w]/g, '')
3754 .toLowerCase();
3755 }
3756
3757 if (options.rawPrefixHeaderId) {
3758 title = prefix + title;
3759 }
3760
3761 if (globals.hashLinkCounts[title]) {
3762 title = title + '-' + (globals.hashLinkCounts[title]++);
3763 } else {
3764 globals.hashLinkCounts[title] = 1;
3765 }
3766 return title;
3767 }
3768
3769 text = globals.converter._dispatch('headers.after', text, options, globals);
3770 return text;
3771 });
3772
3773 /**
3774 * Turn Markdown link shortcuts into XHTML <a> tags.
3775 */
3776 showdown.subParser('horizontalRule', function (text, options, globals) {
3777 'use strict';
3778 text = globals.converter._dispatch('horizontalRule.before', text, options, globals);
3779
3780 var key = showdown.subParser('hashBlock')('<hr />', options, globals);
3781 text = text.replace(/^ {0,2}( ?-){3,}[ \t]*$/gm, key);
3782 text = text.replace(/^ {0,2}( ?\*){3,}[ \t]*$/gm, key);
3783 text = text.replace(/^ {0,2}( ?_){3,}[ \t]*$/gm, key);
3784
3785 text = globals.converter._dispatch('horizontalRule.after', text, options, globals);
3786 return text;
3787 });
3788
3789 /**
3790 * Turn Markdown image shortcuts into <img> tags.
3791 */
3792 showdown.subParser('images', function (text, options, globals) {
3793 'use strict';
3794
3795 text = globals.converter._dispatch('images.before', text, options, globals);
3796
3797 var inlineRegExp = /!\[([^\]]*?)][ \t]*()\([ \t]?<?([\S]+?(?:\([\S]*?\)[\S]*?)?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(["'])([^"]*?)\6)?[ \t]?\)/g,
3798 crazyRegExp = /!\[([^\]]*?)][ \t]*()\([ \t]?<([^>]*)>(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(?:(["'])([^"]*?)\6))?[ \t]?\)/g,
3799 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,
3800 referenceRegExp = /!\[([^\]]*?)] ?(?:\n *)?\[([\s\S]*?)]()()()()()/g,
3801 refShortcutRegExp = /!\[([^\[\]]+)]()()()()()/g;
3802
3803 function writeImageTagBase64 (wholeMatch, altText, linkId, url, width, height, m5, title) {
3804 url = url.replace(/\s/g, '');
3805 return writeImageTag (wholeMatch, altText, linkId, url, width, height, m5, title);
3806 }
3807
3808 function writeImageTag (wholeMatch, altText, linkId, url, width, height, m5, title) {
3809
3810 var gUrls = globals.gUrls,
3811 gTitles = globals.gTitles,
3812 gDims = globals.gDimensions;
3813
3814 linkId = linkId.toLowerCase();
3815
3816 if (!title) {
3817 title = '';
3818 }
3819 // Special case for explicit empty url
3820 if (wholeMatch.search(/\(<?\s*>? ?(['"].*['"])?\)$/m) > -1) {
3821 url = '';
3822
3823 } else if (url === '' || url === null) {
3824 if (linkId === '' || linkId === null) {
3825 // lower-case and turn embedded newlines into spaces
3826 linkId = altText.toLowerCase().replace(/ ?\n/g, ' ');
3827 }
3828 url = '#' + linkId;
3829
3830 if (!showdown.helper.isUndefined(gUrls[linkId])) {
3831 url = gUrls[linkId];
3832 if (!showdown.helper.isUndefined(gTitles[linkId])) {
3833 title = gTitles[linkId];
3834 }
3835 if (!showdown.helper.isUndefined(gDims[linkId])) {
3836 width = gDims[linkId].width;
3837 height = gDims[linkId].height;
3838 }
3839 } else {
3840 return wholeMatch;
3841 }
3842 }
3843
3844 altText = altText
3845 .replace(/"/g, '&quot;')
3846 //altText = showdown.helper.escapeCharacters(altText, '*_', false);
3847 .replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback);
3848 //url = showdown.helper.escapeCharacters(url, '*_', false);
3849 url = url.replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback);
3850 var result = '<img src="' + url + '" alt="' + altText + '"';
3851
3852 if (title && showdown.helper.isString(title)) {
3853 title = title
3854 .replace(/"/g, '&quot;')
3855 //title = showdown.helper.escapeCharacters(title, '*_', false);
3856 .replace(showdown.helper.regexes.asteriskDashAndColon, showdown.helper.escapeCharactersCallback);
3857 result += ' title="' + title + '"';
3858 }
3859
3860 if (width && height) {
3861 width = (width === '*') ? 'auto' : width;
3862 height = (height === '*') ? 'auto' : height;
3863
3864 result += ' width="' + width + '"';
3865 result += ' height="' + height + '"';
3866 }
3867
3868 result += ' />';
3869
3870 return result;
3871 }
3872
3873 // First, handle reference-style labeled images: ![alt text][id]
3874 text = text.replace(referenceRegExp, writeImageTag);
3875
3876 // Next, handle inline images: ![alt text](url =<width>x<height> "optional title")
3877
3878 // base64 encoded images
3879 text = text.replace(base64RegExp, writeImageTagBase64);
3880
3881 // cases with crazy urls like ./image/cat1).png
3882 text = text.replace(crazyRegExp, writeImageTag);
3883
3884 // normal cases
3885 text = text.replace(inlineRegExp, writeImageTag);
3886
3887 // handle reference-style shortcuts: ![img text]
3888 text = text.replace(refShortcutRegExp, writeImageTag);
3889
3890 text = globals.converter._dispatch('images.after', text, options, globals);
3891 return text;
3892 });
3893
3894 showdown.subParser('italicsAndBold', function (text, options, globals) {
3895 'use strict';
3896
3897 text = globals.converter._dispatch('italicsAndBold.before', text, options, globals);
3898
3899 // it's faster to have 3 separate regexes for each case than have just one
3900 // because of backtracing, in some cases, it could lead to an exponential effect
3901 // called "catastrophic backtrace". Ominous!
3902
3903 function parseInside (txt, left, right) {
3904 /*
3905 if (options.simplifiedAutoLink) {
3906 txt = showdown.subParser('simplifiedAutoLinks')(txt, options, globals);
3907 }
3908 */
3909 return left + txt + right;
3910 }
3911
3912 // Parse underscores
3913 if (options.literalMidWordUnderscores) {
3914 text = text.replace(/\b___(\S[\s\S]*?)___\b/g, function (wm, txt) {
3915 return parseInside (txt, '<strong><em>', '</em></strong>');
3916 });
3917 text = text.replace(/\b__(\S[\s\S]*?)__\b/g, function (wm, txt) {
3918 return parseInside (txt, '<strong>', '</strong>');
3919 });
3920 text = text.replace(/\b_(\S[\s\S]*?)_\b/g, function (wm, txt) {
3921 return parseInside (txt, '<em>', '</em>');
3922 });
3923 } else {
3924 text = text.replace(/___(\S[\s\S]*?)___/g, function (wm, m) {
3925 return (/\S$/.test(m)) ? parseInside (m, '<strong><em>', '</em></strong>') : wm;
3926 });
3927 text = text.replace(/__(\S[\s\S]*?)__/g, function (wm, m) {
3928 return (/\S$/.test(m)) ? parseInside (m, '<strong>', '</strong>') : wm;
3929 });
3930 text = text.replace(/_([^\s_][\s\S]*?)_/g, function (wm, m) {
3931 // !/^_[^_]/.test(m) - test if it doesn't start with __ (since it seems redundant, we removed it)
3932 return (/\S$/.test(m)) ? parseInside (m, '<em>', '</em>') : wm;
3933 });
3934 }
3935
3936 // Now parse asterisks
3937 if (options.literalMidWordAsterisks) {
3938 text = text.replace(/([^*]|^)\B\*\*\*(\S[\s\S]*?)\*\*\*\B(?!\*)/g, function (wm, lead, txt) {
3939 return parseInside (txt, lead + '<strong><em>', '</em></strong>');
3940 });
3941 text = text.replace(/([^*]|^)\B\*\*(\S[\s\S]*?)\*\*\B(?!\*)/g, function (wm, lead, txt) {
3942 return parseInside (txt, lead + '<strong>', '</strong>');
3943 });
3944 text = text.replace(/([^*]|^)\B\*(\S[\s\S]*?)\*\B(?!\*)/g, function (wm, lead, txt) {
3945 return parseInside (txt, lead + '<em>', '</em>');
3946 });
3947 } else {
3948 text = text.replace(/\*\*\*(\S[\s\S]*?)\*\*\*/g, function (wm, m) {
3949 return (/\S$/.test(m)) ? parseInside (m, '<strong><em>', '</em></strong>') : wm;
3950 });
3951 text = text.replace(/\*\*(\S[\s\S]*?)\*\*/g, function (wm, m) {
3952 return (/\S$/.test(m)) ? parseInside (m, '<strong>', '</strong>') : wm;
3953 });
3954 text = text.replace(/\*([^\s*][\s\S]*?)\*/g, function (wm, m) {
3955 // !/^\*[^*]/.test(m) - test if it doesn't start with ** (since it seems redundant, we removed it)
3956 return (/\S$/.test(m)) ? parseInside (m, '<em>', '</em>') : wm;
3957 });
3958 }
3959
3960
3961 text = globals.converter._dispatch('italicsAndBold.after', text, options, globals);
3962 return text;
3963 });
3964
3965 /**
3966 * Form HTML ordered (numbered) and unordered (bulleted) lists.
3967 */
3968 showdown.subParser('lists', function (text, options, globals) {
3969 'use strict';
3970
3971 /**
3972 * Process the contents of a single ordered or unordered list, splitting it
3973 * into individual list items.
3974 * @param {string} listStr
3975 * @param {boolean} trimTrailing
3976 * @returns {string}
3977 */
3978 function processListItems (listStr, trimTrailing) {
3979 // The $g_list_level global keeps track of when we're inside a list.
3980 // Each time we enter a list, we increment it; when we leave a list,
3981 // we decrement. If it's zero, we're not in a list anymore.
3982 //
3983 // We do this because when we're not inside a list, we want to treat
3984 // something like this:
3985 //
3986 // I recommend upgrading to version
3987 // 8. Oops, now this line is treated
3988 // as a sub-list.
3989 //
3990 // As a single paragraph, despite the fact that the second line starts
3991 // with a digit-period-space sequence.
3992 //
3993 // Whereas when we're inside a list (or sub-list), that line will be
3994 // treated as the start of a sub-list. What a kludge, huh? This is
3995 // an aspect of Markdown's syntax that's hard to parse perfectly
3996 // without resorting to mind-reading. Perhaps the solution is to
3997 // change the syntax rules such that sub-lists must start with a
3998 // starting cardinal number; e.g. "1." or "a.".
3999 globals.gListLevel++;
4000
4001 // trim trailing blank lines:
4002 listStr = listStr.replace(/\n{2,}$/, '\n');
4003
4004 // attacklab: add sentinel to emulate \z
4005 listStr += '¨0';
4006
4007 var rgx = /(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0| {0,3}([*+-]|\d+[.])[ \t]+))/gm,
4008 isParagraphed = (/\n[ \t]*\n(?!¨0)/.test(listStr));
4009
4010 // Since version 1.5, nesting sublists requires 4 spaces (or 1 tab) indentation,
4011 // which is a syntax breaking change
4012 // activating this option reverts to old behavior
4013 if (options.disableForced4SpacesIndentedSublists) {
4014 rgx = /(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0|\2([*+-]|\d+[.])[ \t]+))/gm;
4015 }
4016
4017 listStr = listStr.replace(rgx, function (wholeMatch, m1, m2, m3, m4, taskbtn, checked) {
4018 checked = (checked && checked.trim() !== '');
4019
4020 var item = showdown.subParser('outdent')(m4, options, globals),
4021 bulletStyle = '';
4022
4023 // Support for github tasklists
4024 if (taskbtn && options.tasklists) {
4025 bulletStyle = ' class="task-list-item" style="list-style-type: none;"';
4026 item = item.replace(/^[ \t]*\[(x|X| )?]/m, function () {
4027 var otp = '<input type="checkbox" disabled style="margin: 0px 0.35em 0.25em -1.6em; vertical-align: middle;"';
4028 if (checked) {
4029 otp += ' checked';
4030 }
4031 otp += '>';
4032 return otp;
4033 });
4034 }
4035
4036 // ISSUE #312
4037 // This input: - - - a
4038 // causes trouble to the parser, since it interprets it as:
4039 // <ul><li><li><li>a</li></li></li></ul>
4040 // instead of:
4041 // <ul><li>- - a</li></ul>
4042 // So, to prevent it, we will put a marker (¨A)in the beginning of the line
4043 // Kind of hackish/monkey patching, but seems more effective than overcomplicating the list parser
4044 item = item.replace(/^([-*+]|\d\.)[ \t]+[\S\n ]*/g, function (wm2) {
4045 return '¨A' + wm2;
4046 });
4047
4048 // m1 - Leading line or
4049 // Has a double return (multi paragraph) or
4050 // Has sublist
4051 if (m1 || (item.search(/\n{2,}/) > -1)) {
4052 item = showdown.subParser('githubCodeBlocks')(item, options, globals);
4053 item = showdown.subParser('blockGamut')(item, options, globals);
4054 } else {
4055 // Recursion for sub-lists:
4056 item = showdown.subParser('lists')(item, options, globals);
4057 item = item.replace(/\n$/, ''); // chomp(item)
4058 item = showdown.subParser('hashHTMLBlocks')(item, options, globals);
4059
4060 // Colapse double linebreaks
4061 item = item.replace(/\n\n+/g, '\n\n');
4062 if (isParagraphed) {
4063 item = showdown.subParser('paragraphs')(item, options, globals);
4064 } else {
4065 item = showdown.subParser('spanGamut')(item, options, globals);
4066 }
4067 }
4068
4069 // now we need to remove the marker (¨A)
4070 item = item.replace('¨A', '');
4071 // we can finally wrap the line in list item tags
4072 item = '<li' + bulletStyle + '>' + item + '</li>\n';
4073
4074 return item;
4075 });
4076
4077 // attacklab: strip sentinel
4078 listStr = listStr.replace(/¨0/g, '');
4079
4080 globals.gListLevel--;
4081
4082 if (trimTrailing) {
4083 listStr = listStr.replace(/\s+$/, '');
4084 }
4085
4086 return listStr;
4087 }
4088
4089 function styleStartNumber (list, listType) {
4090 // check if ol and starts by a number different than 1
4091 if (listType === 'ol') {
4092 var res = list.match(/^ *(\d+)\./);
4093 if (res && res[1] !== '1') {
4094 return ' start="' + res[1] + '"';
4095 }
4096 }
4097 return '';
4098 }
4099
4100 /**
4101 * Check and parse consecutive lists (better fix for issue #142)
4102 * @param {string} list
4103 * @param {string} listType
4104 * @param {boolean} trimTrailing
4105 * @returns {string}
4106 */
4107 function parseConsecutiveLists (list, listType, trimTrailing) {
4108 // check if we caught 2 or more consecutive lists by mistake
4109 // we use the counterRgx, meaning if listType is UL we look for OL and vice versa
4110 var olRgx = (options.disableForced4SpacesIndentedSublists) ? /^ ?\d+\.[ \t]/gm : /^ {0,3}\d+\.[ \t]/gm,
4111 ulRgx = (options.disableForced4SpacesIndentedSublists) ? /^ ?[*+-][ \t]/gm : /^ {0,3}[*+-][ \t]/gm,
4112 counterRxg = (listType === 'ul') ? olRgx : ulRgx,
4113 result = '';
4114
4115 if (list.search(counterRxg) !== -1) {
4116 (function parseCL (txt) {
4117 var pos = txt.search(counterRxg),
4118 style = styleStartNumber(list, listType);
4119 if (pos !== -1) {
4120 // slice
4121 result += '\n\n<' + listType + style + '>\n' + processListItems(txt.slice(0, pos), !!trimTrailing) + '</' + listType + '>\n';
4122
4123 // invert counterType and listType
4124 listType = (listType === 'ul') ? 'ol' : 'ul';
4125 counterRxg = (listType === 'ul') ? olRgx : ulRgx;
4126
4127 //recurse
4128 parseCL(txt.slice(pos));
4129 } else {
4130 result += '\n\n<' + listType + style + '>\n' + processListItems(txt, !!trimTrailing) + '</' + listType + '>\n';
4131 }
4132 })(list);
4133 } else {
4134 var style = styleStartNumber(list, listType);
4135 result = '\n\n<' + listType + style + '>\n' + processListItems(list, !!trimTrailing) + '</' + listType + '>\n';
4136 }
4137
4138 return result;
4139 }
4140
4141 /** Start of list parsing **/
4142 text = globals.converter._dispatch('lists.before', text, options, globals);
4143 // add sentinel to hack around khtml/safari bug:
4144 // http://bugs.webkit.org/show_bug.cgi?id=11231
4145 text += '¨0';
4146
4147 if (globals.gListLevel) {
4148 text = text.replace(/^(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(¨0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm,
4149 function (wholeMatch, list, m2) {
4150 var listType = (m2.search(/[*+-]/g) > -1) ? 'ul' : 'ol';
4151 return parseConsecutiveLists(list, listType, true);
4152 }
4153 );
4154 } else {
4155 text = text.replace(/(\n\n|^\n?)(( {0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(¨0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm,
4156 function (wholeMatch, m1, list, m3) {
4157 var listType = (m3.search(/[*+-]/g) > -1) ? 'ul' : 'ol';
4158 return parseConsecutiveLists(list, listType, false);
4159 }
4160 );
4161 }
4162
4163 // strip sentinel
4164 text = text.replace(/¨0/, '');
4165 text = globals.converter._dispatch('lists.after', text, options, globals);
4166 return text;
4167 });
4168
4169 /**
4170 * Parse metadata at the top of the document
4171 */
4172 showdown.subParser('metadata', function (text, options, globals) {
4173 'use strict';
4174
4175 if (!options.metadata) {
4176 return text;
4177 }
4178
4179 text = globals.converter._dispatch('metadata.before', text, options, globals);
4180
4181 function parseMetadataContents (content) {
4182 // raw is raw so it's not changed in any way
4183 globals.metadata.raw = content;
4184
4185 // escape chars forbidden in html attributes
4186 // double quotes
4187 content = content
4188 // ampersand first
4189 .replace(/&/g, '&amp;')
4190 // double quotes
4191 .replace(/"/g, '&quot;');
4192
4193 content = content.replace(/\n {4}/g, ' ');
4194 content.replace(/^([\S ]+): +([\s\S]+?)$/gm, function (wm, key, value) {
4195 globals.metadata.parsed[key] = value;
4196 return '';
4197 });
4198 }
4199
4200 text = text.replace(/^\s*«««+(\S*?)\n([\s\S]+?)\n»»»+\n/, function (wholematch, format, content) {
4201 parseMetadataContents(content);
4202 return '¨M';
4203 });
4204
4205 text = text.replace(/^\s*---+(\S*?)\n([\s\S]+?)\n---+\n/, function (wholematch, format, content) {
4206 if (format) {
4207 globals.metadata.format = format;
4208 }
4209 parseMetadataContents(content);
4210 return '¨M';
4211 });
4212
4213 text = text.replace(/¨M/g, '');
4214
4215 text = globals.converter._dispatch('metadata.after', text, options, globals);
4216 return text;
4217 });
4218
4219 /**
4220 * Remove one level of line-leading tabs or spaces
4221 */
4222 showdown.subParser('outdent', function (text, options, globals) {
4223 'use strict';
4224 text = globals.converter._dispatch('outdent.before', text, options, globals);
4225
4226 // attacklab: hack around Konqueror 3.5.4 bug:
4227 // "----------bug".replace(/^-/g,"") == "bug"
4228 text = text.replace(/^(\t|[ ]{1,4})/gm, '¨0'); // attacklab: g_tab_width
4229
4230 // attacklab: clean up hack
4231 text = text.replace(/¨0/g, '');
4232
4233 text = globals.converter._dispatch('outdent.after', text, options, globals);
4234 return text;
4235 });
4236
4237 /**
4238 *
4239 */
4240 showdown.subParser('paragraphs', function (text, options, globals) {
4241 'use strict';
4242
4243 text = globals.converter._dispatch('paragraphs.before', text, options, globals);
4244 // Strip leading and trailing lines:
4245 text = text.replace(/^\n+/g, '');
4246 text = text.replace(/\n+$/g, '');
4247
4248 var grafs = text.split(/\n{2,}/g),
4249 grafsOut = [],
4250 end = grafs.length; // Wrap <p> tags
4251
4252 for (var i = 0; i < end; i++) {
4253 var str = grafs[i];
4254 // if this is an HTML marker, copy it
4255 if (str.search(/¨(K|G)(\d+)\1/g) >= 0) {
4256 grafsOut.push(str);
4257
4258 // test for presence of characters to prevent empty lines being parsed
4259 // as paragraphs (resulting in undesired extra empty paragraphs)
4260 } else if (str.search(/\S/) >= 0) {
4261 str = showdown.subParser('spanGamut')(str, options, globals);
4262 str = str.replace(/^([ \t]*)/g, '<p>');
4263 str += '</p>';
4264 grafsOut.push(str);
4265 }
4266 }
4267
4268 /** Unhashify HTML blocks */
4269 end = grafsOut.length;
4270 for (i = 0; i < end; i++) {
4271 var blockText = '',
4272 grafsOutIt = grafsOut[i],
4273 codeFlag = false;
4274 // if this is a marker for an html block...
4275 // use RegExp.test instead of string.search because of QML bug
4276 while (/¨(K|G)(\d+)\1/.test(grafsOutIt)) {
4277 var delim = RegExp.$1,
4278 num = RegExp.$2;
4279
4280 if (delim === 'K') {
4281 blockText = globals.gHtmlBlocks[num];
4282 } else {
4283 // we need to check if ghBlock is a false positive
4284 if (codeFlag) {
4285 // use encoded version of all text
4286 blockText = showdown.subParser('encodeCode')(globals.ghCodeBlocks[num].text, options, globals);
4287 } else {
4288 blockText = globals.ghCodeBlocks[num].codeblock;
4289 }
4290 }
4291 blockText = blockText.replace(/\$/g, '$$$$'); // Escape any dollar signs
4292
4293 grafsOutIt = grafsOutIt.replace(/(\n\n)?¨(K|G)\d+\2(\n\n)?/, blockText);
4294 // Check if grafsOutIt is a pre->code
4295 if (/^<pre\b[^>]*>\s*<code\b[^>]*>/.test(grafsOutIt)) {
4296 codeFlag = true;
4297 }
4298 }
4299 grafsOut[i] = grafsOutIt;
4300 }
4301 text = grafsOut.join('\n');
4302 // Strip leading and trailing lines:
4303 text = text.replace(/^\n+/g, '');
4304 text = text.replace(/\n+$/g, '');
4305 return globals.converter._dispatch('paragraphs.after', text, options, globals);
4306 });
4307
4308 /**
4309 * Run extension
4310 */
4311 showdown.subParser('runExtension', function (ext, text, options, globals) {
4312 'use strict';
4313
4314 if (ext.filter) {
4315 text = ext.filter(text, globals.converter, options);
4316
4317 } else if (ext.regex) {
4318 // TODO remove this when old extension loading mechanism is deprecated
4319 var re = ext.regex;
4320 if (!(re instanceof RegExp)) {
4321 re = new RegExp(re, 'g');
4322 }
4323 text = text.replace(re, ext.replace);
4324 }
4325
4326 return text;
4327 });
4328
4329 /**
4330 * These are all the transformations that occur *within* block-level
4331 * tags like paragraphs, headers, and list items.
4332 */
4333 showdown.subParser('spanGamut', function (text, options, globals) {
4334 'use strict';
4335
4336 text = globals.converter._dispatch('spanGamut.before', text, options, globals);
4337 text = showdown.subParser('codeSpans')(text, options, globals);
4338 text = showdown.subParser('escapeSpecialCharsWithinTagAttributes')(text, options, globals);
4339 text = showdown.subParser('encodeBackslashEscapes')(text, options, globals);
4340
4341 // Process anchor and image tags. Images must come first,
4342 // because ![foo][f] looks like an anchor.
4343 text = showdown.subParser('images')(text, options, globals);
4344 text = showdown.subParser('anchors')(text, options, globals);
4345
4346 // Make links out of things like `<http://example.com/>`
4347 // Must come after anchors, because you can use < and >
4348 // delimiters in inline links like [this](<url>).
4349 text = showdown.subParser('autoLinks')(text, options, globals);
4350 text = showdown.subParser('simplifiedAutoLinks')(text, options, globals);
4351 text = showdown.subParser('emoji')(text, options, globals);
4352 text = showdown.subParser('underline')(text, options, globals);
4353 text = showdown.subParser('italicsAndBold')(text, options, globals);
4354 text = showdown.subParser('strikethrough')(text, options, globals);
4355 text = showdown.subParser('ellipsis')(text, options, globals);
4356
4357 // we need to hash HTML tags inside spans
4358 text = showdown.subParser('hashHTMLSpans')(text, options, globals);
4359
4360 // now we encode amps and angles
4361 text = showdown.subParser('encodeAmpsAndAngles')(text, options, globals);
4362
4363 // Do hard breaks
4364 if (options.simpleLineBreaks) {
4365 // GFM style hard breaks
4366 // only add line breaks if the text does not contain a block (special case for lists)
4367 if (!/\n\n¨K/.test(text)) {
4368 text = text.replace(/\n+/g, '<br />\n');
4369 }
4370 } else {
4371 // Vanilla hard breaks
4372 text = text.replace(/ +\n/g, '<br />\n');
4373 }
4374
4375 text = globals.converter._dispatch('spanGamut.after', text, options, globals);
4376 return text;
4377 });
4378
4379 showdown.subParser('strikethrough', function (text, options, globals) {
4380 'use strict';
4381
4382 function parseInside (txt) {
4383 if (options.simplifiedAutoLink) {
4384 txt = showdown.subParser('simplifiedAutoLinks')(txt, options, globals);
4385 }
4386 return '<del>' + txt + '</del>';
4387 }
4388
4389 if (options.strikethrough) {
4390 text = globals.converter._dispatch('strikethrough.before', text, options, globals);
4391 text = text.replace(/(?:~){2}([\s\S]+?)(?:~){2}/g, function (wm, txt) { return parseInside(txt); });
4392 text = globals.converter._dispatch('strikethrough.after', text, options, globals);
4393 }
4394
4395 return text;
4396 });
4397
4398 /**
4399 * Strips link definitions from text, stores the URLs and titles in
4400 * hash references.
4401 * Link defs are in the form: ^[id]: url "optional title"
4402 */
4403 showdown.subParser('stripLinkDefinitions', function (text, options, globals) {
4404 'use strict';
4405
4406 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,
4407 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;
4408
4409 // attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug
4410 text += '¨0';
4411
4412 var replaceFunc = function (wholeMatch, linkId, url, width, height, blankLines, title) {
4413 linkId = linkId.toLowerCase();
4414 if (url.match(/^data:.+?\/.+?;base64,/)) {
4415 // remove newlines
4416 globals.gUrls[linkId] = url.replace(/\s/g, '');
4417 } else {
4418 globals.gUrls[linkId] = showdown.subParser('encodeAmpsAndAngles')(url, options, globals); // Link IDs are case-insensitive
4419 }
4420
4421 if (blankLines) {
4422 // Oops, found blank lines, so it's not a title.
4423 // Put back the parenthetical statement we stole.
4424 return blankLines + title;
4425
4426 } else {
4427 if (title) {
4428 globals.gTitles[linkId] = title.replace(/"|'/g, '&quot;');
4429 }
4430 if (options.parseImgDimensions && width && height) {
4431 globals.gDimensions[linkId] = {
4432 width: width,
4433 height: height
4434 };
4435 }
4436 }
4437 // Completely remove the definition from the text
4438 return '';
4439 };
4440
4441 // first we try to find base64 link references
4442 text = text.replace(base64Regex, replaceFunc);
4443
4444 text = text.replace(regex, replaceFunc);
4445
4446 // attacklab: strip sentinel
4447 text = text.replace(/¨0/, '');
4448
4449 return text;
4450 });
4451
4452 showdown.subParser('tables', function (text, options, globals) {
4453 'use strict';
4454
4455 if (!options.tables) {
4456 return text;
4457 }
4458
4459 var tableRgx = /^ {0,3}\|?.+\|.+\n {0,3}\|?[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*:?[ \t]*(?:[-=]){2,}[\s\S]+?(?:\n\n|¨0)/gm,
4460 //singeColTblRgx = /^ {0,3}\|.+\|\n {0,3}\|[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*\n(?: {0,3}\|.+\|\n)+(?:\n\n|¨0)/gm;
4461 singeColTblRgx = /^ {0,3}\|.+\|[ \t]*\n {0,3}\|[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*\n( {0,3}\|.+\|[ \t]*\n)*(?:\n|¨0)/gm;
4462
4463 function parseStyles (sLine) {
4464 if (/^:[ \t]*--*$/.test(sLine)) {
4465 return ' style="text-align:left;"';
4466 } else if (/^--*[ \t]*:[ \t]*$/.test(sLine)) {
4467 return ' style="text-align:right;"';
4468 } else if (/^:[ \t]*--*[ \t]*:$/.test(sLine)) {
4469 return ' style="text-align:center;"';
4470 } else {
4471 return '';
4472 }
4473 }
4474
4475 function parseHeaders (header, style) {
4476 var id = '';
4477 header = header.trim();
4478 // support both tablesHeaderId and tableHeaderId due to error in documentation so we don't break backwards compatibility
4479 if (options.tablesHeaderId || options.tableHeaderId) {
4480 id = ' id="' + header.replace(/ /g, '_').toLowerCase() + '"';
4481 }
4482 header = showdown.subParser('spanGamut')(header, options, globals);
4483
4484 return '<th' + id + style + '>' + header + '</th>\n';
4485 }
4486
4487 function parseCells (cell, style) {
4488 var subText = showdown.subParser('spanGamut')(cell, options, globals);
4489 return '<td' + style + '>' + subText + '</td>\n';
4490 }
4491
4492 function buildTable (headers, cells) {
4493 var tb = '<table>\n<thead>\n<tr>\n',
4494 tblLgn = headers.length;
4495
4496 for (var i = 0; i < tblLgn; ++i) {
4497 tb += headers[i];
4498 }
4499 tb += '</tr>\n</thead>\n<tbody>\n';
4500
4501 for (i = 0; i < cells.length; ++i) {
4502 tb += '<tr>\n';
4503 for (var ii = 0; ii < tblLgn; ++ii) {
4504 tb += cells[i][ii];
4505 }
4506 tb += '</tr>\n';
4507 }
4508 tb += '</tbody>\n</table>\n';
4509 return tb;
4510 }
4511
4512 function parseTable (rawTable) {
4513 var i, tableLines = rawTable.split('\n');
4514
4515 for (i = 0; i < tableLines.length; ++i) {
4516 // strip wrong first and last column if wrapped tables are used
4517 if (/^ {0,3}\|/.test(tableLines[i])) {
4518 tableLines[i] = tableLines[i].replace(/^ {0,3}\|/, '');
4519 }
4520 if (/\|[ \t]*$/.test(tableLines[i])) {
4521 tableLines[i] = tableLines[i].replace(/\|[ \t]*$/, '');
4522 }
4523 // parse code spans first, but we only support one line code spans
4524 tableLines[i] = showdown.subParser('codeSpans')(tableLines[i], options, globals);
4525 }
4526
4527 var rawHeaders = tableLines[0].split('|').map(function (s) { return s.trim();}),
4528 rawStyles = tableLines[1].split('|').map(function (s) { return s.trim();}),
4529 rawCells = [],
4530 headers = [],
4531 styles = [],
4532 cells = [];
4533
4534 tableLines.shift();
4535 tableLines.shift();
4536
4537 for (i = 0; i < tableLines.length; ++i) {
4538 if (tableLines[i].trim() === '') {
4539 continue;
4540 }
4541 rawCells.push(
4542 tableLines[i]
4543 .split('|')
4544 .map(function (s) {
4545 return s.trim();
4546 })
4547 );
4548 }
4549
4550 if (rawHeaders.length < rawStyles.length) {
4551 return rawTable;
4552 }
4553
4554 for (i = 0; i < rawStyles.length; ++i) {
4555 styles.push(parseStyles(rawStyles[i]));
4556 }
4557
4558 for (i = 0; i < rawHeaders.length; ++i) {
4559 if (showdown.helper.isUndefined(styles[i])) {
4560 styles[i] = '';
4561 }
4562 headers.push(parseHeaders(rawHeaders[i], styles[i]));
4563 }
4564
4565 for (i = 0; i < rawCells.length; ++i) {
4566 var row = [];
4567 for (var ii = 0; ii < headers.length; ++ii) {
4568 if (showdown.helper.isUndefined(rawCells[i][ii])) {
4569
4570 }
4571 row.push(parseCells(rawCells[i][ii], styles[ii]));
4572 }
4573 cells.push(row);
4574 }
4575
4576 return buildTable(headers, cells);
4577 }
4578
4579 text = globals.converter._dispatch('tables.before', text, options, globals);
4580
4581 // find escaped pipe characters
4582 text = text.replace(/\\(\|)/g, showdown.helper.escapeCharactersCallback);
4583
4584 // parse multi column tables
4585 text = text.replace(tableRgx, parseTable);
4586
4587 // parse one column tables
4588 text = text.replace(singeColTblRgx, parseTable);
4589
4590 text = globals.converter._dispatch('tables.after', text, options, globals);
4591
4592 return text;
4593 });
4594
4595 showdown.subParser('underline', function (text, options, globals) {
4596 'use strict';
4597
4598 if (!options.underline) {
4599 return text;
4600 }
4601
4602 text = globals.converter._dispatch('underline.before', text, options, globals);
4603
4604 if (options.literalMidWordUnderscores) {
4605 text = text.replace(/\b___(\S[\s\S]*?)___\b/g, function (wm, txt) {
4606 return '<u>' + txt + '</u>';
4607 });
4608 text = text.replace(/\b__(\S[\s\S]*?)__\b/g, function (wm, txt) {
4609 return '<u>' + txt + '</u>';
4610 });
4611 } else {
4612 text = text.replace(/___(\S[\s\S]*?)___/g, function (wm, m) {
4613 return (/\S$/.test(m)) ? '<u>' + m + '</u>' : wm;
4614 });
4615 text = text.replace(/__(\S[\s\S]*?)__/g, function (wm, m) {
4616 return (/\S$/.test(m)) ? '<u>' + m + '</u>' : wm;
4617 });
4618 }
4619
4620 // escape remaining underscores to prevent them being parsed by italic and bold
4621 text = text.replace(/(_)/g, showdown.helper.escapeCharactersCallback);
4622
4623 text = globals.converter._dispatch('underline.after', text, options, globals);
4624
4625 return text;
4626 });
4627
4628 /**
4629 * Swap back in all the special characters we've hidden.
4630 */
4631 showdown.subParser('unescapeSpecialChars', function (text, options, globals) {
4632 'use strict';
4633 text = globals.converter._dispatch('unescapeSpecialChars.before', text, options, globals);
4634
4635 text = text.replace(/¨E(\d+)E/g, function (wholeMatch, m1) {
4636 var charCodeToReplace = parseInt(m1);
4637 return String.fromCharCode(charCodeToReplace);
4638 });
4639
4640 text = globals.converter._dispatch('unescapeSpecialChars.after', text, options, globals);
4641 return text;
4642 });
4643
4644 showdown.subParser('makeMarkdown.blockquote', function (node, globals) {
4645 'use strict';
4646
4647 var txt = '';
4648 if (node.hasChildNodes()) {
4649 var children = node.childNodes,
4650 childrenLength = children.length;
4651
4652 for (var i = 0; i < childrenLength; ++i) {
4653 var innerTxt = showdown.subParser('makeMarkdown.node')(children[i], globals);
4654
4655 if (innerTxt === '') {
4656 continue;
4657 }
4658 txt += innerTxt;
4659 }
4660 }
4661 // cleanup
4662 txt = txt.trim();
4663 txt = '> ' + txt.split('\n').join('\n> ');
4664 return txt;
4665 });
4666
4667 showdown.subParser('makeMarkdown.codeBlock', function (node, globals) {
4668 'use strict';
4669
4670 var lang = node.getAttribute('language'),
4671 num = node.getAttribute('precodenum');
4672 return '```' + lang + '\n' + globals.preList[num] + '\n```';
4673 });
4674
4675 showdown.subParser('makeMarkdown.codeSpan', function (node) {
4676 'use strict';
4677
4678 return '`' + node.innerHTML + '`';
4679 });
4680
4681 showdown.subParser('makeMarkdown.emphasis', function (node, globals) {
4682 'use strict';
4683
4684 var txt = '';
4685 if (node.hasChildNodes()) {
4686 txt += '*';
4687 var children = node.childNodes,
4688 childrenLength = children.length;
4689 for (var i = 0; i < childrenLength; ++i) {
4690 txt += showdown.subParser('makeMarkdown.node')(children[i], globals);
4691 }
4692 txt += '*';
4693 }
4694 return txt;
4695 });
4696
4697 showdown.subParser('makeMarkdown.header', function (node, globals, headerLevel) {
4698 'use strict';
4699
4700 var headerMark = new Array(headerLevel + 1).join('#'),
4701 txt = '';
4702
4703 if (node.hasChildNodes()) {
4704 txt = headerMark + ' ';
4705 var children = node.childNodes,
4706 childrenLength = children.length;
4707
4708 for (var i = 0; i < childrenLength; ++i) {
4709 txt += showdown.subParser('makeMarkdown.node')(children[i], globals);
4710 }
4711 }
4712 return txt;
4713 });
4714
4715 showdown.subParser('makeMarkdown.hr', function () {
4716 'use strict';
4717
4718 return '---';
4719 });
4720
4721 showdown.subParser('makeMarkdown.image', function (node) {
4722 'use strict';
4723
4724 var txt = '';
4725 if (node.hasAttribute('src')) {
4726 txt += '![' + node.getAttribute('alt') + '](';
4727 txt += '<' + node.getAttribute('src') + '>';
4728 if (node.hasAttribute('width') && node.hasAttribute('height')) {
4729 txt += ' =' + node.getAttribute('width') + 'x' + node.getAttribute('height');
4730 }
4731
4732 if (node.hasAttribute('title')) {
4733 txt += ' "' + node.getAttribute('title') + '"';
4734 }
4735 txt += ')';
4736 }
4737 return txt;
4738 });
4739
4740 showdown.subParser('makeMarkdown.links', function (node, globals) {
4741 'use strict';
4742
4743 var txt = '';
4744 if (node.hasChildNodes() && node.hasAttribute('href')) {
4745 var children = node.childNodes,
4746 childrenLength = children.length;
4747 txt = '[';
4748 for (var i = 0; i < childrenLength; ++i) {
4749 txt += showdown.subParser('makeMarkdown.node')(children[i], globals);
4750 }
4751 txt += '](';
4752 txt += '<' + node.getAttribute('href') + '>';
4753 if (node.hasAttribute('title')) {
4754 txt += ' "' + node.getAttribute('title') + '"';
4755 }
4756 txt += ')';
4757 }
4758 return txt;
4759 });
4760
4761 showdown.subParser('makeMarkdown.list', function (node, globals, type) {
4762 'use strict';
4763
4764 var txt = '';
4765 if (!node.hasChildNodes()) {
4766 return '';
4767 }
4768 var listItems = node.childNodes,
4769 listItemsLenght = listItems.length,
4770 listNum = node.getAttribute('start') || 1;
4771
4772 for (var i = 0; i < listItemsLenght; ++i) {
4773 if (typeof listItems[i].tagName === 'undefined' || listItems[i].tagName.toLowerCase() !== 'li') {
4774 continue;
4775 }
4776
4777 // define the bullet to use in list
4778 var bullet = '';
4779 if (type === 'ol') {
4780 bullet = listNum.toString() + '. ';
4781 } else {
4782 bullet = '- ';
4783 }
4784
4785 // parse list item
4786 txt += bullet + showdown.subParser('makeMarkdown.listItem')(listItems[i], globals);
4787 ++listNum;
4788 }
4789
4790 // add comment at the end to prevent consecutive lists to be parsed as one
4791 txt += '\n<!-- -->\n';
4792 return txt.trim();
4793 });
4794
4795 showdown.subParser('makeMarkdown.listItem', function (node, globals) {
4796 'use strict';
4797
4798 var listItemTxt = '';
4799
4800 var children = node.childNodes,
4801 childrenLenght = children.length;
4802
4803 for (var i = 0; i < childrenLenght; ++i) {
4804 listItemTxt += showdown.subParser('makeMarkdown.node')(children[i], globals);
4805 }
4806 // if it's only one liner, we need to add a newline at the end
4807 if (!/\n$/.test(listItemTxt)) {
4808 listItemTxt += '\n';
4809 } else {
4810 // it's multiparagraph, so we need to indent
4811 listItemTxt = listItemTxt
4812 .split('\n')
4813 .join('\n ')
4814 .replace(/^ {4}$/gm, '')
4815 .replace(/\n\n+/g, '\n\n');
4816 }
4817
4818 return listItemTxt;
4819 });
4820
4821
4822
4823 showdown.subParser('makeMarkdown.node', function (node, globals, spansOnly) {
4824 'use strict';
4825
4826 spansOnly = spansOnly || false;
4827
4828 var txt = '';
4829
4830 // edge case of text without wrapper paragraph
4831 if (node.nodeType === 3) {
4832 return showdown.subParser('makeMarkdown.txt')(node, globals);
4833 }
4834
4835 // HTML comment
4836 if (node.nodeType === 8) {
4837 return '<!--' + node.data + '-->\n\n';
4838 }
4839
4840 // process only node elements
4841 if (node.nodeType !== 1) {
4842 return '';
4843 }
4844
4845 var tagName = node.tagName.toLowerCase();
4846
4847 switch (tagName) {
4848
4849 //
4850 // BLOCKS
4851 //
4852 case 'h1':
4853 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 1) + '\n\n'; }
4854 break;
4855 case 'h2':
4856 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 2) + '\n\n'; }
4857 break;
4858 case 'h3':
4859 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 3) + '\n\n'; }
4860 break;
4861 case 'h4':
4862 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 4) + '\n\n'; }
4863 break;
4864 case 'h5':
4865 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 5) + '\n\n'; }
4866 break;
4867 case 'h6':
4868 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.header')(node, globals, 6) + '\n\n'; }
4869 break;
4870
4871 case 'p':
4872 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.paragraph')(node, globals) + '\n\n'; }
4873 break;
4874
4875 case 'blockquote':
4876 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.blockquote')(node, globals) + '\n\n'; }
4877 break;
4878
4879 case 'hr':
4880 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.hr')(node, globals) + '\n\n'; }
4881 break;
4882
4883 case 'ol':
4884 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.list')(node, globals, 'ol') + '\n\n'; }
4885 break;
4886
4887 case 'ul':
4888 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.list')(node, globals, 'ul') + '\n\n'; }
4889 break;
4890
4891 case 'precode':
4892 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.codeBlock')(node, globals) + '\n\n'; }
4893 break;
4894
4895 case 'pre':
4896 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.pre')(node, globals) + '\n\n'; }
4897 break;
4898
4899 case 'table':
4900 if (!spansOnly) { txt = showdown.subParser('makeMarkdown.table')(node, globals) + '\n\n'; }
4901 break;
4902
4903 //
4904 // SPANS
4905 //
4906 case 'code':
4907 txt = showdown.subParser('makeMarkdown.codeSpan')(node, globals);
4908 break;
4909
4910 case 'em':
4911 case 'i':
4912 txt = showdown.subParser('makeMarkdown.emphasis')(node, globals);
4913 break;
4914
4915 case 'strong':
4916 case 'b':
4917 txt = showdown.subParser('makeMarkdown.strong')(node, globals);
4918 break;
4919
4920 case 'del':
4921 txt = showdown.subParser('makeMarkdown.strikethrough')(node, globals);
4922 break;
4923
4924 case 'a':
4925 txt = showdown.subParser('makeMarkdown.links')(node, globals);
4926 break;
4927
4928 case 'img':
4929 txt = showdown.subParser('makeMarkdown.image')(node, globals);
4930 break;
4931
4932 default:
4933 txt = node.outerHTML + '\n\n';
4934 }
4935
4936 // common normalization
4937 // TODO eventually
4938
4939 return txt;
4940 });
4941
4942 showdown.subParser('makeMarkdown.paragraph', function (node, globals) {
4943 'use strict';
4944
4945 var txt = '';
4946 if (node.hasChildNodes()) {
4947 var children = node.childNodes,
4948 childrenLength = children.length;
4949 for (var i = 0; i < childrenLength; ++i) {
4950 txt += showdown.subParser('makeMarkdown.node')(children[i], globals);
4951 }
4952 }
4953
4954 // some text normalization
4955 txt = txt.trim();
4956
4957 return txt;
4958 });
4959
4960 showdown.subParser('makeMarkdown.pre', function (node, globals) {
4961 'use strict';
4962
4963 var num = node.getAttribute('prenum');
4964 return '<pre>' + globals.preList[num] + '</pre>';
4965 });
4966
4967 showdown.subParser('makeMarkdown.strikethrough', function (node, globals) {
4968 'use strict';
4969
4970 var txt = '';
4971 if (node.hasChildNodes()) {
4972 txt += '~~';
4973 var children = node.childNodes,
4974 childrenLength = children.length;
4975 for (var i = 0; i < childrenLength; ++i) {
4976 txt += showdown.subParser('makeMarkdown.node')(children[i], globals);
4977 }
4978 txt += '~~';
4979 }
4980 return txt;
4981 });
4982
4983 showdown.subParser('makeMarkdown.strong', function (node, globals) {
4984 'use strict';
4985
4986 var txt = '';
4987 if (node.hasChildNodes()) {
4988 txt += '**';
4989 var children = node.childNodes,
4990 childrenLength = children.length;
4991 for (var i = 0; i < childrenLength; ++i) {
4992 txt += showdown.subParser('makeMarkdown.node')(children[i], globals);
4993 }
4994 txt += '**';
4995 }
4996 return txt;
4997 });
4998
4999 showdown.subParser('makeMarkdown.table', function (node, globals) {
5000 'use strict';
5001
5002 var txt = '',
5003 tableArray = [[], []],
5004 headings = node.querySelectorAll('thead>tr>th'),
5005 rows = node.querySelectorAll('tbody>tr'),
5006 i, ii;
5007 for (i = 0; i < headings.length; ++i) {
5008 var headContent = showdown.subParser('makeMarkdown.tableCell')(headings[i], globals),
5009 allign = '---';
5010
5011 if (headings[i].hasAttribute('style')) {
5012 var style = headings[i].getAttribute('style').toLowerCase().replace(/\s/g, '');
5013 switch (style) {
5014 case 'text-align:left;':
5015 allign = ':---';
5016 break;
5017 case 'text-align:right;':
5018 allign = '---:';
5019 break;
5020 case 'text-align:center;':
5021 allign = ':---:';
5022 break;
5023 }
5024 }
5025 tableArray[0][i] = headContent.trim();
5026 tableArray[1][i] = allign;
5027 }
5028
5029 for (i = 0; i < rows.length; ++i) {
5030 var r = tableArray.push([]) - 1,
5031 cols = rows[i].getElementsByTagName('td');
5032
5033 for (ii = 0; ii < headings.length; ++ii) {
5034 var cellContent = ' ';
5035 if (typeof cols[ii] !== 'undefined') {
5036 cellContent = showdown.subParser('makeMarkdown.tableCell')(cols[ii], globals);
5037 }
5038 tableArray[r].push(cellContent);
5039 }
5040 }
5041
5042 var cellSpacesCount = 3;
5043 for (i = 0; i < tableArray.length; ++i) {
5044 for (ii = 0; ii < tableArray[i].length; ++ii) {
5045 var strLen = tableArray[i][ii].length;
5046 if (strLen > cellSpacesCount) {
5047 cellSpacesCount = strLen;
5048 }
5049 }
5050 }
5051
5052 for (i = 0; i < tableArray.length; ++i) {
5053 for (ii = 0; ii < tableArray[i].length; ++ii) {
5054 if (i === 1) {
5055 if (tableArray[i][ii].slice(-1) === ':') {
5056 tableArray[i][ii] = showdown.helper.padEnd(tableArray[i][ii].slice(-1), cellSpacesCount - 1, '-') + ':';
5057 } else {
5058 tableArray[i][ii] = showdown.helper.padEnd(tableArray[i][ii], cellSpacesCount, '-');
5059 }
5060 } else {
5061 tableArray[i][ii] = showdown.helper.padEnd(tableArray[i][ii], cellSpacesCount);
5062 }
5063 }
5064 txt += '| ' + tableArray[i].join(' | ') + ' |\n';
5065 }
5066
5067 return txt.trim();
5068 });
5069
5070 showdown.subParser('makeMarkdown.tableCell', function (node, globals) {
5071 'use strict';
5072
5073 var txt = '';
5074 if (!node.hasChildNodes()) {
5075 return '';
5076 }
5077 var children = node.childNodes,
5078 childrenLength = children.length;
5079
5080 for (var i = 0; i < childrenLength; ++i) {
5081 txt += showdown.subParser('makeMarkdown.node')(children[i], globals, true);
5082 }
5083 return txt.trim();
5084 });
5085
5086 showdown.subParser('makeMarkdown.txt', function (node) {
5087 'use strict';
5088
5089 var txt = node.nodeValue;
5090
5091 // multiple spaces are collapsed
5092 txt = txt.replace(/ +/g, ' ');
5093
5094 // replace the custom ¨NBSP; with a space
5095 txt = txt.replace(/¨NBSP;/g, ' ');
5096
5097 // ", <, > and & should replace escaped html entities
5098 txt = showdown.helper.unescapeHTMLEntities(txt);
5099
5100 // escape markdown magic characters
5101 // emphasis, strong and strikethrough - can appear everywhere
5102 // we also escape pipe (|) because of tables
5103 // and escape ` because of code blocks and spans
5104 txt = txt.replace(/([*_~|`])/g, '\\$1');
5105
5106 // escape > because of blockquotes
5107 txt = txt.replace(/^(\s*)>/g, '\\$1>');
5108
5109 // hash character, only troublesome at the beginning of a line because of headers
5110 txt = txt.replace(/^#/gm, '\\#');
5111
5112 // horizontal rules
5113 txt = txt.replace(/^(\s*)([-=]{3,})(\s*)$/, '$1\\$2$3');
5114
5115 // dot, because of ordered lists, only troublesome at the beginning of a line when preceded by an integer
5116 txt = txt.replace(/^( {0,3}\d+)\./gm, '$1\\.');
5117
5118 // +, * and -, at the beginning of a line becomes a list, so we need to escape them also (asterisk was already escaped)
5119 txt = txt.replace(/^( {0,3})([+-])/gm, '$1\\$2');
5120
5121 // images and links, ] followed by ( is problematic, so we escape it
5122 txt = txt.replace(/]([\s]*)\(/g, '\\]$1\\(');
5123
5124 // reference URIs must also be escaped
5125 txt = txt.replace(/^ {0,3}\[([\S \t]*?)]:/gm, '\\[$1]:');
5126
5127 return txt;
5128 });
5129
5130 var root = this;
5131
5132 // AMD Loader
5133 if (true) {
5134 !(__WEBPACK_AMD_DEFINE_RESULT__ = (function () {
5135 'use strict';
5136 return showdown;
5137 }).call(exports, __webpack_require__, exports, module),
5138 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
5139
5140 // CommonJS/nodeJS Loader
5141 } else {}
5142 }).call(this);
5143
5144 //# sourceMappingURL=showdown.js.map
5145
5146
5147 /***/ }),
5148
5149 /***/ 7621:
5150 /***/ (function(module, exports, __webpack_require__) {
5151
5152 var __WEBPACK_AMD_DEFINE_RESULT__;// TinyColor v1.4.2
5153 // https://github.com/bgrins/TinyColor
5154 // Brian Grinstead, MIT License
5155
5156 (function(Math) {
5157
5158 var trimLeft = /^\s+/,
5159 trimRight = /\s+$/,
5160 tinyCounter = 0,
5161 mathRound = Math.round,
5162 mathMin = Math.min,
5163 mathMax = Math.max,
5164 mathRandom = Math.random;
5165
5166 function tinycolor (color, opts) {
5167
5168 color = (color) ? color : '';
5169 opts = opts || { };
5170
5171 // If input is already a tinycolor, return itself
5172 if (color instanceof tinycolor) {
5173 return color;
5174 }
5175 // If we are called as a function, call using new instead
5176 if (!(this instanceof tinycolor)) {
5177 return new tinycolor(color, opts);
5178 }
5179
5180 var rgb = inputToRGB(color);
5181 this._originalInput = color,
5182 this._r = rgb.r,
5183 this._g = rgb.g,
5184 this._b = rgb.b,
5185 this._a = rgb.a,
5186 this._roundA = mathRound(100*this._a) / 100,
5187 this._format = opts.format || rgb.format;
5188 this._gradientType = opts.gradientType;
5189
5190 // Don't let the range of [0,255] come back in [0,1].
5191 // Potentially lose a little bit of precision here, but will fix issues where
5192 // .5 gets interpreted as half of the total, instead of half of 1
5193 // If it was supposed to be 128, this was already taken care of by `inputToRgb`
5194 if (this._r < 1) { this._r = mathRound(this._r); }
5195 if (this._g < 1) { this._g = mathRound(this._g); }
5196 if (this._b < 1) { this._b = mathRound(this._b); }
5197
5198 this._ok = rgb.ok;
5199 this._tc_id = tinyCounter++;
5200 }
5201
5202 tinycolor.prototype = {
5203 isDark: function() {
5204 return this.getBrightness() < 128;
5205 },
5206 isLight: function() {
5207 return !this.isDark();
5208 },
5209 isValid: function() {
5210 return this._ok;
5211 },
5212 getOriginalInput: function() {
5213 return this._originalInput;
5214 },
5215 getFormat: function() {
5216 return this._format;
5217 },
5218 getAlpha: function() {
5219 return this._a;
5220 },
5221 getBrightness: function() {
5222 //http://www.w3.org/TR/AERT#color-contrast
5223 var rgb = this.toRgb();
5224 return (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000;
5225 },
5226 getLuminance: function() {
5227 //http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
5228 var rgb = this.toRgb();
5229 var RsRGB, GsRGB, BsRGB, R, G, B;
5230 RsRGB = rgb.r/255;
5231 GsRGB = rgb.g/255;
5232 BsRGB = rgb.b/255;
5233
5234 if (RsRGB <= 0.03928) {R = RsRGB / 12.92;} else {R = Math.pow(((RsRGB + 0.055) / 1.055), 2.4);}
5235 if (GsRGB <= 0.03928) {G = GsRGB / 12.92;} else {G = Math.pow(((GsRGB + 0.055) / 1.055), 2.4);}
5236 if (BsRGB <= 0.03928) {B = BsRGB / 12.92;} else {B = Math.pow(((BsRGB + 0.055) / 1.055), 2.4);}
5237 return (0.2126 * R) + (0.7152 * G) + (0.0722 * B);
5238 },
5239 setAlpha: function(value) {
5240 this._a = boundAlpha(value);
5241 this._roundA = mathRound(100*this._a) / 100;
5242 return this;
5243 },
5244 toHsv: function() {
5245 var hsv = rgbToHsv(this._r, this._g, this._b);
5246 return { h: hsv.h * 360, s: hsv.s, v: hsv.v, a: this._a };
5247 },
5248 toHsvString: function() {
5249 var hsv = rgbToHsv(this._r, this._g, this._b);
5250 var h = mathRound(hsv.h * 360), s = mathRound(hsv.s * 100), v = mathRound(hsv.v * 100);
5251 return (this._a == 1) ?
5252 "hsv(" + h + ", " + s + "%, " + v + "%)" :
5253 "hsva(" + h + ", " + s + "%, " + v + "%, "+ this._roundA + ")";
5254 },
5255 toHsl: function() {
5256 var hsl = rgbToHsl(this._r, this._g, this._b);
5257 return { h: hsl.h * 360, s: hsl.s, l: hsl.l, a: this._a };
5258 },
5259 toHslString: function() {
5260 var hsl = rgbToHsl(this._r, this._g, this._b);
5261 var h = mathRound(hsl.h * 360), s = mathRound(hsl.s * 100), l = mathRound(hsl.l * 100);
5262 return (this._a == 1) ?
5263 "hsl(" + h + ", " + s + "%, " + l + "%)" :
5264 "hsla(" + h + ", " + s + "%, " + l + "%, "+ this._roundA + ")";
5265 },
5266 toHex: function(allow3Char) {
5267 return rgbToHex(this._r, this._g, this._b, allow3Char);
5268 },
5269 toHexString: function(allow3Char) {
5270 return '#' + this.toHex(allow3Char);
5271 },
5272 toHex8: function(allow4Char) {
5273 return rgbaToHex(this._r, this._g, this._b, this._a, allow4Char);
5274 },
5275 toHex8String: function(allow4Char) {
5276 return '#' + this.toHex8(allow4Char);
5277 },
5278 toRgb: function() {
5279 return { r: mathRound(this._r), g: mathRound(this._g), b: mathRound(this._b), a: this._a };
5280 },
5281 toRgbString: function() {
5282 return (this._a == 1) ?
5283 "rgb(" + mathRound(this._r) + ", " + mathRound(this._g) + ", " + mathRound(this._b) + ")" :
5284 "rgba(" + mathRound(this._r) + ", " + mathRound(this._g) + ", " + mathRound(this._b) + ", " + this._roundA + ")";
5285 },
5286 toPercentageRgb: function() {
5287 return { r: mathRound(bound01(this._r, 255) * 100) + "%", g: mathRound(bound01(this._g, 255) * 100) + "%", b: mathRound(bound01(this._b, 255) * 100) + "%", a: this._a };
5288 },
5289 toPercentageRgbString: function() {
5290 return (this._a == 1) ?
5291 "rgb(" + mathRound(bound01(this._r, 255) * 100) + "%, " + mathRound(bound01(this._g, 255) * 100) + "%, " + mathRound(bound01(this._b, 255) * 100) + "%)" :
5292 "rgba(" + mathRound(bound01(this._r, 255) * 100) + "%, " + mathRound(bound01(this._g, 255) * 100) + "%, " + mathRound(bound01(this._b, 255) * 100) + "%, " + this._roundA + ")";
5293 },
5294 toName: function() {
5295 if (this._a === 0) {
5296 return "transparent";
5297 }
5298
5299 if (this._a < 1) {
5300 return false;
5301 }
5302
5303 return hexNames[rgbToHex(this._r, this._g, this._b, true)] || false;
5304 },
5305 toFilter: function(secondColor) {
5306 var hex8String = '#' + rgbaToArgbHex(this._r, this._g, this._b, this._a);
5307 var secondHex8String = hex8String;
5308 var gradientType = this._gradientType ? "GradientType = 1, " : "";
5309
5310 if (secondColor) {
5311 var s = tinycolor(secondColor);
5312 secondHex8String = '#' + rgbaToArgbHex(s._r, s._g, s._b, s._a);
5313 }
5314
5315 return "progid:DXImageTransform.Microsoft.gradient("+gradientType+"startColorstr="+hex8String+",endColorstr="+secondHex8String+")";
5316 },
5317 toString: function(format) {
5318 var formatSet = !!format;
5319 format = format || this._format;
5320
5321 var formattedString = false;
5322 var hasAlpha = this._a < 1 && this._a >= 0;
5323 var needsAlphaFormat = !formatSet && hasAlpha && (format === "hex" || format === "hex6" || format === "hex3" || format === "hex4" || format === "hex8" || format === "name");
5324
5325 if (needsAlphaFormat) {
5326 // Special case for "transparent", all other non-alpha formats
5327 // will return rgba when there is transparency.
5328 if (format === "name" && this._a === 0) {
5329 return this.toName();
5330 }
5331 return this.toRgbString();
5332 }
5333 if (format === "rgb") {
5334 formattedString = this.toRgbString();
5335 }
5336 if (format === "prgb") {
5337 formattedString = this.toPercentageRgbString();
5338 }
5339 if (format === "hex" || format === "hex6") {
5340 formattedString = this.toHexString();
5341 }
5342 if (format === "hex3") {
5343 formattedString = this.toHexString(true);
5344 }
5345 if (format === "hex4") {
5346 formattedString = this.toHex8String(true);
5347 }
5348 if (format === "hex8") {
5349 formattedString = this.toHex8String();
5350 }
5351 if (format === "name") {
5352 formattedString = this.toName();
5353 }
5354 if (format === "hsl") {
5355 formattedString = this.toHslString();
5356 }
5357 if (format === "hsv") {
5358 formattedString = this.toHsvString();
5359 }
5360
5361 return formattedString || this.toHexString();
5362 },
5363 clone: function() {
5364 return tinycolor(this.toString());
5365 },
5366
5367 _applyModification: function(fn, args) {
5368 var color = fn.apply(null, [this].concat([].slice.call(args)));
5369 this._r = color._r;
5370 this._g = color._g;
5371 this._b = color._b;
5372 this.setAlpha(color._a);
5373 return this;
5374 },
5375 lighten: function() {
5376 return this._applyModification(lighten, arguments);
5377 },
5378 brighten: function() {
5379 return this._applyModification(brighten, arguments);
5380 },
5381 darken: function() {
5382 return this._applyModification(darken, arguments);
5383 },
5384 desaturate: function() {
5385 return this._applyModification(desaturate, arguments);
5386 },
5387 saturate: function() {
5388 return this._applyModification(saturate, arguments);
5389 },
5390 greyscale: function() {
5391 return this._applyModification(greyscale, arguments);
5392 },
5393 spin: function() {
5394 return this._applyModification(spin, arguments);
5395 },
5396
5397 _applyCombination: function(fn, args) {
5398 return fn.apply(null, [this].concat([].slice.call(args)));
5399 },
5400 analogous: function() {
5401 return this._applyCombination(analogous, arguments);
5402 },
5403 complement: function() {
5404 return this._applyCombination(complement, arguments);
5405 },
5406 monochromatic: function() {
5407 return this._applyCombination(monochromatic, arguments);
5408 },
5409 splitcomplement: function() {
5410 return this._applyCombination(splitcomplement, arguments);
5411 },
5412 triad: function() {
5413 return this._applyCombination(triad, arguments);
5414 },
5415 tetrad: function() {
5416 return this._applyCombination(tetrad, arguments);
5417 }
5418 };
5419
5420 // If input is an object, force 1 into "1.0" to handle ratios properly
5421 // String input requires "1.0" as input, so 1 will be treated as 1
5422 tinycolor.fromRatio = function(color, opts) {
5423 if (typeof color == "object") {
5424 var newColor = {};
5425 for (var i in color) {
5426 if (color.hasOwnProperty(i)) {
5427 if (i === "a") {
5428 newColor[i] = color[i];
5429 }
5430 else {
5431 newColor[i] = convertToPercentage(color[i]);
5432 }
5433 }
5434 }
5435 color = newColor;
5436 }
5437
5438 return tinycolor(color, opts);
5439 };
5440
5441 // Given a string or object, convert that input to RGB
5442 // Possible string inputs:
5443 //
5444 // "red"
5445 // "#f00" or "f00"
5446 // "#ff0000" or "ff0000"
5447 // "#ff000000" or "ff000000"
5448 // "rgb 255 0 0" or "rgb (255, 0, 0)"
5449 // "rgb 1.0 0 0" or "rgb (1, 0, 0)"
5450 // "rgba (255, 0, 0, 1)" or "rgba 255, 0, 0, 1"
5451 // "rgba (1.0, 0, 0, 1)" or "rgba 1.0, 0, 0, 1"
5452 // "hsl(0, 100%, 50%)" or "hsl 0 100% 50%"
5453 // "hsla(0, 100%, 50%, 1)" or "hsla 0 100% 50%, 1"
5454 // "hsv(0, 100%, 100%)" or "hsv 0 100% 100%"
5455 //
5456 function inputToRGB(color) {
5457
5458 var rgb = { r: 0, g: 0, b: 0 };
5459 var a = 1;
5460 var s = null;
5461 var v = null;
5462 var l = null;
5463 var ok = false;
5464 var format = false;
5465
5466 if (typeof color == "string") {
5467 color = stringInputToObject(color);
5468 }
5469
5470 if (typeof color == "object") {
5471 if (isValidCSSUnit(color.r) && isValidCSSUnit(color.g) && isValidCSSUnit(color.b)) {
5472 rgb = rgbToRgb(color.r, color.g, color.b);
5473 ok = true;
5474 format = String(color.r).substr(-1) === "%" ? "prgb" : "rgb";
5475 }
5476 else if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.v)) {
5477 s = convertToPercentage(color.s);
5478 v = convertToPercentage(color.v);
5479 rgb = hsvToRgb(color.h, s, v);
5480 ok = true;
5481 format = "hsv";
5482 }
5483 else if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.l)) {
5484 s = convertToPercentage(color.s);
5485 l = convertToPercentage(color.l);
5486 rgb = hslToRgb(color.h, s, l);
5487 ok = true;
5488 format = "hsl";
5489 }
5490
5491 if (color.hasOwnProperty("a")) {
5492 a = color.a;
5493 }
5494 }
5495
5496 a = boundAlpha(a);
5497
5498 return {
5499 ok: ok,
5500 format: color.format || format,
5501 r: mathMin(255, mathMax(rgb.r, 0)),
5502 g: mathMin(255, mathMax(rgb.g, 0)),
5503 b: mathMin(255, mathMax(rgb.b, 0)),
5504 a: a
5505 };
5506 }
5507
5508
5509 // Conversion Functions
5510 // --------------------
5511
5512 // `rgbToHsl`, `rgbToHsv`, `hslToRgb`, `hsvToRgb` modified from:
5513 // <http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript>
5514
5515 // `rgbToRgb`
5516 // Handle bounds / percentage checking to conform to CSS color spec
5517 // <http://www.w3.org/TR/css3-color/>
5518 // *Assumes:* r, g, b in [0, 255] or [0, 1]
5519 // *Returns:* { r, g, b } in [0, 255]
5520 function rgbToRgb(r, g, b){
5521 return {
5522 r: bound01(r, 255) * 255,
5523 g: bound01(g, 255) * 255,
5524 b: bound01(b, 255) * 255
5525 };
5526 }
5527
5528 // `rgbToHsl`
5529 // Converts an RGB color value to HSL.
5530 // *Assumes:* r, g, and b are contained in [0, 255] or [0, 1]
5531 // *Returns:* { h, s, l } in [0,1]
5532 function rgbToHsl(r, g, b) {
5533
5534 r = bound01(r, 255);
5535 g = bound01(g, 255);
5536 b = bound01(b, 255);
5537
5538 var max = mathMax(r, g, b), min = mathMin(r, g, b);
5539 var h, s, l = (max + min) / 2;
5540
5541 if(max == min) {
5542 h = s = 0; // achromatic
5543 }
5544 else {
5545 var d = max - min;
5546 s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
5547 switch(max) {
5548 case r: h = (g - b) / d + (g < b ? 6 : 0); break;
5549 case g: h = (b - r) / d + 2; break;
5550 case b: h = (r - g) / d + 4; break;
5551 }
5552
5553 h /= 6;
5554 }
5555
5556 return { h: h, s: s, l: l };
5557 }
5558
5559 // `hslToRgb`
5560 // Converts an HSL color value to RGB.
5561 // *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100]
5562 // *Returns:* { r, g, b } in the set [0, 255]
5563 function hslToRgb(h, s, l) {
5564 var r, g, b;
5565
5566 h = bound01(h, 360);
5567 s = bound01(s, 100);
5568 l = bound01(l, 100);
5569
5570 function hue2rgb(p, q, t) {
5571 if(t < 0) t += 1;
5572 if(t > 1) t -= 1;
5573 if(t < 1/6) return p + (q - p) * 6 * t;
5574 if(t < 1/2) return q;
5575 if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
5576 return p;
5577 }
5578
5579 if(s === 0) {
5580 r = g = b = l; // achromatic
5581 }
5582 else {
5583 var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
5584 var p = 2 * l - q;
5585 r = hue2rgb(p, q, h + 1/3);
5586 g = hue2rgb(p, q, h);
5587 b = hue2rgb(p, q, h - 1/3);
5588 }
5589
5590 return { r: r * 255, g: g * 255, b: b * 255 };
5591 }
5592
5593 // `rgbToHsv`
5594 // Converts an RGB color value to HSV
5595 // *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1]
5596 // *Returns:* { h, s, v } in [0,1]
5597 function rgbToHsv(r, g, b) {
5598
5599 r = bound01(r, 255);
5600 g = bound01(g, 255);
5601 b = bound01(b, 255);
5602
5603 var max = mathMax(r, g, b), min = mathMin(r, g, b);
5604 var h, s, v = max;
5605
5606 var d = max - min;
5607 s = max === 0 ? 0 : d / max;
5608
5609 if(max == min) {
5610 h = 0; // achromatic
5611 }
5612 else {
5613 switch(max) {
5614 case r: h = (g - b) / d + (g < b ? 6 : 0); break;
5615 case g: h = (b - r) / d + 2; break;
5616 case b: h = (r - g) / d + 4; break;
5617 }
5618 h /= 6;
5619 }
5620 return { h: h, s: s, v: v };
5621 }
5622
5623 // `hsvToRgb`
5624 // Converts an HSV color value to RGB.
5625 // *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100]
5626 // *Returns:* { r, g, b } in the set [0, 255]
5627 function hsvToRgb(h, s, v) {
5628
5629 h = bound01(h, 360) * 6;
5630 s = bound01(s, 100);
5631 v = bound01(v, 100);
5632
5633 var i = Math.floor(h),
5634 f = h - i,
5635 p = v * (1 - s),
5636 q = v * (1 - f * s),
5637 t = v * (1 - (1 - f) * s),
5638 mod = i % 6,
5639 r = [v, q, p, p, t, v][mod],
5640 g = [t, v, v, q, p, p][mod],
5641 b = [p, p, t, v, v, q][mod];
5642
5643 return { r: r * 255, g: g * 255, b: b * 255 };
5644 }
5645
5646 // `rgbToHex`
5647 // Converts an RGB color to hex
5648 // Assumes r, g, and b are contained in the set [0, 255]
5649 // Returns a 3 or 6 character hex
5650 function rgbToHex(r, g, b, allow3Char) {
5651
5652 var hex = [
5653 pad2(mathRound(r).toString(16)),
5654 pad2(mathRound(g).toString(16)),
5655 pad2(mathRound(b).toString(16))
5656 ];
5657
5658 // Return a 3 character hex if possible
5659 if (allow3Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) {
5660 return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0);
5661 }
5662
5663 return hex.join("");
5664 }
5665
5666 // `rgbaToHex`
5667 // Converts an RGBA color plus alpha transparency to hex
5668 // Assumes r, g, b are contained in the set [0, 255] and
5669 // a in [0, 1]. Returns a 4 or 8 character rgba hex
5670 function rgbaToHex(r, g, b, a, allow4Char) {
5671
5672 var hex = [
5673 pad2(mathRound(r).toString(16)),
5674 pad2(mathRound(g).toString(16)),
5675 pad2(mathRound(b).toString(16)),
5676 pad2(convertDecimalToHex(a))
5677 ];
5678
5679 // Return a 4 character hex if possible
5680 if (allow4Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1) && hex[3].charAt(0) == hex[3].charAt(1)) {
5681 return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0) + hex[3].charAt(0);
5682 }
5683
5684 return hex.join("");
5685 }
5686
5687 // `rgbaToArgbHex`
5688 // Converts an RGBA color to an ARGB Hex8 string
5689 // Rarely used, but required for "toFilter()"
5690 function rgbaToArgbHex(r, g, b, a) {
5691
5692 var hex = [
5693 pad2(convertDecimalToHex(a)),
5694 pad2(mathRound(r).toString(16)),
5695 pad2(mathRound(g).toString(16)),
5696 pad2(mathRound(b).toString(16))
5697 ];
5698
5699 return hex.join("");
5700 }
5701
5702 // `equals`
5703 // Can be called with any tinycolor input
5704 tinycolor.equals = function (color1, color2) {
5705 if (!color1 || !color2) { return false; }
5706 return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString();
5707 };
5708
5709 tinycolor.random = function() {
5710 return tinycolor.fromRatio({
5711 r: mathRandom(),
5712 g: mathRandom(),
5713 b: mathRandom()
5714 });
5715 };
5716
5717
5718 // Modification Functions
5719 // ----------------------
5720 // Thanks to less.js for some of the basics here
5721 // <https://github.com/cloudhead/less.js/blob/master/lib/less/functions.js>
5722
5723 function desaturate(color, amount) {
5724 amount = (amount === 0) ? 0 : (amount || 10);
5725 var hsl = tinycolor(color).toHsl();
5726 hsl.s -= amount / 100;
5727 hsl.s = clamp01(hsl.s);
5728 return tinycolor(hsl);
5729 }
5730
5731 function saturate(color, amount) {
5732 amount = (amount === 0) ? 0 : (amount || 10);
5733 var hsl = tinycolor(color).toHsl();
5734 hsl.s += amount / 100;
5735 hsl.s = clamp01(hsl.s);
5736 return tinycolor(hsl);
5737 }
5738
5739 function greyscale(color) {
5740 return tinycolor(color).desaturate(100);
5741 }
5742
5743 function lighten (color, amount) {
5744 amount = (amount === 0) ? 0 : (amount || 10);
5745 var hsl = tinycolor(color).toHsl();
5746 hsl.l += amount / 100;
5747 hsl.l = clamp01(hsl.l);
5748 return tinycolor(hsl);
5749 }
5750
5751 function brighten(color, amount) {
5752 amount = (amount === 0) ? 0 : (amount || 10);
5753 var rgb = tinycolor(color).toRgb();
5754 rgb.r = mathMax(0, mathMin(255, rgb.r - mathRound(255 * - (amount / 100))));
5755 rgb.g = mathMax(0, mathMin(255, rgb.g - mathRound(255 * - (amount / 100))));
5756 rgb.b = mathMax(0, mathMin(255, rgb.b - mathRound(255 * - (amount / 100))));
5757 return tinycolor(rgb);
5758 }
5759
5760 function darken (color, amount) {
5761 amount = (amount === 0) ? 0 : (amount || 10);
5762 var hsl = tinycolor(color).toHsl();
5763 hsl.l -= amount / 100;
5764 hsl.l = clamp01(hsl.l);
5765 return tinycolor(hsl);
5766 }
5767
5768 // Spin takes a positive or negative amount within [-360, 360] indicating the change of hue.
5769 // Values outside of this range will be wrapped into this range.
5770 function spin(color, amount) {
5771 var hsl = tinycolor(color).toHsl();
5772 var hue = (hsl.h + amount) % 360;
5773 hsl.h = hue < 0 ? 360 + hue : hue;
5774 return tinycolor(hsl);
5775 }
5776
5777 // Combination Functions
5778 // ---------------------
5779 // Thanks to jQuery xColor for some of the ideas behind these
5780 // <https://github.com/infusion/jQuery-xcolor/blob/master/jquery.xcolor.js>
5781
5782 function complement(color) {
5783 var hsl = tinycolor(color).toHsl();
5784 hsl.h = (hsl.h + 180) % 360;
5785 return tinycolor(hsl);
5786 }
5787
5788 function triad(color) {
5789 var hsl = tinycolor(color).toHsl();
5790 var h = hsl.h;
5791 return [
5792 tinycolor(color),
5793 tinycolor({ h: (h + 120) % 360, s: hsl.s, l: hsl.l }),
5794 tinycolor({ h: (h + 240) % 360, s: hsl.s, l: hsl.l })
5795 ];
5796 }
5797
5798 function tetrad(color) {
5799 var hsl = tinycolor(color).toHsl();
5800 var h = hsl.h;
5801 return [
5802 tinycolor(color),
5803 tinycolor({ h: (h + 90) % 360, s: hsl.s, l: hsl.l }),
5804 tinycolor({ h: (h + 180) % 360, s: hsl.s, l: hsl.l }),
5805 tinycolor({ h: (h + 270) % 360, s: hsl.s, l: hsl.l })
5806 ];
5807 }
5808
5809 function splitcomplement(color) {
5810 var hsl = tinycolor(color).toHsl();
5811 var h = hsl.h;
5812 return [
5813 tinycolor(color),
5814 tinycolor({ h: (h + 72) % 360, s: hsl.s, l: hsl.l}),
5815 tinycolor({ h: (h + 216) % 360, s: hsl.s, l: hsl.l})
5816 ];
5817 }
5818
5819 function analogous(color, results, slices) {
5820 results = results || 6;
5821 slices = slices || 30;
5822
5823 var hsl = tinycolor(color).toHsl();
5824 var part = 360 / slices;
5825 var ret = [tinycolor(color)];
5826
5827 for (hsl.h = ((hsl.h - (part * results >> 1)) + 720) % 360; --results; ) {
5828 hsl.h = (hsl.h + part) % 360;
5829 ret.push(tinycolor(hsl));
5830 }
5831 return ret;
5832 }
5833
5834 function monochromatic(color, results) {
5835 results = results || 6;
5836 var hsv = tinycolor(color).toHsv();
5837 var h = hsv.h, s = hsv.s, v = hsv.v;
5838 var ret = [];
5839 var modification = 1 / results;
5840
5841 while (results--) {
5842 ret.push(tinycolor({ h: h, s: s, v: v}));
5843 v = (v + modification) % 1;
5844 }
5845
5846 return ret;
5847 }
5848
5849 // Utility Functions
5850 // ---------------------
5851
5852 tinycolor.mix = function(color1, color2, amount) {
5853 amount = (amount === 0) ? 0 : (amount || 50);
5854
5855 var rgb1 = tinycolor(color1).toRgb();
5856 var rgb2 = tinycolor(color2).toRgb();
5857
5858 var p = amount / 100;
5859
5860 var rgba = {
5861 r: ((rgb2.r - rgb1.r) * p) + rgb1.r,
5862 g: ((rgb2.g - rgb1.g) * p) + rgb1.g,
5863 b: ((rgb2.b - rgb1.b) * p) + rgb1.b,
5864 a: ((rgb2.a - rgb1.a) * p) + rgb1.a
5865 };
5866
5867 return tinycolor(rgba);
5868 };
5869
5870
5871 // Readability Functions
5872 // ---------------------
5873 // <http://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef (WCAG Version 2)
5874
5875 // `contrast`
5876 // Analyze the 2 colors and returns the color contrast defined by (WCAG Version 2)
5877 tinycolor.readability = function(color1, color2) {
5878 var c1 = tinycolor(color1);
5879 var c2 = tinycolor(color2);
5880 return (Math.max(c1.getLuminance(),c2.getLuminance())+0.05) / (Math.min(c1.getLuminance(),c2.getLuminance())+0.05);
5881 };
5882
5883 // `isReadable`
5884 // Ensure that foreground and background color combinations meet WCAG2 guidelines.
5885 // The third argument is an optional Object.
5886 // the 'level' property states 'AA' or 'AAA' - if missing or invalid, it defaults to 'AA';
5887 // the 'size' property states 'large' or 'small' - if missing or invalid, it defaults to 'small'.
5888 // If the entire object is absent, isReadable defaults to {level:"AA",size:"small"}.
5889
5890 // *Example*
5891 // tinycolor.isReadable("#000", "#111") => false
5892 // tinycolor.isReadable("#000", "#111",{level:"AA",size:"large"}) => false
5893 tinycolor.isReadable = function(color1, color2, wcag2) {
5894 var readability = tinycolor.readability(color1, color2);
5895 var wcag2Parms, out;
5896
5897 out = false;
5898
5899 wcag2Parms = validateWCAG2Parms(wcag2);
5900 switch (wcag2Parms.level + wcag2Parms.size) {
5901 case "AAsmall":
5902 case "AAAlarge":
5903 out = readability >= 4.5;
5904 break;
5905 case "AAlarge":
5906 out = readability >= 3;
5907 break;
5908 case "AAAsmall":
5909 out = readability >= 7;
5910 break;
5911 }
5912 return out;
5913
5914 };
5915
5916 // `mostReadable`
5917 // Given a base color and a list of possible foreground or background
5918 // colors for that base, returns the most readable color.
5919 // Optionally returns Black or White if the most readable color is unreadable.
5920 // *Example*
5921 // tinycolor.mostReadable(tinycolor.mostReadable("#123", ["#124", "#125"],{includeFallbackColors:false}).toHexString(); // "#112255"
5922 // tinycolor.mostReadable(tinycolor.mostReadable("#123", ["#124", "#125"],{includeFallbackColors:true}).toHexString(); // "#ffffff"
5923 // tinycolor.mostReadable("#a8015a", ["#faf3f3"],{includeFallbackColors:true,level:"AAA",size:"large"}).toHexString(); // "#faf3f3"
5924 // tinycolor.mostReadable("#a8015a", ["#faf3f3"],{includeFallbackColors:true,level:"AAA",size:"small"}).toHexString(); // "#ffffff"
5925 tinycolor.mostReadable = function(baseColor, colorList, args) {
5926 var bestColor = null;
5927 var bestScore = 0;
5928 var readability;
5929 var includeFallbackColors, level, size ;
5930 args = args || {};
5931 includeFallbackColors = args.includeFallbackColors ;
5932 level = args.level;
5933 size = args.size;
5934
5935 for (var i= 0; i < colorList.length ; i++) {
5936 readability = tinycolor.readability(baseColor, colorList[i]);
5937 if (readability > bestScore) {
5938 bestScore = readability;
5939 bestColor = tinycolor(colorList[i]);
5940 }
5941 }
5942
5943 if (tinycolor.isReadable(baseColor, bestColor, {"level":level,"size":size}) || !includeFallbackColors) {
5944 return bestColor;
5945 }
5946 else {
5947 args.includeFallbackColors=false;
5948 return tinycolor.mostReadable(baseColor,["#fff", "#000"],args);
5949 }
5950 };
5951
5952
5953 // Big List of Colors
5954 // ------------------
5955 // <http://www.w3.org/TR/css3-color/#svg-color>
5956 var names = tinycolor.names = {
5957 aliceblue: "f0f8ff",
5958 antiquewhite: "faebd7",
5959 aqua: "0ff",
5960 aquamarine: "7fffd4",
5961 azure: "f0ffff",
5962 beige: "f5f5dc",
5963 bisque: "ffe4c4",
5964 black: "000",
5965 blanchedalmond: "ffebcd",
5966 blue: "00f",
5967 blueviolet: "8a2be2",
5968 brown: "a52a2a",
5969 burlywood: "deb887",
5970 burntsienna: "ea7e5d",
5971 cadetblue: "5f9ea0",
5972 chartreuse: "7fff00",
5973 chocolate: "d2691e",
5974 coral: "ff7f50",
5975 cornflowerblue: "6495ed",
5976 cornsilk: "fff8dc",
5977 crimson: "dc143c",
5978 cyan: "0ff",
5979 darkblue: "00008b",
5980 darkcyan: "008b8b",
5981 darkgoldenrod: "b8860b",
5982 darkgray: "a9a9a9",
5983 darkgreen: "006400",
5984 darkgrey: "a9a9a9",
5985 darkkhaki: "bdb76b",
5986 darkmagenta: "8b008b",
5987 darkolivegreen: "556b2f",
5988 darkorange: "ff8c00",
5989 darkorchid: "9932cc",
5990 darkred: "8b0000",
5991 darksalmon: "e9967a",
5992 darkseagreen: "8fbc8f",
5993 darkslateblue: "483d8b",
5994 darkslategray: "2f4f4f",
5995 darkslategrey: "2f4f4f",
5996 darkturquoise: "00ced1",
5997 darkviolet: "9400d3",
5998 deeppink: "ff1493",
5999 deepskyblue: "00bfff",
6000 dimgray: "696969",
6001 dimgrey: "696969",
6002 dodgerblue: "1e90ff",
6003 firebrick: "b22222",
6004 floralwhite: "fffaf0",
6005 forestgreen: "228b22",
6006 fuchsia: "f0f",
6007 gainsboro: "dcdcdc",
6008 ghostwhite: "f8f8ff",
6009 gold: "ffd700",
6010 goldenrod: "daa520",
6011 gray: "808080",
6012 green: "008000",
6013 greenyellow: "adff2f",
6014 grey: "808080",
6015 honeydew: "f0fff0",
6016 hotpink: "ff69b4",
6017 indianred: "cd5c5c",
6018 indigo: "4b0082",
6019 ivory: "fffff0",
6020 khaki: "f0e68c",
6021 lavender: "e6e6fa",
6022 lavenderblush: "fff0f5",
6023 lawngreen: "7cfc00",
6024 lemonchiffon: "fffacd",
6025 lightblue: "add8e6",
6026 lightcoral: "f08080",
6027 lightcyan: "e0ffff",
6028 lightgoldenrodyellow: "fafad2",
6029 lightgray: "d3d3d3",
6030 lightgreen: "90ee90",
6031 lightgrey: "d3d3d3",
6032 lightpink: "ffb6c1",
6033 lightsalmon: "ffa07a",
6034 lightseagreen: "20b2aa",
6035 lightskyblue: "87cefa",
6036 lightslategray: "789",
6037 lightslategrey: "789",
6038 lightsteelblue: "b0c4de",
6039 lightyellow: "ffffe0",
6040 lime: "0f0",
6041 limegreen: "32cd32",
6042 linen: "faf0e6",
6043 magenta: "f0f",
6044 maroon: "800000",
6045 mediumaquamarine: "66cdaa",
6046 mediumblue: "0000cd",
6047 mediumorchid: "ba55d3",
6048 mediumpurple: "9370db",
6049 mediumseagreen: "3cb371",
6050 mediumslateblue: "7b68ee",
6051 mediumspringgreen: "00fa9a",
6052 mediumturquoise: "48d1cc",
6053 mediumvioletred: "c71585",
6054 midnightblue: "191970",
6055 mintcream: "f5fffa",
6056 mistyrose: "ffe4e1",
6057 moccasin: "ffe4b5",
6058 navajowhite: "ffdead",
6059 navy: "000080",
6060 oldlace: "fdf5e6",
6061 olive: "808000",
6062 olivedrab: "6b8e23",
6063 orange: "ffa500",
6064 orangered: "ff4500",
6065 orchid: "da70d6",
6066 palegoldenrod: "eee8aa",
6067 palegreen: "98fb98",
6068 paleturquoise: "afeeee",
6069 palevioletred: "db7093",
6070 papayawhip: "ffefd5",
6071 peachpuff: "ffdab9",
6072 peru: "cd853f",
6073 pink: "ffc0cb",
6074 plum: "dda0dd",
6075 powderblue: "b0e0e6",
6076 purple: "800080",
6077 rebeccapurple: "663399",
6078 red: "f00",
6079 rosybrown: "bc8f8f",
6080 royalblue: "4169e1",
6081 saddlebrown: "8b4513",
6082 salmon: "fa8072",
6083 sandybrown: "f4a460",
6084 seagreen: "2e8b57",
6085 seashell: "fff5ee",
6086 sienna: "a0522d",
6087 silver: "c0c0c0",
6088 skyblue: "87ceeb",
6089 slateblue: "6a5acd",
6090 slategray: "708090",
6091 slategrey: "708090",
6092 snow: "fffafa",
6093 springgreen: "00ff7f",
6094 steelblue: "4682b4",
6095 tan: "d2b48c",
6096 teal: "008080",
6097 thistle: "d8bfd8",
6098 tomato: "ff6347",
6099 turquoise: "40e0d0",
6100 violet: "ee82ee",
6101 wheat: "f5deb3",
6102 white: "fff",
6103 whitesmoke: "f5f5f5",
6104 yellow: "ff0",
6105 yellowgreen: "9acd32"
6106 };
6107
6108 // Make it easy to access colors via `hexNames[hex]`
6109 var hexNames = tinycolor.hexNames = flip(names);
6110
6111
6112 // Utilities
6113 // ---------
6114
6115 // `{ 'name1': 'val1' }` becomes `{ 'val1': 'name1' }`
6116 function flip(o) {
6117 var flipped = { };
6118 for (var i in o) {
6119 if (o.hasOwnProperty(i)) {
6120 flipped[o[i]] = i;
6121 }
6122 }
6123 return flipped;
6124 }
6125
6126 // Return a valid alpha value [0,1] with all invalid values being set to 1
6127 function boundAlpha(a) {
6128 a = parseFloat(a);
6129
6130 if (isNaN(a) || a < 0 || a > 1) {
6131 a = 1;
6132 }
6133
6134 return a;
6135 }
6136
6137 // Take input from [0, n] and return it as [0, 1]
6138 function bound01(n, max) {
6139 if (isOnePointZero(n)) { n = "100%"; }
6140
6141 var processPercent = isPercentage(n);
6142 n = mathMin(max, mathMax(0, parseFloat(n)));
6143
6144 // Automatically convert percentage into number
6145 if (processPercent) {
6146 n = parseInt(n * max, 10) / 100;
6147 }
6148
6149 // Handle floating point rounding errors
6150 if ((Math.abs(n - max) < 0.000001)) {
6151 return 1;
6152 }
6153
6154 // Convert into [0, 1] range if it isn't already
6155 return (n % max) / parseFloat(max);
6156 }
6157
6158 // Force a number between 0 and 1
6159 function clamp01(val) {
6160 return mathMin(1, mathMax(0, val));
6161 }
6162
6163 // Parse a base-16 hex value into a base-10 integer
6164 function parseIntFromHex(val) {
6165 return parseInt(val, 16);
6166 }
6167
6168 // Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1
6169 // <http://stackoverflow.com/questions/7422072/javascript-how-to-detect-number-as-a-decimal-including-1-0>
6170 function isOnePointZero(n) {
6171 return typeof n == "string" && n.indexOf('.') != -1 && parseFloat(n) === 1;
6172 }
6173
6174 // Check to see if string passed in is a percentage
6175 function isPercentage(n) {
6176 return typeof n === "string" && n.indexOf('%') != -1;
6177 }
6178
6179 // Force a hex value to have 2 characters
6180 function pad2(c) {
6181 return c.length == 1 ? '0' + c : '' + c;
6182 }
6183
6184 // Replace a decimal with it's percentage value
6185 function convertToPercentage(n) {
6186 if (n <= 1) {
6187 n = (n * 100) + "%";
6188 }
6189
6190 return n;
6191 }
6192
6193 // Converts a decimal to a hex value
6194 function convertDecimalToHex(d) {
6195 return Math.round(parseFloat(d) * 255).toString(16);
6196 }
6197 // Converts a hex value to a decimal
6198 function convertHexToDecimal(h) {
6199 return (parseIntFromHex(h) / 255);
6200 }
6201
6202 var matchers = (function() {
6203
6204 // <http://www.w3.org/TR/css3-values/#integers>
6205 var CSS_INTEGER = "[-\\+]?\\d+%?";
6206
6207 // <http://www.w3.org/TR/css3-values/#number-value>
6208 var CSS_NUMBER = "[-\\+]?\\d*\\.\\d+%?";
6209
6210 // Allow positive/negative integer/number. Don't capture the either/or, just the entire outcome.
6211 var CSS_UNIT = "(?:" + CSS_NUMBER + ")|(?:" + CSS_INTEGER + ")";
6212
6213 // Actual matching.
6214 // Parentheses and commas are optional, but not required.
6215 // Whitespace can take the place of commas or opening paren
6216 var PERMISSIVE_MATCH3 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
6217 var PERMISSIVE_MATCH4 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
6218
6219 return {
6220 CSS_UNIT: new RegExp(CSS_UNIT),
6221 rgb: new RegExp("rgb" + PERMISSIVE_MATCH3),
6222 rgba: new RegExp("rgba" + PERMISSIVE_MATCH4),
6223 hsl: new RegExp("hsl" + PERMISSIVE_MATCH3),
6224 hsla: new RegExp("hsla" + PERMISSIVE_MATCH4),
6225 hsv: new RegExp("hsv" + PERMISSIVE_MATCH3),
6226 hsva: new RegExp("hsva" + PERMISSIVE_MATCH4),
6227 hex3: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
6228 hex6: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,
6229 hex4: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
6230 hex8: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/
6231 };
6232 })();
6233
6234 // `isValidCSSUnit`
6235 // Take in a single string / number and check to see if it looks like a CSS unit
6236 // (see `matchers` above for definition).
6237 function isValidCSSUnit(color) {
6238 return !!matchers.CSS_UNIT.exec(color);
6239 }
6240
6241 // `stringInputToObject`
6242 // Permissive string parsing. Take in a number of formats, and output an object
6243 // based on detected format. Returns `{ r, g, b }` or `{ h, s, l }` or `{ h, s, v}`
6244 function stringInputToObject(color) {
6245
6246 color = color.replace(trimLeft,'').replace(trimRight, '').toLowerCase();
6247 var named = false;
6248 if (names[color]) {
6249 color = names[color];
6250 named = true;
6251 }
6252 else if (color == 'transparent') {
6253 return { r: 0, g: 0, b: 0, a: 0, format: "name" };
6254 }
6255
6256 // Try to match string input using regular expressions.
6257 // Keep most of the number bounding out of this function - don't worry about [0,1] or [0,100] or [0,360]
6258 // Just return an object and let the conversion functions handle that.
6259 // This way the result will be the same whether the tinycolor is initialized with string or object.
6260 var match;
6261 if ((match = matchers.rgb.exec(color))) {
6262 return { r: match[1], g: match[2], b: match[3] };
6263 }
6264 if ((match = matchers.rgba.exec(color))) {
6265 return { r: match[1], g: match[2], b: match[3], a: match[4] };
6266 }
6267 if ((match = matchers.hsl.exec(color))) {
6268 return { h: match[1], s: match[2], l: match[3] };
6269 }
6270 if ((match = matchers.hsla.exec(color))) {
6271 return { h: match[1], s: match[2], l: match[3], a: match[4] };
6272 }
6273 if ((match = matchers.hsv.exec(color))) {
6274 return { h: match[1], s: match[2], v: match[3] };
6275 }
6276 if ((match = matchers.hsva.exec(color))) {
6277 return { h: match[1], s: match[2], v: match[3], a: match[4] };
6278 }
6279 if ((match = matchers.hex8.exec(color))) {
6280 return {
6281 r: parseIntFromHex(match[1]),
6282 g: parseIntFromHex(match[2]),
6283 b: parseIntFromHex(match[3]),
6284 a: convertHexToDecimal(match[4]),
6285 format: named ? "name" : "hex8"
6286 };
6287 }
6288 if ((match = matchers.hex6.exec(color))) {
6289 return {
6290 r: parseIntFromHex(match[1]),
6291 g: parseIntFromHex(match[2]),
6292 b: parseIntFromHex(match[3]),
6293 format: named ? "name" : "hex"
6294 };
6295 }
6296 if ((match = matchers.hex4.exec(color))) {
6297 return {
6298 r: parseIntFromHex(match[1] + '' + match[1]),
6299 g: parseIntFromHex(match[2] + '' + match[2]),
6300 b: parseIntFromHex(match[3] + '' + match[3]),
6301 a: convertHexToDecimal(match[4] + '' + match[4]),
6302 format: named ? "name" : "hex8"
6303 };
6304 }
6305 if ((match = matchers.hex3.exec(color))) {
6306 return {
6307 r: parseIntFromHex(match[1] + '' + match[1]),
6308 g: parseIntFromHex(match[2] + '' + match[2]),
6309 b: parseIntFromHex(match[3] + '' + match[3]),
6310 format: named ? "name" : "hex"
6311 };
6312 }
6313
6314 return false;
6315 }
6316
6317 function validateWCAG2Parms(parms) {
6318 // return valid WCAG2 parms for isReadable.
6319 // If input parms are invalid, return {"level":"AA", "size":"small"}
6320 var level, size;
6321 parms = parms || {"level":"AA", "size":"small"};
6322 level = (parms.level || "AA").toUpperCase();
6323 size = (parms.size || "small").toLowerCase();
6324 if (level !== "AA" && level !== "AAA") {
6325 level = "AA";
6326 }
6327 if (size !== "small" && size !== "large") {
6328 size = "small";
6329 }
6330 return {"level":level, "size":size};
6331 }
6332
6333 // Node: Export function
6334 if ( true && module.exports) {
6335 module.exports = tinycolor;
6336 }
6337 // AMD/requirejs: Define the module
6338 else if (true) {
6339 !(__WEBPACK_AMD_DEFINE_RESULT__ = (function () {return tinycolor;}).call(exports, __webpack_require__, exports, module),
6340 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
6341 }
6342 // Browser: Expose to window
6343 else {}
6344
6345 })(Math);
6346
6347
6348 /***/ })
6349
6350 /******/ });
6351 /************************************************************************/
6352 /******/ // The module cache
6353 /******/ var __webpack_module_cache__ = {};
6354 /******/
6355 /******/ // The require function
6356 /******/ function __webpack_require__(moduleId) {
6357 /******/ // Check if module is in cache
6358 /******/ var cachedModule = __webpack_module_cache__[moduleId];
6359 /******/ if (cachedModule !== undefined) {
6360 /******/ return cachedModule.exports;
6361 /******/ }
6362 /******/ // Create a new module (and put it into the cache)
6363 /******/ var module = __webpack_module_cache__[moduleId] = {
6364 /******/ // no module.id needed
6365 /******/ // no module.loaded needed
6366 /******/ exports: {}
6367 /******/ };
6368 /******/
6369 /******/ // Execute the module function
6370 /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
6371 /******/
6372 /******/ // Return the exports of the module
6373 /******/ return module.exports;
6374 /******/ }
6375 /******/
6376 /************************************************************************/
6377 /******/ /* webpack/runtime/compat get default export */
6378 /******/ !function() {
6379 /******/ // getDefaultExport function for compatibility with non-harmony modules
6380 /******/ __webpack_require__.n = function(module) {
6381 /******/ var getter = module && module.__esModule ?
6382 /******/ function() { return module['default']; } :
6383 /******/ function() { return module; };
6384 /******/ __webpack_require__.d(getter, { a: getter });
6385 /******/ return getter;
6386 /******/ };
6387 /******/ }();
6388 /******/
6389 /******/ /* webpack/runtime/define property getters */
6390 /******/ !function() {
6391 /******/ // define getter functions for harmony exports
6392 /******/ __webpack_require__.d = function(exports, definition) {
6393 /******/ for(var key in definition) {
6394 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
6395 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
6396 /******/ }
6397 /******/ }
6398 /******/ };
6399 /******/ }();
6400 /******/
6401 /******/ /* webpack/runtime/hasOwnProperty shorthand */
6402 /******/ !function() {
6403 /******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }
6404 /******/ }();
6405 /******/
6406 /******/ /* webpack/runtime/make namespace object */
6407 /******/ !function() {
6408 /******/ // define __esModule on exports
6409 /******/ __webpack_require__.r = function(exports) {
6410 /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
6411 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
6412 /******/ }
6413 /******/ Object.defineProperty(exports, '__esModule', { value: true });
6414 /******/ };
6415 /******/ }();
6416 /******/
6417 /************************************************************************/
6418 var __webpack_exports__ = {};
6419 // This entry need to be wrapped in an IIFE because it need to be in strict mode.
6420 !function() {
6421 "use strict";
6422 // ESM COMPAT FLAG
6423 __webpack_require__.r(__webpack_exports__);
6424
6425 // EXPORTS
6426 __webpack_require__.d(__webpack_exports__, {
6427 "__EXPERIMENTAL_ELEMENTS": function() { return /* reexport */ __EXPERIMENTAL_ELEMENTS; },
6428 "__EXPERIMENTAL_PATHS_WITH_MERGE": function() { return /* reexport */ __EXPERIMENTAL_PATHS_WITH_MERGE; },
6429 "__EXPERIMENTAL_STYLE_PROPERTY": function() { return /* reexport */ __EXPERIMENTAL_STYLE_PROPERTY; },
6430 "__experimentalCloneSanitizedBlock": function() { return /* reexport */ __experimentalCloneSanitizedBlock; },
6431 "__experimentalGetAccessibleBlockLabel": function() { return /* reexport */ getAccessibleBlockLabel; },
6432 "__experimentalGetBlockAttributesNamesByRole": function() { return /* reexport */ __experimentalGetBlockAttributesNamesByRole; },
6433 "__experimentalGetBlockLabel": function() { return /* reexport */ getBlockLabel; },
6434 "__experimentalSanitizeBlockAttributes": function() { return /* reexport */ __experimentalSanitizeBlockAttributes; },
6435 "__unstableGetBlockProps": function() { return /* reexport */ getBlockProps; },
6436 "__unstableSerializeAndClean": function() { return /* reexport */ __unstableSerializeAndClean; },
6437 "children": function() { return /* reexport */ children; },
6438 "cloneBlock": function() { return /* reexport */ cloneBlock; },
6439 "createBlock": function() { return /* reexport */ createBlock; },
6440 "createBlocksFromInnerBlocksTemplate": function() { return /* reexport */ createBlocksFromInnerBlocksTemplate; },
6441 "doBlocksMatchTemplate": function() { return /* reexport */ doBlocksMatchTemplate; },
6442 "findTransform": function() { return /* reexport */ findTransform; },
6443 "getBlockAttributes": function() { return /* reexport */ getBlockAttributes; },
6444 "getBlockContent": function() { return /* reexport */ getBlockInnerHTML; },
6445 "getBlockDefaultClassName": function() { return /* reexport */ getBlockDefaultClassName; },
6446 "getBlockFromExample": function() { return /* reexport */ getBlockFromExample; },
6447 "getBlockMenuDefaultClassName": function() { return /* reexport */ getBlockMenuDefaultClassName; },
6448 "getBlockSupport": function() { return /* reexport */ registration_getBlockSupport; },
6449 "getBlockTransforms": function() { return /* reexport */ getBlockTransforms; },
6450 "getBlockType": function() { return /* reexport */ registration_getBlockType; },
6451 "getBlockTypes": function() { return /* reexport */ registration_getBlockTypes; },
6452 "getBlockVariations": function() { return /* reexport */ registration_getBlockVariations; },
6453 "getCategories": function() { return /* reexport */ categories_getCategories; },
6454 "getChildBlockNames": function() { return /* reexport */ registration_getChildBlockNames; },
6455 "getDefaultBlockName": function() { return /* reexport */ registration_getDefaultBlockName; },
6456 "getFreeformContentHandlerName": function() { return /* reexport */ getFreeformContentHandlerName; },
6457 "getGroupingBlockName": function() { return /* reexport */ registration_getGroupingBlockName; },
6458 "getPhrasingContentSchema": function() { return /* reexport */ deprecatedGetPhrasingContentSchema; },
6459 "getPossibleBlockTransformations": function() { return /* reexport */ getPossibleBlockTransformations; },
6460 "getSaveContent": function() { return /* reexport */ getSaveContent; },
6461 "getSaveElement": function() { return /* reexport */ getSaveElement; },
6462 "getUnregisteredTypeHandlerName": function() { return /* reexport */ getUnregisteredTypeHandlerName; },
6463 "hasBlockSupport": function() { return /* reexport */ registration_hasBlockSupport; },
6464 "hasChildBlocks": function() { return /* reexport */ registration_hasChildBlocks; },
6465 "hasChildBlocksWithInserterSupport": function() { return /* reexport */ registration_hasChildBlocksWithInserterSupport; },
6466 "isReusableBlock": function() { return /* reexport */ isReusableBlock; },
6467 "isTemplatePart": function() { return /* reexport */ isTemplatePart; },
6468 "isUnmodifiedDefaultBlock": function() { return /* reexport */ isUnmodifiedDefaultBlock; },
6469 "isValidBlockContent": function() { return /* reexport */ isValidBlockContent; },
6470 "isValidIcon": function() { return /* reexport */ isValidIcon; },
6471 "node": function() { return /* reexport */ node; },
6472 "normalizeIconObject": function() { return /* reexport */ normalizeIconObject; },
6473 "parse": function() { return /* reexport */ parser_parse; },
6474 "parseWithAttributeSchema": function() { return /* reexport */ parseWithAttributeSchema; },
6475 "pasteHandler": function() { return /* reexport */ pasteHandler; },
6476 "rawHandler": function() { return /* reexport */ rawHandler; },
6477 "registerBlockCollection": function() { return /* reexport */ registerBlockCollection; },
6478 "registerBlockStyle": function() { return /* reexport */ registerBlockStyle; },
6479 "registerBlockType": function() { return /* reexport */ registerBlockType; },
6480 "registerBlockVariation": function() { return /* reexport */ registerBlockVariation; },
6481 "serialize": function() { return /* reexport */ serialize; },
6482 "setCategories": function() { return /* reexport */ categories_setCategories; },
6483 "setDefaultBlockName": function() { return /* reexport */ registration_setDefaultBlockName; },
6484 "setFreeformContentHandlerName": function() { return /* reexport */ setFreeformContentHandlerName; },
6485 "setGroupingBlockName": function() { return /* reexport */ registration_setGroupingBlockName; },
6486 "setUnregisteredTypeHandlerName": function() { return /* reexport */ setUnregisteredTypeHandlerName; },
6487 "store": function() { return /* reexport */ store; },
6488 "switchToBlockType": function() { return /* reexport */ switchToBlockType; },
6489 "synchronizeBlocksWithTemplate": function() { return /* reexport */ synchronizeBlocksWithTemplate; },
6490 "unregisterBlockStyle": function() { return /* reexport */ unregisterBlockStyle; },
6491 "unregisterBlockType": function() { return /* reexport */ unregisterBlockType; },
6492 "unregisterBlockVariation": function() { return /* reexport */ unregisterBlockVariation; },
6493 "unstable__bootstrapServerSideBlockDefinitions": function() { return /* reexport */ unstable__bootstrapServerSideBlockDefinitions; },
6494 "updateCategory": function() { return /* reexport */ categories_updateCategory; },
6495 "withBlockContentContext": function() { return /* reexport */ withBlockContentContext; }
6496 });
6497
6498 // NAMESPACE OBJECT: ./packages/blocks/build-module/store/selectors.js
6499 var selectors_namespaceObject = {};
6500 __webpack_require__.r(selectors_namespaceObject);
6501 __webpack_require__.d(selectors_namespaceObject, {
6502 "getActiveBlockVariation": function() { return getActiveBlockVariation; },
6503 "getBlockStyles": function() { return getBlockStyles; },
6504 "getBlockSupport": function() { return getBlockSupport; },
6505 "getBlockType": function() { return getBlockType; },
6506 "getBlockTypes": function() { return getBlockTypes; },
6507 "getBlockVariations": function() { return getBlockVariations; },
6508 "getCategories": function() { return getCategories; },
6509 "getChildBlockNames": function() { return getChildBlockNames; },
6510 "getCollections": function() { return getCollections; },
6511 "getDefaultBlockName": function() { return getDefaultBlockName; },
6512 "getDefaultBlockVariation": function() { return getDefaultBlockVariation; },
6513 "getFreeformFallbackBlockName": function() { return getFreeformFallbackBlockName; },
6514 "getGroupingBlockName": function() { return getGroupingBlockName; },
6515 "getUnregisteredFallbackBlockName": function() { return getUnregisteredFallbackBlockName; },
6516 "hasBlockSupport": function() { return hasBlockSupport; },
6517 "hasChildBlocks": function() { return hasChildBlocks; },
6518 "hasChildBlocksWithInserterSupport": function() { return hasChildBlocksWithInserterSupport; },
6519 "isMatchingSearchTerm": function() { return isMatchingSearchTerm; }
6520 });
6521
6522 // NAMESPACE OBJECT: ./packages/blocks/build-module/store/actions.js
6523 var actions_namespaceObject = {};
6524 __webpack_require__.r(actions_namespaceObject);
6525 __webpack_require__.d(actions_namespaceObject, {
6526 "addBlockCollection": function() { return addBlockCollection; },
6527 "addBlockStyles": function() { return addBlockStyles; },
6528 "addBlockTypes": function() { return addBlockTypes; },
6529 "addBlockVariations": function() { return addBlockVariations; },
6530 "removeBlockCollection": function() { return removeBlockCollection; },
6531 "removeBlockStyles": function() { return removeBlockStyles; },
6532 "removeBlockTypes": function() { return removeBlockTypes; },
6533 "removeBlockVariations": function() { return removeBlockVariations; },
6534 "setCategories": function() { return setCategories; },
6535 "setDefaultBlockName": function() { return setDefaultBlockName; },
6536 "setFreeformFallbackBlockName": function() { return setFreeformFallbackBlockName; },
6537 "setGroupingBlockName": function() { return setGroupingBlockName; },
6538 "setUnregisteredFallbackBlockName": function() { return setUnregisteredFallbackBlockName; },
6539 "updateCategory": function() { return updateCategory; }
6540 });
6541
6542 ;// CONCATENATED MODULE: external ["wp","data"]
6543 var external_wp_data_namespaceObject = window["wp"]["data"];
6544 ;// CONCATENATED MODULE: external "lodash"
6545 var external_lodash_namespaceObject = window["lodash"];
6546 ;// CONCATENATED MODULE: external ["wp","i18n"]
6547 var external_wp_i18n_namespaceObject = window["wp"]["i18n"];
6548 ;// CONCATENATED MODULE: ./packages/blocks/build-module/store/reducer.js
6549 /**
6550 * External dependencies
6551 */
6552
6553 /**
6554 * WordPress dependencies
6555 */
6556
6557
6558
6559 /**
6560 * @typedef {Object} WPBlockCategory
6561 *
6562 * @property {string} slug Unique category slug.
6563 * @property {string} title Category label, for display in user interface.
6564 */
6565
6566 /**
6567 * Default set of categories.
6568 *
6569 * @type {WPBlockCategory[]}
6570 */
6571
6572 const DEFAULT_CATEGORIES = [{
6573 slug: 'text',
6574 title: (0,external_wp_i18n_namespaceObject.__)('Text')
6575 }, {
6576 slug: 'media',
6577 title: (0,external_wp_i18n_namespaceObject.__)('Media')
6578 }, {
6579 slug: 'design',
6580 title: (0,external_wp_i18n_namespaceObject.__)('Design')
6581 }, {
6582 slug: 'widgets',
6583 title: (0,external_wp_i18n_namespaceObject.__)('Widgets')
6584 }, {
6585 slug: 'theme',
6586 title: (0,external_wp_i18n_namespaceObject.__)('Theme')
6587 }, {
6588 slug: 'embed',
6589 title: (0,external_wp_i18n_namespaceObject.__)('Embeds')
6590 }, {
6591 slug: 'reusable',
6592 title: (0,external_wp_i18n_namespaceObject.__)('Reusable blocks')
6593 }];
6594 /**
6595 * Reducer managing the block types
6596 *
6597 * @param {Object} state Current state.
6598 * @param {Object} action Dispatched action.
6599 *
6600 * @return {Object} Updated state.
6601 */
6602
6603 function blockTypes(state = {}, action) {
6604 switch (action.type) {
6605 case 'ADD_BLOCK_TYPES':
6606 return { ...state,
6607 ...(0,external_lodash_namespaceObject.keyBy)((0,external_lodash_namespaceObject.map)(action.blockTypes, blockType => (0,external_lodash_namespaceObject.omit)(blockType, 'styles ')), 'name')
6608 };
6609
6610 case 'REMOVE_BLOCK_TYPES':
6611 return (0,external_lodash_namespaceObject.omit)(state, action.names);
6612 }
6613
6614 return state;
6615 }
6616 /**
6617 * Reducer managing the block style variations.
6618 *
6619 * @param {Object} state Current state.
6620 * @param {Object} action Dispatched action.
6621 *
6622 * @return {Object} Updated state.
6623 */
6624
6625 function blockStyles(state = {}, action) {
6626 switch (action.type) {
6627 case 'ADD_BLOCK_TYPES':
6628 return { ...state,
6629 ...(0,external_lodash_namespaceObject.mapValues)((0,external_lodash_namespaceObject.keyBy)(action.blockTypes, 'name'), blockType => {
6630 return (0,external_lodash_namespaceObject.uniqBy)([...(0,external_lodash_namespaceObject.get)(blockType, ['styles'], []), ...(0,external_lodash_namespaceObject.get)(state, [blockType.name], [])], style => style.name);
6631 })
6632 };
6633
6634 case 'ADD_BLOCK_STYLES':
6635 return { ...state,
6636 [action.blockName]: (0,external_lodash_namespaceObject.uniqBy)([...(0,external_lodash_namespaceObject.get)(state, [action.blockName], []), ...action.styles], style => style.name)
6637 };
6638
6639 case 'REMOVE_BLOCK_STYLES':
6640 return { ...state,
6641 [action.blockName]: (0,external_lodash_namespaceObject.filter)((0,external_lodash_namespaceObject.get)(state, [action.blockName], []), style => action.styleNames.indexOf(style.name) === -1)
6642 };
6643 }
6644
6645 return state;
6646 }
6647 /**
6648 * Reducer managing the block variations.
6649 *
6650 * @param {Object} state Current state.
6651 * @param {Object} action Dispatched action.
6652 *
6653 * @return {Object} Updated state.
6654 */
6655
6656 function blockVariations(state = {}, action) {
6657 switch (action.type) {
6658 case 'ADD_BLOCK_TYPES':
6659 return { ...state,
6660 ...(0,external_lodash_namespaceObject.mapValues)((0,external_lodash_namespaceObject.keyBy)(action.blockTypes, 'name'), blockType => {
6661 return (0,external_lodash_namespaceObject.uniqBy)([...(0,external_lodash_namespaceObject.get)(blockType, ['variations'], []), ...(0,external_lodash_namespaceObject.get)(state, [blockType.name], [])], variation => variation.name);
6662 })
6663 };
6664
6665 case 'ADD_BLOCK_VARIATIONS':
6666 return { ...state,
6667 [action.blockName]: (0,external_lodash_namespaceObject.uniqBy)([...(0,external_lodash_namespaceObject.get)(state, [action.blockName], []), ...action.variations], variation => variation.name)
6668 };
6669
6670 case 'REMOVE_BLOCK_VARIATIONS':
6671 return { ...state,
6672 [action.blockName]: (0,external_lodash_namespaceObject.filter)((0,external_lodash_namespaceObject.get)(state, [action.blockName], []), variation => action.variationNames.indexOf(variation.name) === -1)
6673 };
6674 }
6675
6676 return state;
6677 }
6678 /**
6679 * Higher-order Reducer creating a reducer keeping track of given block name.
6680 *
6681 * @param {string} setActionType Action type.
6682 *
6683 * @return {Function} Reducer.
6684 */
6685
6686 function createBlockNameSetterReducer(setActionType) {
6687 return (state = null, action) => {
6688 switch (action.type) {
6689 case 'REMOVE_BLOCK_TYPES':
6690 if (action.names.indexOf(state) !== -1) {
6691 return null;
6692 }
6693
6694 return state;
6695
6696 case setActionType:
6697 return action.name || null;
6698 }
6699
6700 return state;
6701 };
6702 }
6703 const defaultBlockName = createBlockNameSetterReducer('SET_DEFAULT_BLOCK_NAME');
6704 const freeformFallbackBlockName = createBlockNameSetterReducer('SET_FREEFORM_FALLBACK_BLOCK_NAME');
6705 const unregisteredFallbackBlockName = createBlockNameSetterReducer('SET_UNREGISTERED_FALLBACK_BLOCK_NAME');
6706 const groupingBlockName = createBlockNameSetterReducer('SET_GROUPING_BLOCK_NAME');
6707 /**
6708 * Reducer managing the categories
6709 *
6710 * @param {WPBlockCategory[]} state Current state.
6711 * @param {Object} action Dispatched action.
6712 *
6713 * @return {WPBlockCategory[]} Updated state.
6714 */
6715
6716 function categories(state = DEFAULT_CATEGORIES, action) {
6717 switch (action.type) {
6718 case 'SET_CATEGORIES':
6719 return action.categories || [];
6720
6721 case 'UPDATE_CATEGORY':
6722 {
6723 if (!action.category || (0,external_lodash_namespaceObject.isEmpty)(action.category)) {
6724 return state;
6725 }
6726
6727 const categoryToChange = (0,external_lodash_namespaceObject.find)(state, ['slug', action.slug]);
6728
6729 if (categoryToChange) {
6730 return (0,external_lodash_namespaceObject.map)(state, category => {
6731 if (category.slug === action.slug) {
6732 return { ...category,
6733 ...action.category
6734 };
6735 }
6736
6737 return category;
6738 });
6739 }
6740 }
6741 }
6742
6743 return state;
6744 }
6745 function collections(state = {}, action) {
6746 switch (action.type) {
6747 case 'ADD_BLOCK_COLLECTION':
6748 return { ...state,
6749 [action.namespace]: {
6750 title: action.title,
6751 icon: action.icon
6752 }
6753 };
6754
6755 case 'REMOVE_BLOCK_COLLECTION':
6756 return (0,external_lodash_namespaceObject.omit)(state, action.namespace);
6757 }
6758
6759 return state;
6760 }
6761 /* harmony default export */ var reducer = ((0,external_wp_data_namespaceObject.combineReducers)({
6762 blockTypes,
6763 blockStyles,
6764 blockVariations,
6765 defaultBlockName,
6766 freeformFallbackBlockName,
6767 unregisteredFallbackBlockName,
6768 groupingBlockName,
6769 categories,
6770 collections
6771 }));
6772 //# sourceMappingURL=reducer.js.map
6773 ;// CONCATENATED MODULE: ./node_modules/rememo/es/rememo.js
6774
6775
6776 var LEAF_KEY, hasWeakMap;
6777
6778 /**
6779 * Arbitrary value used as key for referencing cache object in WeakMap tree.
6780 *
6781 * @type {Object}
6782 */
6783 LEAF_KEY = {};
6784
6785 /**
6786 * Whether environment supports WeakMap.
6787 *
6788 * @type {boolean}
6789 */
6790 hasWeakMap = typeof WeakMap !== 'undefined';
6791
6792 /**
6793 * Returns the first argument as the sole entry in an array.
6794 *
6795 * @param {*} value Value to return.
6796 *
6797 * @return {Array} Value returned as entry in array.
6798 */
6799 function arrayOf( value ) {
6800 return [ value ];
6801 }
6802
6803 /**
6804 * Returns true if the value passed is object-like, or false otherwise. A value
6805 * is object-like if it can support property assignment, e.g. object or array.
6806 *
6807 * @param {*} value Value to test.
6808 *
6809 * @return {boolean} Whether value is object-like.
6810 */
6811 function isObjectLike( value ) {
6812 return !! value && 'object' === typeof value;
6813 }
6814
6815 /**
6816 * Creates and returns a new cache object.
6817 *
6818 * @return {Object} Cache object.
6819 */
6820 function createCache() {
6821 var cache = {
6822 clear: function() {
6823 cache.head = null;
6824 },
6825 };
6826
6827 return cache;
6828 }
6829
6830 /**
6831 * Returns true if entries within the two arrays are strictly equal by
6832 * reference from a starting index.
6833 *
6834 * @param {Array} a First array.
6835 * @param {Array} b Second array.
6836 * @param {number} fromIndex Index from which to start comparison.
6837 *
6838 * @return {boolean} Whether arrays are shallowly equal.
6839 */
6840 function isShallowEqual( a, b, fromIndex ) {
6841 var i;
6842
6843 if ( a.length !== b.length ) {
6844 return false;
6845 }
6846
6847 for ( i = fromIndex; i < a.length; i++ ) {
6848 if ( a[ i ] !== b[ i ] ) {
6849 return false;
6850 }
6851 }
6852
6853 return true;
6854 }
6855
6856 /**
6857 * Returns a memoized selector function. The getDependants function argument is
6858 * called before the memoized selector and is expected to return an immutable
6859 * reference or array of references on which the selector depends for computing
6860 * its own return value. The memoize cache is preserved only as long as those
6861 * dependant references remain the same. If getDependants returns a different
6862 * reference(s), the cache is cleared and the selector value regenerated.
6863 *
6864 * @param {Function} selector Selector function.
6865 * @param {Function} getDependants Dependant getter returning an immutable
6866 * reference or array of reference used in
6867 * cache bust consideration.
6868 *
6869 * @return {Function} Memoized selector.
6870 */
6871 /* harmony default export */ function rememo(selector, getDependants ) {
6872 var rootCache, getCache;
6873
6874 // Use object source as dependant if getter not provided
6875 if ( ! getDependants ) {
6876 getDependants = arrayOf;
6877 }
6878
6879 /**
6880 * Returns the root cache. If WeakMap is supported, this is assigned to the
6881 * root WeakMap cache set, otherwise it is a shared instance of the default
6882 * cache object.
6883 *
6884 * @return {(WeakMap|Object)} Root cache object.
6885 */
6886 function getRootCache() {
6887 return rootCache;
6888 }
6889
6890 /**
6891 * Returns the cache for a given dependants array. When possible, a WeakMap
6892 * will be used to create a unique cache for each set of dependants. This
6893 * is feasible due to the nature of WeakMap in allowing garbage collection
6894 * to occur on entries where the key object is no longer referenced. Since
6895 * WeakMap requires the key to be an object, this is only possible when the
6896 * dependant is object-like. The root cache is created as a hierarchy where
6897 * each top-level key is the first entry in a dependants set, the value a
6898 * WeakMap where each key is the next dependant, and so on. This continues
6899 * so long as the dependants are object-like. If no dependants are object-
6900 * like, then the cache is shared across all invocations.
6901 *
6902 * @see isObjectLike
6903 *
6904 * @param {Array} dependants Selector dependants.
6905 *
6906 * @return {Object} Cache object.
6907 */
6908 function getWeakMapCache( dependants ) {
6909 var caches = rootCache,
6910 isUniqueByDependants = true,
6911 i, dependant, map, cache;
6912
6913 for ( i = 0; i < dependants.length; i++ ) {
6914 dependant = dependants[ i ];
6915
6916 // Can only compose WeakMap from object-like key.
6917 if ( ! isObjectLike( dependant ) ) {
6918 isUniqueByDependants = false;
6919 break;
6920 }
6921
6922 // Does current segment of cache already have a WeakMap?
6923 if ( caches.has( dependant ) ) {
6924 // Traverse into nested WeakMap.
6925 caches = caches.get( dependant );
6926 } else {
6927 // Create, set, and traverse into a new one.
6928 map = new WeakMap();
6929 caches.set( dependant, map );
6930 caches = map;
6931 }
6932 }
6933
6934 // We use an arbitrary (but consistent) object as key for the last item
6935 // in the WeakMap to serve as our running cache.
6936 if ( ! caches.has( LEAF_KEY ) ) {
6937 cache = createCache();
6938 cache.isUniqueByDependants = isUniqueByDependants;
6939 caches.set( LEAF_KEY, cache );
6940 }
6941
6942 return caches.get( LEAF_KEY );
6943 }
6944
6945 // Assign cache handler by availability of WeakMap
6946 getCache = hasWeakMap ? getWeakMapCache : getRootCache;
6947
6948 /**
6949 * Resets root memoization cache.
6950 */
6951 function clear() {
6952 rootCache = hasWeakMap ? new WeakMap() : createCache();
6953 }
6954
6955 // eslint-disable-next-line jsdoc/check-param-names
6956 /**
6957 * The augmented selector call, considering first whether dependants have
6958 * changed before passing it to underlying memoize function.
6959 *
6960 * @param {Object} source Source object for derivation.
6961 * @param {...*} extraArgs Additional arguments to pass to selector.
6962 *
6963 * @return {*} Selector result.
6964 */
6965 function callSelector( /* source, ...extraArgs */ ) {
6966 var len = arguments.length,
6967 cache, node, i, args, dependants;
6968
6969 // Create copy of arguments (avoid leaking deoptimization).
6970 args = new Array( len );
6971 for ( i = 0; i < len; i++ ) {
6972 args[ i ] = arguments[ i ];
6973 }
6974
6975 dependants = getDependants.apply( null, args );
6976 cache = getCache( dependants );
6977
6978 // If not guaranteed uniqueness by dependants (primitive type or lack
6979 // of WeakMap support), shallow compare against last dependants and, if
6980 // references have changed, destroy cache to recalculate result.
6981 if ( ! cache.isUniqueByDependants ) {
6982 if ( cache.lastDependants && ! isShallowEqual( dependants, cache.lastDependants, 0 ) ) {
6983 cache.clear();
6984 }
6985
6986 cache.lastDependants = dependants;
6987 }
6988
6989 node = cache.head;
6990 while ( node ) {
6991 // Check whether node arguments match arguments
6992 if ( ! isShallowEqual( node.args, args, 1 ) ) {
6993 node = node.next;
6994 continue;
6995 }
6996
6997 // At this point we can assume we've found a match
6998
6999 // Surface matched node to head if not already
7000 if ( node !== cache.head ) {
7001 // Adjust siblings to point to each other.
7002 node.prev.next = node.next;
7003 if ( node.next ) {
7004 node.next.prev = node.prev;
7005 }
7006
7007 node.next = cache.head;
7008 node.prev = null;
7009 cache.head.prev = node;
7010 cache.head = node;
7011 }
7012
7013 // Return immediately
7014 return node.val;
7015 }
7016
7017 // No cached value found. Continue to insertion phase:
7018
7019 node = {
7020 // Generate the result from original function
7021 val: selector.apply( null, args ),
7022 };
7023
7024 // Avoid including the source object in the cache.
7025 args[ 0 ] = null;
7026 node.args = args;
7027
7028 // Don't need to check whether node is already head, since it would
7029 // have been returned above already if it was
7030
7031 // Shift existing head down list
7032 if ( cache.head ) {
7033 cache.head.prev = node;
7034 node.next = cache.head;
7035 }
7036
7037 cache.head = node;
7038
7039 return node.val;
7040 }
7041
7042 callSelector.getDependants = getDependants;
7043 callSelector.clear = clear;
7044 clear();
7045
7046 return callSelector;
7047 }
7048
7049 ;// CONCATENATED MODULE: ./packages/blocks/build-module/store/selectors.js
7050 /**
7051 * External dependencies
7052 */
7053
7054
7055 /** @typedef {import('../api/registration').WPBlockVariation} WPBlockVariation */
7056
7057 /** @typedef {import('../api/registration').WPBlockVariationScope} WPBlockVariationScope */
7058
7059 /** @typedef {import('./reducer').WPBlockCategory} WPBlockCategory */
7060
7061 /**
7062 * Given a block name or block type object, returns the corresponding
7063 * normalized block type object.
7064 *
7065 * @param {Object} state Blocks state.
7066 * @param {(string|Object)} nameOrType Block name or type object
7067 *
7068 * @return {Object} Block type object.
7069 */
7070
7071 const getNormalizedBlockType = (state, nameOrType) => 'string' === typeof nameOrType ? getBlockType(state, nameOrType) : nameOrType;
7072 /**
7073 * Returns all the available block types.
7074 *
7075 * @param {Object} state Data state.
7076 *
7077 * @return {Array} Block Types.
7078 */
7079
7080
7081 const getBlockTypes = rememo(state => {
7082 return Object.values(state.blockTypes).map(blockType => {
7083 return { ...blockType,
7084 variations: getBlockVariations(state, blockType.name)
7085 };
7086 });
7087 }, state => [state.blockTypes, state.blockVariations]);
7088 /**
7089 * Returns a block type by name.
7090 *
7091 * @param {Object} state Data state.
7092 * @param {string} name Block type name.
7093 *
7094 * @return {Object?} Block Type.
7095 */
7096
7097 function getBlockType(state, name) {
7098 return state.blockTypes[name];
7099 }
7100 /**
7101 * Returns block styles by block name.
7102 *
7103 * @param {Object} state Data state.
7104 * @param {string} name Block type name.
7105 *
7106 * @return {Array?} Block Styles.
7107 */
7108
7109 function getBlockStyles(state, name) {
7110 return state.blockStyles[name];
7111 }
7112 /**
7113 * Returns block variations by block name.
7114 *
7115 * @param {Object} state Data state.
7116 * @param {string} blockName Block type name.
7117 * @param {WPBlockVariationScope} [scope] Block variation scope name.
7118 *
7119 * @return {(WPBlockVariation[]|void)} Block variations.
7120 */
7121
7122 const getBlockVariations = rememo((state, blockName, scope) => {
7123 const variations = state.blockVariations[blockName];
7124
7125 if (!variations || !scope) {
7126 return variations;
7127 }
7128
7129 return variations.filter(variation => {
7130 // For backward compatibility reasons, variation's scope defaults to
7131 // `block` and `inserter` when not set.
7132 return (variation.scope || ['block', 'inserter']).includes(scope);
7133 });
7134 }, (state, blockName) => [state.blockVariations[blockName]]);
7135 /**
7136 * Returns the active block variation for a given block based on its attributes.
7137 * Variations are determined by their `isActive` property.
7138 * Which is either an array of block attribute keys or a function.
7139 *
7140 * In case of an array of block attribute keys, the `attributes` are compared
7141 * to the variation's attributes using strict equality check.
7142 *
7143 * In case of function type, the function should accept a block's attributes
7144 * and the variation's attributes and determines if a variation is active.
7145 * A function that accepts a block's attributes and the variation's attributes and determines if a variation is active.
7146 *
7147 * @param {Object} state Data state.
7148 * @param {string} blockName Name of block (example: “core/columns”).
7149 * @param {Object} attributes Block attributes used to determine active variation.
7150 * @param {WPBlockVariationScope} [scope] Block variation scope name.
7151 *
7152 * @return {(WPBlockVariation|undefined)} Active block variation.
7153 */
7154
7155 function getActiveBlockVariation(state, blockName, attributes, scope) {
7156 const variations = getBlockVariations(state, blockName, scope);
7157 const match = variations === null || variations === void 0 ? void 0 : variations.find(variation => {
7158 var _variation$isActive;
7159
7160 if (Array.isArray(variation.isActive)) {
7161 const blockType = getBlockType(state, blockName);
7162 const attributeKeys = Object.keys((blockType === null || blockType === void 0 ? void 0 : blockType.attributes) || {});
7163 const definedAttributes = variation.isActive.filter(attribute => attributeKeys.includes(attribute));
7164
7165 if (definedAttributes.length === 0) {
7166 return false;
7167 }
7168
7169 return definedAttributes.every(attribute => attributes[attribute] === variation.attributes[attribute]);
7170 }
7171
7172 return (_variation$isActive = variation.isActive) === null || _variation$isActive === void 0 ? void 0 : _variation$isActive.call(variation, attributes, variation.attributes);
7173 });
7174 return match;
7175 }
7176 /**
7177 * Returns the default block variation for the given block type.
7178 * When there are multiple variations annotated as the default one,
7179 * the last added item is picked. This simplifies registering overrides.
7180 * When there is no default variation set, it returns the first item.
7181 *
7182 * @param {Object} state Data state.
7183 * @param {string} blockName Block type name.
7184 * @param {WPBlockVariationScope} [scope] Block variation scope name.
7185 *
7186 * @return {?WPBlockVariation} The default block variation.
7187 */
7188
7189 function getDefaultBlockVariation(state, blockName, scope) {
7190 const variations = getBlockVariations(state, blockName, scope);
7191 return (0,external_lodash_namespaceObject.findLast)(variations, 'isDefault') || (0,external_lodash_namespaceObject.first)(variations);
7192 }
7193 /**
7194 * Returns all the available categories.
7195 *
7196 * @param {Object} state Data state.
7197 *
7198 * @return {WPBlockCategory[]} Categories list.
7199 */
7200
7201 function getCategories(state) {
7202 return state.categories;
7203 }
7204 /**
7205 * Returns all the available collections.
7206 *
7207 * @param {Object} state Data state.
7208 *
7209 * @return {Object} Collections list.
7210 */
7211
7212 function getCollections(state) {
7213 return state.collections;
7214 }
7215 /**
7216 * Returns the name of the default block name.
7217 *
7218 * @param {Object} state Data state.
7219 *
7220 * @return {string?} Default block name.
7221 */
7222
7223 function getDefaultBlockName(state) {
7224 return state.defaultBlockName;
7225 }
7226 /**
7227 * Returns the name of the block for handling non-block content.
7228 *
7229 * @param {Object} state Data state.
7230 *
7231 * @return {string?} Name of the block for handling non-block content.
7232 */
7233
7234 function getFreeformFallbackBlockName(state) {
7235 return state.freeformFallbackBlockName;
7236 }
7237 /**
7238 * Returns the name of the block for handling unregistered blocks.
7239 *
7240 * @param {Object} state Data state.
7241 *
7242 * @return {string?} Name of the block for handling unregistered blocks.
7243 */
7244
7245 function getUnregisteredFallbackBlockName(state) {
7246 return state.unregisteredFallbackBlockName;
7247 }
7248 /**
7249 * Returns the name of the block for handling unregistered blocks.
7250 *
7251 * @param {Object} state Data state.
7252 *
7253 * @return {string?} Name of the block for handling unregistered blocks.
7254 */
7255
7256 function getGroupingBlockName(state) {
7257 return state.groupingBlockName;
7258 }
7259 /**
7260 * Returns an array with the child blocks of a given block.
7261 *
7262 * @param {Object} state Data state.
7263 * @param {string} blockName Block type name.
7264 *
7265 * @return {Array} Array of child block names.
7266 */
7267
7268 const getChildBlockNames = rememo((state, blockName) => {
7269 return (0,external_lodash_namespaceObject.map)((0,external_lodash_namespaceObject.filter)(state.blockTypes, blockType => {
7270 return (0,external_lodash_namespaceObject.includes)(blockType.parent, blockName);
7271 }), ({
7272 name
7273 }) => name);
7274 }, state => [state.blockTypes]);
7275 /**
7276 * Returns the block support value for a feature, if defined.
7277 *
7278 * @param {Object} state Data state.
7279 * @param {(string|Object)} nameOrType Block name or type object
7280 * @param {Array|string} feature Feature to retrieve
7281 * @param {*} defaultSupports Default value to return if not
7282 * explicitly defined
7283 *
7284 * @return {?*} Block support value
7285 */
7286
7287 const getBlockSupport = (state, nameOrType, feature, defaultSupports) => {
7288 const blockType = getNormalizedBlockType(state, nameOrType);
7289
7290 if (!(blockType !== null && blockType !== void 0 && blockType.supports)) {
7291 return defaultSupports;
7292 }
7293
7294 return (0,external_lodash_namespaceObject.get)(blockType.supports, feature, defaultSupports);
7295 };
7296 /**
7297 * Returns true if the block defines support for a feature, or false otherwise.
7298 *
7299 * @param {Object} state Data state.
7300 * @param {(string|Object)} nameOrType Block name or type object.
7301 * @param {string} feature Feature to test.
7302 * @param {boolean} defaultSupports Whether feature is supported by
7303 * default if not explicitly defined.
7304 *
7305 * @return {boolean} Whether block supports feature.
7306 */
7307
7308 function hasBlockSupport(state, nameOrType, feature, defaultSupports) {
7309 return !!getBlockSupport(state, nameOrType, feature, defaultSupports);
7310 }
7311 /**
7312 * Returns true if the block type by the given name or object value matches a
7313 * search term, or false otherwise.
7314 *
7315 * @param {Object} state Blocks state.
7316 * @param {(string|Object)} nameOrType Block name or type object.
7317 * @param {string} searchTerm Search term by which to filter.
7318 *
7319 * @return {Object[]} Whether block type matches search term.
7320 */
7321
7322 function isMatchingSearchTerm(state, nameOrType, searchTerm) {
7323 const blockType = getNormalizedBlockType(state, nameOrType);
7324 const getNormalizedSearchTerm = (0,external_lodash_namespaceObject.flow)([// Disregard diacritics.
7325 // Input: "média"
7326 external_lodash_namespaceObject.deburr, // Lowercase.
7327 // Input: "MEDIA"
7328 term => term.toLowerCase(), // Strip leading and trailing whitespace.
7329 // Input: " media "
7330 term => term.trim()]);
7331 const normalizedSearchTerm = getNormalizedSearchTerm(searchTerm);
7332 const isSearchMatch = (0,external_lodash_namespaceObject.flow)([getNormalizedSearchTerm, normalizedCandidate => (0,external_lodash_namespaceObject.includes)(normalizedCandidate, normalizedSearchTerm)]);
7333 return isSearchMatch(blockType.title) || (0,external_lodash_namespaceObject.some)(blockType.keywords, isSearchMatch) || isSearchMatch(blockType.category);
7334 }
7335 /**
7336 * Returns a boolean indicating if a block has child blocks or not.
7337 *
7338 * @param {Object} state Data state.
7339 * @param {string} blockName Block type name.
7340 *
7341 * @return {boolean} True if a block contains child blocks and false otherwise.
7342 */
7343
7344 const hasChildBlocks = (state, blockName) => {
7345 return getChildBlockNames(state, blockName).length > 0;
7346 };
7347 /**
7348 * Returns a boolean indicating if a block has at least one child block with inserter support.
7349 *
7350 * @param {Object} state Data state.
7351 * @param {string} blockName Block type name.
7352 *
7353 * @return {boolean} True if a block contains at least one child blocks with inserter support
7354 * and false otherwise.
7355 */
7356
7357 const hasChildBlocksWithInserterSupport = (state, blockName) => {
7358 return (0,external_lodash_namespaceObject.some)(getChildBlockNames(state, blockName), childBlockName => {
7359 return hasBlockSupport(state, childBlockName, 'inserter', true);
7360 });
7361 };
7362 //# sourceMappingURL=selectors.js.map
7363 ;// CONCATENATED MODULE: ./packages/blocks/build-module/store/actions.js
7364 /**
7365 * External dependencies
7366 */
7367
7368 /** @typedef {import('../api/registration').WPBlockVariation} WPBlockVariation */
7369
7370 /**
7371 * Returns an action object used in signalling that block types have been added.
7372 *
7373 * @param {Array|Object} blockTypes Block types received.
7374 *
7375 * @return {Object} Action object.
7376 */
7377
7378 function addBlockTypes(blockTypes) {
7379 return {
7380 type: 'ADD_BLOCK_TYPES',
7381 blockTypes: (0,external_lodash_namespaceObject.castArray)(blockTypes)
7382 };
7383 }
7384 /**
7385 * Returns an action object used to remove a registered block type.
7386 *
7387 * @param {string|Array} names Block name.
7388 *
7389 * @return {Object} Action object.
7390 */
7391
7392 function removeBlockTypes(names) {
7393 return {
7394 type: 'REMOVE_BLOCK_TYPES',
7395 names: (0,external_lodash_namespaceObject.castArray)(names)
7396 };
7397 }
7398 /**
7399 * Returns an action object used in signalling that new block styles have been added.
7400 *
7401 * @param {string} blockName Block name.
7402 * @param {Array|Object} styles Block styles.
7403 *
7404 * @return {Object} Action object.
7405 */
7406
7407 function addBlockStyles(blockName, styles) {
7408 return {
7409 type: 'ADD_BLOCK_STYLES',
7410 styles: (0,external_lodash_namespaceObject.castArray)(styles),
7411 blockName
7412 };
7413 }
7414 /**
7415 * Returns an action object used in signalling that block styles have been removed.
7416 *
7417 * @param {string} blockName Block name.
7418 * @param {Array|string} styleNames Block style names.
7419 *
7420 * @return {Object} Action object.
7421 */
7422
7423 function removeBlockStyles(blockName, styleNames) {
7424 return {
7425 type: 'REMOVE_BLOCK_STYLES',
7426 styleNames: (0,external_lodash_namespaceObject.castArray)(styleNames),
7427 blockName
7428 };
7429 }
7430 /**
7431 * Returns an action object used in signalling that new block variations have been added.
7432 *
7433 * @param {string} blockName Block name.
7434 * @param {WPBlockVariation|WPBlockVariation[]} variations Block variations.
7435 *
7436 * @return {Object} Action object.
7437 */
7438
7439 function addBlockVariations(blockName, variations) {
7440 return {
7441 type: 'ADD_BLOCK_VARIATIONS',
7442 variations: (0,external_lodash_namespaceObject.castArray)(variations),
7443 blockName
7444 };
7445 }
7446 /**
7447 * Returns an action object used in signalling that block variations have been removed.
7448 *
7449 * @param {string} blockName Block name.
7450 * @param {string|string[]} variationNames Block variation names.
7451 *
7452 * @return {Object} Action object.
7453 */
7454
7455 function removeBlockVariations(blockName, variationNames) {
7456 return {
7457 type: 'REMOVE_BLOCK_VARIATIONS',
7458 variationNames: (0,external_lodash_namespaceObject.castArray)(variationNames),
7459 blockName
7460 };
7461 }
7462 /**
7463 * Returns an action object used to set the default block name.
7464 *
7465 * @param {string} name Block name.
7466 *
7467 * @return {Object} Action object.
7468 */
7469
7470 function setDefaultBlockName(name) {
7471 return {
7472 type: 'SET_DEFAULT_BLOCK_NAME',
7473 name
7474 };
7475 }
7476 /**
7477 * Returns an action object used to set the name of the block used as a fallback
7478 * for non-block content.
7479 *
7480 * @param {string} name Block name.
7481 *
7482 * @return {Object} Action object.
7483 */
7484
7485 function setFreeformFallbackBlockName(name) {
7486 return {
7487 type: 'SET_FREEFORM_FALLBACK_BLOCK_NAME',
7488 name
7489 };
7490 }
7491 /**
7492 * Returns an action object used to set the name of the block used as a fallback
7493 * for unregistered blocks.
7494 *
7495 * @param {string} name Block name.
7496 *
7497 * @return {Object} Action object.
7498 */
7499
7500 function setUnregisteredFallbackBlockName(name) {
7501 return {
7502 type: 'SET_UNREGISTERED_FALLBACK_BLOCK_NAME',
7503 name
7504 };
7505 }
7506 /**
7507 * Returns an action object used to set the name of the block used
7508 * when grouping other blocks
7509 * eg: in "Group/Ungroup" interactions
7510 *
7511 * @param {string} name Block name.
7512 *
7513 * @return {Object} Action object.
7514 */
7515
7516 function setGroupingBlockName(name) {
7517 return {
7518 type: 'SET_GROUPING_BLOCK_NAME',
7519 name
7520 };
7521 }
7522 /**
7523 * Returns an action object used to set block categories.
7524 *
7525 * @param {Object[]} categories Block categories.
7526 *
7527 * @return {Object} Action object.
7528 */
7529
7530 function setCategories(categories) {
7531 return {
7532 type: 'SET_CATEGORIES',
7533 categories
7534 };
7535 }
7536 /**
7537 * Returns an action object used to update a category.
7538 *
7539 * @param {string} slug Block category slug.
7540 * @param {Object} category Object containing the category properties that should be updated.
7541 *
7542 * @return {Object} Action object.
7543 */
7544
7545 function updateCategory(slug, category) {
7546 return {
7547 type: 'UPDATE_CATEGORY',
7548 slug,
7549 category
7550 };
7551 }
7552 /**
7553 * Returns an action object used to add block collections
7554 *
7555 * @param {string} namespace The namespace of the blocks to put in the collection
7556 * @param {string} title The title to display in the block inserter
7557 * @param {Object} icon (optional) The icon to display in the block inserter
7558 *
7559 * @return {Object} Action object.
7560 */
7561
7562 function addBlockCollection(namespace, title, icon) {
7563 return {
7564 type: 'ADD_BLOCK_COLLECTION',
7565 namespace,
7566 title,
7567 icon
7568 };
7569 }
7570 /**
7571 * Returns an action object used to remove block collections
7572 *
7573 * @param {string} namespace The namespace of the blocks to put in the collection
7574 *
7575 * @return {Object} Action object.
7576 */
7577
7578 function removeBlockCollection(namespace) {
7579 return {
7580 type: 'REMOVE_BLOCK_COLLECTION',
7581 namespace
7582 };
7583 }
7584 //# sourceMappingURL=actions.js.map
7585 ;// CONCATENATED MODULE: ./packages/blocks/build-module/store/constants.js
7586 const STORE_NAME = 'core/blocks';
7587 //# sourceMappingURL=constants.js.map
7588 ;// CONCATENATED MODULE: ./packages/blocks/build-module/store/index.js
7589 /**
7590 * WordPress dependencies
7591 */
7592
7593 /**
7594 * Internal dependencies
7595 */
7596
7597
7598
7599
7600
7601 /**
7602 * Store definition for the blocks namespace.
7603 *
7604 * @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/data/README.md#createReduxStore
7605 *
7606 * @type {Object}
7607 */
7608
7609 const store = (0,external_wp_data_namespaceObject.createReduxStore)(STORE_NAME, {
7610 reducer: reducer,
7611 selectors: selectors_namespaceObject,
7612 actions: actions_namespaceObject
7613 });
7614 (0,external_wp_data_namespaceObject.register)(store);
7615 //# sourceMappingURL=index.js.map
7616 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/rng.js
7617 // Unique ID creation requires a high quality random # generator. In the browser we therefore
7618 // require the crypto API and do not support built-in fallback to lower quality random number
7619 // generators (like Math.random()).
7620 // getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. Also,
7621 // find the complete implementation of crypto (msCrypto) on IE11.
7622 var getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || typeof msCrypto !== 'undefined' && typeof msCrypto.getRandomValues === 'function' && msCrypto.getRandomValues.bind(msCrypto);
7623 var rnds8 = new Uint8Array(16);
7624 function rng() {
7625 if (!getRandomValues) {
7626 throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');
7627 }
7628
7629 return getRandomValues(rnds8);
7630 }
7631 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/regex.js
7632 /* harmony default export */ var regex = (/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i);
7633 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/validate.js
7634
7635
7636 function validate(uuid) {
7637 return typeof uuid === 'string' && regex.test(uuid);
7638 }
7639
7640 /* harmony default export */ var esm_browser_validate = (validate);
7641 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/stringify.js
7642
7643 /**
7644 * Convert array of 16 byte values to UUID string format of the form:
7645 * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
7646 */
7647
7648 var byteToHex = [];
7649
7650 for (var i = 0; i < 256; ++i) {
7651 byteToHex.push((i + 0x100).toString(16).substr(1));
7652 }
7653
7654 function stringify(arr) {
7655 var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
7656 // Note: Be careful editing this code! It's been tuned for performance
7657 // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434
7658 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
7659 // of the following:
7660 // - One or more input array values don't map to a hex octet (leading to
7661 // "undefined" in the uuid)
7662 // - Invalid input values for the RFC `version` or `variant` fields
7663
7664 if (!esm_browser_validate(uuid)) {
7665 throw TypeError('Stringified UUID is invalid');
7666 }
7667
7668 return uuid;
7669 }
7670
7671 /* harmony default export */ var esm_browser_stringify = (stringify);
7672 ;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-browser/v4.js
7673
7674
7675
7676 function v4(options, buf, offset) {
7677 options = options || {};
7678 var rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
7679
7680 rnds[6] = rnds[6] & 0x0f | 0x40;
7681 rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided
7682
7683 if (buf) {
7684 offset = offset || 0;
7685
7686 for (var i = 0; i < 16; ++i) {
7687 buf[offset + i] = rnds[i];
7688 }
7689
7690 return buf;
7691 }
7692
7693 return esm_browser_stringify(rnds);
7694 }
7695
7696 /* harmony default export */ var esm_browser_v4 = (v4);
7697 ;// CONCATENATED MODULE: external ["wp","hooks"]
7698 var external_wp_hooks_namespaceObject = window["wp"]["hooks"];
7699 // EXTERNAL MODULE: ./node_modules/tinycolor2/tinycolor.js
7700 var tinycolor = __webpack_require__(7621);
7701 var tinycolor_default = /*#__PURE__*/__webpack_require__.n(tinycolor);
7702 ;// CONCATENATED MODULE: external ["wp","element"]
7703 var external_wp_element_namespaceObject = window["wp"]["element"];
7704 ;// CONCATENATED MODULE: external ["wp","dom"]
7705 var external_wp_dom_namespaceObject = window["wp"]["dom"];
7706 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/constants.js
7707 const BLOCK_ICON_DEFAULT = 'block-default';
7708 /**
7709 * Array of valid keys in a block type settings deprecation object.
7710 *
7711 * @type {string[]}
7712 */
7713
7714 const DEPRECATED_ENTRY_KEYS = ['attributes', 'supports', 'save', 'migrate', 'isEligible', 'apiVersion'];
7715 const __EXPERIMENTAL_STYLE_PROPERTY = {
7716 //kept for back-compatibility purposes.
7717 '--wp--style--color--link': {
7718 value: ['color', 'link'],
7719 support: ['color', 'link']
7720 },
7721 background: {
7722 value: ['color', 'gradient'],
7723 support: ['color', 'gradients']
7724 },
7725 backgroundColor: {
7726 value: ['color', 'background'],
7727 support: ['color', 'background'],
7728 requiresOptOut: true
7729 },
7730 borderColor: {
7731 value: ['border', 'color'],
7732 support: ['__experimentalBorder', 'color']
7733 },
7734 borderRadius: {
7735 value: ['border', 'radius'],
7736 support: ['__experimentalBorder', 'radius'],
7737 properties: {
7738 borderTopLeftRadius: 'topLeft',
7739 borderTopRightRadius: 'topRight',
7740 borderBottomLeftRadius: 'bottomLeft',
7741 borderBottomRightRadius: 'bottomRight'
7742 }
7743 },
7744 borderStyle: {
7745 value: ['border', 'style'],
7746 support: ['__experimentalBorder', 'style']
7747 },
7748 borderWidth: {
7749 value: ['border', 'width'],
7750 support: ['__experimentalBorder', 'width']
7751 },
7752 color: {
7753 value: ['color', 'text'],
7754 support: ['color', 'text'],
7755 requiresOptOut: true
7756 },
7757 linkColor: {
7758 value: ['elements', 'link', 'color', 'text'],
7759 support: ['color', 'link']
7760 },
7761 fontFamily: {
7762 value: ['typography', 'fontFamily'],
7763 support: ['typography', '__experimentalFontFamily']
7764 },
7765 fontSize: {
7766 value: ['typography', 'fontSize'],
7767 support: ['typography', 'fontSize']
7768 },
7769 fontStyle: {
7770 value: ['typography', 'fontStyle'],
7771 support: ['typography', '__experimentalFontStyle']
7772 },
7773 fontWeight: {
7774 value: ['typography', 'fontWeight'],
7775 support: ['typography', '__experimentalFontWeight']
7776 },
7777 lineHeight: {
7778 value: ['typography', 'lineHeight'],
7779 support: ['typography', 'lineHeight']
7780 },
7781 margin: {
7782 value: ['spacing', 'margin'],
7783 support: ['spacing', 'margin'],
7784 properties: {
7785 marginTop: 'top',
7786 marginRight: 'right',
7787 marginBottom: 'bottom',
7788 marginLeft: 'left'
7789 }
7790 },
7791 padding: {
7792 value: ['spacing', 'padding'],
7793 support: ['spacing', 'padding'],
7794 properties: {
7795 paddingTop: 'top',
7796 paddingRight: 'right',
7797 paddingBottom: 'bottom',
7798 paddingLeft: 'left'
7799 }
7800 },
7801 textDecoration: {
7802 value: ['typography', 'textDecoration'],
7803 support: ['typography', '__experimentalTextDecoration']
7804 },
7805 textTransform: {
7806 value: ['typography', 'textTransform'],
7807 support: ['typography', '__experimentalTextTransform']
7808 },
7809 letterSpacing: {
7810 value: ['typography', 'letterSpacing'],
7811 support: ['typography', '__experimentalLetterSpacing']
7812 },
7813 '--wp--style--block-gap': {
7814 value: ['spacing', 'blockGap'],
7815 support: ['spacing', 'blockGap']
7816 }
7817 };
7818 const __EXPERIMENTAL_ELEMENTS = {
7819 link: 'a',
7820 h1: 'h1',
7821 h2: 'h2',
7822 h3: 'h3',
7823 h4: 'h4',
7824 h5: 'h5',
7825 h6: 'h6'
7826 };
7827 const __EXPERIMENTAL_PATHS_WITH_MERGE = {
7828 'color.gradients': true,
7829 'color.palette': true,
7830 'typography.fontFamilies': true,
7831 'typography.fontSizes': true
7832 };
7833 //# sourceMappingURL=constants.js.map
7834 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/utils.js
7835 /**
7836 * External dependencies
7837 */
7838
7839
7840 /**
7841 * WordPress dependencies
7842 */
7843
7844
7845
7846
7847 /**
7848 * Internal dependencies
7849 */
7850
7851
7852
7853
7854 /**
7855 * Array of icon colors containing a color to be used if the icon color
7856 * was not explicitly set but the icon background color was.
7857 *
7858 * @type {Object}
7859 */
7860
7861 const ICON_COLORS = ['#191e23', '#f8f9f9'];
7862 /**
7863 * Determines whether the block is a default block
7864 * and its attributes are equal to the default attributes
7865 * which means the block is unmodified.
7866 *
7867 * @param {WPBlock} block Block Object
7868 *
7869 * @return {boolean} Whether the block is an unmodified default block
7870 */
7871
7872 function isUnmodifiedDefaultBlock(block) {
7873 const defaultBlockName = registration_getDefaultBlockName();
7874
7875 if (block.name !== defaultBlockName) {
7876 return false;
7877 } // Cache a created default block if no cache exists or the default block
7878 // name changed.
7879
7880
7881 if (!isUnmodifiedDefaultBlock.block || isUnmodifiedDefaultBlock.block.name !== defaultBlockName) {
7882 isUnmodifiedDefaultBlock.block = createBlock(defaultBlockName);
7883 }
7884
7885 const newDefaultBlock = isUnmodifiedDefaultBlock.block;
7886 const blockType = registration_getBlockType(defaultBlockName);
7887 return (0,external_lodash_namespaceObject.every)(blockType.attributes, (value, key) => newDefaultBlock.attributes[key] === block.attributes[key]);
7888 }
7889 /**
7890 * Function that checks if the parameter is a valid icon.
7891 *
7892 * @param {*} icon Parameter to be checked.
7893 *
7894 * @return {boolean} True if the parameter is a valid icon and false otherwise.
7895 */
7896
7897 function isValidIcon(icon) {
7898 return !!icon && ((0,external_lodash_namespaceObject.isString)(icon) || (0,external_wp_element_namespaceObject.isValidElement)(icon) || (0,external_lodash_namespaceObject.isFunction)(icon) || icon instanceof external_wp_element_namespaceObject.Component);
7899 }
7900 /**
7901 * Function that receives an icon as set by the blocks during the registration
7902 * and returns a new icon object that is normalized so we can rely on just on possible icon structure
7903 * in the codebase.
7904 *
7905 * @param {WPBlockTypeIconRender} icon Render behavior of a block type icon;
7906 * one of a Dashicon slug, an element, or a
7907 * component.
7908 *
7909 * @return {WPBlockTypeIconDescriptor} Object describing the icon.
7910 */
7911
7912 function normalizeIconObject(icon) {
7913 icon = icon || BLOCK_ICON_DEFAULT;
7914
7915 if (isValidIcon(icon)) {
7916 return {
7917 src: icon
7918 };
7919 }
7920
7921 if ((0,external_lodash_namespaceObject.has)(icon, ['background'])) {
7922 const tinyBgColor = tinycolor_default()(icon.background);
7923 return { ...icon,
7924 foreground: icon.foreground ? icon.foreground : (0,tinycolor.mostReadable)(tinyBgColor, ICON_COLORS, {
7925 includeFallbackColors: true,
7926 level: 'AA',
7927 size: 'large'
7928 }).toHexString(),
7929 shadowColor: tinyBgColor.setAlpha(0.3).toRgbString()
7930 };
7931 }
7932
7933 return icon;
7934 }
7935 /**
7936 * Normalizes block type passed as param. When string is passed then
7937 * it converts it to the matching block type object.
7938 * It passes the original object otherwise.
7939 *
7940 * @param {string|Object} blockTypeOrName Block type or name.
7941 *
7942 * @return {?Object} Block type.
7943 */
7944
7945 function normalizeBlockType(blockTypeOrName) {
7946 if ((0,external_lodash_namespaceObject.isString)(blockTypeOrName)) {
7947 return registration_getBlockType(blockTypeOrName);
7948 }
7949
7950 return blockTypeOrName;
7951 }
7952 /**
7953 * Get the label for the block, usually this is either the block title,
7954 * or the value of the block's `label` function when that's specified.
7955 *
7956 * @param {Object} blockType The block type.
7957 * @param {Object} attributes The values of the block's attributes.
7958 * @param {Object} context The intended use for the label.
7959 *
7960 * @return {string} The block label.
7961 */
7962
7963 function getBlockLabel(blockType, attributes, context = 'visual') {
7964 const {
7965 __experimentalLabel: getLabel,
7966 title
7967 } = blockType;
7968 const label = getLabel && getLabel(attributes, {
7969 context
7970 });
7971
7972 if (!label) {
7973 return title;
7974 } // Strip any HTML (i.e. RichText formatting) before returning.
7975
7976
7977 return (0,external_wp_dom_namespaceObject.__unstableStripHTML)(label);
7978 }
7979 /**
7980 * Get a label for the block for use by screenreaders, this is more descriptive
7981 * than the visual label and includes the block title and the value of the
7982 * `getLabel` function if it's specified.
7983 *
7984 * @param {Object} blockType The block type.
7985 * @param {Object} attributes The values of the block's attributes.
7986 * @param {?number} position The position of the block in the block list.
7987 * @param {string} [direction='vertical'] The direction of the block layout.
7988 *
7989 * @return {string} The block label.
7990 */
7991
7992 function getAccessibleBlockLabel(blockType, attributes, position, direction = 'vertical') {
7993 // `title` is already localized, `label` is a user-supplied value.
7994 const {
7995 title
7996 } = blockType;
7997 const label = getBlockLabel(blockType, attributes, 'accessibility');
7998 const hasPosition = position !== undefined; // getBlockLabel returns the block title as a fallback when there's no label,
7999 // if it did return the title, this function needs to avoid adding the
8000 // title twice within the accessible label. Use this `hasLabel` boolean to
8001 // handle that.
8002
8003 const hasLabel = label && label !== title;
8004
8005 if (hasPosition && direction === 'vertical') {
8006 if (hasLabel) {
8007 return (0,external_wp_i18n_namespaceObject.sprintf)(
8008 /* translators: accessibility text. 1: The block title. 2: The block row number. 3: The block label.. */
8009 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. Row %2$d. %3$s'), title, position, label);
8010 }
8011
8012 return (0,external_wp_i18n_namespaceObject.sprintf)(
8013 /* translators: accessibility text. 1: The block title. 2: The block row number. */
8014 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. Row %2$d'), title, position);
8015 } else if (hasPosition && direction === 'horizontal') {
8016 if (hasLabel) {
8017 return (0,external_wp_i18n_namespaceObject.sprintf)(
8018 /* translators: accessibility text. 1: The block title. 2: The block column number. 3: The block label.. */
8019 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. Column %2$d. %3$s'), title, position, label);
8020 }
8021
8022 return (0,external_wp_i18n_namespaceObject.sprintf)(
8023 /* translators: accessibility text. 1: The block title. 2: The block column number. */
8024 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. Column %2$d'), title, position);
8025 }
8026
8027 if (hasLabel) {
8028 return (0,external_wp_i18n_namespaceObject.sprintf)(
8029 /* translators: accessibility text. %1: The block title. %2: The block label. */
8030 (0,external_wp_i18n_namespaceObject.__)('%1$s Block. %2$s'), title, label);
8031 }
8032
8033 return (0,external_wp_i18n_namespaceObject.sprintf)(
8034 /* translators: accessibility text. %s: The block title. */
8035 (0,external_wp_i18n_namespaceObject.__)('%s Block'), title);
8036 }
8037 /**
8038 * Ensure attributes contains only values defined by block type, and merge
8039 * default values for missing attributes.
8040 *
8041 * @param {string} name The block's name.
8042 * @param {Object} attributes The block's attributes.
8043 * @return {Object} The sanitized attributes.
8044 */
8045
8046 function __experimentalSanitizeBlockAttributes(name, attributes) {
8047 // Get the type definition associated with a registered block.
8048 const blockType = registration_getBlockType(name);
8049
8050 if (undefined === blockType) {
8051 throw new Error(`Block type '${name}' is not registered.`);
8052 }
8053
8054 return (0,external_lodash_namespaceObject.reduce)(blockType.attributes, (accumulator, schema, key) => {
8055 const value = attributes[key];
8056
8057 if (undefined !== value) {
8058 accumulator[key] = value;
8059 } else if (schema.hasOwnProperty('default')) {
8060 accumulator[key] = schema.default;
8061 }
8062
8063 if (['node', 'children'].indexOf(schema.source) !== -1) {
8064 // Ensure value passed is always an array, which we're expecting in
8065 // the RichText component to handle the deprecated value.
8066 if (typeof accumulator[key] === 'string') {
8067 accumulator[key] = [accumulator[key]];
8068 } else if (!Array.isArray(accumulator[key])) {
8069 accumulator[key] = [];
8070 }
8071 }
8072
8073 return accumulator;
8074 }, {});
8075 }
8076 /**
8077 * Filter block attributes by `role` and return their names.
8078 *
8079 * @param {string} name Block attribute's name.
8080 * @param {string} role The role of a block attribute.
8081 *
8082 * @return {string[]} The attribute names that have the provided role.
8083 */
8084
8085 function __experimentalGetBlockAttributesNamesByRole(name, role) {
8086 var _getBlockType;
8087
8088 const attributes = (_getBlockType = registration_getBlockType(name)) === null || _getBlockType === void 0 ? void 0 : _getBlockType.attributes;
8089 if (!attributes) return [];
8090 const attributesNames = Object.keys(attributes);
8091 if (!role) return attributesNames;
8092 return attributesNames.filter(attributeName => {
8093 var _attributes$attribute;
8094
8095 return ((_attributes$attribute = attributes[attributeName]) === null || _attributes$attribute === void 0 ? void 0 : _attributes$attribute.__experimentalRole) === role;
8096 });
8097 }
8098 //# sourceMappingURL=utils.js.map
8099 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/registration.js
8100 /* eslint no-console: [ 'error', { allow: [ 'error', 'warn' ] } ] */
8101
8102 /**
8103 * External dependencies
8104 */
8105
8106 /**
8107 * WordPress dependencies
8108 */
8109
8110
8111
8112
8113 /**
8114 * Internal dependencies
8115 */
8116
8117 const i18nBlockSchema = {
8118 title: "block title",
8119 description: "block description",
8120 keywords: ["block keyword"],
8121 styles: [{
8122 label: "block style label"
8123 }],
8124 variations: [{
8125 title: "block variation title",
8126 description: "block variation description",
8127 keywords: ["block variation keyword"]
8128 }]
8129 };
8130
8131
8132
8133 /**
8134 * An icon type definition. One of a Dashicon slug, an element,
8135 * or a component.
8136 *
8137 * @typedef {(string|WPElement|WPComponent)} WPIcon
8138 *
8139 * @see https://developer.wordpress.org/resource/dashicons/
8140 */
8141
8142 /**
8143 * Render behavior of a block type icon; one of a Dashicon slug, an element,
8144 * or a component.
8145 *
8146 * @typedef {WPIcon} WPBlockTypeIconRender
8147 */
8148
8149 /**
8150 * An object describing a normalized block type icon.
8151 *
8152 * @typedef {Object} WPBlockTypeIconDescriptor
8153 *
8154 * @property {WPBlockTypeIconRender} src Render behavior of the icon,
8155 * one of a Dashicon slug, an
8156 * element, or a component.
8157 * @property {string} background Optimal background hex string
8158 * color when displaying icon.
8159 * @property {string} foreground Optimal foreground hex string
8160 * color when displaying icon.
8161 * @property {string} shadowColor Optimal shadow hex string
8162 * color when displaying icon.
8163 */
8164
8165 /**
8166 * Value to use to render the icon for a block type in an editor interface,
8167 * either a Dashicon slug, an element, a component, or an object describing
8168 * the icon.
8169 *
8170 * @typedef {(WPBlockTypeIconDescriptor|WPBlockTypeIconRender)} WPBlockTypeIcon
8171 */
8172
8173 /**
8174 * Named block variation scopes.
8175 *
8176 * @typedef {'block'|'inserter'|'transform'} WPBlockVariationScope
8177 */
8178
8179 /**
8180 * An object describing a variation defined for the block type.
8181 *
8182 * @typedef {Object} WPBlockVariation
8183 *
8184 * @property {string} name The unique and machine-readable name.
8185 * @property {string} title A human-readable variation title.
8186 * @property {string} [description] A detailed variation description.
8187 * @property {string} [category] Block type category classification,
8188 * used in search interfaces to arrange
8189 * block types by category.
8190 * @property {WPIcon} [icon] An icon helping to visualize the variation.
8191 * @property {boolean} [isDefault] Indicates whether the current variation is
8192 * the default one. Defaults to `false`.
8193 * @property {Object} [attributes] Values which override block attributes.
8194 * @property {Array[]} [innerBlocks] Initial configuration of nested blocks.
8195 * @property {Object} [example] Example provides structured data for
8196 * the block preview. You can set to
8197 * `undefined` to disable the preview shown
8198 * for the block type.
8199 * @property {WPBlockVariationScope[]} [scope] The list of scopes where the variation
8200 * is applicable. When not provided, it
8201 * assumes all available scopes.
8202 * @property {string[]} [keywords] An array of terms (which can be translated)
8203 * that help users discover the variation
8204 * while searching.
8205 * @property {Function|string[]} [isActive] This can be a function or an array of block attributes.
8206 * Function that accepts a block's attributes and the
8207 * variation's attributes and determines if a variation is active.
8208 * This function doesn't try to find a match dynamically based
8209 * on all block's attributes, as in many cases some attributes are irrelevant.
8210 * An example would be for `embed` block where we only care
8211 * about `providerNameSlug` attribute's value.
8212 * We can also use a `string[]` to tell which attributes
8213 * should be compared as a shorthand. Each attributes will
8214 * be matched and the variation will be active if all of them are matching.
8215 */
8216
8217 /**
8218 * Defined behavior of a block type.
8219 *
8220 * @typedef {Object} WPBlockType
8221 *
8222 * @property {string} name Block type's namespaced name.
8223 * @property {string} title Human-readable block type label.
8224 * @property {string} [description] A detailed block type description.
8225 * @property {string} [category] Block type category classification,
8226 * used in search interfaces to arrange
8227 * block types by category.
8228 * @property {WPBlockTypeIcon} [icon] Block type icon.
8229 * @property {string[]} [keywords] Additional keywords to produce block
8230 * type as result in search interfaces.
8231 * @property {Object} [attributes] Block type attributes.
8232 * @property {WPComponent} [save] Optional component describing
8233 * serialized markup structure of a
8234 * block type.
8235 * @property {WPComponent} edit Component rendering an element to
8236 * manipulate the attributes of a block
8237 * in the context of an editor.
8238 * @property {WPBlockVariation[]} [variations] The list of block variations.
8239 * @property {Object} [example] Example provides structured data for
8240 * the block preview. When not defined
8241 * then no preview is shown.
8242 */
8243
8244 /**
8245 * Mapping of legacy category slugs to their latest normal values, used to
8246 * accommodate updates of the default set of block categories.
8247 *
8248 * @type {Record<string,string>}
8249 */
8250
8251 const LEGACY_CATEGORY_MAPPING = {
8252 common: 'text',
8253 formatting: 'text',
8254 layout: 'design'
8255 };
8256 const serverSideBlockDefinitions = {};
8257 /**
8258 * Sets the server side block definition of blocks.
8259 *
8260 * @param {Object} definitions Server-side block definitions
8261 */
8262 // eslint-disable-next-line camelcase
8263
8264 function unstable__bootstrapServerSideBlockDefinitions(definitions) {
8265 for (const blockName of Object.keys(definitions)) {
8266 // Don't overwrite if already set. It covers the case when metadata
8267 // was initialized from the server.
8268 if (serverSideBlockDefinitions[blockName]) {
8269 // We still need to polyfill `apiVersion` for WordPress version
8270 // lower than 5.7. If it isn't present in the definition shared
8271 // from the server, we try to fallback to the definition passed.
8272 // @see https://github.com/WordPress/gutenberg/pull/29279
8273 if (serverSideBlockDefinitions[blockName].apiVersion === undefined && definitions[blockName].apiVersion) {
8274 serverSideBlockDefinitions[blockName].apiVersion = definitions[blockName].apiVersion;
8275 }
8276
8277 continue;
8278 }
8279
8280 serverSideBlockDefinitions[blockName] = (0,external_lodash_namespaceObject.mapKeys)((0,external_lodash_namespaceObject.pickBy)(definitions[blockName], value => !(0,external_lodash_namespaceObject.isNil)(value)), (value, key) => (0,external_lodash_namespaceObject.camelCase)(key));
8281 }
8282 }
8283 /**
8284 * Gets block settings from metadata loaded from `block.json` file.
8285 *
8286 * @param {Object} metadata Block metadata loaded from `block.json`.
8287 * @param {string} metadata.textdomain Textdomain to use with translations.
8288 *
8289 * @return {Object} Block settings.
8290 */
8291
8292 function getBlockSettingsFromMetadata({
8293 textdomain,
8294 ...metadata
8295 }) {
8296 const allowedFields = ['apiVersion', 'title', 'category', 'parent', 'icon', 'description', 'keywords', 'attributes', 'providesContext', 'usesContext', 'supports', 'styles', 'example', 'variations'];
8297 const settings = (0,external_lodash_namespaceObject.pick)(metadata, allowedFields);
8298
8299 if (textdomain) {
8300 Object.keys(i18nBlockSchema).forEach(key => {
8301 if (!settings[key]) {
8302 return;
8303 }
8304
8305 settings[key] = translateBlockSettingUsingI18nSchema(i18nBlockSchema[key], settings[key], textdomain);
8306 });
8307 }
8308
8309 return settings;
8310 }
8311 /**
8312 * Registers a new block provided a unique name and an object defining its
8313 * behavior. Once registered, the block is made available as an option to any
8314 * editor interface where blocks are implemented.
8315 *
8316 * @param {string|Object} blockNameOrMetadata Block type name or its metadata.
8317 * @param {Object} settings Block settings.
8318 *
8319 * @return {?WPBlockType} The block, if it has been successfully registered;
8320 * otherwise `undefined`.
8321 */
8322
8323
8324 function registerBlockType(blockNameOrMetadata, settings) {
8325 const name = (0,external_lodash_namespaceObject.isObject)(blockNameOrMetadata) ? blockNameOrMetadata.name : blockNameOrMetadata;
8326
8327 if (typeof name !== 'string') {
8328 console.error('Block names must be strings.');
8329 return;
8330 }
8331
8332 if ((0,external_lodash_namespaceObject.isObject)(blockNameOrMetadata)) {
8333 unstable__bootstrapServerSideBlockDefinitions({
8334 [name]: getBlockSettingsFromMetadata(blockNameOrMetadata)
8335 });
8336 }
8337
8338 settings = {
8339 name,
8340 icon: BLOCK_ICON_DEFAULT,
8341 keywords: [],
8342 attributes: {},
8343 providesContext: {},
8344 usesContext: [],
8345 supports: {},
8346 styles: [],
8347 save: () => null,
8348 ...(serverSideBlockDefinitions === null || serverSideBlockDefinitions === void 0 ? void 0 : serverSideBlockDefinitions[name]),
8349 ...settings
8350 };
8351
8352 if (!/^[a-z][a-z0-9-]*\/[a-z][a-z0-9-]*$/.test(name)) {
8353 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');
8354 return;
8355 }
8356
8357 if ((0,external_wp_data_namespaceObject.select)(store).getBlockType(name)) {
8358 console.error('Block "' + name + '" is already registered.');
8359 return;
8360 }
8361
8362 const preFilterSettings = { ...settings
8363 };
8364 settings = (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.registerBlockType', settings, name);
8365
8366 if (settings.deprecated) {
8367 settings.deprecated = settings.deprecated.map(deprecation => (0,external_lodash_namespaceObject.pick)( // Only keep valid deprecation keys.
8368 (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.registerBlockType', // Merge deprecation keys with pre-filter settings
8369 // so that filters that depend on specific keys being
8370 // present don't fail.
8371 { // Omit deprecation keys here so that deprecations
8372 // can opt out of specific keys like "supports".
8373 ...(0,external_lodash_namespaceObject.omit)(preFilterSettings, DEPRECATED_ENTRY_KEYS),
8374 ...deprecation
8375 }, name), DEPRECATED_ENTRY_KEYS));
8376 }
8377
8378 if (!(0,external_lodash_namespaceObject.isPlainObject)(settings)) {
8379 console.error('Block settings must be a valid object.');
8380 return;
8381 }
8382
8383 if (!(0,external_lodash_namespaceObject.isFunction)(settings.save)) {
8384 console.error('The "save" property must be a valid function.');
8385 return;
8386 }
8387
8388 if ('edit' in settings && !(0,external_lodash_namespaceObject.isFunction)(settings.edit)) {
8389 console.error('The "edit" property must be a valid function.');
8390 return;
8391 } // Canonicalize legacy categories to equivalent fallback.
8392
8393
8394 if (LEGACY_CATEGORY_MAPPING.hasOwnProperty(settings.category)) {
8395 settings.category = LEGACY_CATEGORY_MAPPING[settings.category];
8396 }
8397
8398 if ('category' in settings && !(0,external_lodash_namespaceObject.some)((0,external_wp_data_namespaceObject.select)(store).getCategories(), {
8399 slug: settings.category
8400 })) {
8401 console.warn('The block "' + name + '" is registered with an invalid category "' + settings.category + '".');
8402 delete settings.category;
8403 }
8404
8405 if (!('title' in settings) || settings.title === '') {
8406 console.error('The block "' + name + '" must have a title.');
8407 return;
8408 }
8409
8410 if (typeof settings.title !== 'string') {
8411 console.error('Block titles must be strings.');
8412 return;
8413 }
8414
8415 settings.icon = normalizeIconObject(settings.icon);
8416
8417 if (!isValidIcon(settings.icon.src)) {
8418 console.error('The icon passed is invalid. ' + 'The icon should be a string, an element, a function, or an object following the specifications documented in https://developer.wordpress.org/block-editor/developers/block-api/block-registration/#icon-optional');
8419 return;
8420 }
8421
8422 (0,external_wp_data_namespaceObject.dispatch)(store).addBlockTypes(settings);
8423 return settings;
8424 }
8425 /**
8426 * Translates block settings provided with metadata using the i18n schema.
8427 *
8428 * @param {string|string[]|Object[]} i18nSchema I18n schema for the block setting.
8429 * @param {string|string[]|Object[]} settingValue Value for the block setting.
8430 * @param {string} textdomain Textdomain to use with translations.
8431 *
8432 * @return {string|string[]|Object[]} Translated setting.
8433 */
8434
8435 function translateBlockSettingUsingI18nSchema(i18nSchema, settingValue, textdomain) {
8436 if ((0,external_lodash_namespaceObject.isString)(i18nSchema) && (0,external_lodash_namespaceObject.isString)(settingValue)) {
8437 // eslint-disable-next-line @wordpress/i18n-no-variables, @wordpress/i18n-text-domain
8438 return (0,external_wp_i18n_namespaceObject._x)(settingValue, i18nSchema, textdomain);
8439 }
8440
8441 if ((0,external_lodash_namespaceObject.isArray)(i18nSchema) && !(0,external_lodash_namespaceObject.isEmpty)(i18nSchema) && (0,external_lodash_namespaceObject.isArray)(settingValue)) {
8442 return settingValue.map(value => translateBlockSettingUsingI18nSchema(i18nSchema[0], value, textdomain));
8443 }
8444
8445 if ((0,external_lodash_namespaceObject.isObject)(i18nSchema) && !(0,external_lodash_namespaceObject.isEmpty)(i18nSchema) && (0,external_lodash_namespaceObject.isObject)(settingValue)) {
8446 return Object.keys(settingValue).reduce((accumulator, key) => {
8447 if (!i18nSchema[key]) {
8448 accumulator[key] = settingValue[key];
8449 return accumulator;
8450 }
8451
8452 accumulator[key] = translateBlockSettingUsingI18nSchema(i18nSchema[key], settingValue[key], textdomain);
8453 return accumulator;
8454 }, {});
8455 }
8456
8457 return settingValue;
8458 }
8459 /**
8460 * Registers a new block collection to group blocks in the same namespace in the inserter.
8461 *
8462 * @param {string} namespace The namespace to group blocks by in the inserter; corresponds to the block namespace.
8463 * @param {Object} settings The block collection settings.
8464 * @param {string} settings.title The title to display in the block inserter.
8465 * @param {Object} [settings.icon] The icon to display in the block inserter.
8466 */
8467
8468
8469 function registerBlockCollection(namespace, {
8470 title,
8471 icon
8472 }) {
8473 (0,external_wp_data_namespaceObject.dispatch)(store).addBlockCollection(namespace, title, icon);
8474 }
8475 /**
8476 * Unregisters a block collection
8477 *
8478 * @param {string} namespace The namespace to group blocks by in the inserter; corresponds to the block namespace
8479 *
8480 */
8481
8482 function unregisterBlockCollection(namespace) {
8483 dispatch(blocksStore).removeBlockCollection(namespace);
8484 }
8485 /**
8486 * Unregisters a block.
8487 *
8488 * @param {string} name Block name.
8489 *
8490 * @return {?WPBlockType} The previous block value, if it has been successfully
8491 * unregistered; otherwise `undefined`.
8492 */
8493
8494 function unregisterBlockType(name) {
8495 const oldBlock = (0,external_wp_data_namespaceObject.select)(store).getBlockType(name);
8496
8497 if (!oldBlock) {
8498 console.error('Block "' + name + '" is not registered.');
8499 return;
8500 }
8501
8502 (0,external_wp_data_namespaceObject.dispatch)(store).removeBlockTypes(name);
8503 return oldBlock;
8504 }
8505 /**
8506 * Assigns name of block for handling non-block content.
8507 *
8508 * @param {string} blockName Block name.
8509 */
8510
8511 function setFreeformContentHandlerName(blockName) {
8512 (0,external_wp_data_namespaceObject.dispatch)(store).setFreeformFallbackBlockName(blockName);
8513 }
8514 /**
8515 * Retrieves name of block handling non-block content, or undefined if no
8516 * handler has been defined.
8517 *
8518 * @return {?string} Block name.
8519 */
8520
8521 function getFreeformContentHandlerName() {
8522 return (0,external_wp_data_namespaceObject.select)(store).getFreeformFallbackBlockName();
8523 }
8524 /**
8525 * Retrieves name of block used for handling grouping interactions.
8526 *
8527 * @return {?string} Block name.
8528 */
8529
8530 function registration_getGroupingBlockName() {
8531 return (0,external_wp_data_namespaceObject.select)(store).getGroupingBlockName();
8532 }
8533 /**
8534 * Assigns name of block handling unregistered block types.
8535 *
8536 * @param {string} blockName Block name.
8537 */
8538
8539 function setUnregisteredTypeHandlerName(blockName) {
8540 (0,external_wp_data_namespaceObject.dispatch)(store).setUnregisteredFallbackBlockName(blockName);
8541 }
8542 /**
8543 * Retrieves name of block handling unregistered block types, or undefined if no
8544 * handler has been defined.
8545 *
8546 * @return {?string} Block name.
8547 */
8548
8549 function getUnregisteredTypeHandlerName() {
8550 return (0,external_wp_data_namespaceObject.select)(store).getUnregisteredFallbackBlockName();
8551 }
8552 /**
8553 * Assigns the default block name.
8554 *
8555 * @param {string} name Block name.
8556 */
8557
8558 function registration_setDefaultBlockName(name) {
8559 (0,external_wp_data_namespaceObject.dispatch)(store).setDefaultBlockName(name);
8560 }
8561 /**
8562 * Assigns name of block for handling block grouping interactions.
8563 *
8564 * @param {string} name Block name.
8565 */
8566
8567 function registration_setGroupingBlockName(name) {
8568 (0,external_wp_data_namespaceObject.dispatch)(store).setGroupingBlockName(name);
8569 }
8570 /**
8571 * Retrieves the default block name.
8572 *
8573 * @return {?string} Block name.
8574 */
8575
8576 function registration_getDefaultBlockName() {
8577 return (0,external_wp_data_namespaceObject.select)(store).getDefaultBlockName();
8578 }
8579 /**
8580 * Returns a registered block type.
8581 *
8582 * @param {string} name Block name.
8583 *
8584 * @return {?Object} Block type.
8585 */
8586
8587 function registration_getBlockType(name) {
8588 var _select;
8589
8590 return (_select = (0,external_wp_data_namespaceObject.select)(store)) === null || _select === void 0 ? void 0 : _select.getBlockType(name);
8591 }
8592 /**
8593 * Returns all registered blocks.
8594 *
8595 * @return {Array} Block settings.
8596 */
8597
8598 function registration_getBlockTypes() {
8599 return (0,external_wp_data_namespaceObject.select)(store).getBlockTypes();
8600 }
8601 /**
8602 * Returns the block support value for a feature, if defined.
8603 *
8604 * @param {(string|Object)} nameOrType Block name or type object
8605 * @param {string} feature Feature to retrieve
8606 * @param {*} defaultSupports Default value to return if not
8607 * explicitly defined
8608 *
8609 * @return {?*} Block support value
8610 */
8611
8612 function registration_getBlockSupport(nameOrType, feature, defaultSupports) {
8613 return (0,external_wp_data_namespaceObject.select)(store).getBlockSupport(nameOrType, feature, defaultSupports);
8614 }
8615 /**
8616 * Returns true if the block defines support for a feature, or false otherwise.
8617 *
8618 * @param {(string|Object)} nameOrType Block name or type object.
8619 * @param {string} feature Feature to test.
8620 * @param {boolean} defaultSupports Whether feature is supported by
8621 * default if not explicitly defined.
8622 *
8623 * @return {boolean} Whether block supports feature.
8624 */
8625
8626 function registration_hasBlockSupport(nameOrType, feature, defaultSupports) {
8627 return (0,external_wp_data_namespaceObject.select)(store).hasBlockSupport(nameOrType, feature, defaultSupports);
8628 }
8629 /**
8630 * Determines whether or not the given block is a reusable block. This is a
8631 * special block type that is used to point to a global block stored via the
8632 * API.
8633 *
8634 * @param {Object} blockOrType Block or Block Type to test.
8635 *
8636 * @return {boolean} Whether the given block is a reusable block.
8637 */
8638
8639 function isReusableBlock(blockOrType) {
8640 return (blockOrType === null || blockOrType === void 0 ? void 0 : blockOrType.name) === 'core/block';
8641 }
8642 /**
8643 * Determines whether or not the given block is a template part. This is a
8644 * special block type that allows composing a page template out of reusable
8645 * design elements.
8646 *
8647 * @param {Object} blockOrType Block or Block Type to test.
8648 *
8649 * @return {boolean} Whether the given block is a template part.
8650 */
8651
8652 function isTemplatePart(blockOrType) {
8653 return blockOrType.name === 'core/template-part';
8654 }
8655 /**
8656 * Returns an array with the child blocks of a given block.
8657 *
8658 * @param {string} blockName Name of block (example: “latest-posts”).
8659 *
8660 * @return {Array} Array of child block names.
8661 */
8662
8663 const registration_getChildBlockNames = blockName => {
8664 return (0,external_wp_data_namespaceObject.select)(store).getChildBlockNames(blockName);
8665 };
8666 /**
8667 * Returns a boolean indicating if a block has child blocks or not.
8668 *
8669 * @param {string} blockName Name of block (example: “latest-posts”).
8670 *
8671 * @return {boolean} True if a block contains child blocks and false otherwise.
8672 */
8673
8674 const registration_hasChildBlocks = blockName => {
8675 return (0,external_wp_data_namespaceObject.select)(store).hasChildBlocks(blockName);
8676 };
8677 /**
8678 * Returns a boolean indicating if a block has at least one child block with inserter support.
8679 *
8680 * @param {string} blockName Block type name.
8681 *
8682 * @return {boolean} True if a block contains at least one child blocks with inserter support
8683 * and false otherwise.
8684 */
8685
8686 const registration_hasChildBlocksWithInserterSupport = blockName => {
8687 return (0,external_wp_data_namespaceObject.select)(store).hasChildBlocksWithInserterSupport(blockName);
8688 };
8689 /**
8690 * Registers a new block style variation for the given block.
8691 *
8692 * @param {string} blockName Name of block (example: “core/latest-posts”).
8693 * @param {Object} styleVariation Object containing `name` which is the class name applied to the block and `label` which identifies the variation to the user.
8694 */
8695
8696 const registerBlockStyle = (blockName, styleVariation) => {
8697 (0,external_wp_data_namespaceObject.dispatch)(store).addBlockStyles(blockName, styleVariation);
8698 };
8699 /**
8700 * Unregisters a block style variation for the given block.
8701 *
8702 * @param {string} blockName Name of block (example: “core/latest-posts”).
8703 * @param {string} styleVariationName Name of class applied to the block.
8704 */
8705
8706 const unregisterBlockStyle = (blockName, styleVariationName) => {
8707 (0,external_wp_data_namespaceObject.dispatch)(store).removeBlockStyles(blockName, styleVariationName);
8708 };
8709 /**
8710 * Returns an array with the variations of a given block type.
8711 *
8712 * @param {string} blockName Name of block (example: “core/columns”).
8713 * @param {WPBlockVariationScope} [scope] Block variation scope name.
8714 *
8715 * @return {(WPBlockVariation[]|void)} Block variations.
8716 */
8717
8718 const registration_getBlockVariations = (blockName, scope) => {
8719 return (0,external_wp_data_namespaceObject.select)(store).getBlockVariations(blockName, scope);
8720 };
8721 /**
8722 * Registers a new block variation for the given block type.
8723 *
8724 * @param {string} blockName Name of the block (example: “core/columns”).
8725 * @param {WPBlockVariation} variation Object describing a block variation.
8726 */
8727
8728 const registerBlockVariation = (blockName, variation) => {
8729 (0,external_wp_data_namespaceObject.dispatch)(store).addBlockVariations(blockName, variation);
8730 };
8731 /**
8732 * Unregisters a block variation defined for the given block type.
8733 *
8734 * @param {string} blockName Name of the block (example: “core/columns”).
8735 * @param {string} variationName Name of the variation defined for the block.
8736 */
8737
8738 const unregisterBlockVariation = (blockName, variationName) => {
8739 (0,external_wp_data_namespaceObject.dispatch)(store).removeBlockVariations(blockName, variationName);
8740 };
8741 //# sourceMappingURL=registration.js.map
8742 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/factory.js
8743 /**
8744 * External dependencies
8745 */
8746
8747
8748 /**
8749 * WordPress dependencies
8750 */
8751
8752
8753 /**
8754 * Internal dependencies
8755 */
8756
8757
8758
8759 /**
8760 * Returns a block object given its type and attributes.
8761 *
8762 * @param {string} name Block name.
8763 * @param {Object} attributes Block attributes.
8764 * @param {?Array} innerBlocks Nested blocks.
8765 *
8766 * @return {Object} Block object.
8767 */
8768
8769 function createBlock(name, attributes = {}, innerBlocks = []) {
8770 const sanitizedAttributes = __experimentalSanitizeBlockAttributes(name, attributes);
8771
8772 const clientId = esm_browser_v4(); // Blocks are stored with a unique ID, the assigned type name, the block
8773 // attributes, and their inner blocks.
8774
8775 return {
8776 clientId,
8777 name,
8778 isValid: true,
8779 attributes: sanitizedAttributes,
8780 innerBlocks
8781 };
8782 }
8783 /**
8784 * Given an array of InnerBlocks templates or Block Objects,
8785 * returns an array of created Blocks from them.
8786 * It handles the case of having InnerBlocks as Blocks by
8787 * converting them to the proper format to continue recursively.
8788 *
8789 * @param {Array} innerBlocksOrTemplate Nested blocks or InnerBlocks templates.
8790 *
8791 * @return {Object[]} Array of Block objects.
8792 */
8793
8794 function createBlocksFromInnerBlocksTemplate(innerBlocksOrTemplate = []) {
8795 return innerBlocksOrTemplate.map(innerBlock => {
8796 const innerBlockTemplate = Array.isArray(innerBlock) ? innerBlock : [innerBlock.name, innerBlock.attributes, innerBlock.innerBlocks];
8797 const [name, attributes, innerBlocks = []] = innerBlockTemplate;
8798 return createBlock(name, attributes, createBlocksFromInnerBlocksTemplate(innerBlocks));
8799 });
8800 }
8801 /**
8802 * Given a block object, returns a copy of the block object while sanitizing its attributes,
8803 * optionally merging new attributes and/or replacing its inner blocks.
8804 *
8805 * @param {Object} block Block instance.
8806 * @param {Object} mergeAttributes Block attributes.
8807 * @param {?Array} newInnerBlocks Nested blocks.
8808 *
8809 * @return {Object} A cloned block.
8810 */
8811
8812 function __experimentalCloneSanitizedBlock(block, mergeAttributes = {}, newInnerBlocks) {
8813 const clientId = esm_browser_v4();
8814
8815 const sanitizedAttributes = __experimentalSanitizeBlockAttributes(block.name, { ...block.attributes,
8816 ...mergeAttributes
8817 });
8818
8819 return { ...block,
8820 clientId,
8821 attributes: sanitizedAttributes,
8822 innerBlocks: newInnerBlocks || block.innerBlocks.map(innerBlock => __experimentalCloneSanitizedBlock(innerBlock))
8823 };
8824 }
8825 /**
8826 * Given a block object, returns a copy of the block object,
8827 * optionally merging new attributes and/or replacing its inner blocks.
8828 *
8829 * @param {Object} block Block instance.
8830 * @param {Object} mergeAttributes Block attributes.
8831 * @param {?Array} newInnerBlocks Nested blocks.
8832 *
8833 * @return {Object} A cloned block.
8834 */
8835
8836 function cloneBlock(block, mergeAttributes = {}, newInnerBlocks) {
8837 const clientId = esm_browser_v4();
8838 return { ...block,
8839 clientId,
8840 attributes: { ...block.attributes,
8841 ...mergeAttributes
8842 },
8843 innerBlocks: newInnerBlocks || block.innerBlocks.map(innerBlock => cloneBlock(innerBlock))
8844 };
8845 }
8846 /**
8847 * Returns a boolean indicating whether a transform is possible based on
8848 * various bits of context.
8849 *
8850 * @param {Object} transform The transform object to validate.
8851 * @param {string} direction Is this a 'from' or 'to' transform.
8852 * @param {Array} blocks The blocks to transform from.
8853 *
8854 * @return {boolean} Is the transform possible?
8855 */
8856
8857 const isPossibleTransformForSource = (transform, direction, blocks) => {
8858 if ((0,external_lodash_namespaceObject.isEmpty)(blocks)) {
8859 return false;
8860 } // If multiple blocks are selected, only multi block transforms
8861 // or wildcard transforms are allowed.
8862
8863
8864 const isMultiBlock = blocks.length > 1;
8865 const firstBlockName = (0,external_lodash_namespaceObject.first)(blocks).name;
8866 const isValidForMultiBlocks = isWildcardBlockTransform(transform) || !isMultiBlock || transform.isMultiBlock;
8867
8868 if (!isValidForMultiBlocks) {
8869 return false;
8870 } // Check non-wildcard transforms to ensure that transform is valid
8871 // for a block selection of multiple blocks of different types
8872
8873
8874 if (!isWildcardBlockTransform(transform) && !(0,external_lodash_namespaceObject.every)(blocks, {
8875 name: firstBlockName
8876 })) {
8877 return false;
8878 } // Only consider 'block' type transforms as valid.
8879
8880
8881 const isBlockType = transform.type === 'block';
8882
8883 if (!isBlockType) {
8884 return false;
8885 } // Check if the transform's block name matches the source block (or is a wildcard)
8886 // only if this is a transform 'from'.
8887
8888
8889 const sourceBlock = (0,external_lodash_namespaceObject.first)(blocks);
8890 const hasMatchingName = direction !== 'from' || transform.blocks.indexOf(sourceBlock.name) !== -1 || isWildcardBlockTransform(transform);
8891
8892 if (!hasMatchingName) {
8893 return false;
8894 } // Don't allow single Grouping blocks to be transformed into
8895 // a Grouping block.
8896
8897
8898 if (!isMultiBlock && isContainerGroupBlock(sourceBlock.name) && isContainerGroupBlock(transform.blockName)) {
8899 return false;
8900 } // If the transform has a `isMatch` function specified, check that it returns true.
8901
8902
8903 if ((0,external_lodash_namespaceObject.isFunction)(transform.isMatch)) {
8904 const attributes = transform.isMultiBlock ? blocks.map(block => block.attributes) : sourceBlock.attributes;
8905 const block = transform.isMultiBlock ? blocks : sourceBlock;
8906
8907 if (!transform.isMatch(attributes, block)) {
8908 return false;
8909 }
8910 }
8911
8912 if (transform.usingMobileTransformations && isWildcardBlockTransform(transform) && !isContainerGroupBlock(sourceBlock.name)) {
8913 return false;
8914 }
8915
8916 return true;
8917 };
8918 /**
8919 * Returns block types that the 'blocks' can be transformed into, based on
8920 * 'from' transforms on other blocks.
8921 *
8922 * @param {Array} blocks The blocks to transform from.
8923 *
8924 * @return {Array} Block types that the blocks can be transformed into.
8925 */
8926
8927
8928 const getBlockTypesForPossibleFromTransforms = blocks => {
8929 if ((0,external_lodash_namespaceObject.isEmpty)(blocks)) {
8930 return [];
8931 }
8932
8933 const allBlockTypes = registration_getBlockTypes(); // filter all blocks to find those with a 'from' transform.
8934
8935 const blockTypesWithPossibleFromTransforms = (0,external_lodash_namespaceObject.filter)(allBlockTypes, blockType => {
8936 const fromTransforms = getBlockTransforms('from', blockType.name);
8937 return !!findTransform(fromTransforms, transform => {
8938 return isPossibleTransformForSource(transform, 'from', blocks);
8939 });
8940 });
8941 return blockTypesWithPossibleFromTransforms;
8942 };
8943 /**
8944 * Returns block types that the 'blocks' can be transformed into, based on
8945 * the source block's own 'to' transforms.
8946 *
8947 * @param {Array} blocks The blocks to transform from.
8948 *
8949 * @return {Array} Block types that the source can be transformed into.
8950 */
8951
8952
8953 const getBlockTypesForPossibleToTransforms = blocks => {
8954 if ((0,external_lodash_namespaceObject.isEmpty)(blocks)) {
8955 return [];
8956 }
8957
8958 const sourceBlock = (0,external_lodash_namespaceObject.first)(blocks);
8959 const blockType = registration_getBlockType(sourceBlock.name);
8960 const transformsTo = blockType ? getBlockTransforms('to', blockType.name) : []; // filter all 'to' transforms to find those that are possible.
8961
8962 const possibleTransforms = (0,external_lodash_namespaceObject.filter)(transformsTo, transform => {
8963 return transform && isPossibleTransformForSource(transform, 'to', blocks);
8964 }); // Build a list of block names using the possible 'to' transforms.
8965
8966 const blockNames = (0,external_lodash_namespaceObject.flatMap)(possibleTransforms, transformation => transformation.blocks); // Map block names to block types.
8967
8968 return blockNames.map(name => registration_getBlockType(name));
8969 };
8970 /**
8971 * Determines whether transform is a "block" type
8972 * and if so whether it is a "wildcard" transform
8973 * ie: targets "any" block type
8974 *
8975 * @param {Object} t the Block transform object
8976 *
8977 * @return {boolean} whether transform is a wildcard transform
8978 */
8979
8980
8981 const isWildcardBlockTransform = t => t && t.type === 'block' && Array.isArray(t.blocks) && t.blocks.includes('*');
8982 /**
8983 * Determines whether the given Block is the core Block which
8984 * acts as a container Block for other Blocks as part of the
8985 * Grouping mechanics
8986 *
8987 * @param {string} name the name of the Block to test against
8988 *
8989 * @return {boolean} whether or not the Block is the container Block type
8990 */
8991
8992 const isContainerGroupBlock = name => name === registration_getGroupingBlockName();
8993 /**
8994 * Returns an array of block types that the set of blocks received as argument
8995 * can be transformed into.
8996 *
8997 * @param {Array} blocks Blocks array.
8998 *
8999 * @return {Array} Block types that the blocks argument can be transformed to.
9000 */
9001
9002 function getPossibleBlockTransformations(blocks) {
9003 if ((0,external_lodash_namespaceObject.isEmpty)(blocks)) {
9004 return [];
9005 }
9006
9007 const blockTypesForFromTransforms = getBlockTypesForPossibleFromTransforms(blocks);
9008 const blockTypesForToTransforms = getBlockTypesForPossibleToTransforms(blocks);
9009 return (0,external_lodash_namespaceObject.uniq)([...blockTypesForFromTransforms, ...blockTypesForToTransforms]);
9010 }
9011 /**
9012 * Given an array of transforms, returns the highest-priority transform where
9013 * the predicate function returns a truthy value. A higher-priority transform
9014 * is one with a lower priority value (i.e. first in priority order). Returns
9015 * null if the transforms set is empty or the predicate function returns a
9016 * falsey value for all entries.
9017 *
9018 * @param {Object[]} transforms Transforms to search.
9019 * @param {Function} predicate Function returning true on matching transform.
9020 *
9021 * @return {?Object} Highest-priority transform candidate.
9022 */
9023
9024 function findTransform(transforms, predicate) {
9025 // The hooks library already has built-in mechanisms for managing priority
9026 // queue, so leverage via locally-defined instance.
9027 const hooks = (0,external_wp_hooks_namespaceObject.createHooks)();
9028
9029 for (let i = 0; i < transforms.length; i++) {
9030 const candidate = transforms[i];
9031
9032 if (predicate(candidate)) {
9033 hooks.addFilter('transform', 'transform/' + i.toString(), result => result ? result : candidate, candidate.priority);
9034 }
9035 } // Filter name is arbitrarily chosen but consistent with above aggregation.
9036
9037
9038 return hooks.applyFilters('transform', null);
9039 }
9040 /**
9041 * Returns normal block transforms for a given transform direction, optionally
9042 * for a specific block by name, or an empty array if there are no transforms.
9043 * If no block name is provided, returns transforms for all blocks. A normal
9044 * transform object includes `blockName` as a property.
9045 *
9046 * @param {string} direction Transform direction ("to", "from").
9047 * @param {string|Object} blockTypeOrName Block type or name.
9048 *
9049 * @return {Array} Block transforms for direction.
9050 */
9051
9052 function getBlockTransforms(direction, blockTypeOrName) {
9053 // When retrieving transforms for all block types, recurse into self.
9054 if (blockTypeOrName === undefined) {
9055 return (0,external_lodash_namespaceObject.flatMap)(registration_getBlockTypes(), ({
9056 name
9057 }) => getBlockTransforms(direction, name));
9058 } // Validate that block type exists and has array of direction.
9059
9060
9061 const blockType = normalizeBlockType(blockTypeOrName);
9062 const {
9063 name: blockName,
9064 transforms
9065 } = blockType || {};
9066
9067 if (!transforms || !Array.isArray(transforms[direction])) {
9068 return [];
9069 }
9070
9071 const usingMobileTransformations = transforms.supportedMobileTransforms && Array.isArray(transforms.supportedMobileTransforms);
9072 const filteredTransforms = usingMobileTransformations ? (0,external_lodash_namespaceObject.filter)(transforms[direction], t => {
9073 if (t.type === 'raw') {
9074 return true;
9075 }
9076
9077 if (!t.blocks || !t.blocks.length) {
9078 return false;
9079 }
9080
9081 if (isWildcardBlockTransform(t)) {
9082 return true;
9083 }
9084
9085 return (0,external_lodash_namespaceObject.every)(t.blocks, transformBlockName => transforms.supportedMobileTransforms.includes(transformBlockName));
9086 }) : transforms[direction]; // Map transforms to normal form.
9087
9088 return filteredTransforms.map(transform => ({ ...transform,
9089 blockName,
9090 usingMobileTransformations
9091 }));
9092 }
9093 /**
9094 * Switch one or more blocks into one or more blocks of the new block type.
9095 *
9096 * @param {Array|Object} blocks Blocks array or block object.
9097 * @param {string} name Block name.
9098 *
9099 * @return {?Array} Array of blocks or null.
9100 */
9101
9102 function switchToBlockType(blocks, name) {
9103 const blocksArray = (0,external_lodash_namespaceObject.castArray)(blocks);
9104 const isMultiBlock = blocksArray.length > 1;
9105 const firstBlock = blocksArray[0];
9106 const sourceName = firstBlock.name; // Find the right transformation by giving priority to the "to"
9107 // transformation.
9108
9109 const transformationsFrom = getBlockTransforms('from', name);
9110 const transformationsTo = getBlockTransforms('to', sourceName);
9111 const transformation = findTransform(transformationsTo, t => t.type === 'block' && (isWildcardBlockTransform(t) || t.blocks.indexOf(name) !== -1) && (!isMultiBlock || t.isMultiBlock)) || findTransform(transformationsFrom, t => t.type === 'block' && (isWildcardBlockTransform(t) || t.blocks.indexOf(sourceName) !== -1) && (!isMultiBlock || t.isMultiBlock)); // Stop if there is no valid transformation.
9112
9113 if (!transformation) {
9114 return null;
9115 }
9116
9117 let transformationResults;
9118
9119 if (transformation.isMultiBlock) {
9120 if ((0,external_lodash_namespaceObject.has)(transformation, '__experimentalConvert')) {
9121 transformationResults = transformation.__experimentalConvert(blocksArray);
9122 } else {
9123 transformationResults = transformation.transform(blocksArray.map(currentBlock => currentBlock.attributes), blocksArray.map(currentBlock => currentBlock.innerBlocks));
9124 }
9125 } else if ((0,external_lodash_namespaceObject.has)(transformation, '__experimentalConvert')) {
9126 transformationResults = transformation.__experimentalConvert(firstBlock);
9127 } else {
9128 transformationResults = transformation.transform(firstBlock.attributes, firstBlock.innerBlocks);
9129 } // Ensure that the transformation function returned an object or an array
9130 // of objects.
9131
9132
9133 if (!(0,external_lodash_namespaceObject.isObjectLike)(transformationResults)) {
9134 return null;
9135 } // If the transformation function returned a single object, we want to work
9136 // with an array instead.
9137
9138
9139 transformationResults = (0,external_lodash_namespaceObject.castArray)(transformationResults); // Ensure that every block object returned by the transformation has a
9140 // valid block type.
9141
9142 if (transformationResults.some(result => !registration_getBlockType(result.name))) {
9143 return null;
9144 }
9145
9146 const hasSwitchedBlock = (0,external_lodash_namespaceObject.some)(transformationResults, result => result.name === name); // Ensure that at least one block object returned by the transformation has
9147 // the expected "destination" block type.
9148
9149 if (!hasSwitchedBlock) {
9150 return null;
9151 }
9152
9153 const ret = transformationResults.map(result => {
9154 /**
9155 * Filters an individual transform result from block transformation.
9156 * All of the original blocks are passed, since transformations are
9157 * many-to-many, not one-to-one.
9158 *
9159 * @param {Object} transformedBlock The transformed block.
9160 * @param {Object[]} blocks Original blocks transformed.
9161 */
9162 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.switchToBlockType.transformedBlock', result, blocks);
9163 });
9164 return ret;
9165 }
9166 /**
9167 * Create a block object from the example API.
9168 *
9169 * @param {string} name
9170 * @param {Object} example
9171 *
9172 * @return {Object} block.
9173 */
9174
9175 const getBlockFromExample = (name, example) => {
9176 return createBlock(name, example.attributes, (0,external_lodash_namespaceObject.map)(example.innerBlocks, innerBlock => getBlockFromExample(innerBlock.name, innerBlock)));
9177 };
9178 //# sourceMappingURL=factory.js.map
9179 ;// CONCATENATED MODULE: external ["wp","blockSerializationDefaultParser"]
9180 var external_wp_blockSerializationDefaultParser_namespaceObject = window["wp"]["blockSerializationDefaultParser"];
9181 ;// CONCATENATED MODULE: external ["wp","autop"]
9182 var external_wp_autop_namespaceObject = window["wp"]["autop"];
9183 ;// CONCATENATED MODULE: external ["wp","isShallowEqual"]
9184 var external_wp_isShallowEqual_namespaceObject = window["wp"]["isShallowEqual"];
9185 var external_wp_isShallowEqual_default = /*#__PURE__*/__webpack_require__.n(external_wp_isShallowEqual_namespaceObject);
9186 ;// CONCATENATED MODULE: ./node_modules/@babel/runtime/helpers/esm/extends.js
9187 function _extends() {
9188 _extends = Object.assign || function (target) {
9189 for (var i = 1; i < arguments.length; i++) {
9190 var source = arguments[i];
9191
9192 for (var key in source) {
9193 if (Object.prototype.hasOwnProperty.call(source, key)) {
9194 target[key] = source[key];
9195 }
9196 }
9197 }
9198
9199 return target;
9200 };
9201
9202 return _extends.apply(this, arguments);
9203 }
9204 ;// CONCATENATED MODULE: external ["wp","compose"]
9205 var external_wp_compose_namespaceObject = window["wp"]["compose"];
9206 ;// CONCATENATED MODULE: ./packages/blocks/build-module/block-content-provider/index.js
9207
9208
9209
9210 /**
9211 * WordPress dependencies
9212 */
9213
9214
9215 /**
9216 * Internal dependencies
9217 */
9218
9219
9220 const {
9221 Consumer,
9222 Provider
9223 } = (0,external_wp_element_namespaceObject.createContext)(() => {});
9224 /**
9225 * An internal block component used in block content serialization to inject
9226 * nested block content within the `save` implementation of the ancestor
9227 * component in which it is nested. The component provides a pre-bound
9228 * `BlockContent` component via context, which is used by the developer-facing
9229 * `InnerBlocks.Content` component to render block content.
9230 *
9231 * @example
9232 *
9233 * ```jsx
9234 * <BlockContentProvider innerBlocks={ innerBlocks }>
9235 * { blockSaveElement }
9236 * </BlockContentProvider>
9237 * ```
9238 *
9239 * @param {Object} props Component props.
9240 * @param {WPElement} props.children Block save result.
9241 * @param {Array} props.innerBlocks Block(s) to serialize.
9242 *
9243 * @return {WPComponent} Element with BlockContent injected via context.
9244 */
9245
9246 const BlockContentProvider = ({
9247 children,
9248 innerBlocks
9249 }) => {
9250 const BlockContent = () => {
9251 // Value is an array of blocks, so defer to block serializer
9252 const html = serialize(innerBlocks, {
9253 isInnerBlocks: true
9254 }); // Use special-cased raw HTML tag to avoid default escaping
9255
9256 return (0,external_wp_element_namespaceObject.createElement)(external_wp_element_namespaceObject.RawHTML, null, html);
9257 };
9258
9259 return (0,external_wp_element_namespaceObject.createElement)(Provider, {
9260 value: BlockContent
9261 }, children);
9262 };
9263 /**
9264 * A Higher Order Component used to inject BlockContent using context to the
9265 * wrapped component.
9266 *
9267 * @return {WPComponent} Enhanced component with injected BlockContent as prop.
9268 */
9269
9270
9271 const withBlockContentContext = (0,external_wp_compose_namespaceObject.createHigherOrderComponent)(OriginalComponent => {
9272 return props => (0,external_wp_element_namespaceObject.createElement)(Consumer, null, context => (0,external_wp_element_namespaceObject.createElement)(OriginalComponent, _extends({}, props, {
9273 BlockContent: context
9274 })));
9275 }, 'withBlockContentContext');
9276 /* harmony default export */ var block_content_provider = (BlockContentProvider);
9277 //# sourceMappingURL=index.js.map
9278 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/serializer.js
9279
9280
9281 /**
9282 * External dependencies
9283 */
9284
9285 /**
9286 * WordPress dependencies
9287 */
9288
9289
9290
9291
9292
9293 /**
9294 * Internal dependencies
9295 */
9296
9297
9298
9299
9300 /**
9301 * @typedef {Object} WPBlockSerializationOptions Serialization Options.
9302 *
9303 * @property {boolean} isInnerBlocks Whether we are serializing inner blocks.
9304 */
9305
9306 /**
9307 * Returns the block's default classname from its name.
9308 *
9309 * @param {string} blockName The block name.
9310 *
9311 * @return {string} The block's default class.
9312 */
9313
9314 function getBlockDefaultClassName(blockName) {
9315 // Generated HTML classes for blocks follow the `wp-block-{name}` nomenclature.
9316 // Blocks provided by WordPress drop the prefixes 'core/' or 'core-' (historically used in 'core-embed/').
9317 const className = 'wp-block-' + blockName.replace(/\//, '-').replace(/^core-/, '');
9318 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getBlockDefaultClassName', className, blockName);
9319 }
9320 /**
9321 * Returns the block's default menu item classname from its name.
9322 *
9323 * @param {string} blockName The block name.
9324 *
9325 * @return {string} The block's default menu item class.
9326 */
9327
9328 function getBlockMenuDefaultClassName(blockName) {
9329 // Generated HTML classes for blocks follow the `editor-block-list-item-{name}` nomenclature.
9330 // Blocks provided by WordPress drop the prefixes 'core/' or 'core-' (historically used in 'core-embed/').
9331 const className = 'editor-block-list-item-' + blockName.replace(/\//, '-').replace(/^core-/, '');
9332 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getBlockMenuDefaultClassName', className, blockName);
9333 }
9334 const blockPropsProvider = {};
9335 /**
9336 * Call within a save function to get the props for the block wrapper.
9337 *
9338 * @param {Object} props Optional. Props to pass to the element.
9339 */
9340
9341 function getBlockProps(props = {}) {
9342 const {
9343 blockType,
9344 attributes
9345 } = blockPropsProvider;
9346 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getSaveContent.extraProps', { ...props
9347 }, blockType, attributes);
9348 }
9349 /**
9350 * Given a block type containing a save render implementation and attributes, returns the
9351 * enhanced element to be saved or string when raw HTML expected.
9352 *
9353 * @param {string|Object} blockTypeOrName Block type or name.
9354 * @param {Object} attributes Block attributes.
9355 * @param {?Array} innerBlocks Nested blocks.
9356 *
9357 * @return {Object|string} Save element or raw HTML string.
9358 */
9359
9360 function getSaveElement(blockTypeOrName, attributes, innerBlocks = []) {
9361 const blockType = normalizeBlockType(blockTypeOrName);
9362 let {
9363 save
9364 } = blockType; // Component classes are unsupported for save since serialization must
9365 // occur synchronously. For improved interoperability with higher-order
9366 // components which often return component class, emulate basic support.
9367
9368 if (save.prototype instanceof external_wp_element_namespaceObject.Component) {
9369 const instance = new save({
9370 attributes
9371 });
9372 save = instance.render.bind(instance);
9373 }
9374
9375 blockPropsProvider.blockType = blockType;
9376 blockPropsProvider.attributes = attributes;
9377 let element = save({
9378 attributes,
9379 innerBlocks
9380 });
9381
9382 if ((0,external_lodash_namespaceObject.isObject)(element) && (0,external_wp_hooks_namespaceObject.hasFilter)('blocks.getSaveContent.extraProps') && !(blockType.apiVersion > 1)) {
9383 /**
9384 * Filters the props applied to the block save result element.
9385 *
9386 * @param {Object} props Props applied to save element.
9387 * @param {WPBlock} blockType Block type definition.
9388 * @param {Object} attributes Block attributes.
9389 */
9390 const props = (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getSaveContent.extraProps', { ...element.props
9391 }, blockType, attributes);
9392
9393 if (!external_wp_isShallowEqual_default()(props, element.props)) {
9394 element = (0,external_wp_element_namespaceObject.cloneElement)(element, props);
9395 }
9396 }
9397 /**
9398 * Filters the save result of a block during serialization.
9399 *
9400 * @param {WPElement} element Block save result.
9401 * @param {WPBlock} blockType Block type definition.
9402 * @param {Object} attributes Block attributes.
9403 */
9404
9405
9406 element = (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getSaveElement', element, blockType, attributes);
9407 return (0,external_wp_element_namespaceObject.createElement)(block_content_provider, {
9408 innerBlocks: innerBlocks
9409 }, element);
9410 }
9411 /**
9412 * Given a block type containing a save render implementation and attributes, returns the
9413 * static markup to be saved.
9414 *
9415 * @param {string|Object} blockTypeOrName Block type or name.
9416 * @param {Object} attributes Block attributes.
9417 * @param {?Array} innerBlocks Nested blocks.
9418 *
9419 * @return {string} Save content.
9420 */
9421
9422 function getSaveContent(blockTypeOrName, attributes, innerBlocks) {
9423 const blockType = normalizeBlockType(blockTypeOrName);
9424 return (0,external_wp_element_namespaceObject.renderToString)(getSaveElement(blockType, attributes, innerBlocks));
9425 }
9426 /**
9427 * Returns attributes which are to be saved and serialized into the block
9428 * comment delimiter.
9429 *
9430 * When a block exists in memory it contains as its attributes both those
9431 * parsed the block comment delimiter _and_ those which matched from the
9432 * contents of the block.
9433 *
9434 * This function returns only those attributes which are needed to persist and
9435 * which cannot be matched from the block content.
9436 *
9437 * @param {Object<string,*>} blockType Block type.
9438 * @param {Object<string,*>} attributes Attributes from in-memory block data.
9439 *
9440 * @return {Object<string,*>} Subset of attributes for comment serialization.
9441 */
9442
9443 function getCommentAttributes(blockType, attributes) {
9444 return (0,external_lodash_namespaceObject.reduce)(blockType.attributes, (accumulator, attributeSchema, key) => {
9445 const value = attributes[key]; // Ignore undefined values.
9446
9447 if (undefined === value) {
9448 return accumulator;
9449 } // Ignore all attributes but the ones with an "undefined" source
9450 // "undefined" source refers to attributes saved in the block comment.
9451
9452
9453 if (attributeSchema.source !== undefined) {
9454 return accumulator;
9455 } // Ignore default value.
9456
9457
9458 if ('default' in attributeSchema && attributeSchema.default === value) {
9459 return accumulator;
9460 } // Otherwise, include in comment set.
9461
9462
9463 accumulator[key] = value;
9464 return accumulator;
9465 }, {});
9466 }
9467 /**
9468 * Given an attributes object, returns a string in the serialized attributes
9469 * format prepared for post content.
9470 *
9471 * @param {Object} attributes Attributes object.
9472 *
9473 * @return {string} Serialized attributes.
9474 */
9475
9476 function serializeAttributes(attributes) {
9477 return JSON.stringify(attributes) // Don't break HTML comments.
9478 .replace(/--/g, '\\u002d\\u002d') // Don't break non-standard-compliant tools.
9479 .replace(/</g, '\\u003c').replace(/>/g, '\\u003e').replace(/&/g, '\\u0026') // Bypass server stripslashes behavior which would unescape stringify's
9480 // escaping of quotation mark.
9481 //
9482 // See: https://developer.wordpress.org/reference/functions/wp_kses_stripslashes/
9483 .replace(/\\"/g, '\\u0022');
9484 }
9485 /**
9486 * Given a block object, returns the Block's Inner HTML markup.
9487 *
9488 * @param {Object} block Block instance.
9489 *
9490 * @return {string} HTML.
9491 */
9492
9493 function getBlockInnerHTML(block) {
9494 // If block was parsed as invalid or encounters an error while generating
9495 // save content, use original content instead to avoid content loss. If a
9496 // block contains nested content, exempt it from this condition because we
9497 // otherwise have no access to its original content and content loss would
9498 // still occur.
9499 let saveContent = block.originalContent;
9500
9501 if (block.isValid || block.innerBlocks.length) {
9502 try {
9503 saveContent = getSaveContent(block.name, block.attributes, block.innerBlocks);
9504 } catch (error) {}
9505 }
9506
9507 return saveContent;
9508 }
9509 /**
9510 * Returns the content of a block, including comment delimiters.
9511 *
9512 * @param {string} rawBlockName Block name.
9513 * @param {Object} attributes Block attributes.
9514 * @param {string} content Block save content.
9515 *
9516 * @return {string} Comment-delimited block content.
9517 */
9518
9519 function getCommentDelimitedContent(rawBlockName, attributes, content) {
9520 const serializedAttributes = !(0,external_lodash_namespaceObject.isEmpty)(attributes) ? serializeAttributes(attributes) + ' ' : ''; // Strip core blocks of their namespace prefix.
9521
9522 const blockName = (0,external_lodash_namespaceObject.startsWith)(rawBlockName, 'core/') ? rawBlockName.slice(5) : rawBlockName; // @todo make the `wp:` prefix potentially configurable.
9523
9524 if (!content) {
9525 return `<!-- wp:${blockName} ${serializedAttributes}/-->`;
9526 }
9527
9528 return `<!-- wp:${blockName} ${serializedAttributes}-->\n` + content + `\n<!-- /wp:${blockName} -->`;
9529 }
9530 /**
9531 * Returns the content of a block, including comment delimiters, determining
9532 * serialized attributes and content form from the current state of the block.
9533 *
9534 * @param {Object} block Block instance.
9535 * @param {WPBlockSerializationOptions} options Serialization options.
9536 *
9537 * @return {string} Serialized block.
9538 */
9539
9540 function serializeBlock(block, {
9541 isInnerBlocks = false
9542 } = {}) {
9543 const blockName = block.name;
9544 const saveContent = getBlockInnerHTML(block);
9545
9546 if (blockName === getUnregisteredTypeHandlerName() || !isInnerBlocks && blockName === getFreeformContentHandlerName()) {
9547 return saveContent;
9548 }
9549
9550 const blockType = registration_getBlockType(blockName);
9551 const saveAttributes = getCommentAttributes(blockType, block.attributes);
9552 return getCommentDelimitedContent(blockName, saveAttributes, saveContent);
9553 }
9554 function __unstableSerializeAndClean(blocks) {
9555 // A single unmodified default block is assumed to
9556 // be equivalent to an empty post.
9557 if (blocks.length === 1 && isUnmodifiedDefaultBlock(blocks[0])) {
9558 blocks = [];
9559 }
9560
9561 let content = serialize(blocks); // For compatibility, treat a post consisting of a
9562 // single freeform block as legacy content and apply
9563 // pre-block-editor removep'd content formatting.
9564
9565 if (blocks.length === 1 && blocks[0].name === getFreeformContentHandlerName()) {
9566 content = (0,external_wp_autop_namespaceObject.removep)(content);
9567 }
9568
9569 return content;
9570 }
9571 /**
9572 * Takes a block or set of blocks and returns the serialized post content.
9573 *
9574 * @param {Array} blocks Block(s) to serialize.
9575 * @param {WPBlockSerializationOptions} options Serialization options.
9576 *
9577 * @return {string} The post content.
9578 */
9579
9580 function serialize(blocks, options) {
9581 return (0,external_lodash_namespaceObject.castArray)(blocks).map(block => serializeBlock(block, options)).join('\n\n');
9582 }
9583 //# sourceMappingURL=serializer.js.map
9584 ;// CONCATENATED MODULE: ./node_modules/simple-html-tokenizer/dist/es6/index.js
9585 /**
9586 * generated from https://raw.githubusercontent.com/w3c/html/26b5126f96f736f796b9e29718138919dd513744/entities.json
9587 * do not edit
9588 */
9589 var namedCharRefs = {
9590 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"
9591 };
9592
9593 var HEXCHARCODE = /^#[xX]([A-Fa-f0-9]+)$/;
9594 var CHARCODE = /^#([0-9]+)$/;
9595 var NAMED = /^([A-Za-z0-9]+)$/;
9596 var EntityParser = /** @class */ (function () {
9597 function EntityParser(named) {
9598 this.named = named;
9599 }
9600 EntityParser.prototype.parse = function (entity) {
9601 if (!entity) {
9602 return;
9603 }
9604 var matches = entity.match(HEXCHARCODE);
9605 if (matches) {
9606 return String.fromCharCode(parseInt(matches[1], 16));
9607 }
9608 matches = entity.match(CHARCODE);
9609 if (matches) {
9610 return String.fromCharCode(parseInt(matches[1], 10));
9611 }
9612 matches = entity.match(NAMED);
9613 if (matches) {
9614 return this.named[matches[1]];
9615 }
9616 };
9617 return EntityParser;
9618 }());
9619
9620 var WSP = /[\t\n\f ]/;
9621 var ALPHA = /[A-Za-z]/;
9622 var CRLF = /\r\n?/g;
9623 function isSpace(char) {
9624 return WSP.test(char);
9625 }
9626 function isAlpha(char) {
9627 return ALPHA.test(char);
9628 }
9629 function preprocessInput(input) {
9630 return input.replace(CRLF, '\n');
9631 }
9632
9633 var EventedTokenizer = /** @class */ (function () {
9634 function EventedTokenizer(delegate, entityParser) {
9635 this.delegate = delegate;
9636 this.entityParser = entityParser;
9637 this.state = "beforeData" /* beforeData */;
9638 this.line = -1;
9639 this.column = -1;
9640 this.input = '';
9641 this.index = -1;
9642 this.tagNameBuffer = '';
9643 this.states = {
9644 beforeData: function () {
9645 var char = this.peek();
9646 if (char === '<') {
9647 this.transitionTo("tagOpen" /* tagOpen */);
9648 this.markTagStart();
9649 this.consume();
9650 }
9651 else {
9652 if (char === '\n') {
9653 var tag = this.tagNameBuffer.toLowerCase();
9654 if (tag === 'pre' || tag === 'textarea') {
9655 this.consume();
9656 }
9657 }
9658 this.transitionTo("data" /* data */);
9659 this.delegate.beginData();
9660 }
9661 },
9662 data: function () {
9663 var char = this.peek();
9664 if (char === '<') {
9665 this.delegate.finishData();
9666 this.transitionTo("tagOpen" /* tagOpen */);
9667 this.markTagStart();
9668 this.consume();
9669 }
9670 else if (char === '&') {
9671 this.consume();
9672 this.delegate.appendToData(this.consumeCharRef() || '&');
9673 }
9674 else {
9675 this.consume();
9676 this.delegate.appendToData(char);
9677 }
9678 },
9679 tagOpen: function () {
9680 var char = this.consume();
9681 if (char === '!') {
9682 this.transitionTo("markupDeclarationOpen" /* markupDeclarationOpen */);
9683 }
9684 else if (char === '/') {
9685 this.transitionTo("endTagOpen" /* endTagOpen */);
9686 }
9687 else if (char === '@' || char === ':' || isAlpha(char)) {
9688 this.transitionTo("tagName" /* tagName */);
9689 this.tagNameBuffer = '';
9690 this.delegate.beginStartTag();
9691 this.appendToTagName(char);
9692 }
9693 },
9694 markupDeclarationOpen: function () {
9695 var char = this.consume();
9696 if (char === '-' && this.input.charAt(this.index) === '-') {
9697 this.consume();
9698 this.transitionTo("commentStart" /* commentStart */);
9699 this.delegate.beginComment();
9700 }
9701 },
9702 commentStart: function () {
9703 var char = this.consume();
9704 if (char === '-') {
9705 this.transitionTo("commentStartDash" /* commentStartDash */);
9706 }
9707 else if (char === '>') {
9708 this.delegate.finishComment();
9709 this.transitionTo("beforeData" /* beforeData */);
9710 }
9711 else {
9712 this.delegate.appendToCommentData(char);
9713 this.transitionTo("comment" /* comment */);
9714 }
9715 },
9716 commentStartDash: function () {
9717 var char = this.consume();
9718 if (char === '-') {
9719 this.transitionTo("commentEnd" /* commentEnd */);
9720 }
9721 else if (char === '>') {
9722 this.delegate.finishComment();
9723 this.transitionTo("beforeData" /* beforeData */);
9724 }
9725 else {
9726 this.delegate.appendToCommentData('-');
9727 this.transitionTo("comment" /* comment */);
9728 }
9729 },
9730 comment: function () {
9731 var char = this.consume();
9732 if (char === '-') {
9733 this.transitionTo("commentEndDash" /* commentEndDash */);
9734 }
9735 else {
9736 this.delegate.appendToCommentData(char);
9737 }
9738 },
9739 commentEndDash: function () {
9740 var char = this.consume();
9741 if (char === '-') {
9742 this.transitionTo("commentEnd" /* commentEnd */);
9743 }
9744 else {
9745 this.delegate.appendToCommentData('-' + char);
9746 this.transitionTo("comment" /* comment */);
9747 }
9748 },
9749 commentEnd: function () {
9750 var char = this.consume();
9751 if (char === '>') {
9752 this.delegate.finishComment();
9753 this.transitionTo("beforeData" /* beforeData */);
9754 }
9755 else {
9756 this.delegate.appendToCommentData('--' + char);
9757 this.transitionTo("comment" /* comment */);
9758 }
9759 },
9760 tagName: function () {
9761 var char = this.consume();
9762 if (isSpace(char)) {
9763 this.transitionTo("beforeAttributeName" /* beforeAttributeName */);
9764 }
9765 else if (char === '/') {
9766 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */);
9767 }
9768 else if (char === '>') {
9769 this.delegate.finishTag();
9770 this.transitionTo("beforeData" /* beforeData */);
9771 }
9772 else {
9773 this.appendToTagName(char);
9774 }
9775 },
9776 beforeAttributeName: function () {
9777 var char = this.peek();
9778 if (isSpace(char)) {
9779 this.consume();
9780 return;
9781 }
9782 else if (char === '/') {
9783 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */);
9784 this.consume();
9785 }
9786 else if (char === '>') {
9787 this.consume();
9788 this.delegate.finishTag();
9789 this.transitionTo("beforeData" /* beforeData */);
9790 }
9791 else if (char === '=') {
9792 this.delegate.reportSyntaxError('attribute name cannot start with equals sign');
9793 this.transitionTo("attributeName" /* attributeName */);
9794 this.delegate.beginAttribute();
9795 this.consume();
9796 this.delegate.appendToAttributeName(char);
9797 }
9798 else {
9799 this.transitionTo("attributeName" /* attributeName */);
9800 this.delegate.beginAttribute();
9801 }
9802 },
9803 attributeName: function () {
9804 var char = this.peek();
9805 if (isSpace(char)) {
9806 this.transitionTo("afterAttributeName" /* afterAttributeName */);
9807 this.consume();
9808 }
9809 else if (char === '/') {
9810 this.delegate.beginAttributeValue(false);
9811 this.delegate.finishAttributeValue();
9812 this.consume();
9813 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */);
9814 }
9815 else if (char === '=') {
9816 this.transitionTo("beforeAttributeValue" /* beforeAttributeValue */);
9817 this.consume();
9818 }
9819 else if (char === '>') {
9820 this.delegate.beginAttributeValue(false);
9821 this.delegate.finishAttributeValue();
9822 this.consume();
9823 this.delegate.finishTag();
9824 this.transitionTo("beforeData" /* beforeData */);
9825 }
9826 else if (char === '"' || char === "'" || char === '<') {
9827 this.delegate.reportSyntaxError(char + ' is not a valid character within attribute names');
9828 this.consume();
9829 this.delegate.appendToAttributeName(char);
9830 }
9831 else {
9832 this.consume();
9833 this.delegate.appendToAttributeName(char);
9834 }
9835 },
9836 afterAttributeName: function () {
9837 var char = this.peek();
9838 if (isSpace(char)) {
9839 this.consume();
9840 return;
9841 }
9842 else if (char === '/') {
9843 this.delegate.beginAttributeValue(false);
9844 this.delegate.finishAttributeValue();
9845 this.consume();
9846 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */);
9847 }
9848 else if (char === '=') {
9849 this.consume();
9850 this.transitionTo("beforeAttributeValue" /* beforeAttributeValue */);
9851 }
9852 else if (char === '>') {
9853 this.delegate.beginAttributeValue(false);
9854 this.delegate.finishAttributeValue();
9855 this.consume();
9856 this.delegate.finishTag();
9857 this.transitionTo("beforeData" /* beforeData */);
9858 }
9859 else {
9860 this.delegate.beginAttributeValue(false);
9861 this.delegate.finishAttributeValue();
9862 this.transitionTo("attributeName" /* attributeName */);
9863 this.delegate.beginAttribute();
9864 this.consume();
9865 this.delegate.appendToAttributeName(char);
9866 }
9867 },
9868 beforeAttributeValue: function () {
9869 var char = this.peek();
9870 if (isSpace(char)) {
9871 this.consume();
9872 }
9873 else if (char === '"') {
9874 this.transitionTo("attributeValueDoubleQuoted" /* attributeValueDoubleQuoted */);
9875 this.delegate.beginAttributeValue(true);
9876 this.consume();
9877 }
9878 else if (char === "'") {
9879 this.transitionTo("attributeValueSingleQuoted" /* attributeValueSingleQuoted */);
9880 this.delegate.beginAttributeValue(true);
9881 this.consume();
9882 }
9883 else if (char === '>') {
9884 this.delegate.beginAttributeValue(false);
9885 this.delegate.finishAttributeValue();
9886 this.consume();
9887 this.delegate.finishTag();
9888 this.transitionTo("beforeData" /* beforeData */);
9889 }
9890 else {
9891 this.transitionTo("attributeValueUnquoted" /* attributeValueUnquoted */);
9892 this.delegate.beginAttributeValue(false);
9893 this.consume();
9894 this.delegate.appendToAttributeValue(char);
9895 }
9896 },
9897 attributeValueDoubleQuoted: function () {
9898 var char = this.consume();
9899 if (char === '"') {
9900 this.delegate.finishAttributeValue();
9901 this.transitionTo("afterAttributeValueQuoted" /* afterAttributeValueQuoted */);
9902 }
9903 else if (char === '&') {
9904 this.delegate.appendToAttributeValue(this.consumeCharRef() || '&');
9905 }
9906 else {
9907 this.delegate.appendToAttributeValue(char);
9908 }
9909 },
9910 attributeValueSingleQuoted: function () {
9911 var char = this.consume();
9912 if (char === "'") {
9913 this.delegate.finishAttributeValue();
9914 this.transitionTo("afterAttributeValueQuoted" /* afterAttributeValueQuoted */);
9915 }
9916 else if (char === '&') {
9917 this.delegate.appendToAttributeValue(this.consumeCharRef() || '&');
9918 }
9919 else {
9920 this.delegate.appendToAttributeValue(char);
9921 }
9922 },
9923 attributeValueUnquoted: function () {
9924 var char = this.peek();
9925 if (isSpace(char)) {
9926 this.delegate.finishAttributeValue();
9927 this.consume();
9928 this.transitionTo("beforeAttributeName" /* beforeAttributeName */);
9929 }
9930 else if (char === '/') {
9931 this.delegate.finishAttributeValue();
9932 this.consume();
9933 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */);
9934 }
9935 else if (char === '&') {
9936 this.consume();
9937 this.delegate.appendToAttributeValue(this.consumeCharRef() || '&');
9938 }
9939 else if (char === '>') {
9940 this.delegate.finishAttributeValue();
9941 this.consume();
9942 this.delegate.finishTag();
9943 this.transitionTo("beforeData" /* beforeData */);
9944 }
9945 else {
9946 this.consume();
9947 this.delegate.appendToAttributeValue(char);
9948 }
9949 },
9950 afterAttributeValueQuoted: function () {
9951 var char = this.peek();
9952 if (isSpace(char)) {
9953 this.consume();
9954 this.transitionTo("beforeAttributeName" /* beforeAttributeName */);
9955 }
9956 else if (char === '/') {
9957 this.consume();
9958 this.transitionTo("selfClosingStartTag" /* selfClosingStartTag */);
9959 }
9960 else if (char === '>') {
9961 this.consume();
9962 this.delegate.finishTag();
9963 this.transitionTo("beforeData" /* beforeData */);
9964 }
9965 else {
9966 this.transitionTo("beforeAttributeName" /* beforeAttributeName */);
9967 }
9968 },
9969 selfClosingStartTag: function () {
9970 var char = this.peek();
9971 if (char === '>') {
9972 this.consume();
9973 this.delegate.markTagAsSelfClosing();
9974 this.delegate.finishTag();
9975 this.transitionTo("beforeData" /* beforeData */);
9976 }
9977 else {
9978 this.transitionTo("beforeAttributeName" /* beforeAttributeName */);
9979 }
9980 },
9981 endTagOpen: function () {
9982 var char = this.consume();
9983 if (char === '@' || char === ':' || isAlpha(char)) {
9984 this.transitionTo("tagName" /* tagName */);
9985 this.tagNameBuffer = '';
9986 this.delegate.beginEndTag();
9987 this.appendToTagName(char);
9988 }
9989 }
9990 };
9991 this.reset();
9992 }
9993 EventedTokenizer.prototype.reset = function () {
9994 this.transitionTo("beforeData" /* beforeData */);
9995 this.input = '';
9996 this.index = 0;
9997 this.line = 1;
9998 this.column = 0;
9999 this.delegate.reset();
10000 };
10001 EventedTokenizer.prototype.transitionTo = function (state) {
10002 this.state = state;
10003 };
10004 EventedTokenizer.prototype.tokenize = function (input) {
10005 this.reset();
10006 this.tokenizePart(input);
10007 this.tokenizeEOF();
10008 };
10009 EventedTokenizer.prototype.tokenizePart = function (input) {
10010 this.input += preprocessInput(input);
10011 while (this.index < this.input.length) {
10012 var handler = this.states[this.state];
10013 if (handler !== undefined) {
10014 handler.call(this);
10015 }
10016 else {
10017 throw new Error("unhandled state " + this.state);
10018 }
10019 }
10020 };
10021 EventedTokenizer.prototype.tokenizeEOF = function () {
10022 this.flushData();
10023 };
10024 EventedTokenizer.prototype.flushData = function () {
10025 if (this.state === 'data') {
10026 this.delegate.finishData();
10027 this.transitionTo("beforeData" /* beforeData */);
10028 }
10029 };
10030 EventedTokenizer.prototype.peek = function () {
10031 return this.input.charAt(this.index);
10032 };
10033 EventedTokenizer.prototype.consume = function () {
10034 var char = this.peek();
10035 this.index++;
10036 if (char === '\n') {
10037 this.line++;
10038 this.column = 0;
10039 }
10040 else {
10041 this.column++;
10042 }
10043 return char;
10044 };
10045 EventedTokenizer.prototype.consumeCharRef = function () {
10046 var endIndex = this.input.indexOf(';', this.index);
10047 if (endIndex === -1) {
10048 return;
10049 }
10050 var entity = this.input.slice(this.index, endIndex);
10051 var chars = this.entityParser.parse(entity);
10052 if (chars) {
10053 var count = entity.length;
10054 // consume the entity chars
10055 while (count) {
10056 this.consume();
10057 count--;
10058 }
10059 // consume the `;`
10060 this.consume();
10061 return chars;
10062 }
10063 };
10064 EventedTokenizer.prototype.markTagStart = function () {
10065 this.delegate.tagOpen();
10066 };
10067 EventedTokenizer.prototype.appendToTagName = function (char) {
10068 this.tagNameBuffer += char;
10069 this.delegate.appendToTagName(char);
10070 };
10071 return EventedTokenizer;
10072 }());
10073
10074 var Tokenizer = /** @class */ (function () {
10075 function Tokenizer(entityParser, options) {
10076 if (options === void 0) { options = {}; }
10077 this.options = options;
10078 this.token = null;
10079 this.startLine = 1;
10080 this.startColumn = 0;
10081 this.tokens = [];
10082 this.tokenizer = new EventedTokenizer(this, entityParser);
10083 this._currentAttribute = undefined;
10084 }
10085 Tokenizer.prototype.tokenize = function (input) {
10086 this.tokens = [];
10087 this.tokenizer.tokenize(input);
10088 return this.tokens;
10089 };
10090 Tokenizer.prototype.tokenizePart = function (input) {
10091 this.tokens = [];
10092 this.tokenizer.tokenizePart(input);
10093 return this.tokens;
10094 };
10095 Tokenizer.prototype.tokenizeEOF = function () {
10096 this.tokens = [];
10097 this.tokenizer.tokenizeEOF();
10098 return this.tokens[0];
10099 };
10100 Tokenizer.prototype.reset = function () {
10101 this.token = null;
10102 this.startLine = 1;
10103 this.startColumn = 0;
10104 };
10105 Tokenizer.prototype.current = function () {
10106 var token = this.token;
10107 if (token === null) {
10108 throw new Error('token was unexpectedly null');
10109 }
10110 if (arguments.length === 0) {
10111 return token;
10112 }
10113 for (var i = 0; i < arguments.length; i++) {
10114 if (token.type === arguments[i]) {
10115 return token;
10116 }
10117 }
10118 throw new Error("token type was unexpectedly " + token.type);
10119 };
10120 Tokenizer.prototype.push = function (token) {
10121 this.token = token;
10122 this.tokens.push(token);
10123 };
10124 Tokenizer.prototype.currentAttribute = function () {
10125 return this._currentAttribute;
10126 };
10127 Tokenizer.prototype.addLocInfo = function () {
10128 if (this.options.loc) {
10129 this.current().loc = {
10130 start: {
10131 line: this.startLine,
10132 column: this.startColumn
10133 },
10134 end: {
10135 line: this.tokenizer.line,
10136 column: this.tokenizer.column
10137 }
10138 };
10139 }
10140 this.startLine = this.tokenizer.line;
10141 this.startColumn = this.tokenizer.column;
10142 };
10143 // Data
10144 Tokenizer.prototype.beginData = function () {
10145 this.push({
10146 type: "Chars" /* Chars */,
10147 chars: ''
10148 });
10149 };
10150 Tokenizer.prototype.appendToData = function (char) {
10151 this.current("Chars" /* Chars */).chars += char;
10152 };
10153 Tokenizer.prototype.finishData = function () {
10154 this.addLocInfo();
10155 };
10156 // Comment
10157 Tokenizer.prototype.beginComment = function () {
10158 this.push({
10159 type: "Comment" /* Comment */,
10160 chars: ''
10161 });
10162 };
10163 Tokenizer.prototype.appendToCommentData = function (char) {
10164 this.current("Comment" /* Comment */).chars += char;
10165 };
10166 Tokenizer.prototype.finishComment = function () {
10167 this.addLocInfo();
10168 };
10169 // Tags - basic
10170 Tokenizer.prototype.tagOpen = function () { };
10171 Tokenizer.prototype.beginStartTag = function () {
10172 this.push({
10173 type: "StartTag" /* StartTag */,
10174 tagName: '',
10175 attributes: [],
10176 selfClosing: false
10177 });
10178 };
10179 Tokenizer.prototype.beginEndTag = function () {
10180 this.push({
10181 type: "EndTag" /* EndTag */,
10182 tagName: ''
10183 });
10184 };
10185 Tokenizer.prototype.finishTag = function () {
10186 this.addLocInfo();
10187 };
10188 Tokenizer.prototype.markTagAsSelfClosing = function () {
10189 this.current("StartTag" /* StartTag */).selfClosing = true;
10190 };
10191 // Tags - name
10192 Tokenizer.prototype.appendToTagName = function (char) {
10193 this.current("StartTag" /* StartTag */, "EndTag" /* EndTag */).tagName += char;
10194 };
10195 // Tags - attributes
10196 Tokenizer.prototype.beginAttribute = function () {
10197 this._currentAttribute = ['', '', false];
10198 };
10199 Tokenizer.prototype.appendToAttributeName = function (char) {
10200 this.currentAttribute()[0] += char;
10201 };
10202 Tokenizer.prototype.beginAttributeValue = function (isQuoted) {
10203 this.currentAttribute()[2] = isQuoted;
10204 };
10205 Tokenizer.prototype.appendToAttributeValue = function (char) {
10206 this.currentAttribute()[1] += char;
10207 };
10208 Tokenizer.prototype.finishAttributeValue = function () {
10209 this.current("StartTag" /* StartTag */).attributes.push(this._currentAttribute);
10210 };
10211 Tokenizer.prototype.reportSyntaxError = function (message) {
10212 this.current().syntaxError = message;
10213 };
10214 return Tokenizer;
10215 }());
10216
10217 function tokenize(input, options) {
10218 var tokenizer = new Tokenizer(new EntityParser(namedCharRefs), options);
10219 return tokenizer.tokenize(input);
10220 }
10221
10222
10223 //# sourceMappingURL=index.js.map
10224 ;// CONCATENATED MODULE: external ["wp","htmlEntities"]
10225 var external_wp_htmlEntities_namespaceObject = window["wp"]["htmlEntities"];
10226 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/validation/logger.js
10227 function createLogger() {
10228 /**
10229 * Creates a log handler with block validation prefix.
10230 *
10231 * @param {Function} logger Original logger function.
10232 *
10233 * @return {Function} Augmented logger function.
10234 */
10235 function createLogHandler(logger) {
10236 let log = (message, ...args) => logger('Block validation: ' + message, ...args); // In test environments, pre-process string substitutions to improve
10237 // readability of error messages. We'd prefer to avoid pulling in this
10238 // dependency in runtime environments, and it can be dropped by a combo
10239 // of Webpack env substitution + UglifyJS dead code elimination.
10240
10241
10242 if (false) {}
10243
10244 return log;
10245 }
10246
10247 return {
10248 // eslint-disable-next-line no-console
10249 error: createLogHandler(console.error),
10250 // eslint-disable-next-line no-console
10251 warning: createLogHandler(console.warn),
10252
10253 getItems() {
10254 return [];
10255 }
10256
10257 };
10258 }
10259 function createQueuedLogger() {
10260 /**
10261 * The list of enqueued log actions to print.
10262 *
10263 * @type {Array}
10264 */
10265 const queue = [];
10266 const logger = createLogger();
10267 return {
10268 error(...args) {
10269 queue.push({
10270 log: logger.error,
10271 args
10272 });
10273 },
10274
10275 warning(...args) {
10276 queue.push({
10277 log: logger.warning,
10278 args
10279 });
10280 },
10281
10282 getItems() {
10283 return queue;
10284 }
10285
10286 };
10287 }
10288 //# sourceMappingURL=logger.js.map
10289 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/validation/index.js
10290 /**
10291 * External dependencies
10292 */
10293
10294
10295 /**
10296 * WordPress dependencies
10297 */
10298
10299
10300 /**
10301 * Internal dependencies
10302 */
10303
10304
10305
10306
10307
10308 /**
10309 * Globally matches any consecutive whitespace
10310 *
10311 * @type {RegExp}
10312 */
10313
10314 const REGEXP_WHITESPACE = /[\t\n\r\v\f ]+/g;
10315 /**
10316 * Matches a string containing only whitespace
10317 *
10318 * @type {RegExp}
10319 */
10320
10321 const REGEXP_ONLY_WHITESPACE = /^[\t\n\r\v\f ]*$/;
10322 /**
10323 * Matches a CSS URL type value
10324 *
10325 * @type {RegExp}
10326 */
10327
10328 const REGEXP_STYLE_URL_TYPE = /^url\s*\(['"\s]*(.*?)['"\s]*\)$/;
10329 /**
10330 * Boolean attributes are attributes whose presence as being assigned is
10331 * meaningful, even if only empty.
10332 *
10333 * See: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#boolean-attributes
10334 * Extracted from: https://html.spec.whatwg.org/multipage/indices.html#attributes-3
10335 *
10336 * Object.keys( Array.from( document.querySelectorAll( '#attributes-1 > tbody > tr' ) )
10337 * .filter( ( tr ) => tr.lastChild.textContent.indexOf( 'Boolean attribute' ) !== -1 )
10338 * .reduce( ( result, tr ) => Object.assign( result, {
10339 * [ tr.firstChild.textContent.trim() ]: true
10340 * } ), {} ) ).sort();
10341 *
10342 * @type {Array}
10343 */
10344
10345 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'];
10346 /**
10347 * Enumerated attributes are attributes which must be of a specific value form.
10348 * Like boolean attributes, these are meaningful if specified, even if not of a
10349 * valid enumerated value.
10350 *
10351 * See: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#enumerated-attribute
10352 * Extracted from: https://html.spec.whatwg.org/multipage/indices.html#attributes-3
10353 *
10354 * Object.keys( Array.from( document.querySelectorAll( '#attributes-1 > tbody > tr' ) )
10355 * .filter( ( tr ) => /^("(.+?)";?\s*)+/.test( tr.lastChild.textContent.trim() ) )
10356 * .reduce( ( result, tr ) => Object.assign( result, {
10357 * [ tr.firstChild.textContent.trim() ]: true
10358 * } ), {} ) ).sort();
10359 *
10360 * @type {Array}
10361 */
10362
10363 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'];
10364 /**
10365 * Meaningful attributes are those who cannot be safely ignored when omitted in
10366 * one HTML markup string and not another.
10367 *
10368 * @type {Array}
10369 */
10370
10371 const MEANINGFUL_ATTRIBUTES = [...BOOLEAN_ATTRIBUTES, ...ENUMERATED_ATTRIBUTES];
10372 /**
10373 * Array of functions which receive a text string on which to apply normalizing
10374 * behavior for consideration in text token equivalence, carefully ordered from
10375 * least-to-most expensive operations.
10376 *
10377 * @type {Array}
10378 */
10379
10380 const TEXT_NORMALIZATIONS = [external_lodash_namespaceObject.identity, getTextWithCollapsedWhitespace];
10381 /**
10382 * Regular expression matching a named character reference. In lieu of bundling
10383 * a full set of references, the pattern covers the minimal necessary to test
10384 * positively against the full set.
10385 *
10386 * "The ampersand must be followed by one of the names given in the named
10387 * character references section, using the same case."
10388 *
10389 * Tested aginst "12.5 Named character references":
10390 *
10391 * ```
10392 * const references = Array.from( document.querySelectorAll(
10393 * '#named-character-references-table tr[id^=entity-] td:first-child'
10394 * ) ).map( ( code ) => code.textContent )
10395 * references.every( ( reference ) => /^[\da-z]+$/i.test( reference ) )
10396 * ```
10397 *
10398 * @see https://html.spec.whatwg.org/multipage/syntax.html#character-references
10399 * @see https://html.spec.whatwg.org/multipage/named-characters.html#named-character-references
10400 *
10401 * @type {RegExp}
10402 */
10403
10404 const REGEXP_NAMED_CHARACTER_REFERENCE = /^[\da-z]+$/i;
10405 /**
10406 * Regular expression matching a decimal character reference.
10407 *
10408 * "The ampersand must be followed by a U+0023 NUMBER SIGN character (#),
10409 * followed by one or more ASCII digits, representing a base-ten integer"
10410 *
10411 * @see https://html.spec.whatwg.org/multipage/syntax.html#character-references
10412 *
10413 * @type {RegExp}
10414 */
10415
10416 const REGEXP_DECIMAL_CHARACTER_REFERENCE = /^#\d+$/;
10417 /**
10418 * Regular expression matching a hexadecimal character reference.
10419 *
10420 * "The ampersand must be followed by a U+0023 NUMBER SIGN character (#), which
10421 * must be followed by either a U+0078 LATIN SMALL LETTER X character (x) or a
10422 * U+0058 LATIN CAPITAL LETTER X character (X), which must then be followed by
10423 * one or more ASCII hex digits, representing a hexadecimal integer"
10424 *
10425 * @see https://html.spec.whatwg.org/multipage/syntax.html#character-references
10426 *
10427 * @type {RegExp}
10428 */
10429
10430 const REGEXP_HEXADECIMAL_CHARACTER_REFERENCE = /^#x[\da-f]+$/i;
10431 /**
10432 * Returns true if the given string is a valid character reference segment, or
10433 * false otherwise. The text should be stripped of `&` and `;` demarcations.
10434 *
10435 * @param {string} text Text to test.
10436 *
10437 * @return {boolean} Whether text is valid character reference.
10438 */
10439
10440 function isValidCharacterReference(text) {
10441 return REGEXP_NAMED_CHARACTER_REFERENCE.test(text) || REGEXP_DECIMAL_CHARACTER_REFERENCE.test(text) || REGEXP_HEXADECIMAL_CHARACTER_REFERENCE.test(text);
10442 }
10443 /**
10444 * Subsitute EntityParser class for `simple-html-tokenizer` which uses the
10445 * implementation of `decodeEntities` from `html-entities`, in order to avoid
10446 * bundling a massive named character reference.
10447 *
10448 * @see https://github.com/tildeio/simple-html-tokenizer/tree/HEAD/src/entity-parser.ts
10449 */
10450
10451 class DecodeEntityParser {
10452 /**
10453 * Returns a substitute string for an entity string sequence between `&`
10454 * and `;`, or undefined if no substitution should occur.
10455 *
10456 * @param {string} entity Entity fragment discovered in HTML.
10457 *
10458 * @return {?string} Entity substitute value.
10459 */
10460 parse(entity) {
10461 if (isValidCharacterReference(entity)) {
10462 return (0,external_wp_htmlEntities_namespaceObject.decodeEntities)('&' + entity + ';');
10463 }
10464 }
10465
10466 }
10467 /**
10468 * Given a specified string, returns an array of strings split by consecutive
10469 * whitespace, ignoring leading or trailing whitespace.
10470 *
10471 * @param {string} text Original text.
10472 *
10473 * @return {string[]} Text pieces split on whitespace.
10474 */
10475
10476 function getTextPiecesSplitOnWhitespace(text) {
10477 return text.trim().split(REGEXP_WHITESPACE);
10478 }
10479 /**
10480 * Given a specified string, returns a new trimmed string where all consecutive
10481 * whitespace is collapsed to a single space.
10482 *
10483 * @param {string} text Original text.
10484 *
10485 * @return {string} Trimmed text with consecutive whitespace collapsed.
10486 */
10487
10488 function getTextWithCollapsedWhitespace(text) {
10489 // This is an overly simplified whitespace comparison. The specification is
10490 // more prescriptive of whitespace behavior in inline and block contexts.
10491 //
10492 // See: https://medium.com/@patrickbrosset/when-does-white-space-matter-in-html-b90e8a7cdd33
10493 return getTextPiecesSplitOnWhitespace(text).join(' ');
10494 }
10495 /**
10496 * Returns attribute pairs of the given StartTag token, including only pairs
10497 * where the value is non-empty or the attribute is a boolean attribute, an
10498 * enumerated attribute, or a custom data- attribute.
10499 *
10500 * @see MEANINGFUL_ATTRIBUTES
10501 *
10502 * @param {Object} token StartTag token.
10503 *
10504 * @return {Array[]} Attribute pairs.
10505 */
10506
10507 function getMeaningfulAttributePairs(token) {
10508 return token.attributes.filter(pair => {
10509 const [key, value] = pair;
10510 return value || key.indexOf('data-') === 0 || (0,external_lodash_namespaceObject.includes)(MEANINGFUL_ATTRIBUTES, key);
10511 });
10512 }
10513 /**
10514 * Returns true if two text tokens (with `chars` property) are equivalent, or
10515 * false otherwise.
10516 *
10517 * @param {Object} actual Actual token.
10518 * @param {Object} expected Expected token.
10519 * @param {Object} logger Validation logger object.
10520 *
10521 * @return {boolean} Whether two text tokens are equivalent.
10522 */
10523
10524 function isEquivalentTextTokens(actual, expected, logger = createLogger()) {
10525 // This function is intentionally written as syntactically "ugly" as a hot
10526 // path optimization. Text is progressively normalized in order from least-
10527 // to-most operationally expensive, until the earliest point at which text
10528 // can be confidently inferred as being equal.
10529 let actualChars = actual.chars;
10530 let expectedChars = expected.chars;
10531
10532 for (let i = 0; i < TEXT_NORMALIZATIONS.length; i++) {
10533 const normalize = TEXT_NORMALIZATIONS[i];
10534 actualChars = normalize(actualChars);
10535 expectedChars = normalize(expectedChars);
10536
10537 if (actualChars === expectedChars) {
10538 return true;
10539 }
10540 }
10541
10542 logger.warning('Expected text `%s`, saw `%s`.', expected.chars, actual.chars);
10543 return false;
10544 }
10545 /**
10546 * Given a CSS length value, returns a normalized CSS length value for strict equality
10547 * comparison.
10548 *
10549 * @param {string} value CSS length value.
10550 *
10551 * @return {string} Normalized CSS length value.
10552 */
10553
10554 function getNormalizedLength(value) {
10555 if (0 === parseFloat(value)) {
10556 return '0';
10557 } // Normalize strings with floats to always include a leading zero.
10558
10559
10560 if (value.indexOf('.') === 0) {
10561 return '0' + value;
10562 }
10563
10564 return value;
10565 }
10566 /**
10567 * Given a style value, returns a normalized style value for strict equality
10568 * comparison.
10569 *
10570 * @param {string} value Style value.
10571 *
10572 * @return {string} Normalized style value.
10573 */
10574
10575 function getNormalizedStyleValue(value) {
10576 const textPieces = getTextPiecesSplitOnWhitespace(value);
10577 const normalizedPieces = textPieces.map(getNormalizedLength);
10578 const result = normalizedPieces.join(' ');
10579 return result // Normalize URL type to omit whitespace or quotes
10580 .replace(REGEXP_STYLE_URL_TYPE, 'url($1)');
10581 }
10582 /**
10583 * Given a style attribute string, returns an object of style properties.
10584 *
10585 * @param {string} text Style attribute.
10586 *
10587 * @return {Object} Style properties.
10588 */
10589
10590 function getStyleProperties(text) {
10591 const pairs = text // Trim ending semicolon (avoid including in split)
10592 .replace(/;?\s*$/, '') // Split on property assignment
10593 .split(';') // For each property assignment...
10594 .map(style => {
10595 // ...split further into key-value pairs
10596 const [key, ...valueParts] = style.split(':');
10597 const value = valueParts.join(':');
10598 return [key.trim(), getNormalizedStyleValue(value.trim())];
10599 });
10600 return (0,external_lodash_namespaceObject.fromPairs)(pairs);
10601 }
10602 /**
10603 * Attribute-specific equality handlers
10604 *
10605 * @type {Object}
10606 */
10607
10608 const isEqualAttributesOfName = {
10609 class: (actual, expected) => {
10610 // Class matches if members are the same, even if out of order or
10611 // superfluous whitespace between.
10612 return !(0,external_lodash_namespaceObject.xor)(...[actual, expected].map(getTextPiecesSplitOnWhitespace)).length;
10613 },
10614 style: (actual, expected) => {
10615 return (0,external_lodash_namespaceObject.isEqual)(...[actual, expected].map(getStyleProperties));
10616 },
10617 // For each boolean attribute, mere presence of attribute in both is enough
10618 // to assume equivalence.
10619 ...(0,external_lodash_namespaceObject.fromPairs)(BOOLEAN_ATTRIBUTES.map(attribute => [attribute, external_lodash_namespaceObject.stubTrue]))
10620 };
10621 /**
10622 * Given two sets of attribute tuples, returns true if the attribute sets are
10623 * equivalent.
10624 *
10625 * @param {Array[]} actual Actual attributes tuples.
10626 * @param {Array[]} expected Expected attributes tuples.
10627 * @param {Object} logger Validation logger object.
10628 *
10629 * @return {boolean} Whether attributes are equivalent.
10630 */
10631
10632 function isEqualTagAttributePairs(actual, expected, logger = createLogger()) {
10633 // Attributes is tokenized as tuples. Their lengths should match. This also
10634 // avoids us needing to check both attributes sets, since if A has any keys
10635 // which do not exist in B, we know the sets to be different.
10636 if (actual.length !== expected.length) {
10637 logger.warning('Expected attributes %o, instead saw %o.', expected, actual);
10638 return false;
10639 } // Attributes are not guaranteed to occur in the same order. For validating
10640 // actual attributes, first convert the set of expected attribute values to
10641 // an object, for lookup by key.
10642
10643
10644 const expectedAttributes = {};
10645
10646 for (let i = 0; i < expected.length; i++) {
10647 expectedAttributes[expected[i][0].toLowerCase()] = expected[i][1];
10648 }
10649
10650 for (let i = 0; i < actual.length; i++) {
10651 const [name, actualValue] = actual[i];
10652 const nameLower = name.toLowerCase(); // As noted above, if missing member in B, assume different
10653
10654 if (!expectedAttributes.hasOwnProperty(nameLower)) {
10655 logger.warning('Encountered unexpected attribute `%s`.', name);
10656 return false;
10657 }
10658
10659 const expectedValue = expectedAttributes[nameLower];
10660 const isEqualAttributes = isEqualAttributesOfName[nameLower];
10661
10662 if (isEqualAttributes) {
10663 // Defer custom attribute equality handling
10664 if (!isEqualAttributes(actualValue, expectedValue)) {
10665 logger.warning('Expected attribute `%s` of value `%s`, saw `%s`.', name, expectedValue, actualValue);
10666 return false;
10667 }
10668 } else if (actualValue !== expectedValue) {
10669 // Otherwise strict inequality should bail
10670 logger.warning('Expected attribute `%s` of value `%s`, saw `%s`.', name, expectedValue, actualValue);
10671 return false;
10672 }
10673 }
10674
10675 return true;
10676 }
10677 /**
10678 * Token-type-specific equality handlers
10679 *
10680 * @type {Object}
10681 */
10682
10683 const isEqualTokensOfType = {
10684 StartTag: (actual, expected, logger = createLogger()) => {
10685 if (actual.tagName !== expected.tagName && // Optimization: Use short-circuit evaluation to defer case-
10686 // insensitive check on the assumption that the majority case will
10687 // have exactly equal tag names.
10688 actual.tagName.toLowerCase() !== expected.tagName.toLowerCase()) {
10689 logger.warning('Expected tag name `%s`, instead saw `%s`.', expected.tagName, actual.tagName);
10690 return false;
10691 }
10692
10693 return isEqualTagAttributePairs(...[actual, expected].map(getMeaningfulAttributePairs), logger);
10694 },
10695 Chars: isEquivalentTextTokens,
10696 Comment: isEquivalentTextTokens
10697 };
10698 /**
10699 * Given an array of tokens, returns the first token which is not purely
10700 * whitespace.
10701 *
10702 * Mutates the tokens array.
10703 *
10704 * @param {Object[]} tokens Set of tokens to search.
10705 *
10706 * @return {Object} Next non-whitespace token.
10707 */
10708
10709 function getNextNonWhitespaceToken(tokens) {
10710 let token;
10711
10712 while (token = tokens.shift()) {
10713 if (token.type !== 'Chars') {
10714 return token;
10715 }
10716
10717 if (!REGEXP_ONLY_WHITESPACE.test(token.chars)) {
10718 return token;
10719 }
10720 }
10721 }
10722 /**
10723 * Tokenize an HTML string, gracefully handling any errors thrown during
10724 * underlying tokenization.
10725 *
10726 * @param {string} html HTML string to tokenize.
10727 * @param {Object} logger Validation logger object.
10728 *
10729 * @return {Object[]|null} Array of valid tokenized HTML elements, or null on error
10730 */
10731
10732 function getHTMLTokens(html, logger = createLogger()) {
10733 try {
10734 return new Tokenizer(new DecodeEntityParser()).tokenize(html);
10735 } catch (e) {
10736 logger.warning('Malformed HTML detected: %s', html);
10737 }
10738
10739 return null;
10740 }
10741 /**
10742 * Returns true if the next HTML token closes the current token.
10743 *
10744 * @param {Object} currentToken Current token to compare with.
10745 * @param {Object|undefined} nextToken Next token to compare against.
10746 *
10747 * @return {boolean} true if `nextToken` closes `currentToken`, false otherwise
10748 */
10749
10750
10751 function isClosedByToken(currentToken, nextToken) {
10752 // Ensure this is a self closed token
10753 if (!currentToken.selfClosing) {
10754 return false;
10755 } // Check token names and determine if nextToken is the closing tag for currentToken
10756
10757
10758 if (nextToken && nextToken.tagName === currentToken.tagName && nextToken.type === 'EndTag') {
10759 return true;
10760 }
10761
10762 return false;
10763 }
10764 /**
10765 * Returns true if the given HTML strings are effectively equivalent, or
10766 * false otherwise. Invalid HTML is not considered equivalent, even if the
10767 * strings directly match.
10768 *
10769 * @param {string} actual Actual HTML string.
10770 * @param {string} expected Expected HTML string.
10771 * @param {Object} logger Validation logger object.
10772 *
10773 * @return {boolean} Whether HTML strings are equivalent.
10774 */
10775
10776 function isEquivalentHTML(actual, expected, logger = createLogger()) {
10777 // Short-circuit if markup is identical.
10778 if (actual === expected) {
10779 return true;
10780 } // Tokenize input content and reserialized save content
10781
10782
10783 const [actualTokens, expectedTokens] = [actual, expected].map(html => getHTMLTokens(html, logger)); // If either is malformed then stop comparing - the strings are not equivalent
10784
10785 if (!actualTokens || !expectedTokens) {
10786 return false;
10787 }
10788
10789 let actualToken, expectedToken;
10790
10791 while (actualToken = getNextNonWhitespaceToken(actualTokens)) {
10792 expectedToken = getNextNonWhitespaceToken(expectedTokens); // Inequal if exhausted all expected tokens
10793
10794 if (!expectedToken) {
10795 logger.warning('Expected end of content, instead saw %o.', actualToken);
10796 return false;
10797 } // Inequal if next non-whitespace token of each set are not same type
10798
10799
10800 if (actualToken.type !== expectedToken.type) {
10801 logger.warning('Expected token of type `%s` (%o), instead saw `%s` (%o).', expectedToken.type, expectedToken, actualToken.type, actualToken);
10802 return false;
10803 } // Defer custom token type equality handling, otherwise continue and
10804 // assume as equal
10805
10806
10807 const isEqualTokens = isEqualTokensOfType[actualToken.type];
10808
10809 if (isEqualTokens && !isEqualTokens(actualToken, expectedToken, logger)) {
10810 return false;
10811 } // Peek at the next tokens (actual and expected) to see if they close
10812 // a self-closing tag
10813
10814
10815 if (isClosedByToken(actualToken, expectedTokens[0])) {
10816 // Consume the next expected token that closes the current actual
10817 // self-closing token
10818 getNextNonWhitespaceToken(expectedTokens);
10819 } else if (isClosedByToken(expectedToken, actualTokens[0])) {
10820 // Consume the next actual token that closes the current expected
10821 // self-closing token
10822 getNextNonWhitespaceToken(actualTokens);
10823 }
10824 }
10825
10826 if (expectedToken = getNextNonWhitespaceToken(expectedTokens)) {
10827 // If any non-whitespace tokens remain in expected token set, this
10828 // indicates inequality
10829 logger.warning('Expected %o, instead saw end of content.', expectedToken);
10830 return false;
10831 }
10832
10833 return true;
10834 }
10835 /**
10836 * Returns an object with `isValid` property set to `true` if the parsed block
10837 * is valid given the input content. A block is considered valid if, when serialized
10838 * with assumed attributes, the content matches the original value. If block is
10839 * invalid, this function returns all validations issues as well.
10840 *
10841 * @param {string|Object} blockTypeOrName Block type.
10842 * @param {Object} attributes Parsed block attributes.
10843 * @param {string} originalBlockContent Original block content.
10844 * @param {Object} logger Validation logger object.
10845 *
10846 * @return {Object} Whether block is valid and contains validation messages.
10847 */
10848
10849 /**
10850 * Returns an object with `isValid` property set to `true` if the parsed block
10851 * is valid given the input content. A block is considered valid if, when serialized
10852 * with assumed attributes, the content matches the original value. If block is
10853 * invalid, this function returns all validations issues as well.
10854 *
10855 * @param {import('../parser').WPBlock} block block object.
10856 * @param {import('../registration').WPBlockType} blockTypeOrName Block type or name.
10857 *
10858 * @return {[boolean,Object]} validation results.
10859 */
10860
10861 function validateBlock(block, blockTypeOrName) {
10862 const isFallbackBlock = block.name === getFreeformContentHandlerName() || block.name === getUnregisteredTypeHandlerName(); // Shortcut to avoid costly validation.
10863
10864 if (isFallbackBlock) {
10865 return [true];
10866 }
10867
10868 const logger = createQueuedLogger();
10869 const blockType = normalizeBlockType(blockTypeOrName);
10870 let generatedBlockContent;
10871
10872 try {
10873 generatedBlockContent = getSaveContent(blockType, block.attributes);
10874 } catch (error) {
10875 logger.error('Block validation failed because an error occurred while generating block content:\n\n%s', error.toString());
10876 return [false, logger.getItems()];
10877 }
10878
10879 const isValid = isEquivalentHTML(block.originalContent, generatedBlockContent, logger);
10880
10881 if (!isValid) {
10882 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);
10883 }
10884
10885 return [isValid, logger.getItems()];
10886 }
10887 /**
10888 * Returns true if the parsed block is valid given the input content. A block
10889 * is considered valid if, when serialized with assumed attributes, the content
10890 * matches the original value.
10891 *
10892 * Logs to console in development environments when invalid.
10893 *
10894 * @param {string|Object} blockTypeOrName Block type.
10895 * @param {Object} attributes Parsed block attributes.
10896 * @param {string} originalBlockContent Original block content.
10897 *
10898 * @return {boolean} Whether block is valid.
10899 */
10900
10901 function isValidBlockContent(blockTypeOrName, attributes, originalBlockContent) {
10902 const blockType = normalizeBlockType(blockTypeOrName);
10903 const block = {
10904 name: blockType.name,
10905 attributes,
10906 innerBlocks: [],
10907 originalContent: originalBlockContent
10908 };
10909 const [isValid] = validateBlock(block, blockType);
10910 return isValid;
10911 }
10912 //# sourceMappingURL=index.js.map
10913 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/parser/convert-legacy-block.js
10914 /**
10915 * Convert legacy blocks to their canonical form. This function is used
10916 * both in the parser level for previous content and to convert such blocks
10917 * used in Custom Post Types templates.
10918 *
10919 * @param {string} name The block's name
10920 * @param {Object} attributes The block's attributes
10921 *
10922 * @return {[string, Object]} The block's name and attributes, changed accordingly if a match was found
10923 */
10924 function convertLegacyBlockNameAndAttributes(name, attributes) {
10925 const newAttributes = { ...attributes
10926 }; // Convert 'core/cover-image' block in existing content to 'core/cover'.
10927
10928 if ('core/cover-image' === name) {
10929 name = 'core/cover';
10930 } // Convert 'core/text' blocks in existing content to 'core/paragraph'.
10931
10932
10933 if ('core/text' === name || 'core/cover-text' === name) {
10934 name = 'core/paragraph';
10935 } // Convert derivative blocks such as 'core/social-link-wordpress' to the
10936 // canonical form 'core/social-link'.
10937
10938
10939 if (name && name.indexOf('core/social-link-') === 0) {
10940 // Capture `social-link-wordpress` into `{"service":"wordpress"}`
10941 newAttributes.service = name.substring(17);
10942 name = 'core/social-link';
10943 } // Convert derivative blocks such as 'core-embed/instagram' to the
10944 // canonical form 'core/embed'.
10945
10946
10947 if (name && name.indexOf('core-embed/') === 0) {
10948 // Capture `core-embed/instagram` into `{"providerNameSlug":"instagram"}`
10949 const providerSlug = name.substring(11);
10950 const deprecated = {
10951 speaker: 'speaker-deck',
10952 polldaddy: 'crowdsignal'
10953 };
10954 newAttributes.providerNameSlug = providerSlug in deprecated ? deprecated[providerSlug] : providerSlug; // this is needed as the `responsive` attribute was passed
10955 // in a different way before the refactoring to block variations
10956
10957 if (!['amazon-kindle', 'wordpress'].includes(providerSlug)) {
10958 newAttributes.responsive = true;
10959 }
10960
10961 name = 'core/embed';
10962 } // Convert 'core/query-loop' blocks in existing content to 'core/post-template'.
10963 // TODO: Remove this check when WordPress 5.9 is released.
10964
10965
10966 if (name === 'core/query-loop') {
10967 name = 'core/post-template';
10968 }
10969
10970 return [name, newAttributes];
10971 }
10972 //# sourceMappingURL=convert-legacy-block.js.map
10973 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/parser/serialize-raw-block.js
10974 /**
10975 * Internal dependencies
10976 */
10977
10978 /**
10979 * Serializes a block node into the native HTML-comment-powered block format.
10980 * CAVEAT: This function is intended for reserializing blocks as parsed by
10981 * valid parsers and skips any validation steps. This is NOT a generic
10982 * serialization function for in-memory blocks. For most purposes, see the
10983 * following functions available in the `@wordpress/blocks` package:
10984 *
10985 * @see serializeBlock
10986 * @see serialize
10987 *
10988 * For more on the format of block nodes as returned by valid parsers:
10989 *
10990 * @see `@wordpress/block-serialization-default-parser` package
10991 * @see `@wordpress/block-serialization-spec-parser` package
10992 *
10993 * @param {import(".").WPRawBlock} rawBlock A block node as returned by a valid parser.
10994 * @param {?Object} options Serialization options.
10995 * @param {?boolean} options.isCommentDelimited Whether to output HTML comments around blocks.
10996 *
10997 * @return {string} An HTML string representing a block.
10998 */
10999
11000 function serializeRawBlock(rawBlock, options = {}) {
11001 const {
11002 isCommentDelimited = true
11003 } = options;
11004 const {
11005 blockName,
11006 attrs = {},
11007 innerBlocks = [],
11008 innerContent = []
11009 } = rawBlock;
11010 let childIndex = 0;
11011 const content = innerContent.map(item => // `null` denotes a nested block, otherwise we have an HTML fragment.
11012 item !== null ? item : serializeRawBlock(innerBlocks[childIndex++], options)).join('\n').replace(/\n+/g, '\n').trim();
11013 return isCommentDelimited ? getCommentDelimitedContent(blockName, attrs, content) : content;
11014 }
11015 //# sourceMappingURL=serialize-raw-block.js.map
11016 ;// CONCATENATED MODULE: ./node_modules/hpq/es/get-path.js
11017 /**
11018 * Given object and string of dot-delimited path segments, returns value at
11019 * path or undefined if path cannot be resolved.
11020 *
11021 * @param {Object} object Lookup object
11022 * @param {string} path Path to resolve
11023 * @return {?*} Resolved value
11024 */
11025 function getPath(object, path) {
11026 var segments = path.split('.');
11027 var segment;
11028
11029 while (segment = segments.shift()) {
11030 if (!(segment in object)) {
11031 return;
11032 }
11033
11034 object = object[segment];
11035 }
11036
11037 return object;
11038 }
11039 ;// CONCATENATED MODULE: ./node_modules/hpq/es/index.js
11040 /**
11041 * Internal dependencies
11042 */
11043
11044 /**
11045 * Function returning a DOM document created by `createHTMLDocument`. The same
11046 * document is returned between invocations.
11047 *
11048 * @return {Document} DOM document.
11049 */
11050
11051 var getDocument = function () {
11052 var doc;
11053 return function () {
11054 if (!doc) {
11055 doc = document.implementation.createHTMLDocument('');
11056 }
11057
11058 return doc;
11059 };
11060 }();
11061 /**
11062 * Given a markup string or DOM element, creates an object aligning with the
11063 * shape of the matchers object, or the value returned by the matcher.
11064 *
11065 * @param {(string|Element)} source Source content
11066 * @param {(Object|Function)} matchers Matcher function or object of matchers
11067 * @return {(Object|*)} Matched value(s), shaped by object
11068 */
11069
11070
11071 function parse(source, matchers) {
11072 if (!matchers) {
11073 return;
11074 } // Coerce to element
11075
11076
11077 if ('string' === typeof source) {
11078 var doc = getDocument();
11079 doc.body.innerHTML = source;
11080 source = doc.body;
11081 } // Return singular value
11082
11083
11084 if ('function' === typeof matchers) {
11085 return matchers(source);
11086 } // Bail if we can't handle matchers
11087
11088
11089 if (Object !== matchers.constructor) {
11090 return;
11091 } // Shape result by matcher object
11092
11093
11094 return Object.keys(matchers).reduce(function (memo, key) {
11095 memo[key] = parse(source, matchers[key]);
11096 return memo;
11097 }, {});
11098 }
11099 /**
11100 * Generates a function which matches node of type selector, returning an
11101 * attribute by property if the attribute exists. If no selector is passed,
11102 * returns property of the query element.
11103 *
11104 * @param {?string} selector Optional selector
11105 * @param {string} name Property name
11106 * @return {*} Property value
11107 */
11108
11109 function prop(selector, name) {
11110 if (1 === arguments.length) {
11111 name = selector;
11112 selector = undefined;
11113 }
11114
11115 return function (node) {
11116 var match = node;
11117
11118 if (selector) {
11119 match = node.querySelector(selector);
11120 }
11121
11122 if (match) {
11123 return getPath(match, name);
11124 }
11125 };
11126 }
11127 /**
11128 * Generates a function which matches node of type selector, returning an
11129 * attribute by name if the attribute exists. If no selector is passed,
11130 * returns attribute of the query element.
11131 *
11132 * @param {?string} selector Optional selector
11133 * @param {string} name Attribute name
11134 * @return {?string} Attribute value
11135 */
11136
11137 function attr(selector, name) {
11138 if (1 === arguments.length) {
11139 name = selector;
11140 selector = undefined;
11141 }
11142
11143 return function (node) {
11144 var attributes = prop(selector, 'attributes')(node);
11145
11146 if (attributes && attributes.hasOwnProperty(name)) {
11147 return attributes[name].value;
11148 }
11149 };
11150 }
11151 /**
11152 * Convenience for `prop( selector, 'innerHTML' )`.
11153 *
11154 * @see prop()
11155 *
11156 * @param {?string} selector Optional selector
11157 * @return {string} Inner HTML
11158 */
11159
11160 function html(selector) {
11161 return prop(selector, 'innerHTML');
11162 }
11163 /**
11164 * Convenience for `prop( selector, 'textContent' )`.
11165 *
11166 * @see prop()
11167 *
11168 * @param {?string} selector Optional selector
11169 * @return {string} Text content
11170 */
11171
11172 function es_text(selector) {
11173 return prop(selector, 'textContent');
11174 }
11175 /**
11176 * Creates a new matching context by first finding elements matching selector
11177 * using querySelectorAll before then running another `parse` on `matchers`
11178 * scoped to the matched elements.
11179 *
11180 * @see parse()
11181 *
11182 * @param {string} selector Selector to match
11183 * @param {(Object|Function)} matchers Matcher function or object of matchers
11184 * @return {Array.<*,Object>} Array of matched value(s)
11185 */
11186
11187 function query(selector, matchers) {
11188 return function (node) {
11189 var matches = node.querySelectorAll(selector);
11190 return [].map.call(matches, function (match) {
11191 return parse(match, matchers);
11192 });
11193 };
11194 }
11195 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/matchers.js
11196 /**
11197 * External dependencies
11198 */
11199
11200 /**
11201 * Internal dependencies
11202 */
11203
11204
11205
11206 function matchers_html(selector, multilineTag) {
11207 return domNode => {
11208 let match = domNode;
11209
11210 if (selector) {
11211 match = domNode.querySelector(selector);
11212 }
11213
11214 if (!match) {
11215 return '';
11216 }
11217
11218 if (multilineTag) {
11219 let value = '';
11220 const length = match.children.length;
11221
11222 for (let index = 0; index < length; index++) {
11223 const child = match.children[index];
11224
11225 if (child.nodeName.toLowerCase() !== multilineTag) {
11226 continue;
11227 }
11228
11229 value += child.outerHTML;
11230 }
11231
11232 return value;
11233 }
11234
11235 return match.innerHTML;
11236 };
11237 }
11238 //# sourceMappingURL=matchers.js.map
11239 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/node.js
11240 /**
11241 * Internal dependencies
11242 */
11243
11244 /**
11245 * A representation of a single node within a block's rich text value. If
11246 * representing a text node, the value is simply a string of the node value.
11247 * As representing an element node, it is an object of:
11248 *
11249 * 1. `type` (string): Tag name.
11250 * 2. `props` (object): Attributes and children array of WPBlockNode.
11251 *
11252 * @typedef {string|Object} WPBlockNode
11253 */
11254
11255 /**
11256 * Given a single node and a node type (e.g. `'br'`), returns true if the node
11257 * corresponds to that type, false otherwise.
11258 *
11259 * @param {WPBlockNode} node Block node to test
11260 * @param {string} type Node to type to test against.
11261 *
11262 * @return {boolean} Whether node is of intended type.
11263 */
11264
11265 function isNodeOfType(node, type) {
11266 return node && node.type === type;
11267 }
11268 /**
11269 * Given an object implementing the NamedNodeMap interface, returns a plain
11270 * object equivalent value of name, value key-value pairs.
11271 *
11272 * @see https://dom.spec.whatwg.org/#interface-namednodemap
11273 *
11274 * @param {NamedNodeMap} nodeMap NamedNodeMap to convert to object.
11275 *
11276 * @return {Object} Object equivalent value of NamedNodeMap.
11277 */
11278
11279
11280 function getNamedNodeMapAsObject(nodeMap) {
11281 const result = {};
11282
11283 for (let i = 0; i < nodeMap.length; i++) {
11284 const {
11285 name,
11286 value
11287 } = nodeMap[i];
11288 result[name] = value;
11289 }
11290
11291 return result;
11292 }
11293 /**
11294 * Given a DOM Element or Text node, returns an equivalent block node. Throws
11295 * if passed any node type other than element or text.
11296 *
11297 * @throws {TypeError} If non-element/text node is passed.
11298 *
11299 * @param {Node} domNode DOM node to convert.
11300 *
11301 * @return {WPBlockNode} Block node equivalent to DOM node.
11302 */
11303
11304 function fromDOM(domNode) {
11305 if (domNode.nodeType === domNode.TEXT_NODE) {
11306 return domNode.nodeValue;
11307 }
11308
11309 if (domNode.nodeType !== domNode.ELEMENT_NODE) {
11310 throw new TypeError('A block node can only be created from a node of type text or ' + 'element.');
11311 }
11312
11313 return {
11314 type: domNode.nodeName.toLowerCase(),
11315 props: { ...getNamedNodeMapAsObject(domNode.attributes),
11316 children: children_fromDOM(domNode.childNodes)
11317 }
11318 };
11319 }
11320 /**
11321 * Given a block node, returns its HTML string representation.
11322 *
11323 * @param {WPBlockNode} node Block node to convert to string.
11324 *
11325 * @return {string} String HTML representation of block node.
11326 */
11327
11328 function toHTML(node) {
11329 return children_toHTML([node]);
11330 }
11331 /**
11332 * Given a selector, returns an hpq matcher generating a WPBlockNode value
11333 * matching the selector result.
11334 *
11335 * @param {string} selector DOM selector.
11336 *
11337 * @return {Function} hpq matcher.
11338 */
11339
11340 function node_matcher(selector) {
11341 return domNode => {
11342 let match = domNode;
11343
11344 if (selector) {
11345 match = domNode.querySelector(selector);
11346 }
11347
11348 try {
11349 return fromDOM(match);
11350 } catch (error) {
11351 return null;
11352 }
11353 };
11354 }
11355 /**
11356 * Object of utility functions used in managing block attribute values of
11357 * source `node`.
11358 *
11359 * @see https://github.com/WordPress/gutenberg/pull/10439
11360 *
11361 * @deprecated since 4.0. The `node` source should not be used, and can be
11362 * replaced by the `html` source.
11363 *
11364 * @private
11365 */
11366
11367 /* harmony default export */ var node = ({
11368 isNodeOfType,
11369 fromDOM,
11370 toHTML,
11371 matcher: node_matcher
11372 });
11373 //# sourceMappingURL=node.js.map
11374 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/children.js
11375 /**
11376 * External dependencies
11377 */
11378
11379 /**
11380 * WordPress dependencies
11381 */
11382
11383
11384 /**
11385 * Internal dependencies
11386 */
11387
11388
11389 /**
11390 * A representation of a block's rich text value.
11391 *
11392 * @typedef {WPBlockNode[]} WPBlockChildren
11393 */
11394
11395 /**
11396 * Given block children, returns a serialize-capable WordPress element.
11397 *
11398 * @param {WPBlockChildren} children Block children object to convert.
11399 *
11400 * @return {WPElement} A serialize-capable element.
11401 */
11402
11403 function getSerializeCapableElement(children) {
11404 // The fact that block children are compatible with the element serializer is
11405 // merely an implementation detail that currently serves to be true, but
11406 // should not be mistaken as being a guarantee on the external API. The
11407 // public API only offers guarantees to work with strings (toHTML) and DOM
11408 // elements (fromDOM), and should provide utilities to manipulate the value
11409 // rather than expect consumers to inspect or construct its shape (concat).
11410 return children;
11411 }
11412 /**
11413 * Given block children, returns an array of block nodes.
11414 *
11415 * @param {WPBlockChildren} children Block children object to convert.
11416 *
11417 * @return {Array<WPBlockNode>} An array of individual block nodes.
11418 */
11419
11420 function getChildrenArray(children) {
11421 // The fact that block children are compatible with the element serializer
11422 // is merely an implementation detail that currently serves to be true, but
11423 // should not be mistaken as being a guarantee on the external API.
11424 return children;
11425 }
11426 /**
11427 * Given two or more block nodes, returns a new block node representing a
11428 * concatenation of its values.
11429 *
11430 * @param {...WPBlockChildren} blockNodes Block nodes to concatenate.
11431 *
11432 * @return {WPBlockChildren} Concatenated block node.
11433 */
11434
11435
11436 function concat(...blockNodes) {
11437 const result = [];
11438
11439 for (let i = 0; i < blockNodes.length; i++) {
11440 const blockNode = (0,external_lodash_namespaceObject.castArray)(blockNodes[i]);
11441
11442 for (let j = 0; j < blockNode.length; j++) {
11443 const child = blockNode[j];
11444 const canConcatToPreviousString = typeof child === 'string' && typeof result[result.length - 1] === 'string';
11445
11446 if (canConcatToPreviousString) {
11447 result[result.length - 1] += child;
11448 } else {
11449 result.push(child);
11450 }
11451 }
11452 }
11453
11454 return result;
11455 }
11456 /**
11457 * Given an iterable set of DOM nodes, returns equivalent block children.
11458 * Ignores any non-element/text nodes included in set.
11459 *
11460 * @param {Iterable.<Node>} domNodes Iterable set of DOM nodes to convert.
11461 *
11462 * @return {WPBlockChildren} Block children equivalent to DOM nodes.
11463 */
11464
11465 function children_fromDOM(domNodes) {
11466 const result = [];
11467
11468 for (let i = 0; i < domNodes.length; i++) {
11469 try {
11470 result.push(fromDOM(domNodes[i]));
11471 } catch (error) {// Simply ignore if DOM node could not be converted.
11472 }
11473 }
11474
11475 return result;
11476 }
11477 /**
11478 * Given a block node, returns its HTML string representation.
11479 *
11480 * @param {WPBlockChildren} children Block node(s) to convert to string.
11481 *
11482 * @return {string} String HTML representation of block node.
11483 */
11484
11485 function children_toHTML(children) {
11486 const element = getSerializeCapableElement(children);
11487 return (0,external_wp_element_namespaceObject.renderToString)(element);
11488 }
11489 /**
11490 * Given a selector, returns an hpq matcher generating a WPBlockChildren value
11491 * matching the selector result.
11492 *
11493 * @param {string} selector DOM selector.
11494 *
11495 * @return {Function} hpq matcher.
11496 */
11497
11498 function children_matcher(selector) {
11499 return domNode => {
11500 let match = domNode;
11501
11502 if (selector) {
11503 match = domNode.querySelector(selector);
11504 }
11505
11506 if (match) {
11507 return children_fromDOM(match.childNodes);
11508 }
11509
11510 return [];
11511 };
11512 }
11513 /**
11514 * Object of utility functions used in managing block attribute values of
11515 * source `children`.
11516 *
11517 * @see https://github.com/WordPress/gutenberg/pull/10439
11518 *
11519 * @deprecated since 4.0. The `children` source should not be used, and can be
11520 * replaced by the `html` source.
11521 *
11522 * @private
11523 */
11524
11525 /* harmony default export */ var children = ({
11526 concat,
11527 getChildrenArray,
11528 fromDOM: children_fromDOM,
11529 toHTML: children_toHTML,
11530 matcher: children_matcher
11531 });
11532 //# sourceMappingURL=children.js.map
11533 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/parser/get-block-attributes.js
11534 /**
11535 * External dependencies
11536 */
11537
11538
11539 /**
11540 * WordPress dependencies
11541 */
11542
11543
11544 /**
11545 * Internal dependencies
11546 */
11547
11548
11549
11550 /**
11551 * Higher-order hpq matcher which enhances an attribute matcher to return true
11552 * or false depending on whether the original matcher returns undefined. This
11553 * is useful for boolean attributes (e.g. disabled) whose attribute values may
11554 * be technically falsey (empty string), though their mere presence should be
11555 * enough to infer as true.
11556 *
11557 * @param {Function} matcher Original hpq matcher.
11558 *
11559 * @return {Function} Enhanced hpq matcher.
11560 */
11561
11562 const toBooleanAttributeMatcher = matcher => (0,external_lodash_namespaceObject.flow)([matcher, // Expected values from `attr( 'disabled' )`:
11563 //
11564 // <input>
11565 // - Value: `undefined`
11566 // - Transformed: `false`
11567 //
11568 // <input disabled>
11569 // - Value: `''`
11570 // - Transformed: `true`
11571 //
11572 // <input disabled="disabled">
11573 // - Value: `'disabled'`
11574 // - Transformed: `true`
11575 value => value !== undefined]);
11576 /**
11577 * Returns true if value is of the given JSON schema type, or false otherwise.
11578 *
11579 * @see http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.25
11580 *
11581 * @param {*} value Value to test.
11582 * @param {string} type Type to test.
11583 *
11584 * @return {boolean} Whether value is of type.
11585 */
11586
11587 function isOfType(value, type) {
11588 switch (type) {
11589 case 'string':
11590 return typeof value === 'string';
11591
11592 case 'boolean':
11593 return typeof value === 'boolean';
11594
11595 case 'object':
11596 return !!value && value.constructor === Object;
11597
11598 case 'null':
11599 return value === null;
11600
11601 case 'array':
11602 return Array.isArray(value);
11603
11604 case 'integer':
11605 case 'number':
11606 return typeof value === 'number';
11607 }
11608
11609 return true;
11610 }
11611 /**
11612 * Returns true if value is of an array of given JSON schema types, or false
11613 * otherwise.
11614 *
11615 * @see http://json-schema.org/latest/json-schema-validation.html#rfc.section.6.25
11616 *
11617 * @param {*} value Value to test.
11618 * @param {string[]} types Types to test.
11619 *
11620 * @return {boolean} Whether value is of types.
11621 */
11622
11623 function isOfTypes(value, types) {
11624 return types.some(type => isOfType(value, type));
11625 }
11626 /**
11627 * Given an attribute key, an attribute's schema, a block's raw content and the
11628 * commentAttributes returns the attribute value depending on its source
11629 * definition of the given attribute key.
11630 *
11631 * @param {string} attributeKey Attribute key.
11632 * @param {Object} attributeSchema Attribute's schema.
11633 * @param {string} innerHTML Block's raw content.
11634 * @param {Object} commentAttributes Block's comment attributes.
11635 *
11636 * @return {*} Attribute value.
11637 */
11638
11639 function getBlockAttribute(attributeKey, attributeSchema, innerHTML, commentAttributes) {
11640 const {
11641 type,
11642 enum: enumSet
11643 } = attributeSchema;
11644 let value;
11645
11646 switch (attributeSchema.source) {
11647 // An undefined source means that it's an attribute serialized to the
11648 // block's "comment".
11649 case undefined:
11650 value = commentAttributes ? commentAttributes[attributeKey] : undefined;
11651 break;
11652
11653 case 'attribute':
11654 case 'property':
11655 case 'html':
11656 case 'text':
11657 case 'children':
11658 case 'node':
11659 case 'query':
11660 case 'tag':
11661 value = parseWithAttributeSchema(innerHTML, attributeSchema);
11662 break;
11663 }
11664
11665 if (!isValidByType(value, type) || !isValidByEnum(value, enumSet)) {
11666 // Reject the value if it is not valid. Reverting to the undefined
11667 // value ensures the default is respected, if applicable.
11668 value = undefined;
11669 }
11670
11671 if (value === undefined) {
11672 return attributeSchema.default;
11673 }
11674
11675 return value;
11676 }
11677 /**
11678 * Returns true if value is valid per the given block attribute schema type
11679 * definition, or false otherwise.
11680 *
11681 * @see https://json-schema.org/latest/json-schema-validation.html#rfc.section.6.1.1
11682 *
11683 * @param {*} value Value to test.
11684 * @param {?(Array<string>|string)} type Block attribute schema type.
11685 *
11686 * @return {boolean} Whether value is valid.
11687 */
11688
11689 function isValidByType(value, type) {
11690 return type === undefined || isOfTypes(value, (0,external_lodash_namespaceObject.castArray)(type));
11691 }
11692 /**
11693 * Returns true if value is valid per the given block attribute schema enum
11694 * definition, or false otherwise.
11695 *
11696 * @see https://json-schema.org/latest/json-schema-validation.html#rfc.section.6.1.2
11697 *
11698 * @param {*} value Value to test.
11699 * @param {?Array} enumSet Block attribute schema enum.
11700 *
11701 * @return {boolean} Whether value is valid.
11702 */
11703
11704 function isValidByEnum(value, enumSet) {
11705 return !Array.isArray(enumSet) || enumSet.includes(value);
11706 }
11707 /**
11708 * Returns an hpq matcher given a source object.
11709 *
11710 * @param {Object} sourceConfig Attribute Source object.
11711 *
11712 * @return {Function} A hpq Matcher.
11713 */
11714
11715 function matcherFromSource(sourceConfig) {
11716 switch (sourceConfig.source) {
11717 case 'attribute':
11718 let matcher = attr(sourceConfig.selector, sourceConfig.attribute);
11719
11720 if (sourceConfig.type === 'boolean') {
11721 matcher = toBooleanAttributeMatcher(matcher);
11722 }
11723
11724 return matcher;
11725
11726 case 'html':
11727 return matchers_html(sourceConfig.selector, sourceConfig.multiline);
11728
11729 case 'text':
11730 return es_text(sourceConfig.selector);
11731
11732 case 'children':
11733 return children_matcher(sourceConfig.selector);
11734
11735 case 'node':
11736 return node_matcher(sourceConfig.selector);
11737
11738 case 'query':
11739 const subMatchers = (0,external_lodash_namespaceObject.mapValues)(sourceConfig.query, matcherFromSource);
11740 return query(sourceConfig.selector, subMatchers);
11741
11742 case 'tag':
11743 return (0,external_lodash_namespaceObject.flow)([prop(sourceConfig.selector, 'nodeName'), nodeName => nodeName ? nodeName.toLowerCase() : undefined]);
11744
11745 default:
11746 // eslint-disable-next-line no-console
11747 console.error(`Unknown source type "${sourceConfig.source}"`);
11748 }
11749 }
11750 /**
11751 * Given a block's raw content and an attribute's schema returns the attribute's
11752 * value depending on its source.
11753 *
11754 * @param {string} innerHTML Block's raw content.
11755 * @param {Object} attributeSchema Attribute's schema.
11756 *
11757 * @return {*} Attribute value.
11758 */
11759
11760 function parseWithAttributeSchema(innerHTML, attributeSchema) {
11761 return parse(innerHTML, matcherFromSource(attributeSchema));
11762 }
11763 /**
11764 * Returns the block attributes of a registered block node given its type.
11765 *
11766 * @param {string|Object} blockTypeOrName Block type or name.
11767 * @param {string} innerHTML Raw block content.
11768 * @param {?Object} attributes Known block attributes (from delimiters).
11769 *
11770 * @return {Object} All block attributes.
11771 */
11772
11773 function getBlockAttributes(blockTypeOrName, innerHTML, attributes = {}) {
11774 const blockType = normalizeBlockType(blockTypeOrName);
11775 const blockAttributes = (0,external_lodash_namespaceObject.mapValues)(blockType.attributes, (attributeSchema, attributeKey) => {
11776 return getBlockAttribute(attributeKey, attributeSchema, innerHTML, attributes);
11777 });
11778 return (0,external_wp_hooks_namespaceObject.applyFilters)('blocks.getBlockAttributes', blockAttributes, blockType, innerHTML, attributes);
11779 }
11780 //# sourceMappingURL=get-block-attributes.js.map
11781 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/parser/fix-custom-classname.js
11782 /**
11783 * External dependencies
11784 */
11785
11786 /**
11787 * Internal dependencies
11788 */
11789
11790
11791
11792
11793 /**
11794 * Given an HTML string, returns an array of class names assigned to the root
11795 * element in the markup.
11796 *
11797 * @param {string} innerHTML Markup string from which to extract classes.
11798 *
11799 * @return {string[]} Array of class names assigned to the root element.
11800 */
11801
11802 function getHTMLRootElementClasses(innerHTML) {
11803 innerHTML = `<div data-custom-class-name>${innerHTML}</div>`;
11804 const parsed = parseWithAttributeSchema(innerHTML, {
11805 type: 'string',
11806 source: 'attribute',
11807 selector: '[data-custom-class-name] > *',
11808 attribute: 'class'
11809 });
11810 return parsed ? parsed.trim().split(/\s+/) : [];
11811 }
11812 /**
11813 * Given a parsed set of block attributes, if the block supports custom class
11814 * names and an unknown class (per the block's serialization behavior) is
11815 * found, the unknown classes are treated as custom classes. This prevents the
11816 * block from being considered as invalid.
11817 *
11818 * @param {Object} blockAttributes Original block attributes.
11819 * @param {Object} blockType Block type settings.
11820 * @param {string} innerHTML Original block markup.
11821 *
11822 * @return {Object} Filtered block attributes.
11823 */
11824
11825 function fixCustomClassname(blockAttributes, blockType, innerHTML) {
11826 if (registration_hasBlockSupport(blockType, 'customClassName', true)) {
11827 // To determine difference, serialize block given the known set of
11828 // attributes, with the exception of `className`. This will determine
11829 // the default set of classes. From there, any difference in innerHTML
11830 // can be considered as custom classes.
11831 const attributesSansClassName = (0,external_lodash_namespaceObject.omit)(blockAttributes, ['className']);
11832 const serialized = getSaveContent(blockType, attributesSansClassName);
11833 const defaultClasses = getHTMLRootElementClasses(serialized);
11834 const actualClasses = getHTMLRootElementClasses(innerHTML);
11835 const customClasses = (0,external_lodash_namespaceObject.difference)(actualClasses, defaultClasses);
11836
11837 if (customClasses.length) {
11838 blockAttributes.className = customClasses.join(' ');
11839 } else if (serialized) {
11840 delete blockAttributes.className;
11841 }
11842 }
11843
11844 return blockAttributes;
11845 }
11846 //# sourceMappingURL=fix-custom-classname.js.map
11847 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/parser/apply-built-in-validation-fixes.js
11848 /**
11849 * Internal dependencies
11850 */
11851
11852 /**
11853 * Attempts to fix block invalidation by applying build-in validation fixes
11854 * like moving all extra classNames to the className attribute.
11855 *
11856 * @param {WPBlock} block block object.
11857 * @param {import('../registration').WPBlockType} blockType Block type. This is normalize not necessary and
11858 * can be inferred from the block name,
11859 * but it's here for performance reasons.
11860 *
11861 * @return {WPBlock} Fixed block object
11862 */
11863
11864 function applyBuiltInValidationFixes(block, blockType) {
11865 const updatedBlockAttributes = fixCustomClassname(block.attributes, blockType, block.originalContent);
11866 return { ...block,
11867 attributes: updatedBlockAttributes
11868 };
11869 }
11870 //# sourceMappingURL=apply-built-in-validation-fixes.js.map
11871 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/parser/apply-block-deprecated-versions.js
11872 /**
11873 * External dependencies
11874 */
11875
11876 /**
11877 * Internal dependencies
11878 */
11879
11880
11881
11882
11883
11884 /**
11885 * Given a block object, returns a new copy of the block with any applicable
11886 * deprecated migrations applied, or the original block if it was both valid
11887 * and no eligible migrations exist.
11888 *
11889 * @param {import(".").WPBlock} block Parsed and invalid block object.
11890 * @param {import(".").WPRawBlock} rawBlock Raw block object.
11891 * @param {import('../registration').WPBlockType} blockType Block type. This is normalize not necessary and
11892 * can be inferred from the block name,
11893 * but it's here for performance reasons.
11894 *
11895 * @return {import(".").WPBlock} Migrated block object.
11896 */
11897
11898 function applyBlockDeprecatedVersions(block, rawBlock, blockType) {
11899 const parsedAttributes = rawBlock.attrs;
11900 const {
11901 deprecated: deprecatedDefinitions
11902 } = blockType; // Bail early if there are no registered deprecations to be handled.
11903
11904 if (!deprecatedDefinitions || !deprecatedDefinitions.length) {
11905 return block;
11906 } // By design, blocks lack any sort of version tracking. Instead, to process
11907 // outdated content the system operates a queue out of all the defined
11908 // attribute shapes and tries each definition until the input produces a
11909 // valid result. This mechanism seeks to avoid polluting the user-space with
11910 // machine-specific code. An invalid block is thus a block that could not be
11911 // matched successfully with any of the registered deprecation definitions.
11912
11913
11914 for (let i = 0; i < deprecatedDefinitions.length; i++) {
11915 // A block can opt into a migration even if the block is valid by
11916 // defining `isEligible` on its deprecation. If the block is both valid
11917 // and does not opt to migrate, skip.
11918 const {
11919 isEligible = external_lodash_namespaceObject.stubFalse
11920 } = deprecatedDefinitions[i];
11921
11922 if (block.isValid && !isEligible(parsedAttributes, block.innerBlocks)) {
11923 continue;
11924 } // Block type properties which could impact either serialization or
11925 // parsing are not considered in the deprecated block type by default,
11926 // and must be explicitly provided.
11927
11928
11929 const deprecatedBlockType = Object.assign((0,external_lodash_namespaceObject.omit)(blockType, DEPRECATED_ENTRY_KEYS), deprecatedDefinitions[i]);
11930 let migratedBlock = { ...block,
11931 attributes: getBlockAttributes(deprecatedBlockType, block.originalContent, parsedAttributes)
11932 }; // Ignore the deprecation if it produces a block which is not valid.
11933
11934 let [isValid] = validateBlock(migratedBlock, deprecatedBlockType); // If the migrated block is not valid intiailly, try the built-in fixes.
11935
11936 if (!isValid) {
11937 migratedBlock = applyBuiltInValidationFixes(migratedBlock, deprecatedBlockType);
11938 [isValid] = validateBlock(migratedBlock, deprecatedBlockType);
11939 } // An invalid block does not imply incorrect HTML but the fact block
11940 // source information could be lost on reserialization.
11941
11942
11943 if (!isValid) {
11944 continue;
11945 }
11946
11947 let migratedInnerBlocks = migratedBlock.innerBlocks;
11948 let migratedAttributes = migratedBlock.attributes; // A block may provide custom behavior to assign new attributes and/or
11949 // inner blocks.
11950
11951 const {
11952 migrate
11953 } = deprecatedBlockType;
11954
11955 if (migrate) {
11956 [migratedAttributes = parsedAttributes, migratedInnerBlocks = block.innerBlocks] = (0,external_lodash_namespaceObject.castArray)(migrate(migratedAttributes, block.innerBlocks));
11957 }
11958
11959 block = { ...block,
11960 attributes: migratedAttributes,
11961 innerBlocks: migratedInnerBlocks,
11962 isValid: true,
11963 validationIssues: []
11964 };
11965 }
11966
11967 return block;
11968 }
11969 //# sourceMappingURL=apply-block-deprecated-versions.js.map
11970 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/parser/index.js
11971 /**
11972 * WordPress dependencies
11973 */
11974
11975
11976 /**
11977 * Internal dependencies
11978 */
11979
11980
11981
11982
11983
11984
11985
11986
11987
11988
11989 /**
11990 * The raw structure of a block includes its attributes, inner
11991 * blocks, and inner HTML. It is important to distinguish inner blocks from
11992 * the HTML content of the block as only the latter is relevant for block
11993 * validation and edit operations.
11994 *
11995 * @typedef WPRawBlock
11996 *
11997 * @property {string=} blockName Block name
11998 * @property {Object=} attrs Block raw or comment attributes.
11999 * @property {string} innerHTML HTML content of the block.
12000 * @property {(string|null)[]} innerContent Content without inner blocks.
12001 * @property {WPRawBlock[]} innerBlocks Inner Blocks.
12002 */
12003
12004 /**
12005 * Fully parsed block object.
12006 *
12007 * @typedef WPBlock
12008 *
12009 * @property {string} name Block name
12010 * @property {Object } attributes Block raw or comment attributes.
12011 * @property {WPBlock[]} innerBlocks Inner Blocks.
12012 * @property {string} originalContent Original content of the block before validation fixes.
12013 * @property {boolean} isValid Whether the block is valid.
12014 * @property {Object[]} validationIssues Validation issues.
12015 */
12016
12017 /**
12018 * Convert legacy blocks to their canonical form. This function is used
12019 * both in the parser level for previous content and to convert such blocks
12020 * used in Custom Post Types templates.
12021 *
12022 * @param {WPRawBlock} rawBlock
12023 *
12024 * @return {WPRawBlock} The block's name and attributes, changed accordingly if a match was found
12025 */
12026
12027 function convertLegacyBlocks(rawBlock) {
12028 const [correctName, correctedAttributes] = convertLegacyBlockNameAndAttributes(rawBlock.blockName, rawBlock.attrs);
12029 return { ...rawBlock,
12030 blockName: correctName,
12031 attrs: correctedAttributes
12032 };
12033 }
12034 /**
12035 * Normalize the raw block by applying the fallback block name if none given,
12036 * sanitize the parsed HTML...
12037 *
12038 * @param {WPRawBlock} rawBlock The raw block object.
12039 *
12040 * @return {WPRawBlock} The normalized block object.
12041 */
12042
12043
12044 function normalizeRawBlock(rawBlock) {
12045 const fallbackBlockName = getFreeformContentHandlerName(); // If the grammar parsing don't produce any block name, use the freeform block.
12046
12047 const rawBlockName = rawBlock.blockName || getFreeformContentHandlerName();
12048 const rawAttributes = rawBlock.attrs || {};
12049 const rawInnerBlocks = rawBlock.innerBlocks || [];
12050 let rawInnerHTML = rawBlock.innerHTML.trim(); // Fallback content may be upgraded from classic content expecting implicit
12051 // automatic paragraphs, so preserve them. Assumes wpautop is idempotent,
12052 // meaning there are no negative consequences to repeated autop calls.
12053
12054 if (rawBlockName === fallbackBlockName) {
12055 rawInnerHTML = (0,external_wp_autop_namespaceObject.autop)(rawInnerHTML).trim();
12056 }
12057
12058 return { ...rawBlock,
12059 blockName: rawBlockName,
12060 attrs: rawAttributes,
12061 innerHTML: rawInnerHTML,
12062 innerBlocks: rawInnerBlocks
12063 };
12064 }
12065 /**
12066 * Uses the "unregistered blockType" to create a block object.
12067 *
12068 * @param {WPRawBlock} rawBlock block.
12069 *
12070 * @return {WPRawBlock} The unregistered block object.
12071 */
12072
12073 function createMissingBlockType(rawBlock) {
12074 const unregisteredFallbackBlock = getUnregisteredTypeHandlerName() || getFreeformContentHandlerName(); // Preserve undelimited content for use by the unregistered type
12075 // handler. A block node's `innerHTML` isn't enough, as that field only
12076 // carries the block's own HTML and not its nested blocks.
12077
12078 const originalUndelimitedContent = serializeRawBlock(rawBlock, {
12079 isCommentDelimited: false
12080 }); // Preserve full block content for use by the unregistered type
12081 // handler, block boundaries included.
12082
12083 const originalContent = serializeRawBlock(rawBlock, {
12084 isCommentDelimited: true
12085 });
12086 return {
12087 blockName: unregisteredFallbackBlock,
12088 attrs: {
12089 originalName: rawBlock.blockName,
12090 originalContent,
12091 originalUndelimitedContent
12092 },
12093 innerHTML: rawBlock.blockName ? originalContent : rawBlock.innerHTML,
12094 innerBlocks: rawBlock.innerBlocks,
12095 innerContent: rawBlock.innerContent
12096 };
12097 }
12098 /**
12099 * Given a raw block returned by grammar parsing, returns a fully parsed block.
12100 *
12101 * @param {WPRawBlock} rawBlock The raw block object.
12102 *
12103 * @return {WPBlock} Fully parsed block.
12104 */
12105
12106
12107 function parseRawBlock(rawBlock) {
12108 let normalizedBlock = normalizeRawBlock(rawBlock); // During the lifecycle of the project, we renamed some old blocks
12109 // and transformed others to new blocks. To avoid breaking existing content,
12110 // we added this function to properly parse the old content.
12111
12112 normalizedBlock = convertLegacyBlocks(normalizedBlock); // Try finding the type for known block name.
12113
12114 let blockType = registration_getBlockType(normalizedBlock.blockName); // If not blockType is found for the specified name, fallback to the "unregistedBlockType".
12115
12116 if (!blockType) {
12117 normalizedBlock = createMissingBlockType(normalizedBlock);
12118 blockType = registration_getBlockType(normalizedBlock.blockName);
12119 } // If it's an empty freeform block or there's no blockType (no missing block handler)
12120 // Then, just ignore the block.
12121 // It might be a good idea to throw a warning here.
12122 // TODO: I'm unsure about the unregisteredFallbackBlock check,
12123 // it might ignore some dynamic unregistered third party blocks wrongly.
12124
12125
12126 const isFallbackBlock = normalizedBlock.blockName === getFreeformContentHandlerName() || normalizedBlock.blockName === getUnregisteredTypeHandlerName();
12127
12128 if (!blockType || !normalizedBlock.innerHTML && isFallbackBlock) {
12129 return;
12130 } // Parse inner blocks recursively.
12131
12132
12133 const parsedInnerBlocks = normalizedBlock.innerBlocks.map(parseRawBlock) // See https://github.com/WordPress/gutenberg/pull/17164.
12134 .filter(innerBlock => !!innerBlock); // Get the fully parsed block.
12135
12136 let parsedBlock = createBlock(normalizedBlock.blockName, getBlockAttributes(blockType, normalizedBlock.innerHTML, normalizedBlock.attrs), parsedInnerBlocks);
12137 parsedBlock.originalContent = normalizedBlock.innerHTML; // Attempt to validate the block.
12138
12139 let [isValid, validationIssues] = validateBlock(parsedBlock, blockType); // If the block is invalid, attempt some built-in fixes
12140 // like custom classNames handling.
12141
12142 if (!isValid) {
12143 parsedBlock = applyBuiltInValidationFixes(parsedBlock, blockType); // Attempt to validate the block once again after the built-in fixes.
12144
12145 [isValid, validationIssues] = validateBlock(parsedBlock, blockType);
12146 }
12147
12148 parsedBlock.isValid = isValid;
12149 parsedBlock.validationIssues = validationIssues; // Run the block deprecation and migrations.
12150 // This is performed on both invalid and valid blocks because
12151 // migration using the `migrate` functions should run even
12152 // if the output is deemed valid.
12153
12154 parsedBlock = applyBlockDeprecatedVersions(parsedBlock, normalizedBlock, blockType);
12155
12156 if (validationIssues && validationIssues.length > 0) {
12157 if (parsedBlock.isValid) {
12158 /* eslint-disable no-console */
12159 console.groupCollapsed('Updated Block: %s', blockType.name);
12160 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, parsedBlock.attributes), parsedBlock.originalContent);
12161 console.groupEnd();
12162 /* eslint-enable no-console */
12163 } else {
12164 validationIssues.forEach(({
12165 log,
12166 args
12167 }) => log(...args));
12168 }
12169 }
12170
12171 return parsedBlock;
12172 }
12173 /**
12174 * Utilizes an optimized token-driven parser based on the Gutenberg grammar spec
12175 * defined through a parsing expression grammar to take advantage of the regular
12176 * cadence provided by block delimiters -- composed syntactically through HTML
12177 * comments -- which, given a general HTML document as an input, returns a block
12178 * list array representation.
12179 *
12180 * This is a recursive-descent parser that scans linearly once through the input
12181 * document. Instead of directly recursing it utilizes a trampoline mechanism to
12182 * prevent stack overflow. This initial pass is mainly interested in separating
12183 * and isolating the blocks serialized in the document and manifestly not in the
12184 * content within the blocks.
12185 *
12186 * @see
12187 * https://developer.wordpress.org/block-editor/packages/packages-block-serialization-default-parser/
12188 *
12189 * @param {string} content The post content.
12190 *
12191 * @return {Array} Block list.
12192 */
12193
12194 function parser_parse(content) {
12195 return (0,external_wp_blockSerializationDefaultParser_namespaceObject.parse)(content).reduce((accumulator, rawBlock) => {
12196 const block = parseRawBlock(rawBlock);
12197
12198 if (block) {
12199 accumulator.push(block);
12200 }
12201
12202 return accumulator;
12203 }, []);
12204 }
12205 //# sourceMappingURL=index.js.map
12206 ;// CONCATENATED MODULE: external ["wp","deprecated"]
12207 var external_wp_deprecated_namespaceObject = window["wp"]["deprecated"];
12208 var external_wp_deprecated_default = /*#__PURE__*/__webpack_require__.n(external_wp_deprecated_namespaceObject);
12209 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/get-raw-transforms.js
12210 /**
12211 * External dependencies
12212 */
12213
12214 /**
12215 * Internal dependencies
12216 */
12217
12218
12219 function getRawTransforms() {
12220 return (0,external_lodash_namespaceObject.filter)(getBlockTransforms('from'), {
12221 type: 'raw'
12222 }).map(transform => {
12223 return transform.isMatch ? transform : { ...transform,
12224 isMatch: node => transform.selector && node.matches(transform.selector)
12225 };
12226 });
12227 }
12228 //# sourceMappingURL=get-raw-transforms.js.map
12229 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/html-to-blocks.js
12230 /**
12231 * Internal dependencies
12232 */
12233
12234
12235
12236 /**
12237 * Converts HTML directly to blocks. Looks for a matching transform for each
12238 * top-level tag. The HTML should be filtered to not have any text between
12239 * top-level tags and formatted in a way that blocks can handle the HTML.
12240 *
12241 * @param {string} html HTML to convert.
12242 *
12243 * @return {Array} An array of blocks.
12244 */
12245
12246 function htmlToBlocks(html) {
12247 const doc = document.implementation.createHTMLDocument('');
12248 doc.body.innerHTML = html;
12249 return Array.from(doc.body.children).flatMap(node => {
12250 const rawTransform = findTransform(getRawTransforms(), ({
12251 isMatch
12252 }) => isMatch(node));
12253
12254 if (!rawTransform) {
12255 return createBlock( // Should not be hardcoded.
12256 'core/html', getBlockAttributes('core/html', node.outerHTML));
12257 }
12258
12259 const {
12260 transform,
12261 blockName
12262 } = rawTransform;
12263
12264 if (transform) {
12265 return transform(node);
12266 }
12267
12268 return createBlock(blockName, getBlockAttributes(blockName, node.outerHTML));
12269 });
12270 }
12271 //# sourceMappingURL=html-to-blocks.js.map
12272 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/normalise-blocks.js
12273 /**
12274 * WordPress dependencies
12275 */
12276
12277 function normaliseBlocks(HTML) {
12278 const decuDoc = document.implementation.createHTMLDocument('');
12279 const accuDoc = document.implementation.createHTMLDocument('');
12280 const decu = decuDoc.body;
12281 const accu = accuDoc.body;
12282 decu.innerHTML = HTML;
12283
12284 while (decu.firstChild) {
12285 const node = decu.firstChild; // Text nodes: wrap in a paragraph, or append to previous.
12286
12287 if (node.nodeType === node.TEXT_NODE) {
12288 if ((0,external_wp_dom_namespaceObject.isEmpty)(node)) {
12289 decu.removeChild(node);
12290 } else {
12291 if (!accu.lastChild || accu.lastChild.nodeName !== 'P') {
12292 accu.appendChild(accuDoc.createElement('P'));
12293 }
12294
12295 accu.lastChild.appendChild(node);
12296 } // Element nodes.
12297
12298 } else if (node.nodeType === node.ELEMENT_NODE) {
12299 // BR nodes: create a new paragraph on double, or append to previous.
12300 if (node.nodeName === 'BR') {
12301 if (node.nextSibling && node.nextSibling.nodeName === 'BR') {
12302 accu.appendChild(accuDoc.createElement('P'));
12303 decu.removeChild(node.nextSibling);
12304 } // Don't append to an empty paragraph.
12305
12306
12307 if (accu.lastChild && accu.lastChild.nodeName === 'P' && accu.lastChild.hasChildNodes()) {
12308 accu.lastChild.appendChild(node);
12309 } else {
12310 decu.removeChild(node);
12311 }
12312 } else if (node.nodeName === 'P') {
12313 // Only append non-empty paragraph nodes.
12314 if ((0,external_wp_dom_namespaceObject.isEmpty)(node)) {
12315 decu.removeChild(node);
12316 } else {
12317 accu.appendChild(node);
12318 }
12319 } else if ((0,external_wp_dom_namespaceObject.isPhrasingContent)(node)) {
12320 if (!accu.lastChild || accu.lastChild.nodeName !== 'P') {
12321 accu.appendChild(accuDoc.createElement('P'));
12322 }
12323
12324 accu.lastChild.appendChild(node);
12325 } else {
12326 accu.appendChild(node);
12327 }
12328 } else {
12329 decu.removeChild(node);
12330 }
12331 }
12332
12333 return accu.innerHTML;
12334 }
12335 //# sourceMappingURL=normalise-blocks.js.map
12336 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/special-comment-converter.js
12337 /**
12338 * WordPress dependencies
12339 */
12340
12341 /**
12342 * Looks for `<!--nextpage-->` and `<!--more-->` comments, as well as the
12343 * `<!--more Some text-->` variant and its `<!--noteaser-->` companion,
12344 * and replaces them with a custom element representing a future block.
12345 *
12346 * The custom element is a way to bypass the rest of the `raw-handling`
12347 * transforms, which would eliminate other kinds of node with which to carry
12348 * `<!--more-->`'s data: nodes with `data` attributes, empty paragraphs, etc.
12349 *
12350 * The custom element is then expected to be recognized by any registered
12351 * block's `raw` transform.
12352 *
12353 * @param {Node} node The node to be processed.
12354 * @param {Document} doc The document of the node.
12355 * @return {void}
12356 */
12357
12358 function specialCommentConverter(node, doc) {
12359 if (node.nodeType !== node.COMMENT_NODE) {
12360 return;
12361 }
12362
12363 if (node.nodeValue === 'nextpage') {
12364 (0,external_wp_dom_namespaceObject.replace)(node, createNextpage(doc));
12365 return;
12366 }
12367
12368 if (node.nodeValue.indexOf('more') === 0) {
12369 // Grab any custom text in the comment.
12370 const customText = node.nodeValue.slice(4).trim();
12371 /*
12372 * When a `<!--more-->` comment is found, we need to look for any
12373 * `<!--noteaser-->` sibling, but it may not be a direct sibling
12374 * (whitespace typically lies in between)
12375 */
12376
12377 let sibling = node;
12378 let noTeaser = false;
12379
12380 while (sibling = sibling.nextSibling) {
12381 if (sibling.nodeType === sibling.COMMENT_NODE && sibling.nodeValue === 'noteaser') {
12382 noTeaser = true;
12383 (0,external_wp_dom_namespaceObject.remove)(sibling);
12384 break;
12385 }
12386 }
12387
12388 (0,external_wp_dom_namespaceObject.replace)(node, createMore(customText, noTeaser, doc));
12389 }
12390 }
12391
12392 function createMore(customText, noTeaser, doc) {
12393 const node = doc.createElement('wp-block');
12394 node.dataset.block = 'core/more';
12395
12396 if (customText) {
12397 node.dataset.customText = customText;
12398 }
12399
12400 if (noTeaser) {
12401 // "Boolean" data attribute
12402 node.dataset.noTeaser = '';
12403 }
12404
12405 return node;
12406 }
12407
12408 function createNextpage(doc) {
12409 const node = doc.createElement('wp-block');
12410 node.dataset.block = 'core/nextpage';
12411 return node;
12412 }
12413 //# sourceMappingURL=special-comment-converter.js.map
12414 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/list-reducer.js
12415 /**
12416 * WordPress dependencies
12417 */
12418
12419
12420 function isList(node) {
12421 return node.nodeName === 'OL' || node.nodeName === 'UL';
12422 }
12423
12424 function shallowTextContent(element) {
12425 return Array.from(element.childNodes).map(({
12426 nodeValue = ''
12427 }) => nodeValue).join('');
12428 }
12429
12430 function listReducer(node) {
12431 if (!isList(node)) {
12432 return;
12433 }
12434
12435 const list = node;
12436 const prevElement = node.previousElementSibling; // Merge with previous list if:
12437 // * There is a previous list of the same type.
12438 // * There is only one list item.
12439
12440 if (prevElement && prevElement.nodeName === node.nodeName && list.children.length === 1) {
12441 // Move all child nodes, including any text nodes, if any.
12442 while (list.firstChild) {
12443 prevElement.appendChild(list.firstChild);
12444 }
12445
12446 list.parentNode.removeChild(list);
12447 }
12448
12449 const parentElement = node.parentNode; // Nested list with empty parent item.
12450
12451 if (parentElement && parentElement.nodeName === 'LI' && parentElement.children.length === 1 && !/\S/.test(shallowTextContent(parentElement))) {
12452 const parentListItem = parentElement;
12453 const prevListItem = parentListItem.previousElementSibling;
12454 const parentList = parentListItem.parentNode;
12455
12456 if (prevListItem) {
12457 prevListItem.appendChild(list);
12458 parentList.removeChild(parentListItem);
12459 } else {
12460 parentList.parentNode.insertBefore(list, parentList);
12461 parentList.parentNode.removeChild(parentList);
12462 }
12463 } // Invalid: OL/UL > OL/UL.
12464
12465
12466 if (parentElement && isList(parentElement)) {
12467 const prevListItem = node.previousElementSibling;
12468
12469 if (prevListItem) {
12470 prevListItem.appendChild(node);
12471 } else {
12472 (0,external_wp_dom_namespaceObject.unwrap)(node);
12473 }
12474 }
12475 }
12476 //# sourceMappingURL=list-reducer.js.map
12477 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/blockquote-normaliser.js
12478 /**
12479 * Internal dependencies
12480 */
12481
12482 function blockquoteNormaliser(node) {
12483 if (node.nodeName !== 'BLOCKQUOTE') {
12484 return;
12485 }
12486
12487 node.innerHTML = normaliseBlocks(node.innerHTML);
12488 }
12489 //# sourceMappingURL=blockquote-normaliser.js.map
12490 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/figure-content-reducer.js
12491 /**
12492 * External dependencies
12493 */
12494
12495 /**
12496 * WordPress dependencies
12497 */
12498
12499
12500 /**
12501 * Whether or not the given node is figure content.
12502 *
12503 * @param {Node} node The node to check.
12504 * @param {Object} schema The schema to use.
12505 *
12506 * @return {boolean} True if figure content, false if not.
12507 */
12508
12509 function isFigureContent(node, schema) {
12510 const tag = node.nodeName.toLowerCase(); // We are looking for tags that can be a child of the figure tag, excluding
12511 // `figcaption` and any phrasing content.
12512
12513 if (tag === 'figcaption' || (0,external_wp_dom_namespaceObject.isTextContent)(node)) {
12514 return false;
12515 }
12516
12517 return (0,external_lodash_namespaceObject.has)(schema, ['figure', 'children', tag]);
12518 }
12519 /**
12520 * Whether or not the given node can have an anchor.
12521 *
12522 * @param {Node} node The node to check.
12523 * @param {Object} schema The schema to use.
12524 *
12525 * @return {boolean} True if it can, false if not.
12526 */
12527
12528
12529 function canHaveAnchor(node, schema) {
12530 const tag = node.nodeName.toLowerCase();
12531 return (0,external_lodash_namespaceObject.has)(schema, ['figure', 'children', 'a', 'children', tag]);
12532 }
12533 /**
12534 * Wraps the given element in a figure element.
12535 *
12536 * @param {Element} element The element to wrap.
12537 * @param {Element} beforeElement The element before which to place the figure.
12538 */
12539
12540
12541 function wrapFigureContent(element, beforeElement = element) {
12542 const figure = element.ownerDocument.createElement('figure');
12543 beforeElement.parentNode.insertBefore(figure, beforeElement);
12544 figure.appendChild(element);
12545 }
12546 /**
12547 * This filter takes figure content out of paragraphs, wraps it in a figure
12548 * element, and moves any anchors with it if needed.
12549 *
12550 * @param {Node} node The node to filter.
12551 * @param {Document} doc The document of the node.
12552 * @param {Object} schema The schema to use.
12553 *
12554 * @return {void}
12555 */
12556
12557
12558 function figureContentReducer(node, doc, schema) {
12559 if (!isFigureContent(node, schema)) {
12560 return;
12561 }
12562
12563 let nodeToInsert = node;
12564 const parentNode = node.parentNode; // If the figure content can have an anchor and its parent is an anchor with
12565 // only the figure content, take the anchor out instead of just the content.
12566
12567 if (canHaveAnchor(node, schema) && parentNode.nodeName === 'A' && parentNode.childNodes.length === 1) {
12568 nodeToInsert = node.parentNode;
12569 }
12570
12571 const wrapper = nodeToInsert.closest('p,div'); // If wrapped in a paragraph or div, only extract if it's aligned or if
12572 // there is no text content.
12573 // Otherwise, if directly at the root, wrap in a figure element.
12574
12575 if (wrapper) {
12576 // In jsdom-jscore, 'node.classList' can be undefined.
12577 // In this case, default to extract as it offers a better UI experience on mobile.
12578 if (!node.classList) {
12579 wrapFigureContent(nodeToInsert, wrapper);
12580 } else if (node.classList.contains('alignright') || node.classList.contains('alignleft') || node.classList.contains('aligncenter') || !wrapper.textContent.trim()) {
12581 wrapFigureContent(nodeToInsert, wrapper);
12582 }
12583 } else if (nodeToInsert.parentNode.nodeName === 'BODY') {
12584 wrapFigureContent(nodeToInsert);
12585 }
12586 }
12587 //# sourceMappingURL=figure-content-reducer.js.map
12588 ;// CONCATENATED MODULE: external ["wp","shortcode"]
12589 var external_wp_shortcode_namespaceObject = window["wp"]["shortcode"];
12590 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/shortcode-converter.js
12591 /**
12592 * External dependencies
12593 */
12594
12595 /**
12596 * WordPress dependencies
12597 */
12598
12599
12600 /**
12601 * Internal dependencies
12602 */
12603
12604
12605
12606
12607
12608
12609 function segmentHTMLToShortcodeBlock(HTML, lastIndex = 0, excludedBlockNames = []) {
12610 // Get all matches.
12611 const transformsFrom = getBlockTransforms('from');
12612 const transformation = findTransform(transformsFrom, transform => excludedBlockNames.indexOf(transform.blockName) === -1 && transform.type === 'shortcode' && (0,external_lodash_namespaceObject.some)((0,external_lodash_namespaceObject.castArray)(transform.tag), tag => (0,external_wp_shortcode_namespaceObject.regexp)(tag).test(HTML)));
12613
12614 if (!transformation) {
12615 return [HTML];
12616 }
12617
12618 const transformTags = (0,external_lodash_namespaceObject.castArray)(transformation.tag);
12619 const transformTag = (0,external_lodash_namespaceObject.find)(transformTags, tag => (0,external_wp_shortcode_namespaceObject.regexp)(tag).test(HTML));
12620 let match;
12621 const previousIndex = lastIndex;
12622
12623 if (match = (0,external_wp_shortcode_namespaceObject.next)(transformTag, HTML, lastIndex)) {
12624 lastIndex = match.index + match.content.length;
12625 const beforeHTML = HTML.substr(0, match.index);
12626 const afterHTML = HTML.substr(lastIndex); // If the shortcode content does not contain HTML and the shortcode is
12627 // not on a new line (or in paragraph from Markdown converter),
12628 // consider the shortcode as inline text, and thus skip conversion for
12629 // this segment.
12630
12631 if (!(0,external_lodash_namespaceObject.includes)(match.shortcode.content || '', '<') && !(/(\n|<p>)\s*$/.test(beforeHTML) && /^\s*(\n|<\/p>)/.test(afterHTML))) {
12632 return segmentHTMLToShortcodeBlock(HTML, lastIndex);
12633 } // If a transformation's `isMatch` predicate fails for the inbound
12634 // shortcode, try again by excluding the current block type.
12635 //
12636 // This is the only call to `segmentHTMLToShortcodeBlock` that should
12637 // ever carry over `excludedBlockNames`. Other calls in the module
12638 // should skip that argument as a way to reset the exclusion state, so
12639 // that one `isMatch` fail in an HTML fragment doesn't prevent any
12640 // valid matches in subsequent fragments.
12641
12642
12643 if (transformation.isMatch && !transformation.isMatch(match.shortcode.attrs)) {
12644 return segmentHTMLToShortcodeBlock(HTML, previousIndex, [...excludedBlockNames, transformation.blockName]);
12645 }
12646
12647 const attributes = (0,external_lodash_namespaceObject.mapValues)((0,external_lodash_namespaceObject.pickBy)(transformation.attributes, schema => schema.shortcode), // Passing all of `match` as second argument is intentionally broad
12648 // but shouldn't be too relied upon.
12649 //
12650 // See: https://github.com/WordPress/gutenberg/pull/3610#discussion_r152546926
12651 schema => schema.shortcode(match.shortcode.attrs, match));
12652 const transformationBlockType = { ...registration_getBlockType(transformation.blockName),
12653 attributes: transformation.attributes
12654 };
12655 let block = createBlock(transformation.blockName, getBlockAttributes(transformationBlockType, match.shortcode.content, attributes));
12656 block.originalContent = match.shortcode.content; // Applying the built-in fixes can enhance the attributes with missing content like "className".
12657
12658 block = applyBuiltInValidationFixes(block, transformationBlockType);
12659 return [...segmentHTMLToShortcodeBlock(beforeHTML), block, ...segmentHTMLToShortcodeBlock(afterHTML)];
12660 }
12661
12662 return [HTML];
12663 }
12664
12665 /* harmony default export */ var shortcode_converter = (segmentHTMLToShortcodeBlock);
12666 //# sourceMappingURL=shortcode-converter.js.map
12667 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/utils.js
12668 /**
12669 * External dependencies
12670 */
12671
12672 /**
12673 * WordPress dependencies
12674 */
12675
12676
12677 /**
12678 * Internal dependencies
12679 */
12680
12681
12682
12683 function getBlockContentSchemaFromTransforms(transforms, context) {
12684 const phrasingContentSchema = (0,external_wp_dom_namespaceObject.getPhrasingContentSchema)(context);
12685 const schemaArgs = {
12686 phrasingContentSchema,
12687 isPaste: context === 'paste'
12688 };
12689 const schemas = transforms.map(({
12690 isMatch,
12691 blockName,
12692 schema
12693 }) => {
12694 const hasAnchorSupport = registration_hasBlockSupport(blockName, 'anchor');
12695 schema = (0,external_lodash_namespaceObject.isFunction)(schema) ? schema(schemaArgs) : schema; // If the block does not has anchor support and the transform does not
12696 // provides an isMatch we can return the schema right away.
12697
12698 if (!hasAnchorSupport && !isMatch) {
12699 return schema;
12700 }
12701
12702 return (0,external_lodash_namespaceObject.mapValues)(schema, value => {
12703 let attributes = value.attributes || []; // If the block supports the "anchor" functionality, it needs to keep its ID attribute.
12704
12705 if (hasAnchorSupport) {
12706 attributes = [...attributes, 'id'];
12707 }
12708
12709 return { ...value,
12710 attributes,
12711 isMatch: isMatch ? isMatch : undefined
12712 };
12713 });
12714 });
12715 return (0,external_lodash_namespaceObject.mergeWith)({}, ...schemas, (objValue, srcValue, key) => {
12716 switch (key) {
12717 case 'children':
12718 {
12719 if (objValue === '*' || srcValue === '*') {
12720 return '*';
12721 }
12722
12723 return { ...objValue,
12724 ...srcValue
12725 };
12726 }
12727
12728 case 'attributes':
12729 case 'require':
12730 {
12731 return [...(objValue || []), ...(srcValue || [])];
12732 }
12733
12734 case 'isMatch':
12735 {
12736 // If one of the values being merge is undefined (matches everything),
12737 // the result of the merge will be undefined.
12738 if (!objValue || !srcValue) {
12739 return undefined;
12740 } // When merging two isMatch functions, the result is a new function
12741 // that returns if one of the source functions returns true.
12742
12743
12744 return (...args) => {
12745 return objValue(...args) || srcValue(...args);
12746 };
12747 }
12748 }
12749 });
12750 }
12751 /**
12752 * Gets the block content schema, which is extracted and merged from all
12753 * registered blocks with raw transfroms.
12754 *
12755 * @param {string} context Set to "paste" when in paste context, where the
12756 * schema is more strict.
12757 *
12758 * @return {Object} A complete block content schema.
12759 */
12760
12761 function getBlockContentSchema(context) {
12762 return getBlockContentSchemaFromTransforms(getRawTransforms(), context);
12763 }
12764 /**
12765 * Checks whether HTML can be considered plain text. That is, it does not contain
12766 * any elements that are not line breaks.
12767 *
12768 * @param {string} HTML The HTML to check.
12769 *
12770 * @return {boolean} Whether the HTML can be considered plain text.
12771 */
12772
12773 function isPlain(HTML) {
12774 return !/<(?!br[ />])/i.test(HTML);
12775 }
12776 /**
12777 * Given node filters, deeply filters and mutates a NodeList.
12778 *
12779 * @param {NodeList} nodeList The nodeList to filter.
12780 * @param {Array} filters An array of functions that can mutate with the provided node.
12781 * @param {Document} doc The document of the nodeList.
12782 * @param {Object} schema The schema to use.
12783 */
12784
12785 function deepFilterNodeList(nodeList, filters, doc, schema) {
12786 Array.from(nodeList).forEach(node => {
12787 deepFilterNodeList(node.childNodes, filters, doc, schema);
12788 filters.forEach(item => {
12789 // Make sure the node is still attached to the document.
12790 if (!doc.contains(node)) {
12791 return;
12792 }
12793
12794 item(node, doc, schema);
12795 });
12796 });
12797 }
12798 /**
12799 * Given node filters, deeply filters HTML tags.
12800 * Filters from the deepest nodes to the top.
12801 *
12802 * @param {string} HTML The HTML to filter.
12803 * @param {Array} filters An array of functions that can mutate with the provided node.
12804 * @param {Object} schema The schema to use.
12805 *
12806 * @return {string} The filtered HTML.
12807 */
12808
12809 function deepFilterHTML(HTML, filters = [], schema) {
12810 const doc = document.implementation.createHTMLDocument('');
12811 doc.body.innerHTML = HTML;
12812 deepFilterNodeList(doc.body.childNodes, filters, doc, schema);
12813 return doc.body.innerHTML;
12814 }
12815 /**
12816 * Gets a sibling within text-level context.
12817 *
12818 * @param {Element} node The subject node.
12819 * @param {string} which "next" or "previous".
12820 */
12821
12822 function getSibling(node, which) {
12823 const sibling = node[`${which}Sibling`];
12824
12825 if (sibling && (0,external_wp_dom_namespaceObject.isPhrasingContent)(sibling)) {
12826 return sibling;
12827 }
12828
12829 const {
12830 parentNode
12831 } = node;
12832
12833 if (!parentNode || !(0,external_wp_dom_namespaceObject.isPhrasingContent)(parentNode)) {
12834 return;
12835 }
12836
12837 return getSibling(parentNode, which);
12838 }
12839 //# sourceMappingURL=utils.js.map
12840 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/index.js
12841 /**
12842 * External dependencies
12843 */
12844
12845 /**
12846 * WordPress dependencies
12847 */
12848
12849
12850
12851 /**
12852 * Internal dependencies
12853 */
12854
12855
12856
12857
12858
12859
12860
12861
12862
12863
12864
12865 function deprecatedGetPhrasingContentSchema(context) {
12866 external_wp_deprecated_default()('wp.blocks.getPhrasingContentSchema', {
12867 since: '5.6',
12868 alternative: 'wp.dom.getPhrasingContentSchema'
12869 });
12870 return (0,external_wp_dom_namespaceObject.getPhrasingContentSchema)(context);
12871 }
12872 /**
12873 * Converts an HTML string to known blocks.
12874 *
12875 * @param {Object} $1
12876 * @param {string} $1.HTML The HTML to convert.
12877 *
12878 * @return {Array} A list of blocks.
12879 */
12880
12881 function rawHandler({
12882 HTML = ''
12883 }) {
12884 // If we detect block delimiters, parse entirely as blocks.
12885 if (HTML.indexOf('<!-- wp:') !== -1) {
12886 return parser_parse(HTML);
12887 } // An array of HTML strings and block objects. The blocks replace matched
12888 // shortcodes.
12889
12890
12891 const pieces = shortcode_converter(HTML);
12892 const blockContentSchema = getBlockContentSchema();
12893 return (0,external_lodash_namespaceObject.compact)((0,external_lodash_namespaceObject.flatMap)(pieces, piece => {
12894 // Already a block from shortcode.
12895 if (typeof piece !== 'string') {
12896 return piece;
12897 } // These filters are essential for some blocks to be able to transform
12898 // from raw HTML. These filters move around some content or add
12899 // additional tags, they do not remove any content.
12900
12901
12902 const filters = [// Needed to adjust invalid lists.
12903 listReducer, // Needed to create more and nextpage blocks.
12904 specialCommentConverter, // Needed to create media blocks.
12905 figureContentReducer, // Needed to create the quote block, which cannot handle text
12906 // without wrapper paragraphs.
12907 blockquoteNormaliser];
12908 piece = deepFilterHTML(piece, filters, blockContentSchema);
12909 piece = normaliseBlocks(piece);
12910 return htmlToBlocks(piece);
12911 }));
12912 }
12913 //# sourceMappingURL=index.js.map
12914 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/comment-remover.js
12915 /**
12916 * WordPress dependencies
12917 */
12918
12919 /**
12920 * Looks for comments, and removes them.
12921 *
12922 * @param {Node} node The node to be processed.
12923 * @return {void}
12924 */
12925
12926 function commentRemover(node) {
12927 if (node.nodeType === node.COMMENT_NODE) {
12928 (0,external_wp_dom_namespaceObject.remove)(node);
12929 }
12930 }
12931 //# sourceMappingURL=comment-remover.js.map
12932 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/is-inline-content.js
12933 /**
12934 * External dependencies
12935 */
12936
12937 /**
12938 * WordPress dependencies
12939 */
12940
12941
12942 /**
12943 * Checks if the given node should be considered inline content, optionally
12944 * depending on a context tag.
12945 *
12946 * @param {Node} node Node name.
12947 * @param {string} contextTag Tag name.
12948 *
12949 * @return {boolean} True if the node is inline content, false if nohe.
12950 */
12951
12952 function isInline(node, contextTag) {
12953 if ((0,external_wp_dom_namespaceObject.isTextContent)(node)) {
12954 return true;
12955 }
12956
12957 if (!contextTag) {
12958 return false;
12959 }
12960
12961 const tag = node.nodeName.toLowerCase();
12962 const inlineAllowedTagGroups = [['ul', 'li', 'ol'], ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']];
12963 return inlineAllowedTagGroups.some(tagGroup => (0,external_lodash_namespaceObject.difference)([tag, contextTag], tagGroup).length === 0);
12964 }
12965
12966 function deepCheck(nodes, contextTag) {
12967 return nodes.every(node => isInline(node, contextTag) && deepCheck(Array.from(node.children), contextTag));
12968 }
12969
12970 function isDoubleBR(node) {
12971 return node.nodeName === 'BR' && node.previousSibling && node.previousSibling.nodeName === 'BR';
12972 }
12973
12974 function isInlineContent(HTML, contextTag) {
12975 const doc = document.implementation.createHTMLDocument('');
12976 doc.body.innerHTML = HTML;
12977 const nodes = Array.from(doc.body.children);
12978 return !nodes.some(isDoubleBR) && deepCheck(nodes, contextTag);
12979 }
12980 //# sourceMappingURL=is-inline-content.js.map
12981 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/phrasing-content-reducer.js
12982 /**
12983 * External dependencies
12984 */
12985
12986 /**
12987 * WordPress dependencies
12988 */
12989
12990
12991 function phrasingContentReducer(node, doc) {
12992 // In jsdom-jscore, 'node.style' can be null.
12993 // TODO: Explore fixing this by patching jsdom-jscore.
12994 if (node.nodeName === 'SPAN' && node.style) {
12995 const {
12996 fontWeight,
12997 fontStyle,
12998 textDecorationLine,
12999 textDecoration,
13000 verticalAlign
13001 } = node.style;
13002
13003 if (fontWeight === 'bold' || fontWeight === '700') {
13004 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('strong'), node);
13005 }
13006
13007 if (fontStyle === 'italic') {
13008 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('em'), node);
13009 } // Some DOM implementations (Safari, JSDom) don't support
13010 // style.textDecorationLine, so we check style.textDecoration as a
13011 // fallback.
13012
13013
13014 if (textDecorationLine === 'line-through' || (0,external_lodash_namespaceObject.includes)(textDecoration, 'line-through')) {
13015 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('s'), node);
13016 }
13017
13018 if (verticalAlign === 'super') {
13019 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('sup'), node);
13020 } else if (verticalAlign === 'sub') {
13021 (0,external_wp_dom_namespaceObject.wrap)(doc.createElement('sub'), node);
13022 }
13023 } else if (node.nodeName === 'B') {
13024 node = (0,external_wp_dom_namespaceObject.replaceTag)(node, 'strong');
13025 } else if (node.nodeName === 'I') {
13026 node = (0,external_wp_dom_namespaceObject.replaceTag)(node, 'em');
13027 } else if (node.nodeName === 'A') {
13028 // In jsdom-jscore, 'node.target' can be null.
13029 // TODO: Explore fixing this by patching jsdom-jscore.
13030 if (node.target && node.target.toLowerCase() === '_blank') {
13031 node.rel = 'noreferrer noopener';
13032 } else {
13033 node.removeAttribute('target');
13034 node.removeAttribute('rel');
13035 } // Saves anchor elements name attribute as id
13036
13037
13038 if (node.name && !node.id) {
13039 node.id = node.name;
13040 } // Keeps id only if there is an internal link pointing to it
13041
13042
13043 if (node.id && !node.ownerDocument.querySelector(`[href="#${node.id}"]`)) {
13044 node.removeAttribute('id');
13045 }
13046 }
13047 }
13048 //# sourceMappingURL=phrasing-content-reducer.js.map
13049 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/head-remover.js
13050 function headRemover(node) {
13051 if (node.nodeName !== 'SCRIPT' && node.nodeName !== 'NOSCRIPT' && node.nodeName !== 'TEMPLATE' && node.nodeName !== 'STYLE') {
13052 return;
13053 }
13054
13055 node.parentNode.removeChild(node);
13056 }
13057 //# sourceMappingURL=head-remover.js.map
13058 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/ms-list-converter.js
13059 /**
13060 * Browser dependencies
13061 */
13062 const {
13063 parseInt: ms_list_converter_parseInt
13064 } = window;
13065
13066 function ms_list_converter_isList(node) {
13067 return node.nodeName === 'OL' || node.nodeName === 'UL';
13068 }
13069
13070 function msListConverter(node, doc) {
13071 if (node.nodeName !== 'P') {
13072 return;
13073 }
13074
13075 const style = node.getAttribute('style');
13076
13077 if (!style) {
13078 return;
13079 } // Quick check.
13080
13081
13082 if (style.indexOf('mso-list') === -1) {
13083 return;
13084 }
13085
13086 const matches = /mso-list\s*:[^;]+level([0-9]+)/i.exec(style);
13087
13088 if (!matches) {
13089 return;
13090 }
13091
13092 let level = ms_list_converter_parseInt(matches[1], 10) - 1 || 0;
13093 const prevNode = node.previousElementSibling; // Add new list if no previous.
13094
13095 if (!prevNode || !ms_list_converter_isList(prevNode)) {
13096 // See https://html.spec.whatwg.org/multipage/grouping-content.html#attr-ol-type.
13097 const type = node.textContent.trim().slice(0, 1);
13098 const isNumeric = /[1iIaA]/.test(type);
13099 const newListNode = doc.createElement(isNumeric ? 'ol' : 'ul');
13100
13101 if (isNumeric) {
13102 newListNode.setAttribute('type', type);
13103 }
13104
13105 node.parentNode.insertBefore(newListNode, node);
13106 }
13107
13108 const listNode = node.previousElementSibling;
13109 const listType = listNode.nodeName;
13110 const listItem = doc.createElement('li');
13111 let receivingNode = listNode; // Remove the first span with list info.
13112
13113 node.removeChild(node.firstElementChild); // Add content.
13114
13115 while (node.firstChild) {
13116 listItem.appendChild(node.firstChild);
13117 } // Change pointer depending on indentation level.
13118
13119
13120 while (level--) {
13121 receivingNode = receivingNode.lastElementChild || receivingNode; // If it's a list, move pointer to the last item.
13122
13123 if (ms_list_converter_isList(receivingNode)) {
13124 receivingNode = receivingNode.lastElementChild || receivingNode;
13125 }
13126 } // Make sure we append to a list.
13127
13128
13129 if (!ms_list_converter_isList(receivingNode)) {
13130 receivingNode = receivingNode.appendChild(doc.createElement(listType));
13131 } // Append the list item to the list.
13132
13133
13134 receivingNode.appendChild(listItem); // Remove the wrapper paragraph.
13135
13136 node.parentNode.removeChild(node);
13137 }
13138 //# sourceMappingURL=ms-list-converter.js.map
13139 ;// CONCATENATED MODULE: external ["wp","blob"]
13140 var external_wp_blob_namespaceObject = window["wp"]["blob"];
13141 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/image-corrector.js
13142 /**
13143 * WordPress dependencies
13144 */
13145
13146 /**
13147 * Browser dependencies
13148 */
13149
13150 const {
13151 atob,
13152 File
13153 } = window;
13154 function imageCorrector(node) {
13155 if (node.nodeName !== 'IMG') {
13156 return;
13157 }
13158
13159 if (node.src.indexOf('file:') === 0) {
13160 node.src = '';
13161 } // This piece cannot be tested outside a browser env.
13162
13163
13164 if (node.src.indexOf('data:') === 0) {
13165 const [properties, data] = node.src.split(',');
13166 const [type] = properties.slice(5).split(';');
13167
13168 if (!data || !type) {
13169 node.src = '';
13170 return;
13171 }
13172
13173 let decoded; // Can throw DOMException!
13174
13175 try {
13176 decoded = atob(data);
13177 } catch (e) {
13178 node.src = '';
13179 return;
13180 }
13181
13182 const uint8Array = new Uint8Array(decoded.length);
13183
13184 for (let i = 0; i < uint8Array.length; i++) {
13185 uint8Array[i] = decoded.charCodeAt(i);
13186 }
13187
13188 const name = type.replace('/', '.');
13189 const file = new File([uint8Array], name, {
13190 type
13191 });
13192 node.src = (0,external_wp_blob_namespaceObject.createBlobURL)(file);
13193 } // Remove trackers and hardly visible images.
13194
13195
13196 if (node.height === 1 || node.width === 1) {
13197 node.parentNode.removeChild(node);
13198 }
13199 }
13200 //# sourceMappingURL=image-corrector.js.map
13201 // EXTERNAL MODULE: ./node_modules/showdown/dist/showdown.js
13202 var showdown = __webpack_require__(3787);
13203 var showdown_default = /*#__PURE__*/__webpack_require__.n(showdown);
13204 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/markdown-converter.js
13205 /**
13206 * External dependencies
13207 */
13208 // Reuse the same showdown converter.
13209
13210 const converter = new (showdown_default()).Converter({
13211 noHeaderId: true,
13212 tables: true,
13213 literalMidWordUnderscores: true,
13214 omitExtraWLInCodeBlocks: true,
13215 simpleLineBreaks: true,
13216 strikethrough: true
13217 });
13218 /**
13219 * Corrects the Slack Markdown variant of the code block.
13220 * If uncorrected, it will be converted to inline code.
13221 *
13222 * @see https://get.slack.help/hc/en-us/articles/202288908-how-can-i-add-formatting-to-my-messages-#code-blocks
13223 *
13224 * @param {string} text The potential Markdown text to correct.
13225 *
13226 * @return {string} The corrected Markdown.
13227 */
13228
13229 function slackMarkdownVariantCorrector(text) {
13230 return text.replace(/((?:^|\n)```)([^\n`]+)(```(?:$|\n))/, (match, p1, p2, p3) => `${p1}\n${p2}\n${p3}`);
13231 }
13232 /**
13233 * Converts a piece of text into HTML based on any Markdown present.
13234 * Also decodes any encoded HTML.
13235 *
13236 * @param {string} text The plain text to convert.
13237 *
13238 * @return {string} HTML.
13239 */
13240
13241
13242 function markdownConverter(text) {
13243 return converter.makeHtml(slackMarkdownVariantCorrector(text));
13244 }
13245 //# sourceMappingURL=markdown-converter.js.map
13246 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/iframe-remover.js
13247 /**
13248 * Removes iframes.
13249 *
13250 * @param {Node} node The node to check.
13251 *
13252 * @return {void}
13253 */
13254 function iframeRemover(node) {
13255 if (node.nodeName === 'IFRAME') {
13256 const text = node.ownerDocument.createTextNode(node.src);
13257 node.parentNode.replaceChild(text, node);
13258 }
13259 }
13260 //# sourceMappingURL=iframe-remover.js.map
13261 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/google-docs-uid-remover.js
13262 /**
13263 * WordPress dependencies
13264 */
13265
13266 function googleDocsUIdRemover(node) {
13267 if (!node.id || node.id.indexOf('docs-internal-guid-') !== 0) {
13268 return;
13269 }
13270
13271 (0,external_wp_dom_namespaceObject.unwrap)(node);
13272 }
13273 //# sourceMappingURL=google-docs-uid-remover.js.map
13274 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/html-formatting-remover.js
13275 /**
13276 * Internal dependencies
13277 */
13278
13279
13280 function isFormattingSpace(character) {
13281 return character === ' ' || character === '\r' || character === '\n' || character === '\t';
13282 }
13283 /**
13284 * Removes spacing that formats HTML.
13285 *
13286 * @see https://www.w3.org/TR/css-text-3/#white-space-processing
13287 *
13288 * @param {Node} node The node to be processed.
13289 * @return {void}
13290 */
13291
13292
13293 function htmlFormattingRemover(node) {
13294 if (node.nodeType !== node.TEXT_NODE) {
13295 return;
13296 } // Ignore pre content. Note that this does not use Element#closest due to
13297 // a combination of (a) node may not be Element and (b) node.parentElement
13298 // does not have full support in all browsers (Internet Exporer).
13299 //
13300 // See: https://developer.mozilla.org/en-US/docs/Web/API/Node/parentElement#Browser_compatibility
13301
13302 /** @type {Node?} */
13303
13304
13305 let parent = node;
13306
13307 while (parent = parent.parentNode) {
13308 if (parent.nodeType === parent.ELEMENT_NODE && parent.nodeName === 'PRE') {
13309 return;
13310 }
13311 } // First, replace any sequence of HTML formatting space with a single space.
13312
13313
13314 let newData = node.data.replace(/[ \r\n\t]+/g, ' '); // Remove the leading space if the text element is at the start of a block,
13315 // is preceded by a line break element, or has a space in the previous
13316 // node.
13317
13318 if (newData[0] === ' ') {
13319 const previousSibling = getSibling(node, 'previous');
13320
13321 if (!previousSibling || previousSibling.nodeName === 'BR' || previousSibling.textContent.slice(-1) === ' ') {
13322 newData = newData.slice(1);
13323 }
13324 } // Remove the trailing space if the text element is at the end of a block,
13325 // is succeded by a line break element, or has a space in the next text
13326 // node.
13327
13328
13329 if (newData[newData.length - 1] === ' ') {
13330 const nextSibling = getSibling(node, 'next');
13331
13332 if (!nextSibling || nextSibling.nodeName === 'BR' || nextSibling.nodeType === nextSibling.TEXT_NODE && isFormattingSpace(nextSibling.textContent[0])) {
13333 newData = newData.slice(0, -1);
13334 }
13335 } // If there's no data left, remove the node, so `previousSibling` stays
13336 // accurate. Otherwise, update the node data.
13337
13338
13339 if (!newData) {
13340 node.parentNode.removeChild(node);
13341 } else {
13342 node.data = newData;
13343 }
13344 }
13345 //# sourceMappingURL=html-formatting-remover.js.map
13346 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/br-remover.js
13347 /**
13348 * Internal dependencies
13349 */
13350
13351 /**
13352 * Removes trailing br elements from text-level content.
13353 *
13354 * @param {Element} node Node to check.
13355 */
13356
13357 function brRemover(node) {
13358 if (node.nodeName !== 'BR') {
13359 return;
13360 }
13361
13362 if (getSibling(node, 'next')) {
13363 return;
13364 }
13365
13366 node.parentNode.removeChild(node);
13367 }
13368 //# sourceMappingURL=br-remover.js.map
13369 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/empty-paragraph-remover.js
13370 /**
13371 * Removes empty paragraph elements.
13372 *
13373 * @param {Element} node Node to check.
13374 */
13375 function emptyParagraphRemover(node) {
13376 if (node.nodeName !== 'P') {
13377 return;
13378 }
13379
13380 if (node.hasChildNodes()) {
13381 return;
13382 }
13383
13384 node.parentNode.removeChild(node);
13385 }
13386 //# sourceMappingURL=empty-paragraph-remover.js.map
13387 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/raw-handling/paste-handler.js
13388 /**
13389 * External dependencies
13390 */
13391
13392 /**
13393 * WordPress dependencies
13394 */
13395
13396
13397 /**
13398 * Internal dependencies
13399 */
13400
13401
13402
13403
13404
13405
13406
13407
13408
13409
13410
13411
13412
13413
13414
13415
13416
13417
13418
13419
13420
13421
13422
13423
13424 /**
13425 * Browser dependencies
13426 */
13427
13428 const {
13429 console: paste_handler_console
13430 } = window;
13431 /**
13432 * Filters HTML to only contain phrasing content.
13433 *
13434 * @param {string} HTML The HTML to filter.
13435 * @param {boolean} preserveWhiteSpace Whether or not to preserve consequent white space.
13436 *
13437 * @return {string} HTML only containing phrasing content.
13438 */
13439
13440 function filterInlineHTML(HTML, preserveWhiteSpace) {
13441 HTML = deepFilterHTML(HTML, [googleDocsUIdRemover, phrasingContentReducer, commentRemover]);
13442 HTML = (0,external_wp_dom_namespaceObject.removeInvalidHTML)(HTML, (0,external_wp_dom_namespaceObject.getPhrasingContentSchema)('paste'), {
13443 inline: true
13444 });
13445
13446 if (!preserveWhiteSpace) {
13447 HTML = deepFilterHTML(HTML, [htmlFormattingRemover, brRemover]);
13448 } // Allows us to ask for this information when we get a report.
13449
13450
13451 paste_handler_console.log('Processed inline HTML:\n\n', HTML);
13452 return HTML;
13453 }
13454 /**
13455 * Converts an HTML string to known blocks. Strips everything else.
13456 *
13457 * @param {Object} options
13458 * @param {string} [options.HTML] The HTML to convert.
13459 * @param {string} [options.plainText] Plain text version.
13460 * @param {string} [options.mode] Handle content as blocks or inline content.
13461 * * 'AUTO': Decide based on the content passed.
13462 * * 'INLINE': Always handle as inline content, and return string.
13463 * * 'BLOCKS': Always handle as blocks, and return array of blocks.
13464 * @param {Array} [options.tagName] The tag into which content will be inserted.
13465 * @param {boolean} [options.preserveWhiteSpace] Whether or not to preserve consequent white space.
13466 *
13467 * @return {Array|string} A list of blocks or a string, depending on `handlerMode`.
13468 */
13469
13470
13471 function pasteHandler({
13472 HTML = '',
13473 plainText = '',
13474 mode = 'AUTO',
13475 tagName,
13476 preserveWhiteSpace
13477 }) {
13478 // First of all, strip any meta tags.
13479 HTML = HTML.replace(/<meta[^>]+>/g, ''); // Strip Windows markers.
13480
13481 HTML = HTML.replace(/^\s*<html[^>]*>\s*<body[^>]*>(?:\s*<!--\s*StartFragment\s*-->)?/i, '');
13482 HTML = HTML.replace(/(?:<!--\s*EndFragment\s*-->\s*)?<\/body>\s*<\/html>\s*$/i, ''); // If we detect block delimiters in HTML, parse entirely as blocks.
13483
13484 if (mode !== 'INLINE') {
13485 // Check plain text if there is no HTML.
13486 const content = HTML ? HTML : plainText;
13487
13488 if (content.indexOf('<!-- wp:') !== -1) {
13489 return parser_parse(content);
13490 }
13491 } // Normalize unicode to use composed characters.
13492 // This is unsupported in IE 11 but it's a nice-to-have feature, not mandatory.
13493 // Not normalizing the content will only affect older browsers and won't
13494 // entirely break the app.
13495 // See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize
13496 // See: https://core.trac.wordpress.org/ticket/30130
13497 // See: https://github.com/WordPress/gutenberg/pull/6983#pullrequestreview-125151075
13498
13499
13500 if (String.prototype.normalize) {
13501 HTML = HTML.normalize();
13502 } // Parse Markdown (and encoded HTML) if:
13503 // * There is a plain text version.
13504 // * There is no HTML version, or it has no formatting.
13505
13506
13507 if (plainText && (!HTML || isPlain(HTML))) {
13508 HTML = plainText; // The markdown converter (Showdown) trims whitespace.
13509
13510 if (!/^\s+$/.test(plainText)) {
13511 HTML = markdownConverter(HTML);
13512 } // Switch to inline mode if:
13513 // * The current mode is AUTO.
13514 // * The original plain text had no line breaks.
13515 // * The original plain text was not an HTML paragraph.
13516 // * The converted text is just a paragraph.
13517
13518
13519 if (mode === 'AUTO' && plainText.indexOf('\n') === -1 && plainText.indexOf('<p>') !== 0 && HTML.indexOf('<p>') === 0) {
13520 mode = 'INLINE';
13521 }
13522 }
13523
13524 if (mode === 'INLINE') {
13525 return filterInlineHTML(HTML, preserveWhiteSpace);
13526 } // An array of HTML strings and block objects. The blocks replace matched
13527 // shortcodes.
13528
13529
13530 const pieces = shortcode_converter(HTML); // The call to shortcodeConverter will always return more than one element
13531 // if shortcodes are matched. The reason is when shortcodes are matched
13532 // empty HTML strings are included.
13533
13534 const hasShortcodes = pieces.length > 1;
13535
13536 if (mode === 'AUTO' && !hasShortcodes && isInlineContent(HTML, tagName)) {
13537 return filterInlineHTML(HTML, preserveWhiteSpace);
13538 }
13539
13540 const phrasingContentSchema = (0,external_wp_dom_namespaceObject.getPhrasingContentSchema)('paste');
13541 const blockContentSchema = getBlockContentSchema('paste');
13542 const blocks = (0,external_lodash_namespaceObject.compact)((0,external_lodash_namespaceObject.flatMap)(pieces, piece => {
13543 // Already a block from shortcode.
13544 if (typeof piece !== 'string') {
13545 return piece;
13546 }
13547
13548 const filters = [googleDocsUIdRemover, msListConverter, headRemover, listReducer, imageCorrector, phrasingContentReducer, specialCommentConverter, commentRemover, iframeRemover, figureContentReducer, blockquoteNormaliser];
13549 const schema = { ...blockContentSchema,
13550 // Keep top-level phrasing content, normalised by `normaliseBlocks`.
13551 ...phrasingContentSchema
13552 };
13553 piece = deepFilterHTML(piece, filters, blockContentSchema);
13554 piece = (0,external_wp_dom_namespaceObject.removeInvalidHTML)(piece, schema);
13555 piece = normaliseBlocks(piece);
13556 piece = deepFilterHTML(piece, [htmlFormattingRemover, brRemover, emptyParagraphRemover], blockContentSchema); // Allows us to ask for this information when we get a report.
13557
13558 paste_handler_console.log('Processed HTML piece:\n\n', piece);
13559 return htmlToBlocks(piece);
13560 })); // If we're allowed to return inline content, and there is only one
13561 // inlineable block, and the original plain text content does not have any
13562 // line breaks, then treat it as inline paste.
13563
13564 if (mode === 'AUTO' && blocks.length === 1 && registration_hasBlockSupport(blocks[0].name, '__unstablePasteTextInline', false)) {
13565 // Don't catch line breaks at the start or end.
13566 const trimmedPlainText = plainText.replace(/^[\n]+|[\n]+$/g, '');
13567
13568 if (trimmedPlainText !== '' && trimmedPlainText.indexOf('\n') === -1) {
13569 return (0,external_wp_dom_namespaceObject.removeInvalidHTML)(getBlockInnerHTML(blocks[0]), phrasingContentSchema);
13570 }
13571 }
13572
13573 return blocks;
13574 }
13575 //# sourceMappingURL=paste-handler.js.map
13576 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/categories.js
13577 /**
13578 * WordPress dependencies
13579 */
13580
13581 /**
13582 * Internal dependencies
13583 */
13584
13585
13586 /** @typedef {import('../store/reducer').WPBlockCategory} WPBlockCategory */
13587
13588 /**
13589 * Returns all the block categories.
13590 *
13591 * @return {WPBlockCategory[]} Block categories.
13592 */
13593
13594 function categories_getCategories() {
13595 return (0,external_wp_data_namespaceObject.select)(store).getCategories();
13596 }
13597 /**
13598 * Sets the block categories.
13599 *
13600 * @param {WPBlockCategory[]} categories Block categories.
13601 */
13602
13603 function categories_setCategories(categories) {
13604 (0,external_wp_data_namespaceObject.dispatch)(store).setCategories(categories);
13605 }
13606 /**
13607 * Updates a category.
13608 *
13609 * @param {string} slug Block category slug.
13610 * @param {WPBlockCategory} category Object containing the category properties
13611 * that should be updated.
13612 */
13613
13614 function categories_updateCategory(slug, category) {
13615 (0,external_wp_data_namespaceObject.dispatch)(store).updateCategory(slug, category);
13616 }
13617 //# sourceMappingURL=categories.js.map
13618 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/templates.js
13619 /**
13620 * External dependencies
13621 */
13622
13623 /**
13624 * WordPress dependencies
13625 */
13626
13627
13628 /**
13629 * Internal dependencies
13630 */
13631
13632
13633
13634
13635 /**
13636 * Checks whether a list of blocks matches a template by comparing the block names.
13637 *
13638 * @param {Array} blocks Block list.
13639 * @param {Array} template Block template.
13640 *
13641 * @return {boolean} Whether the list of blocks matches a templates.
13642 */
13643
13644 function doBlocksMatchTemplate(blocks = [], template = []) {
13645 return blocks.length === template.length && (0,external_lodash_namespaceObject.every)(template, ([name,, innerBlocksTemplate], index) => {
13646 const block = blocks[index];
13647 return name === block.name && doBlocksMatchTemplate(block.innerBlocks, innerBlocksTemplate);
13648 });
13649 }
13650 /**
13651 * Synchronize a block list with a block template.
13652 *
13653 * Synchronizing a block list with a block template means that we loop over the blocks
13654 * keep the block as is if it matches the block at the same position in the template
13655 * (If it has the same name) and if doesn't match, we create a new block based on the template.
13656 * Extra blocks not present in the template are removed.
13657 *
13658 * @param {Array} blocks Block list.
13659 * @param {Array} template Block template.
13660 *
13661 * @return {Array} Updated Block list.
13662 */
13663
13664 function synchronizeBlocksWithTemplate(blocks = [], template) {
13665 // If no template is provided, return blocks unmodified.
13666 if (!template) {
13667 return blocks;
13668 }
13669
13670 return (0,external_lodash_namespaceObject.map)(template, ([name, attributes, innerBlocksTemplate], index) => {
13671 const block = blocks[index];
13672
13673 if (block && block.name === name) {
13674 const innerBlocks = synchronizeBlocksWithTemplate(block.innerBlocks, innerBlocksTemplate);
13675 return { ...block,
13676 innerBlocks
13677 };
13678 } // To support old templates that were using the "children" format
13679 // for the attributes using "html" strings now, we normalize the template attributes
13680 // before creating the blocks.
13681
13682
13683 const blockType = registration_getBlockType(name);
13684
13685 const isHTMLAttribute = attributeDefinition => (0,external_lodash_namespaceObject.get)(attributeDefinition, ['source']) === 'html';
13686
13687 const isQueryAttribute = attributeDefinition => (0,external_lodash_namespaceObject.get)(attributeDefinition, ['source']) === 'query';
13688
13689 const normalizeAttributes = (schema, values) => {
13690 return (0,external_lodash_namespaceObject.mapValues)(values, (value, key) => {
13691 return normalizeAttribute(schema[key], value);
13692 });
13693 };
13694
13695 const normalizeAttribute = (definition, value) => {
13696 if (isHTMLAttribute(definition) && (0,external_lodash_namespaceObject.isArray)(value)) {
13697 // Introduce a deprecated call at this point
13698 // When we're confident that "children" format should be removed from the templates.
13699 return (0,external_wp_element_namespaceObject.renderToString)(value);
13700 }
13701
13702 if (isQueryAttribute(definition) && value) {
13703 return value.map(subValues => {
13704 return normalizeAttributes(definition.query, subValues);
13705 });
13706 }
13707
13708 return value;
13709 };
13710
13711 const normalizedAttributes = normalizeAttributes((0,external_lodash_namespaceObject.get)(blockType, ['attributes'], {}), attributes);
13712 const [blockName, blockAttributes] = convertLegacyBlockNameAndAttributes(name, normalizedAttributes);
13713 return createBlock(blockName, blockAttributes, synchronizeBlocksWithTemplate([], innerBlocksTemplate));
13714 });
13715 }
13716 //# sourceMappingURL=templates.js.map
13717 ;// CONCATENATED MODULE: ./packages/blocks/build-module/api/index.js
13718 // The blocktype is the most important concept within the block API. It defines
13719 // all aspects of the block configuration and its interfaces, including `edit`
13720 // and `save`. The transforms specification allows converting one blocktype to
13721 // another through formulas defined by either the source or the destination.
13722 // Switching a blocktype is to be considered a one-way operation implying a
13723 // transformation in the opposite way has to be handled explicitly.
13724 // The block tree is composed of a collection of block nodes. Blocks contained
13725 // within other blocks are called inner blocks. An important design
13726 // consideration is that inner blocks are -- conceptually -- not part of the
13727 // territory established by the parent block that contains them.
13728 //
13729 // This has multiple practical implications: when parsing, we can safely dispose
13730 // of any block boundary found within a block from the innerHTML property when
13731 // transfering to state. Not doing so would have a compounding effect on memory
13732 // and uncertainty over the source of truth. This can be illustrated in how,
13733 // given a tree of `n` nested blocks, the entry node would have to contain the
13734 // actual content of each block while each subsequent block node in the state
13735 // tree would replicate the entire chain `n-1`, meaning the extreme end node
13736 // would have been replicated `n` times as the tree is traversed and would
13737 // generate uncertainty as to which one is to hold the current value of the
13738 // block. For composition, it also means inner blocks can effectively be child
13739 // components whose mechanisms can be shielded from the `edit` implementation
13740 // and just passed along.
13741
13742
13743 // While block transformations account for a specific surface of the API, there
13744 // are also raw transformations which handle arbitrary sources not made out of
13745 // blocks but producing block basaed on various heursitics. This includes
13746 // pasting rich text or HTML data.
13747
13748 // The process of serialization aims to deflate the internal memory of the block
13749 // editor and its state representation back into an HTML valid string. This
13750 // process restores the document integrity and inserts invisible delimiters
13751 // around each block with HTML comment boundaries which can contain any extra
13752 // attributes needed to operate with the block later on.
13753
13754 // Validation is the process of comparing a block source with its output before
13755 // there is any user input or interaction with a block. When this operation
13756 // fails -- for whatever reason -- the block is to be considered invalid. As
13757 // part of validating a block the system will attempt to run the source against
13758 // any provided deprecation definitions.
13759 //
13760 // Worth emphasizing that validation is not a case of whether the markup is
13761 // merely HTML spec-compliant but about how the editor knows to create such
13762 // markup and that its inability to create an identical result can be a strong
13763 // indicator of potential data loss (the invalidation is then a protective
13764 // measure).
13765 //
13766 // The invalidation process can also be deconstructed in phases: 1) validate the
13767 // block exists; 2) validate the source matches the output; 3) validate the
13768 // source matches deprecated outputs; 4) work through the significance of
13769 // differences. These are stacked in a way that favors performance and optimizes
13770 // for the majority of cases. That is to say, the evaluation logic can become
13771 // more sophisticated the further down it goes in the process as the cost is
13772 // accounted for. The first logic checks have to be extremely efficient since
13773 // they will be run for all valid and invalid blocks alike. However, once a
13774 // block is detected as invalid -- failing the three first steps -- it is
13775 // adequate to spend more time determining validity before throwing a conflict.
13776
13777
13778 // Blocks are inherently indifferent about where the data they operate with ends
13779 // up being saved. For example, all blocks can have a static and dynamic aspect
13780 // to them depending on the needs. The static nature of a block is the `save()`
13781 // definition that is meant to be serialized into HTML and which can be left
13782 // void. Any block can also register a `render_callback` on the server, which
13783 // makes its output dynamic either in part or in its totality.
13784 //
13785 // Child blocks are defined as a relationship that builds on top of the inner
13786 // blocks mechanism. A child block is a block node of a particular type that can
13787 // only exist within the inner block boundaries of a specific parent type. This
13788 // allows block authors to compose specific blocks that are not meant to be used
13789 // outside of a specified parent block context. Thus, child blocks extend the
13790 // concept of inner blocks to support a more direct relationship between sets of
13791 // blocks. The addition of parent–child would be a subset of the inner block
13792 // functionality under the premise that certain blocks only make sense as
13793 // children of another block.
13794
13795
13796 // Templates are, in a general sense, a basic collection of block nodes with any
13797 // given set of predefined attributes that are supplied as the initial state of
13798 // an inner blocks group. These nodes can, in turn, contain any number of nested
13799 // blocks within their definition. Templates allow both to specify a default
13800 // state for an editor session or a default set of blocks for any inner block
13801 // implementation within a specific block.
13802
13803
13804
13805
13806
13807 //# sourceMappingURL=index.js.map
13808 ;// CONCATENATED MODULE: ./packages/blocks/build-module/index.js
13809 // A "block" is the abstract term used to describe units of markup that,
13810 // when composed together, form the content or layout of a page.
13811 // The API for blocks is exposed via `wp.blocks`.
13812 //
13813 // Supported blocks are registered by calling `registerBlockType`. Once registered,
13814 // the block is made available as an option to the editor interface.
13815 //
13816 // Blocks are inferred from the HTML source of a post through a parsing mechanism
13817 // and then stored as objects in state, from which it is then rendered for editing.
13818
13819
13820
13821 //# sourceMappingURL=index.js.map
13822 }();
13823 (window.wp = window.wp || {}).blocks = __webpack_exports__;
13824 /******/ })()
13825 ;