PageSourceSearch

https://avi.nyc/assets/lexxy-a1b1695e.js

js avi.nyc collected 2026-09-25 21:20:20 UTC 1,017,634 bytes, 19,972 lines download raw bytes

vendor: 5,745 bytes, lines 1-185
1var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
2
3function getDefaultExportFromCjs (x) {
4	return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
5}
6
7var prism = {exports: {}};
8
9var hasRequiredPrism;
10
11function requirePrism () {
12	if (hasRequiredPrism) return prism.exports;
13	hasRequiredPrism = 1;
14	(function (module) {
15		/* **********************************************
16		     Begin prism-core.js
17		********************************************** */
18
19		/// <reference lib="WebWorker"/>
20
21		var _self = (typeof window !== 'undefined')
22			? window   // if in browser
23			: (
24				(typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope)
25					? self // if in worker
26					: {}   // if in node js
27			);
28
29		/**
30		 * Prism: Lightweight, robust, elegant syntax highlighting
31		 *
32		 * @license MIT <https://opensource.org/licenses/MIT>
33		 * @author Lea Verou <https://lea.verou.me>
34		 * @namespace
35		 * @public
36		 */
37		var Prism = (function (_self) {
38
39			// Private helper vars
40			var lang = /(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i;
41			var uniqueId = 0;
42
43			// The grammar object for plaintext
44			var plainTextGrammar = {};
45
46
47			var _ = {
48				/**
49				 * By default, Prism will attempt to highlight all code elements (by calling {@link Prism.highlightAll}) on the
50				 * current page after the page finished loading. This might be a problem if e.g. you wanted to asynchronously load
51				 * additional languages or plugins yourself.
52				 *
53				 * By setting this value to `true`, Prism will not automatically highlight all code elements on the page.
54				 *
55				 * You obviously have to change this value before the automatic highlighting started. To do this, you can add an
56				 * empty Prism object into the global scope before loading the Prism script like this:
57				 *
58				 * ```js
59				 * window.Prism = window.Prism || {};
60				 * Prism.manual = true;
61				 * // add a new <script> to load Prism's script
62				 * ```
63				 *
64				 * @default false
65				 * @type {boolean}
66				 * @memberof Prism
67				 * @public
68				 */
69				manual: _self.Prism && _self.Prism.manual,
70				/**
71				 * By default, if Prism is in a web worker, it assumes that it is in a worker it created itself, so it uses
72				 * `addEventListener` to communicate with its parent instance. However, if you're using Prism manually in your
73				 * own worker, you don't want it to do this.
74				 *
75				 * By setting this value to `true`, Prism will not add its own listeners to the worker.
76				 *
77				 * You obviously have to change this value before Prism executes. To do this, you can add an
78				 * empty Prism object into the global scope before loading the Prism script like this:
79				 *
80				 * ```js
81				 * window.Prism = window.Prism || {};
82				 * Prism.disableWorkerMessageHandler = true;
83				 * // Load Prism's script
84				 * ```
85				 *
86				 * @default false
87				 * @type {boolean}
88				 * @memberof Prism
89				 * @public
90				 */
91				disableWorkerMessageHandler: _self.Prism && _self.Prism.disableWorkerMessageHandler,
92
93				/**
94				 * A namespace for utility methods.
95				 *
96				 * All function in this namespace that are not explicitly marked as _public_ are for __internal use only__ and may
97				 * change or disappear at any time.
98				 *
99				 * @namespace
100				 * @memberof Prism
101				 */
102				util: {
103					encode: function encode(tokens) {
104						if (tokens instanceof Token) {
105							return new Token(tokens.type, encode(tokens.content), tokens.alias);
106						} else if (Array.isArray(tokens)) {
107							return tokens.map(encode);
108						} else {
109							return tokens.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/\u00a0/g, ' ');
110						}
111					},
112
113					/**
114					 * Returns the name of the type of the given value.
115					 *
116					 * @param {any} o
117					 * @returns {string}
118					 * @example
119					 * type(null)      === 'Null'
120					 * type(undefined) === 'Undefined'
121					 * type(123)       === 'Number'
122					 * type('foo')     === 'String'
123					 * type(true)      === 'Boolean'
124					 * type([1, 2])    === 'Array'
125					 * type({})        === 'Object'
126					 * type(String)    === 'Function'
127					 * type(/abc+/)    === 'RegExp'
128					 */
129					type: function (o) {
130						return Object.prototype.toString.call(o).slice(8, -1);
131					},
132
133					/**
134					 * Returns a unique number for the given object. Later calls will still return the same number.
135					 *
136					 * @param {Object} obj
137					 * @returns {number}
138					 */
139					objId: function (obj) {
140						if (!obj['__id']) {
141							Object.defineProperty(obj, '__id', { value: ++uniqueId });
142						}
143						return obj['__id'];
144					},
145
146					/**
147					 * Creates a deep clone of the given object.
148					 *
149					 * The main intended use of this function is to clone language definitions.
150					 *
151					 * @param {T} o
152					 * @param {Record<number, any>} [visited]
153					 * @returns {T}
154					 * @template T
155					 */
156					clone: function deepClone(o, visited) {
157						visited = visited || {};
158
159						var clone; var id;
160						switch (_.util.type(o)) {
161							case 'Object':
162								id = _.util.objId(o);
163								if (visited[id]) {
164									return visited[id];
165								}
166								clone = /** @type {Record<string, any>} */ ({});
167								visited[id] = clone;
168
169								for (var key in o) {
170									if (o.hasOwnProperty(key)) {
171										clone[key] = deepClone(o[key], visited);
172									}
173								}
174
175								return /** @type {any} */ (clone);
176
177							case 'Array':
178								id = _.util.objId(o);
179								if (visited[id]) {
180									return visited[id];
181								}
182								clone = [];
183								visited[id] = clone;
184
185								(/** @type {Array} */(/** @type {any}
vendor: 4,983 bytes, lines 185-334
185 */(o))).forEach(function (v, i) {
186									clone[i] = deepClone(v, visited);
187								});
188
189								return /** @type {any} */ (clone);
190
191							default:
192								return o;
193						}
194					},
195
196					/**
197					 * Returns the Prism language of the given element set by a `language-xxxx` or `lang-xxxx` class.
198					 *
199					 * If no language is set for the element or the element is `null` or `undefined`, `none` will be returned.
200					 *
201					 * @param {Element} element
202					 * @returns {string}
203					 */
204					getLanguage: function (element) {
205						while (element) {
206							var m = lang.exec(element.className);
207							if (m) {
208								return m[1].toLowerCase();
209							}
210							element = element.parentElement;
211						}
212						return 'none';
213					},
214
215					/**
216					 * Sets the Prism `language-xxxx` class of the given element.
217					 *
218					 * @param {Element} element
219					 * @param {string} language
220					 * @returns {void}
221					 */
222					setLanguage: function (element, language) {
223						// remove all `language-xxxx` classes
224						// (this might leave behind a leading space)
225						element.className = element.className.replace(RegExp(lang, 'gi'), '');
226
227						// add the new `language-xxxx` class
228						// (using `classList` will automatically clean up spaces for us)
229						element.classList.add('language-' + language);
230					},
231
232					/**
233					 * Returns the script element that is currently executing.
234					 *
235					 * This does __not__ work for line script element.
236					 *
237					 * @returns {HTMLScriptElement | null}
238					 */
239					currentScript: function () {
240						if (typeof document === 'undefined') {
241							return null;
242						}
243						if (document.currentScript && document.currentScript.tagName === 'SCRIPT' && 1 < 2 /* hack to trip TS' flow analysis */) {
244							return /** @type {any} */ (document.currentScript);
245						}
246
247						// IE11 workaround
248						// we'll get the src of the current script by parsing IE11's error stack trace
249						// this will not work for inline scripts
250
251						try {
252							throw new Error();
253						} catch (err) {
254							// Get file src url from stack. Specifically works with the format of stack traces in IE.
255							// A stack will look like this:
256							//
257							// Error
258							//    at _.util.currentScript (http://localhost/components/prism-core.js:119:5)
259							//    at Global code (http://localhost/components/prism-core.js:606:1)
260
261							var src = (/at [^(\r\n]*\((.*):[^:]+:[^:]+\)$/i.exec(err.stack) || [])[1];
262							if (src) {
263								var scripts = document.getElementsByTagName('script');
264								for (var i in scripts) {
265									if (scripts[i].src == src) {
266										return scripts[i];
267									}
268								}
269							}
270							return null;
271						}
272					},
273
274					/**
275					 * Returns whether a given class is active for `element`.
276					 *
277					 * The class can be activated if `element` or one of its ancestors has the given class and it can be deactivated
278					 * if `element` or one of its ancestors has the negated version of the given class. The _negated version_ of the
279					 * given class is just the given class with a `no-` prefix.
280					 *
281					 * Whether the class is active is determined by the closest ancestor of `element` (where `element` itself is
282					 * closest ancestor) that has the given class or the negated version of it. If neither `element` nor any of its
283					 * ancestors have the given class or the negated version of it, then the default activation will be returned.
284					 *
285					 * In the paradoxical situation where the closest ancestor contains __both__ the given class and the negated
286					 * version of it, the class is considered active.
287					 *
288					 * @param {Element} element
289					 * @param {string} className
290					 * @param {boolean} [defaultActivation=false]
291					 * @returns {boolean}
292					 */
293					isActive: function (element, className, defaultActivation) {
294						var no = 'no-' + className;
295
296						while (element) {
297							var classList = element.classList;
298							if (classList.contains(className)) {
299								return true;
300							}
301							if (classList.contains(no)) {
302								return false;
303							}
304							element = element.parentElement;
305						}
306						return !!defaultActivation;
307					}
308				},
309
310				/**
311				 * This namespace contains all currently loaded languages and the some helper functions to create and modify languages.
312				 *
313				 * @namespace
314				 * @memberof Prism
315				 * @public
316				 */
317				languages: {
318					/**
319					 * The grammar for plain, unformatted text.
320					 */
321					plain: plainTextGrammar,
322					plaintext: plainTextGrammar,
323					text: plainTextGrammar,
324					txt: plainTextGrammar,
325
326					/**
327					 * Creates a deep copy of the language with the given id and appends the given tokens.
328					 *
329					 * If a token in `redef` also appears in the copied language, then the existing token in the copied language
330					 * will be overwritten at its original position.
331					 *
332					 * ## Best practices
333					 *
334					 * Since the position of overwriting tokens (token in `redef` that over
334write tokens in the copied language)
335					 * doesn't matter, they can technically be in any order. However, this can be confusing to others that trying to
336					 * understand the language definition because, normally, the order of tokens matters in Prism grammars.
337					 *
338					 * Therefore, it is encouraged to order overwriting tokens according to the positions of the overwritten tokens.
339					 * Furthermore, all non-overwriting tokens should be placed after the overwriting ones.
340					 *
341					 * @param {string} id The id of the language to extend. This has to be a key in `Prism.languages`.
342					 * @param {Grammar} redef The new tokens to append.
343					 * @returns {Grammar} The new language created.
344					 * @public
345					 * @example
346					 * Prism.languages['css-with-colors'] = Prism.languages.extend('css', {
347					 *     // Prism.languages.css already has a 'comment' token, so this token will overwrite CSS' 'comment' token
348					 *     // at its original position
349					 *     'comment': { ... },
350					 *     // CSS doesn't have a 'color' token, so this token will be appended
351					 *     'color': /\b(?:red|green|blue)\b/
352					 * });
353					 */
354					extend: function (id, redef) {
355						var lang = _.util.clone(_.languages[id]);
356
357						for (var key in redef) {
358							lang[key] = redef[key];
359						}
360
361						return lang;
362					},
363
364					/**
365					 * Inserts tokens _before_ another token in a language definition or any other grammar.
366					 *
367					 * ## Usage
368					 *
369					 * This helper method makes it easy to modify existing languages. For example, the CSS language definition
370					 * not only defines CSS highlighting for CSS documents, but also needs to define highlighting for CSS embedded
371					 * in HTML through `<style>` elements. To do this, it needs to modify `Prism.languages.markup` and add the
372					 * appropriate tokens. However, `Prism.languages.markup` is a regular JavaScript object literal, so if you do
373					 * this:
374					 *
375					 * ```js
376					 * Prism.languages.markup.style = {
377					 *     // token
378					 * };
379					 * ```
380					 *
381					 * then the `style` token will be added (and processed) at the end. `insertBefore` allows you to insert tokens
382					 * before existing tokens. For the CSS example above, you would use it like this:
383					 *
384					 * ```js
385					 * Prism.languages.insertBefore('markup', 'cdata', {
386					 *     'style': {
387					 *         // token
388					 *     }
389					 * });
390					 * ```
391					 *
392					 * ## Special cases
393					 *
394					 * If the grammars of `inside` and `insert` have tokens with the same name, the tokens in `inside`'s grammar
395					 * will be ignored.
396					 *
397					 * This behavior can be used to insert tokens after `before`:
398					 *
399					 * ```js
400					 * Prism.languages.insertBefore('markup', 'comment', {
401					 *     'comment': Prism.languages.markup.comment,
402					 *     // tokens after 'comment'
403					 * });
404					 * ```
405					 *
406					 * ## Limitations
407					 *
408					 * The main problem `insertBefore` has to solve is iteration order. Since ES2015, the iteration order for object
409					 * properties is guaranteed to be the insertion order (except for integer keys) but some browsers behave
410					 * differently when keys are deleted and re-inserted. So `insertBefore` can't be implemented by temporarily
411					 * deleting properties which is necessary to insert at arbitrary positions.
412					 *
413					 * To solve this problem, `insertBefore` doesn't actually insert the given tokens into the target object.
414					 * Instead, it will create a new object and replace all references to the target object with the new one. This
415					 * can be done without temporarily deleting properties, so the iteration order is well-defined.
416					 *
417					 * However, only references that can be reached from `Prism.languages` or `insert` will be replaced. I.e. if
418					 * you hold the target object in a variable, then the value of the variable will not change.
419					 *
420					 * ```js
421					 * var oldMarkup = Prism.languages.markup;
422					 * var newMarkup = Prism.languages.insertBefore('markup', 'comment', { ... });
423					 *
424					 * assert(oldMarkup !== Prism.languages.markup);
425					 * assert(newMarkup === Prism.languages.markup);
426					 * ```
427					 *
428					 * @param {string} inside The property of `root` (e.g. a language id in `Prism.languages`) that contains the
429					 * object to be modified.
430					 * @param {string} before The key to insert before.
431					 * @param {Grammar}
vendor: 7,557 bytes, lines 431-653
431 insert An object containing the key-value pairs to be inserted.
432					 * @param {Object<string, any>} [root] The object containing `inside`, i.e. the object that contains the
433					 * object to be modified.
434					 *
435					 * Defaults to `Prism.languages`.
436					 * @returns {Grammar} The new grammar object.
437					 * @public
438					 */
439					insertBefore: function (inside, before, insert, root) {
440						root = root || /** @type {any} */ (_.languages);
441						var grammar = root[inside];
442						/** @type {Grammar} */
443						var ret = {};
444
445						for (var token in grammar) {
446							if (grammar.hasOwnProperty(token)) {
447
448								if (token == before) {
449									for (var newToken in insert) {
450										if (insert.hasOwnProperty(newToken)) {
451											ret[newToken] = insert[newToken];
452										}
453									}
454								}
455
456								// Do not insert token which also occur in insert. See #1525
457								if (!insert.hasOwnProperty(token)) {
458									ret[token] = grammar[token];
459								}
460							}
461						}
462
463						var old = root[inside];
464						root[inside] = ret;
465
466						// Update references in other language definitions
467						_.languages.DFS(_.languages, function (key, value) {
468							if (value === old && key != inside) {
469								this[key] = ret;
470							}
471						});
472
473						return ret;
474					},
475
476					// Traverse a language definition with Depth First Search
477					DFS: function DFS(o, callback, type, visited) {
478						visited = visited || {};
479
480						var objId = _.util.objId;
481
482						for (var i in o) {
483							if (o.hasOwnProperty(i)) {
484								callback.call(o, i, o[i], type || i);
485
486								var property = o[i];
487								var propertyType = _.util.type(property);
488
489								if (propertyType === 'Object' && !visited[objId(property)]) {
490									visited[objId(property)] = true;
491									DFS(property, callback, null, visited);
492								} else if (propertyType === 'Array' && !visited[objId(property)]) {
493									visited[objId(property)] = true;
494									DFS(property, callback, i, visited);
495								}
496							}
497						}
498					}
499				},
500
501				plugins: {},
502
503				/**
504				 * This is the most high-level function in Prism’s API.
505				 * It fetches all the elements that have a `.language-xxxx` class and then calls {@link Prism.highlightElement} on
506				 * each one of them.
507				 *
508				 * This is equivalent to `Prism.highlightAllUnder(document, async, callback)`.
509				 *
510				 * @param {boolean} [async=false] Same as in {@link Prism.highlightAllUnder}.
511				 * @param {HighlightCallback} [callback] Same as in {@link Prism.highlightAllUnder}.
512				 * @memberof Prism
513				 * @public
514				 */
515				highlightAll: function (async, callback) {
516					_.highlightAllUnder(document, async, callback);
517				},
518
519				/**
520				 * Fetches all the descendants of `container` that have a `.language-xxxx` class and then calls
521				 * {@link Prism.highlightElement} on each one of them.
522				 *
523				 * The following hooks will be run:
524				 * 1. `before-highlightall`
525				 * 2. `before-all-elements-highlight`
526				 * 3. All hooks of {@link Prism.highlightElement} for each element.
527				 *
528				 * @param {ParentNode} container The root element, whose descendants that have a `.language-xxxx` class will be highlighted.
529				 * @param {boolean} [async=false] Whether each element is to be highlighted asynchronously using Web Workers.
530				 * @param {HighlightCallback} [callback] An optional callback to be invoked on each element after its highlighting is done.
531				 * @memberof Prism
532				 * @public
533				 */
534				highlightAllUnder: function (container, async, callback) {
535					var env = {
536						callback: callback,
537						container: container,
538						selector: 'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'
539					};
540
541					_.hooks.run('before-highlightall', env);
542
543					env.elements = Array.prototype.slice.apply(env.container.querySelectorAll(env.selector));
544
545					_.hooks.run('before-all-elements-highlight', env);
546
547					for (var i = 0, element; (element = env.elements[i++]);) {
548						_.highlightElement(element, async === true, env.callback);
549					}
550				},
551
552				/**
553				 * Highlights the code inside a single element.
554				 *
555				 * The following hooks will be run:
556				 * 1. `before-sanity-check`
557				 * 2. `before-highlight`
558				 * 3. All hooks of {@link Prism.highlight}. These hooks will be run by an asynchronous worker if `async` is `true`.
559				 * 4. `before-insert`
560				 * 5. `after-highlight`
561				 * 6. `complete`
562				 *
563				 * Some the above hooks will be skipped if the element doesn't contain any text or there is no grammar loaded for
564				 * the element's language.
565				 *
566				 * @param {Element} element The element containing the code.
567				 * It must have a class of `language-xxxx` to be processed, where `xxxx` is a valid language identifier.
568				 * @param {boolean} [async=false] Whether the element is to be highlighted asynchronously using Web Workers
569				 * to improve performance and avoid blocking the UI when highlighting very large chunks of code. This option is
570				 * [disabled by default](https://prismjs.com/faq.html#why-is-asynchronous-highlighting-disabled-by-default).
571				 *
572				 * Note: All language definitions required to highlight the code must be included in the main `prism.js` file for
573				 * asynchronous highlighting to work. You can build your own bundle on the
574				 * [Download page](https://prismjs.com/download.html).
575				 * @param {HighlightCallback} [callback] An optional callback to be invoked after the highlighting is done.
576				 * Mostly useful when `async` is `true`, since in that case, the highlighting is done asynchronously.
577				 * @memberof Prism
578				 * @public
579				 */
580				highlightElement: function (element, async, callback) {
581					// Find language
582					var language = _.util.getLanguage(element);
583					var grammar = _.languages[language];
584
585					// Set language on the element, if not present
586					_.util.setLanguage(element, language);
587
588					// Set language on the parent, for styling
589					var parent = element.parentElement;
590					if (parent && parent.nodeName.toLowerCase() === 'pre') {
591						_.util.setLanguage(parent, language);
592					}
593
594					var code = element.textContent;
595
596					var env = {
597						element: element,
598						language: language,
599						grammar: grammar,
600						code: code
601					};
602
603					function insertHighlightedCode(highlightedCode) {
604						env.highlightedCode = highlightedCode;
605
606						_.hooks.run('before-insert', env);
607
608						env.element.innerHTML = env.highlightedCode;
609
610						_.hooks.run('after-highlight', env);
611						_.hooks.run('complete', env);
612						callback && callback.call(env.element);
613					}
614
615					_.hooks.run('before-sanity-check', env);
616
617					// plugins may change/add the parent/element
618					parent = env.element.parentElement;
619					if (parent && parent.nodeName.toLowerCase() === 'pre' && !parent.hasAttribute('tabindex')) {
620						parent.setAttribute('tabindex', '0');
621					}
622
623					if (!env.code) {
624						_.hooks.run('complete', env);
625						callback && callback.call(env.element);
626						return;
627					}
628
629					_.hooks.run('before-highlight', env);
630
631					if (!env.grammar) {
632						insertHighlightedCode(_.util.encode(env.code));
633						return;
634					}
635
636					if (async && _self.Worker) {
637						var worker = new Worker(_.filename);
638
639						worker.onmessage = function (evt) {
640							insertHighlightedCode(evt.data);
641						};
642
643						worker.postMessage(JSON.stringify({
644							language: env.language,
645							code: env.code,
646							immediateClose: true
647						}));
648					} else {
649						insertHighlightedCode(_.highlight(env.code, env.grammar, env.language));
650					}
651				},
652
653				/**
654				 * Low-level function, only use if you know what you’re doing. It accepts a string of text as input
655				 * and the language definitions to use, and returns a string with the HTML produced.
656				 *
657				 * The following hooks will be run:
658				 * 1. `before-tokenize`
659				 * 2. `after-tokenize`
660				 * 3. `wrap`: On each {@link Token}.
661				 *
662				 * @param {string} text A string with the code to be highlighted.
663				 * @param {Grammar} grammar An object containing the tokens to use.
664				 *
665				 * Usually a language definition like `Prism.languages.markup`.
666				 * @param {string} language The name of the language definition passed to `grammar`.
667				 * @returns {string} The highlighted HTML.
668				 * @memberof Prism
669				 * @public
670				 * @example
671				 * Prism.highlight('var foo = true;', Prism.languages.javascript, 'javascript');
672				 */
673				highlight: function (text, grammar, language) {
674					var env = {
675						code: text,
676						grammar: grammar,
677						language: language
678					};
679					_.hooks.run('before-tokenize', env);
680					if (!env.grammar) {
681						throw new Error('The language "' + env.language + '" has no grammar.');
682					}
683					env.tokens = _.tokenize(env.code, env.grammar);
684					_.hooks.run('after-tokenize', env);
685					return Token.stringify(_.util.encode(env.tokens), env.language);
686				},
687
688				/**
689				 * This is the heart of Prism, and the most low-level function you can use. It accepts a string of text as input
690				 * and the language definitions to use, and returns an array with the tokenized code.
691				 *
692				 * When the language definition includes nested tokens, the function is called recursively on each of these tokens.
693				 *
694				 * This method could be useful in other contexts as well, as a very crude parser.
695				 *
696				 * @param {string} text A string with the code to be highlighted.
697				 * @param {Grammar} grammar An object containing the tokens to use.
698				 *
699				 * Usually a language definition like `Prism.languages.markup`.
700				 * @returns {TokenStream} An array of strings and tokens, a token stream.
701				 * @memberof Prism
702				 * @public
703				 * @example
704				 * let code = `var foo = 0;`;
705				 * let tokens = Prism.tokenize(code, Prism.languages.javascript);
706				 * tokens.forEach(token => {
707				 *     if (token instanceof Prism.Token && token.type === 'number') {
708				 *         console.log(`Found numeric literal: ${token.content}`);
709				 *     }
710				 * });
711				 */
712				tokenize: function (text, grammar) {
713					var rest = grammar.rest;
714					if (rest) {
715						for (var token in rest) {
716							grammar[token] = rest[token];
717						}
718
719						delete grammar.rest;
720					}
721
722					var tokenList = new LinkedList();
723					addAfter(tokenList, tokenList.head, text);
724
725					matchGrammar(text, tokenList, grammar, tokenList.head, 0);
726
727					return toArray(tokenList);
728				},
729
730				/**
731				 * @namespace
732				 * @memberof Prism
733				 * @public
734				 */
735				hooks: {
736					all: {},
737
738					/**
739					 * Adds the given callback to the list of callbacks for the given hook.
740					 *
741					 * The callback will be invoked when the hook it is registered for is run.
742					 * Hooks are usually directly run by a highlight function but you can also run hooks yourself.
743					 *
744					 * One callback function can be registered to multiple hooks and the same hook multiple times.
745					 *
746					 * @param {string} name The name of the hook.
747					 * @param {HookCallback} callback The callback function which is given environment variables.
748					 * @public
749					 */
750					add: function (name, callback) {
751						var hooks = _.hooks.all;
752
753						hooks[name] = hooks[name] || [];
754
755						hooks[name].push(callback);
756					},
757
758					/**
759					 * Runs a hook invoking all registered callbacks with the given environment variables.
760					 *
761					 * Callbacks will be invoked synchronously and in the order in which they were registered.
762					 *
763					 * @param {string} name The name of the hook.
764					 * @param {Object<string, any>} env The environment variables of the hook passed to all callbacks registered.
765					 * @public
766					 */
767					run: function (name, env) {
768						var callbacks = _.hooks.all[name];
769
770						if (!callbacks || !callbacks.length) {
771							return;
772						}
773
774						for (var i = 0, callback; (callback = callbacks[i++]);) {
775							callback(env);
776						}
777					}
778				},
779
780				Token: Token
781			};
782			_self.Prism = _;
783
784
785			// Typescript note:
786			// The following can be used to import the Token type in JSDoc:
787			//
788			//   @typedef {InstanceType<import("./prism-core")["Token"]>} Token
789
790			/**
791			 * Creates a new token.
792			 *
793			 * @param {string} type See {@link Token#type type}
794			 * @param {string | TokenStream} content See {@link Token#content content}
795			 * @param {string|string[]} [alias] The alias(es) of the token.
796			 * @param {string} [matchedStr=""] A copy of the full string this token was created from.
797			 * @class
798			 * @global
799			 * @public
800			 */
801			function Token(type, content, alias, matchedStr) {
802				/**
803				 * The type of the token.
804				 *
805				 * This is usually the key of a pattern in a {@link Grammar}.
806				 *
807				 * @type {string}
808				 * @see GrammarToken
809				 * @public
810				 */
811				this.type = type;
812				/**
813				 * The strings or tokens contained by this token.
814				 *
815				 * This will be a token stream if the pattern matched also defined an `inside` grammar.
816				 *
817				 * @type {string | TokenStream}
818				 * @public
819				 */
820				this.content = content;
821				/**
822				 * The alias(es) of the token.
823				 *
824				 * @type {string|string[]}
825				 * @see GrammarToken
826				 * @public
827				 */
828				this.alias = alias;
829				// Copy of the full string this token was created from
830				this.length = (matchedStr || '').length | 0;
831			}
832
833			/**
vendor: 4,762 bytes, lines 834-996
834			 * A token stream is an array of strings and {@link Token Token} objects.
835			 *
836			 * Token streams have to fulfill a few properties that are assumed by most functions (mostly internal ones) that process
837			 * them.
838			 *
839			 * 1. No adjacent strings.
840			 * 2. No empty strings.
841			 *
842			 *    The only exception here is the token stream that only contains the empty string and nothing else.
843			 *
844			 * @typedef {Array<string | Token>} TokenStream
845			 * @global
846			 * @public
847			 */
848
849			/**
850			 * Converts the given token or token stream to an HTML representation.
851			 *
852			 * The following hooks will be run:
853			 * 1. `wrap`: On each {@link Token}.
854			 *
855			 * @param {string | Token | TokenStream} o The token or token stream to be converted.
856			 * @param {string} language The name of current language.
857			 * @returns {string} The HTML representation of the token or token stream.
858			 * @memberof Token
859			 * @static
860			 */
861			Token.stringify = function stringify(o, language) {
862				if (typeof o == 'string') {
863					return o;
864				}
865				if (Array.isArray(o)) {
866					var s = '';
867					o.forEach(function (e) {
868						s += stringify(e, language);
869					});
870					return s;
871				}
872
873				var env = {
874					type: o.type,
875					content: stringify(o.content, language),
876					tag: 'span',
877					classes: ['token', o.type],
878					attributes: {},
879					language: language
880				};
881
882				var aliases = o.alias;
883				if (aliases) {
884					if (Array.isArray(aliases)) {
885						Array.prototype.push.apply(env.classes, aliases);
886					} else {
887						env.classes.push(aliases);
888					}
889				}
890
891				_.hooks.run('wrap', env);
892
893				var attributes = '';
894				for (var name in env.attributes) {
895					attributes += ' ' + name + '="' + (env.attributes[name] || '').replace(/"/g, '&quot;') + '"';
896				}
897
898				return '<' + env.tag + ' class="' + env.classes.join(' ') + '"' + attributes + '>' + env.content + '</' + env.tag + '>';
899			};
900
901			/**
902			 * @param {RegExp} pattern
903			 * @param {number} pos
904			 * @param {string} text
905			 * @param {boolean} lookbehind
906			 * @returns {RegExpExecArray | null}
907			 */
908			function matchPattern(pattern, pos, text, lookbehind) {
909				pattern.lastIndex = pos;
910				var match = pattern.exec(text);
911				if (match && lookbehind && match[1]) {
912					// change the match to remove the text matched by the Prism lookbehind group
913					var lookbehindLength = match[1].length;
914					match.index += lookbehindLength;
915					match[0] = match[0].slice(lookbehindLength);
916				}
917				return match;
918			}
919
920			/**
921			 * @param {string} text
922			 * @param {LinkedList<string | Token>} tokenList
923			 * @param {any} grammar
924			 * @param {LinkedListNode<string | Token>} startNode
925			 * @param {number} startPos
926			 * @param {RematchOptions} [rematch]
927			 * @returns {void}
928			 * @private
929			 *
930			 * @typedef RematchOptions
931			 * @property {string} cause
932			 * @property {number} reach
933			 */
934			function matchGrammar(text, tokenList, grammar, startNode, startPos, rematch) {
935				for (var token in grammar) {
936					if (!grammar.hasOwnProperty(token) || !grammar[token]) {
937						continue;
938					}
939
940					var patterns = grammar[token];
941					patterns = Array.isArray(patterns) ? patterns : [patterns];
942
943					for (var j = 0; j < patterns.length; ++j) {
944						if (rematch && rematch.cause == token + ',' + j) {
945							return;
946						}
947
948						var patternObj = patterns[j];
949						var inside = patternObj.inside;
950						var lookbehind = !!patternObj.lookbehind;
951						var greedy = !!patternObj.greedy;
952						var alias = patternObj.alias;
953
954						if (greedy && !patternObj.pattern.global) {
955							// Without the global flag, lastIndex won't work
956							var flags = patternObj.pattern.toString().match(/[imsuy]*$/)[0];
957							patternObj.pattern = RegExp(patternObj.pattern.source, flags + 'g');
958						}
959
960						/** @type {RegExp} */
961						var pattern = patternObj.pattern || patternObj;
962
963						for ( // iterate the token list and keep track of the current token/string position
964							var currentNode = startNode.next, pos = startPos;
965							currentNode !== tokenList.tail;
966							pos += currentNode.value.length, currentNode = currentNode.next
967						) {
968
969							if (rematch && pos >= rematch.reach) {
970								break;
971							}
972
973							var str = currentNode.value;
974
975							if (tokenList.length > text.length) {
976								// Something went terribly wrong, ABORT, ABORT!
977								return;
978							}
979
980							if (str instanceof Token) {
981								continue;
982							}
983
984							var removeCount = 1; // this is the to parameter of removeBetween
985							var match;
986
987							if (greedy) {
988								match = matchPattern(pattern, pos, text, lookbehind);
989								if (!match || match.index >= text.length) {
990									break;
991								}
992
993								var from = match.index;
994								var to = match.index + match[0].length;
995								var p = pos;
996
vendor: 6,526 bytes, lines 997-1236
997								// find the node that contains the match
998								p += currentNode.value.length;
999								while (from >= p) {
1000									currentNode = currentNode.next;
1001									p += currentNode.value.length;
1002								}
1003								// adjust pos (and p)
1004								p -= currentNode.value.length;
1005								pos = p;
1006
1007								// the current node is a Token, then the match starts inside another Token, which is invalid
1008								if (currentNode.value instanceof Token) {
1009									continue;
1010								}
1011
1012								// find the last node which is affected by this match
1013								for (
1014									var k = currentNode;
1015									k !== tokenList.tail && (p < to || typeof k.value === 'string');
1016									k = k.next
1017								) {
1018									removeCount++;
1019									p += k.value.length;
1020								}
1021								removeCount--;
1022
1023								// replace with the new match
1024								str = text.slice(pos, p);
1025								match.index -= pos;
1026							} else {
1027								match = matchPattern(pattern, 0, str, lookbehind);
1028								if (!match) {
1029									continue;
1030								}
1031							}
1032
1033							// eslint-disable-next-line no-redeclare
1034							var from = match.index;
1035							var matchStr = match[0];
1036							var before = str.slice(0, from);
1037							var after = str.slice(from + matchStr.length);
1038
1039							var reach = pos + str.length;
1040							if (rematch && reach > rematch.reach) {
1041								rematch.reach = reach;
1042							}
1043
1044							var removeFrom = currentNode.prev;
1045
1046							if (before) {
1047								removeFrom = addAfter(tokenList, removeFrom, before);
1048								pos += before.length;
1049							}
1050
1051							removeRange(tokenList, removeFrom, removeCount);
1052
1053							var wrapped = new Token(token, inside ? _.tokenize(matchStr, inside) : matchStr, alias, matchStr);
1054							currentNode = addAfter(tokenList, removeFrom, wrapped);
1055
1056							if (after) {
1057								addAfter(tokenList, currentNode, after);
1058							}
1059
1060							if (removeCount > 1) {
1061								// at least one Token object was removed, so we have to do some rematching
1062								// this can only happen if the current pattern is greedy
1063
1064								/** @type {RematchOptions} */
1065								var nestedRematch = {
1066									cause: token + ',' + j,
1067									reach: reach
1068								};
1069								matchGrammar(text, tokenList, grammar, currentNode.prev, pos, nestedRematch);
1070
1071								// the reach might have been extended because of the rematching
1072								if (rematch && nestedRematch.reach > rematch.reach) {
1073									rematch.reach = nestedRematch.reach;
1074								}
1075							}
1076						}
1077					}
1078				}
1079			}
1080
1081			/**
1082			 * @typedef LinkedListNode
1083			 * @property {T} value
1084			 * @property {LinkedListNode<T> | null} prev The previous node.
1085			 * @property {LinkedListNode<T> | null} next The next node.
1086			 * @template T
1087			 * @private
1088			 */
1089
1090			/**
1091			 * @template T
1092			 * @private
1093			 */
1094			function LinkedList() {
1095				/** @type {LinkedListNode<T>} */
1096				var head = { value: null, prev: null, next: null };
1097				/** @type {LinkedListNode<T>} */
1098				var tail = { value: null, prev: head, next: null };
1099				head.next = tail;
1100
1101				/** @type {LinkedListNode<T>} */
1102				this.head = head;
1103				/** @type {LinkedListNode<T>} */
1104				this.tail = tail;
1105				this.length = 0;
1106			}
1107
1108			/**
1109			 * Adds a new node with the given value to the list.
1110			 *
1111			 * @param {LinkedList<T>} list
1112			 * @param {LinkedListNode<T>} node
1113			 * @param {T} value
1114			 * @returns {LinkedListNode<T>} The added node.
1115			 * @template T
1116			 */
1117			function addAfter(list, node, value) {
1118				// assumes that node != list.tail && values.length >= 0
1119				var next = node.next;
1120
1121				var newNode = { value: value, prev: node, next: next };
1122				node.next = newNode;
1123				next.prev = newNode;
1124				list.length++;
1125
1126				return newNode;
1127			}
1128			/**
1129			 * Removes `count` nodes after the given node. The given node will not be removed.
1130			 *
1131			 * @param {LinkedList<T>} list
1132			 * @param {LinkedListNode<T>} node
1133			 * @param {number} count
1134			 * @template T
1135			 */
1136			function removeRange(list, node, count) {
1137				var next = node.next;
1138				for (var i = 0; i < count && next !== list.tail; i++) {
1139					next = next.next;
1140				}
1141				node.next = next;
1142				next.prev = node;
1143				list.length -= i;
1144			}
1145			/**
1146			 * @param {LinkedList<T>} list
1147			 * @returns {T[]}
1148			 * @template T
1149			 */
1150			function toArray(list) {
1151				var array = [];
1152				var node = list.head.next;
1153				while (node !== list.tail) {
1154					array.push(node.value);
1155					node = node.next;
1156				}
1157				return array;
1158			}
1159
1160
1161			if (!_self.document) {
1162				if (!_self.addEventListener) {
1163					// in Node.js
1164					return _;
1165				}
1166
1167				if (!_.disableWorkerMessageHandler) {
1168					// In worker
1169					_self.addEventListener('message', function (evt) {
1170						var message = JSON.parse(evt.data);
1171						var lang = message.language;
1172						var code = message.code;
1173						var immediateClose = message.immediateClose;
1174
1175						_self.postMessage(_.highlight(code, _.languages[lang], lang));
1176						if (immediateClose) {
1177							_self.close();
1178						}
1179					}, false);
1180				}
1181
1182				return _;
1183			}
1184
1185			// Get current script and highlight
1186			var script = _.util.currentScript();
1187
1188			if (script) {
1189				_.filename = script.src;
1190
1191				if (script.hasAttribute('data-manual')) {
1192					_.manual = true;
1193				}
1194			}
1195
1196			function highlightAutomaticallyCallback() {
1197				if (!_.manual) {
1198					_.highlightAll();
1199				}
1200			}
1201
1202			if (!_.manual) {
1203				// If the document state is "loading", then we'll use DOMContentLoaded.
1204				// If the document state is "interactive" and the prism.js script is deferred, then we'll also use the
1205				// DOMContentLoaded event because there might be some plugins or languages which have also been deferred and they
1206				// might take longer one animation frame to execute which can create a race condition where only some plugins have
1207				// been loaded when Prism.highlightAll() is executed, depending on how fast resources are loaded.
1208				// See https://github.com/PrismJS/prism/issues/2102
1209				var readyState = document.readyState;
1210				if (readyState === 'loading' || readyState === 'interactive' && script && script.defer) {
1211					document.addEventListener('DOMContentLoaded', highlightAutomaticallyCallback);
1212				} else {
1213					if (window.requestAnimationFrame) {
1214						window.requestAnimationFrame(highlightAutomaticallyCallback);
1215					} else {
1216						window.setTimeout(highlightAutomaticallyCallback, 16);
1217					}
1218				}
1219			}
1220
1221			return _;
1222
1223		}(_self));
1224
1225		if (module.exports) {
1226			module.exports = Prism;
1227		}
1228
1229		// hack for components to work correctly in node.js
1230		if (typeof commonjsGlobal !== 'undefined') {
1231			commonjsGlobal.Prism = Prism;
1232		}
1233
1234		// some additional documentation/types
1235
1236		/**
1237		 * The expansion of a simple `RegExp` literal to support additional properties.
1238		 *
1239		 * @typedef GrammarToken
1240		 * @property {RegExp} pattern The regular expression of the token.
1241		 * @property {boolean} [lookbehind=false] If `true`, then the first capturing group of `pattern` will (effectively)
1242		 * behave as a lookbehind group meaning that the captured text will not be part of the matched text of the new token.
1243		 * @property {boolean} [greedy=false] Whether the token is greedy.
1244		 * @property {string|string[]} [alias] An optional alias or list of aliases.
1245		 * @property {Grammar} [inside] The nested grammar of this token.
1246		 *
1247		 * The `inside` grammar will be used to tokenize the text value of each token of this kind.
1248		 *
1249		 * This can be used to make nested and even recursive language definitions.
1250		 *
1251		 * Note: This can cause infinite recursion. Be careful when you embed different languages or even the same language into
1252		 * each another.
1253		 * @global
1254		 * @public
1255		 */
1256
1257		/**
1258		 * @typedef Grammar
1259		 * @type {Object<string, RegExp | GrammarToken | Array<RegExp | GrammarToken>>}
1260		 * @property {Grammar} [rest] An optional grammar object that will be appended to this grammar.
1261		 * @global
1262		 * @public
1263		 */
1264
1265		/**
1266		 * A function which will invoked after an element was successfully highlighted.
1267		 *
1268		 * @callback HighlightCallback
1269		 * @param {Element} element The element successfully highlighted.
1270		 * @returns {void}
1271		 * @global
1272		 * @public
1273		 */
1274
1275		/**
1276		 * @callback HookCallback
1277		 * @param {Object<string, any>} env The environment variables of the hook.
1278		 * @returns {void}
1279		 * @global
1280		 * @public
1281		 */
1282
1283
1284		/* **********************************************
1285		     Begin prism-markup.js
1286		********************************************** */
1287
1288		Prism.languages.markup = {
1289			'comment': {
1290				pattern: /<!--(?:(?!<!--)[\s\S])*?-->/,
1291				greedy: true
1292			},
1293			'prolog': {
1294				pattern: /<\?[\s\S]+?\?>/,
1295				greedy: true
1296			},
1297			'doctype': {
1298				// https://www.w3.org/TR/xml/#NT-doctypedecl
1299				pattern: /<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,
1300				greedy: true,
1301				inside: {
1302					'internal-subset': {
1303						pattern: /(^[^\[]*\[)[\s\S]+(?=\]>$)/,
1304						lookbehind: true,
1305						greedy: true,
1306						inside: null // see below
1307					},
1308					'string': {
1309						pattern: /"[^"]*"|'[^']*'/,
1310						greedy: true
1311					},
1312					'punctuation': /^<!|>$|[[\]]/,
1313					'doctype-tag': /^DOCTYPE/i,
1314					'name': /[^\s<>'"]+/
1315				}
1316			},
1317			'cdata': {
1318				pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i,
1319				greedy: true
1320			},
1321			'tag': {
1322				pattern: /<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,
1323				greedy: true,
1324				inside: {
1325					'tag': {
1326						pattern: /^<\/?[^\s>\/]+/,
1327						inside: {
1328							'punctuation': /^<\/?/,
1329							'namespace': /^[^\s>\/:]+:/
1330						}
1331					},
1332					'special-attr': [],
1333					'attr-value': {
1334						pattern: /=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,
1335						inside: {
1336							'punctuation': [
1337								{
1338									pattern: /^=/,
1339									alias: 'attr-equals'
1340								},
1341								{
1342									pattern: /^(\s*)["']|["']$/,
1343									lookbehind: true
1344								}
1345							]
1346						}
1347					},
1348					'punctuation': /\/?>/,
1349					'attr-name': {
1350						pattern: /[^\s>\/]+/,
1351						inside: {
1352							'namespace': /^[^\s>\/:]+:/
1353						}
1354					}
1355
1356				}
1357			},
1358			'entity': [
1359				{
1360					pattern: /&[\da-z]{1,8};/i,
1361					alias: 'named-entity'
1362				},
1363				/&#x?[\da-f]{1,8};/i
1364			]
1365		};
1366
1367		Prism.languages.markup['tag'].inside['attr-value'].inside['entity'] =
1368			Prism.languages.markup['entity'];
1369		Prism.languages.markup['doctype'].inside['internal-subset'].inside = Prism.languages.markup;
1370
1371		// Plugin to make entity title show the real entity, idea by Roman Komarov
1372		Prism.hooks.add('wrap', function (env) {
1373
1374			if (env.type === 'entity') {
1375				env.attributes['title'] = env.content.replace(/&amp;/, '&');
1376			}
1377		});
1378
1379		Object.defineProperty(Prism.languages.markup.tag, 'addInlined', {
1380			/**
1381			 * Adds an inlined language to markup.
1382			 *
1383			 * An example of an inlined language is CSS with `<style>` tags.
1384			 *
1385			 * @param {string} tagName The name of the tag that contains the inlined language. This name will be treated as
1386			 * case insensitive.
1387			 * @param {string} lang The language key.
1388			 * @example
1389			 * addInlined('style', 'css');
1390			 */
1391			value: function addInlined(tagName, lang) {
1392				var includedCdataInside = {};
vendor: 17,693 bytes, lines 1393-1949
1393				includedCdataInside['language-' + lang] = {
1394					pattern: /(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,
1395					lookbehind: true,
1396					inside: Prism.languages[lang]
1397				};
1398				includedCdataInside['cdata'] = /^<!\[CDATA\[|\]\]>$/i;
1399
1400				var inside = {
1401					'included-cdata': {
1402						pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i,
1403						inside: includedCdataInside
1404					}
1405				};
1406				inside['language-' + lang] = {
1407					pattern: /[\s\S]+/,
1408					inside: Prism.languages[lang]
1409				};
1410
1411				var def = {};
1412				def[tagName] = {
1413					pattern: RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g, function () { return tagName; }), 'i'),
1414					lookbehind: true,
1415					greedy: true,
1416					inside: inside
1417				};
1418
1419				Prism.languages.insertBefore('markup', 'cdata', def);
1420			}
1421		});
1422		Object.defineProperty(Prism.languages.markup.tag, 'addAttribute', {
1423			/**
1424			 * Adds an pattern to highlight languages embedded in HTML attributes.
1425			 *
1426			 * An example of an inlined language is CSS with `style` attributes.
1427			 *
1428			 * @param {string} attrName The name of the tag that contains the inlined language. This name will be treated as
1429			 * case insensitive.
1430			 * @param {string} lang The language key.
1431			 * @example
1432			 * addAttribute('style', 'css');
1433			 */
1434			value: function (attrName, lang) {
1435				Prism.languages.markup.tag.inside['special-attr'].push({
1436					pattern: RegExp(
1437						/(^|["'\s])/.source + '(?:' + attrName + ')' + /\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,
1438						'i'
1439					),
1440					lookbehind: true,
1441					inside: {
1442						'attr-name': /^[^\s=]+/,
1443						'attr-value': {
1444							pattern: /=[\s\S]+/,
1445							inside: {
1446								'value': {
1447									pattern: /(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,
1448									lookbehind: true,
1449									alias: [lang, 'language-' + lang],
1450									inside: Prism.languages[lang]
1451								},
1452								'punctuation': [
1453									{
1454										pattern: /^=/,
1455										alias: 'attr-equals'
1456									},
1457									/"|'/
1458								]
1459							}
1460						}
1461					}
1462				});
1463			}
1464		});
1465
1466		Prism.languages.html = Prism.languages.markup;
1467		Prism.languages.mathml = Prism.languages.markup;
1468		Prism.languages.svg = Prism.languages.markup;
1469
1470		Prism.languages.xml = Prism.languages.extend('markup', {});
1471		Prism.languages.ssml = Prism.languages.xml;
1472		Prism.languages.atom = Prism.languages.xml;
1473		Prism.languages.rss = Prism.languages.xml;
1474
1475
1476		/* **********************************************
1477		     Begin prism-css.js
1478		********************************************** */
1479
1480		(function (Prism) {
1481
1482			var string = /(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;
1483
1484			Prism.languages.css = {
1485				'comment': /\/\*[\s\S]*?\*\//,
1486				'atrule': {
1487					pattern: RegExp('@[\\w-](?:' + /[^;{\s"']|\s+(?!\s)/.source + '|' + string.source + ')*?' + /(?:;|(?=\s*\{))/.source),
1488					inside: {
1489						'rule': /^@[\w-]+/,
1490						'selector-function-argument': {
1491							pattern: /(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,
1492							lookbehind: true,
1493							alias: 'selector'
1494						},
1495						'keyword': {
1496							pattern: /(^|[^\w-])(?:and|not|only|or)(?![\w-])/,
1497							lookbehind: true
1498						}
1499						// See rest below
1500					}
1501				},
1502				'url': {
1503					// https://drafts.csswg.org/css-values-3/#urls
1504					pattern: RegExp('\\burl\\((?:' + string.source + '|' + /(?:[^\\\r\n()"']|\\[\s\S])*/.source + ')\\)', 'i'),
1505					greedy: true,
1506					inside: {
1507						'function': /^url/i,
1508						'punctuation': /^\(|\)$/,
1509						'string': {
1510							pattern: RegExp('^' + string.source + '$'),
1511							alias: 'url'
1512						}
1513					}
1514				},
1515				'selector': {
1516					pattern: RegExp('(^|[{}\\s])[^{}\\s](?:[^{};"\'\\s]|\\s+(?![\\s{])|' + string.source + ')*(?=\\s*\\{)'),
1517					lookbehind: true
1518				},
1519				'string': {
1520					pattern: string,
1521					greedy: true
1522				},
1523				'property': {
1524					pattern: /(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,
1525					lookbehind: true
1526				},
1527				'important': /!important\b/i,
1528				'function': {
1529					pattern: /(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,
1530					lookbehind: true
1531				},
1532				'punctuation': /[(){};:,]/
1533			};
1534
1535			Prism.languages.css['atrule'].inside.rest = Prism.languages.css;
1536
1537			var markup = Prism.languages.markup;
1538			if (markup) {
1539				markup.tag.addInlined('style', 'css');
1540				markup.tag.addAttribute('style', 'css');
1541			}
1542
1543		}(Prism));
1544
1545
1546		/* **********************************************
1547		     Begin prism-clike.js
1548		********************************************** */
1549
1550		Prism.languages.clike = {
1551			'comment': [
1552				{
1553					pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,
1554					lookbehind: true,
1555					greedy: true
1556				},
1557				{
1558					pattern: /(^|[^\\:])\/\/.*/,
1559					lookbehind: true,
1560					greedy: true
1561				}
1562			],
1563			'string': {
1564				pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
1565				greedy: true
1566			},
1567			'class-name': {
1568				pattern: /(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,
1569				lookbehind: true,
1570				inside: {
1571					'punctuation': /[.\\]/
1572				}
1573			},
1574			'keyword': /\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,
1575			'boolean': /\b(?:false|true)\b/,
1576			'function': /\b\w+(?=\()/,
1577			'number': /\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,
1578			'operator': /[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,
1579			'punctuation': /[{}[\];(),.:]/
1580		};
1581
1582
1583		/* **********************************************
1584		     Begin prism-javascript.js
1585		********************************************** */
1586
1587		Prism.languages.javascript = Prism.languages.extend('clike', {
1588			'class-name': [
1589				Prism.languages.clike['class-name'],
1590				{
1591					pattern: /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,
1592					lookbehind: true
1593				}
1594			],
1595			'keyword': [
1596				{
1597					pattern: /((?:^|\})\s*)catch\b/,
1598					lookbehind: true
1599				},
1600				{
1601					pattern: /(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,
1602					lookbehind: true
1603				},
1604			],
1605			// Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444)
1606			'function': /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,
1607			'number': {
1608				pattern: RegExp(
1609					/(^|[^\w$])/.source +
1610					'(?:' +
1611					(
1612						// constant
1613						/NaN|Infinity/.source +
1614						'|' +
1615						// binary integer
1616						/0[bB][01]+(?:_[01]+)*n?/.source +
1617						'|' +
1618						// octal integer
1619						/0[oO][0-7]+(?:_[0-7]+)*n?/.source +
1620						'|' +
1621						// hexadecimal integer
1622						/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source +
1623						'|' +
1624						// decimal bigint
1625						/\d+(?:_\d+)*n/.source +
1626						'|' +
1627						// decimal number (integer or float) but no bigint
1628						/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source
1629					) +
1630					')' +
1631					/(?![\w$])/.source
1632				),
1633				lookbehind: true
1634			},
1635			'operator': /--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/
1636		});
1637
1638		Prism.languages.javascript['class-name'][0].pattern = /(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/;
1639
1640		Prism.languages.insertBefore('javascript', 'keyword', {
1641			'regex': {
1642				pattern: RegExp(
1643					// lookbehind
1644					// eslint-disable-next-line regexp/no-dupe-characters-character-class
1645					/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source +
1646					// Regex pattern:
1647					// There are 2 regex patterns here. The RegExp set notation proposal added support for nested character
1648					// classes if the `v` flag is present. Unfortunately, nested CCs are both context-free and incompatible
1649					// with the only syntax, so we have to define 2 different regex patterns.
1650					/\//.source +
1651					'(?:' +
1652					/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/.source +
1653					'|' +
1654					// `v` flag syntax. This supports 3 levels of nested character classes.
1655					/(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/.source +
1656					')' +
1657					// lookahead
1658					/(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source
1659				),
1660				lookbehind: true,
1661				greedy: true,
1662				inside: {
1663					'regex-source': {
1664						pattern: /^(\/)[\s\S]+(?=\/[a-z]*$)/,
1665						lookbehind: true,
1666						alias: 'language-regex',
1667						inside: Prism.languages.regex
1668					},
1669					'regex-delimiter': /^\/|\/$/,
1670					'regex-flags': /^[a-z]+$/,
1671				}
1672			},
1673			// This must be declared before keyword because we use "function" inside the look-forward
1674			'function-variable': {
1675				pattern: /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,
1676				alias: 'function'
1677			},
1678			'parameter': [
1679				{
1680					pattern: /(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,
1681					lookbehind: true,
1682					inside: Prism.languages.javascript
1683				},
1684				{
1685					pattern: /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,
1686					lookbehind: true,
1687					inside: Prism.languages.javascript
1688				},
1689				{
1690					pattern: /(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,
1691					lookbehind: true,
1692					inside: Prism.languages.javascript
1693				},
1694				{
1695					pattern: /((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,
1696					lookbehind: true,
1697					inside: Prism.languages.javascript
1698				}
1699			],
1700			'constant': /\b[A-Z](?:[A-Z_]|\dx?)*\b/
1701		});
1702
1703		Prism.languages.insertBefore('javascript', 'string', {
1704			'hashbang': {
1705				pattern: /^#!.*/,
1706				greedy: true,
1707				alias: 'comment'
1708			},
1709			'template-string': {
1710				pattern: /`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,
1711				greedy: true,
1712				inside: {
1713					'template-punctuation': {
1714						pattern: /^`|`$/,
1715						alias: 'string'
1716					},
1717					'interpolation': {
1718						pattern: /((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,
1719						lookbehind: true,
1720						inside: {
1721							'interpolation-punctuation': {
1722								pattern: /^\$\{|\}$/,
1723								alias: 'punctuation'
1724							},
1725							rest: Prism.languages.javascript
1726						}
1727					},
1728					'string': /[\s\S]+/
1729				}
1730			},
1731			'string-property': {
1732				pattern: /((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,
1733				lookbehind: true,
1734				greedy: true,
1735				alias: 'property'
1736			}
1737		});
1738
1739		Prism.languages.insertBefore('javascript', 'operator', {
1740			'literal-property': {
1741				pattern: /((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,
1742				lookbehind: true,
1743				alias: 'property'
1744			},
1745		});
1746
1747		if (Prism.languages.markup) {
1748			Prism.languages.markup.tag.addInlined('script', 'javascript');
1749
1750			// add attribute support for all DOM events.
1751			// https://developer.mozilla.org/en-US/docs/Web/Events#Standard_events
1752			Prism.languages.markup.tag.addAttribute(
1753				/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,
1754				'javascript'
1755			);
1756		}
1757
1758		Prism.languages.js = Prism.languages.javascript;
1759
1760
1761		/* **********************************************
1762		     Begin prism-file-highlight.js
1763		********************************************** */
1764
1765		(function () {
1766
1767			if (typeof Prism === 'undefined' || typeof document === 'undefined') {
1768				return;
1769			}
1770
1771			// https://developer.mozilla.org/en-US/docs/Web/API/Element/matches#Polyfill
1772			if (!Element.prototype.matches) {
1773				Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
1774			}
1775
1776			var LOADING_MESSAGE = 'Loading…';
1777			var FAILURE_MESSAGE = function (status, message) {
1778				return '✖ Error ' + status + ' while fetching file: ' + message;
1779			};
1780			var FAILURE_EMPTY_MESSAGE = '✖ Error: File does not exist or is empty';
1781
1782			var EXTENSIONS = {
1783				'js': 'javascript',
1784				'py': 'python',
1785				'rb': 'ruby',
1786				'ps1': 'powershell',
1787				'psm1': 'powershell',
1788				'sh': 'bash',
1789				'bat': 'batch',
1790				'h': 'c',
1791				'tex': 'latex'
1792			};
1793
1794			var STATUS_ATTR = 'data-src-status';
1795			var STATUS_LOADING = 'loading';
1796			var STATUS_LOADED = 'loaded';
1797			var STATUS_FAILED = 'failed';
1798
1799			var SELECTOR = 'pre[data-src]:not([' + STATUS_ATTR + '="' + STATUS_LOADED + '"])'
1800				+ ':not([' + STATUS_ATTR + '="' + STATUS_LOADING + '"])';
1801
1802			/**
1803			 * Loads the given file.
1804			 *
1805			 * @param {string} src The URL or path of the source file to load.
1806			 * @param {(result: string) => void} success
1807			 * @param {(reason: string) => void} error
1808			 */
1809			function loadFile(src, success, error) {
1810				var xhr = new XMLHttpRequest();
1811				xhr.open('GET', src, true);
1812				xhr.onreadystatechange = function () {
1813					if (xhr.readyState == 4) {
1814						if (xhr.status < 400 && xhr.responseText) {
1815							success(xhr.responseText);
1816						} else {
1817							if (xhr.status >= 400) {
1818								error(FAILURE_MESSAGE(xhr.status, xhr.statusText));
1819							} else {
1820								error(FAILURE_EMPTY_MESSAGE);
1821							}
1822						}
1823					}
1824				};
1825				xhr.send(null);
1826			}
1827
1828			/**
1829			 * Parses the given range.
1830			 *
1831			 * This returns a range with inclusive ends.
1832			 *
1833			 * @param {string | null | undefined} range
1834			 * @returns {[number, number | undefined] | undefined}
1835			 */
1836			function parseRange(range) {
1837				var m = /^\s*(\d+)\s*(?:(,)\s*(?:(\d+)\s*)?)?$/.exec(range || '');
1838				if (m) {
1839					var start = Number(m[1]);
1840					var comma = m[2];
1841					var end = m[3];
1842
1843					if (!comma) {
1844						return [start, start];
1845					}
1846					if (!end) {
1847						return [start, undefined];
1848					}
1849					return [start, Number(end)];
1850				}
1851				return undefined;
1852			}
1853
1854			Prism.hooks.add('before-highlightall', function (env) {
1855				env.selector += ', ' + SELECTOR;
1856			});
1857
1858			Prism.hooks.add('before-sanity-check', function (env) {
1859				var pre = /** @type {HTMLPreElement} */ (env.element);
1860				if (pre.matches(SELECTOR)) {
1861					env.code = ''; // fast-path the whole thing and go to complete
1862
1863					pre.setAttribute(STATUS_ATTR, STATUS_LOADING); // mark as loading
1864
1865					// add code element with loading message
1866					var code = pre.appendChild(document.createElement('CODE'));
1867					code.textContent = LOADING_MESSAGE;
1868
1869					var src = pre.getAttribute('data-src');
1870
1871					var language = env.language;
1872					if (language === 'none') {
1873						// the language might be 'none' because there is no language set;
1874						// in this case, we want to use the extension as the language
1875						var extension = (/\.(\w+)$/.exec(src) || [, 'none'])[1];
1876						language = EXTENSIONS[extension] || extension;
1877					}
1878
1879					// set language classes
1880					Prism.util.setLanguage(code, language);
1881					Prism.util.setLanguage(pre, language);
1882
1883					// preload the language
1884					var autoloader = Prism.plugins.autoloader;
1885					if (autoloader) {
1886						autoloader.loadLanguages(language);
1887					}
1888
1889					// load file
1890					loadFile(
1891						src,
1892						function (text) {
1893							// mark as loaded
1894							pre.setAttribute(STATUS_ATTR, STATUS_LOADED);
1895
1896							// handle data-range
1897							var range = parseRange(pre.getAttribute('data-range'));
1898							if (range) {
1899								var lines = text.split(/\r\n?|\n/g);
1900
1901								// the range is one-based and inclusive on both ends
1902								var start = range[0];
1903								var end = range[1] == null ? lines.length : range[1];
1904
1905								if (start < 0) { start += lines.length; }
1906								start = Math.max(0, Math.min(start - 1, lines.length));
1907								if (end < 0) { end += lines.length; }
1908								end = Math.max(0, Math.min(end, lines.length));
1909
1910								text = lines.slice(start, end).join('\n');
1911
1912								// add data-start for line numbers
1913								if (!pre.hasAttribute('data-start')) {
1914									pre.setAttribute('data-start', String(start + 1));
1915								}
1916							}
1917
1918							// highlight code
1919							code.textContent = text;
1920							Prism.highlightElement(code);
1921						},
1922						function (error) {
1923							// mark as failed
1924							pre.setAttribute(STATUS_ATTR, STATUS_FAILED);
1925
1926							code.textContent = error;
1927						}
1928					);
1929				}
1930			});
1931
1932			Prism.plugins.fileHighlight = {
1933				/**
1934				 * Executes the File Highlight plugin for all matching `pre` elements under the given container.
1935				 *
1936				 * Note: Elements which are already loaded or currently loading will not be touched by this method.
1937				 *
1938				 * @param {ParentNode} [container=document]
1939				 */
1940				highlight: function highlight(container) {
1941					var elements = (container || document).querySelectorAll(SELECTOR);
1942
1943					for (var i = 0, element; (element = elements[i++]);) {
1944						Prism.highlightElement(element);
1945					}
1946				}
1947			};
1948
1949			var logged = false;
vendor: 4,244 bytes, lines 1950-2104
1950			/** @deprecated Use `Prism.plugins.fileHighlight.highlight` instead. */
1951			Prism.fileHighlight = function () {
1952				if (!logged) {
1953					console.warn('Prism.fileHighlight is deprecated. Use `Prism.plugins.fileHighlight.highlight` instead.');
1954					logged = true;
1955				}
1956				Prism.plugins.fileHighlight.highlight.apply(this, arguments);
1957			};
1958
1959		}()); 
1960	} (prism));
1961	return prism.exports;
1962}
1963
1964var prismExports = requirePrism();
1965var Prism$1 = /*@__PURE__*/getDefaultExportFromCjs(prismExports);
1966
1967Prism$1.languages.clike = {
1968	'comment': [
1969		{
1970			pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,
1971			lookbehind: true,
1972			greedy: true
1973		},
1974		{
1975			pattern: /(^|[^\\:])\/\/.*/,
1976			lookbehind: true,
1977			greedy: true
1978		}
1979	],
1980	'string': {
1981		pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
1982		greedy: true
1983	},
1984	'class-name': {
1985		pattern: /(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,
1986		lookbehind: true,
1987		inside: {
1988			'punctuation': /[.\\]/
1989		}
1990	},
1991	'keyword': /\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,
1992	'boolean': /\b(?:false|true)\b/,
1993	'function': /\b\w+(?=\()/,
1994	'number': /\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,
1995	'operator': /[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,
1996	'punctuation': /[{}[\];(),.:]/
1997};
1998
1999(function (Prism) {
2000
2001	Prism.languages.diff = {
2002		'coord': [
2003			// Match all kinds of coord lines (prefixed by "+++", "---" or "***").
2004			/^(?:\*{3}|-{3}|\+{3}).*$/m,
2005			// Match "@@ ... @@" coord lines in unified diff.
2006			/^@@.*@@$/m,
2007			// Match coord lines in normal diff (starts with a number).
2008			/^\d.*$/m
2009		]
2010
2011		// deleted, inserted, unchanged, diff
2012	};
2013
2014	/**
2015	 * A map from the name of a block to its line prefix.
2016	 *
2017	 * @type {Object<string, string>}
2018	 */
2019	var PREFIXES = {
2020		'deleted-sign': '-',
2021		'deleted-arrow': '<',
2022		'inserted-sign': '+',
2023		'inserted-arrow': '>',
2024		'unchanged': ' ',
2025		'diff': '!',
2026	};
2027
2028	// add a token for each prefix
2029	Object.keys(PREFIXES).forEach(function (name) {
2030		var prefix = PREFIXES[name];
2031
2032		var alias = [];
2033		if (!/^\w+$/.test(name)) { // "deleted-sign" -> "deleted"
2034			alias.push(/\w+/.exec(name)[0]);
2035		}
2036		if (name === 'diff') {
2037			alias.push('bold');
2038		}
2039
2040		Prism.languages.diff[name] = {
2041			pattern: RegExp('^(?:[' + prefix + '].*(?:\r\n?|\n|(?![\\s\\S])))+', 'm'),
2042			alias: alias,
2043			inside: {
2044				'line': {
2045					pattern: /(.)(?=[\s\S]).*(?:\r\n?|\n)?/,
2046					lookbehind: true
2047				},
2048				'prefix': {
2049					pattern: /[\s\S]/,
2050					alias: /\w+/.exec(name)[0]
2051				}
2052			}
2053		};
2054
2055	});
2056
2057	// make prefixes available to Diff plugin
2058	Object.defineProperty(Prism.languages.diff, 'PREFIXES', {
2059		value: PREFIXES
2060	});
2061
2062}(Prism$1));
2063
2064Prism$1.languages.javascript = Prism$1.languages.extend('clike', {
2065	'class-name': [
2066		Prism$1.languages.clike['class-name'],
2067		{
2068			pattern: /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,
2069			lookbehind: true
2070		}
2071	],
2072	'keyword': [
2073		{
2074			pattern: /((?:^|\})\s*)catch\b/,
2075			lookbehind: true
2076		},
2077		{
2078			pattern: /(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,
2079			lookbehind: true
2080		},
2081	],
2082	// Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444)
2083	'function': /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,
2084	'number': {
2085		pattern: RegExp(
2086			/(^|[^\w$])/.source +
2087			'(?:' +
2088			(
2089				// constant
2090				/NaN|Infinity/.source +
2091				'|' +
2092				// binary integer
2093				/0[bB][01]+(?:_[01]+)*n?/.source +
2094				'|' +
2095				// octal integer
2096				/0[oO][0-7]+(?:_[0-7]+)*n?/.source +
2097				'|' +
2098				// hexadecimal integer
2099				/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source +
2100				'|' +
2101				// decimal bigint
2102				/\d+(?:_\d+)*n/.source +
2103				'|' +
2104				// decimal number (integer or float) but no bigint
vendor: 4,609 bytes, lines 2105-2230
2105				/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source
2106			) +
2107			')' +
2108			/(?![\w$])/.source
2109		),
2110		lookbehind: true
2111	},
2112	'operator': /--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/
2113});
2114
2115Prism$1.languages.javascript['class-name'][0].pattern = /(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/;
2116
2117Prism$1.languages.insertBefore('javascript', 'keyword', {
2118	'regex': {
2119		pattern: RegExp(
2120			// lookbehind
2121			// eslint-disable-next-line regexp/no-dupe-characters-character-class
2122			/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source +
2123			// Regex pattern:
2124			// There are 2 regex patterns here. The RegExp set notation proposal added support for nested character
2125			// classes if the `v` flag is present. Unfortunately, nested CCs are both context-free and incompatible
2126			// with the only syntax, so we have to define 2 different regex patterns.
2127			/\//.source +
2128			'(?:' +
2129			/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/.source +
2130			'|' +
2131			// `v` flag syntax. This supports 3 levels of nested character classes.
2132			/(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/.source +
2133			')' +
2134			// lookahead
2135			/(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source
2136		),
2137		lookbehind: true,
2138		greedy: true,
2139		inside: {
2140			'regex-source': {
2141				pattern: /^(\/)[\s\S]+(?=\/[a-z]*$)/,
2142				lookbehind: true,
2143				alias: 'language-regex',
2144				inside: Prism$1.languages.regex
2145			},
2146			'regex-delimiter': /^\/|\/$/,
2147			'regex-flags': /^[a-z]+$/,
2148		}
2149	},
2150	// This must be declared before keyword because we use "function" inside the look-forward
2151	'function-variable': {
2152		pattern: /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,
2153		alias: 'function'
2154	},
2155	'parameter': [
2156		{
2157			pattern: /(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,
2158			lookbehind: true,
2159			inside: Prism$1.languages.javascript
2160		},
2161		{
2162			pattern: /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,
2163			lookbehind: true,
2164			inside: Prism$1.languages.javascript
2165		},
2166		{
2167			pattern: /(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,
2168			lookbehind: true,
2169			inside: Prism$1.languages.javascript
2170		},
2171		{
2172			pattern: /((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,
2173			lookbehind: true,
2174			inside: Prism$1.languages.javascript
2175		}
2176	],
2177	'constant': /\b[A-Z](?:[A-Z_]|\dx?)*\b/
2178});
2179
2180Prism$1.languages.insertBefore('javascript', 'string', {
2181	'hashbang': {
2182		pattern: /^#!.*/,
2183		greedy: true,
2184		alias: 'comment'
2185	},
2186	'template-string': {
2187		pattern: /`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,
2188		greedy: true,
2189		inside: {
2190			'template-punctuation': {
2191				pattern: /^`|`$/,
2192				alias: 'string'
2193			},
2194			'interpolation': {
2195				pattern: /((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,
2196				lookbehind: true,
2197				inside: {
2198					'interpolation-punctuation': {
2199						pattern: /^\$\{|\}$/,
2200						alias: 'punctuation'
2201					},
2202					rest: Prism$1.languages.javascript
2203				}
2204			},
2205			'string': /[\s\S]+/
2206		}
2207	},
2208	'string-property': {
2209		pattern: /((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,
2210		lookbehind: true,
2211		greedy: true,
2212		alias: 'property'
2213	}
2214});
2215
2216Prism$1.languages.insertBefore('javascript', 'operator', {
2217	'literal-property': {
2218		pattern: /((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,
2219		lookbehind: true,
2220		alias: 'property'
2221	},
2222});
2223
2224if (Prism$1.languages.markup) {
2225	Prism$1.languages.markup.tag.addInlined('script', 'javascript');
2226
2227	// add attribute support for all DOM events.
2228	// https://developer.mozilla.org/en-US/docs/Web/Events#Standard_events
2229	Prism$1.languages.markup.tag.addAttribute(
2230		/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?
vendor: 4,158 bytes, lines 2230-2386
2230:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,
2231		'javascript'
2232	);
2233}
2234
2235Prism$1.languages.js = Prism$1.languages.javascript;
2236
2237Prism$1.languages.markup = {
2238	'comment': {
2239		pattern: /<!--(?:(?!<!--)[\s\S])*?-->/,
2240		greedy: true
2241	},
2242	'prolog': {
2243		pattern: /<\?[\s\S]+?\?>/,
2244		greedy: true
2245	},
2246	'doctype': {
2247		// https://www.w3.org/TR/xml/#NT-doctypedecl
2248		pattern: /<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,
2249		greedy: true,
2250		inside: {
2251			'internal-subset': {
2252				pattern: /(^[^\[]*\[)[\s\S]+(?=\]>$)/,
2253				lookbehind: true,
2254				greedy: true,
2255				inside: null // see below
2256			},
2257			'string': {
2258				pattern: /"[^"]*"|'[^']*'/,
2259				greedy: true
2260			},
2261			'punctuation': /^<!|>$|[[\]]/,
2262			'doctype-tag': /^DOCTYPE/i,
2263			'name': /[^\s<>'"]+/
2264		}
2265	},
2266	'cdata': {
2267		pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i,
2268		greedy: true
2269	},
2270	'tag': {
2271		pattern: /<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,
2272		greedy: true,
2273		inside: {
2274			'tag': {
2275				pattern: /^<\/?[^\s>\/]+/,
2276				inside: {
2277					'punctuation': /^<\/?/,
2278					'namespace': /^[^\s>\/:]+:/
2279				}
2280			},
2281			'special-attr': [],
2282			'attr-value': {
2283				pattern: /=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,
2284				inside: {
2285					'punctuation': [
2286						{
2287							pattern: /^=/,
2288							alias: 'attr-equals'
2289						},
2290						{
2291							pattern: /^(\s*)["']|["']$/,
2292							lookbehind: true
2293						}
2294					]
2295				}
2296			},
2297			'punctuation': /\/?>/,
2298			'attr-name': {
2299				pattern: /[^\s>\/]+/,
2300				inside: {
2301					'namespace': /^[^\s>\/:]+:/
2302				}
2303			}
2304
2305		}
2306	},
2307	'entity': [
2308		{
2309			pattern: /&[\da-z]{1,8};/i,
2310			alias: 'named-entity'
2311		},
2312		/&#x?[\da-f]{1,8};/i
2313	]
2314};
2315
2316Prism$1.languages.markup['tag'].inside['attr-value'].inside['entity'] =
2317	Prism$1.languages.markup['entity'];
2318Prism$1.languages.markup['doctype'].inside['internal-subset'].inside = Prism$1.languages.markup;
2319
2320// Plugin to make entity title show the real entity, idea by Roman Komarov
2321Prism$1.hooks.add('wrap', function (env) {
2322
2323	if (env.type === 'entity') {
2324		env.attributes['title'] = env.content.replace(/&amp;/, '&');
2325	}
2326});
2327
2328Object.defineProperty(Prism$1.languages.markup.tag, 'addInlined', {
2329	/**
2330	 * Adds an inlined language to markup.
2331	 *
2332	 * An example of an inlined language is CSS with `<style>` tags.
2333	 *
2334	 * @param {string} tagName The name of the tag that contains the inlined language. This name will be treated as
2335	 * case insensitive.
2336	 * @param {string} lang The language key.
2337	 * @example
2338	 * addInlined('style', 'css');
2339	 */
2340	value: function addInlined(tagName, lang) {
2341		var includedCdataInside = {};
2342		includedCdataInside['language-' + lang] = {
2343			pattern: /(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,
2344			lookbehind: true,
2345			inside: Prism$1.languages[lang]
2346		};
2347		includedCdataInside['cdata'] = /^<!\[CDATA\[|\]\]>$/i;
2348
2349		var inside = {
2350			'included-cdata': {
2351				pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i,
2352				inside: includedCdataInside
2353			}
2354		};
2355		inside['language-' + lang] = {
2356			pattern: /[\s\S]+/,
2357			inside: Prism$1.languages[lang]
2358		};
2359
2360		var def = {};
2361		def[tagName] = {
2362			pattern: RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g, function () { return tagName; }), 'i'),
2363			lookbehind: true,
2364			greedy: true,
2365			inside: inside
2366		};
2367
2368		Prism$1.languages.insertBefore('markup', 'cdata', def);
2369	}
2370});
2371Object.defineProperty(Prism$1.languages.markup.tag, 'addAttribute', {
2372	/**
2373	 * Adds an pattern to highlight languages embedded in HTML attributes.
2374	 *
2375	 * An example of an inlined language is CSS with `style` attributes.
2376	 *
2377	 * @param {string} attrName The name of the tag that contains the inlined language. This name will be treated as
2378	 * case insensitive.
2379	 * @param {string} lang The language key.
2380	 * @example
2381	 * addAttribute('style', 'css');
2382	 */
2383	value: function (attrName, lang) {
2384		Prism$1.languages.markup.tag.inside['special-attr'].push({
2385			pattern: RegExp(
2386				/(^|["'\s])/.source + '(?:' + attrName + ')' + /\s*=\s*(?:"[^"]*"|'[^']*'|[^\
vendor: 13,576 bytes, lines 2386-2894
2386s'">=]+(?=[\s>]))/.source,
2387				'i'
2388			),
2389			lookbehind: true,
2390			inside: {
2391				'attr-name': /^[^\s=]+/,
2392				'attr-value': {
2393					pattern: /=[\s\S]+/,
2394					inside: {
2395						'value': {
2396							pattern: /(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,
2397							lookbehind: true,
2398							alias: [lang, 'language-' + lang],
2399							inside: Prism$1.languages[lang]
2400						},
2401						'punctuation': [
2402							{
2403								pattern: /^=/,
2404								alias: 'attr-equals'
2405							},
2406							/"|'/
2407						]
2408					}
2409				}
2410			}
2411		});
2412	}
2413});
2414
2415Prism$1.languages.html = Prism$1.languages.markup;
2416Prism$1.languages.mathml = Prism$1.languages.markup;
2417Prism$1.languages.svg = Prism$1.languages.markup;
2418
2419Prism$1.languages.xml = Prism$1.languages.extend('markup', {});
2420Prism$1.languages.ssml = Prism$1.languages.xml;
2421Prism$1.languages.atom = Prism$1.languages.xml;
2422Prism$1.languages.rss = Prism$1.languages.xml;
2423
2424(function (Prism) {
2425
2426	// Allow only one line break
2427	var inner = /(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;
2428
2429	/**
2430	 * This function is intended for the creation of the bold or italic pattern.
2431	 *
2432	 * This also adds a lookbehind group to the given pattern to ensure that the pattern is not backslash-escaped.
2433	 *
2434	 * _Note:_ Keep in mind that this adds a capturing group.
2435	 *
2436	 * @param {string} pattern
2437	 * @returns {RegExp}
2438	 */
2439	function createInline(pattern) {
2440		pattern = pattern.replace(/<inner>/g, function () { return inner; });
2441		return RegExp(/((?:^|[^\\])(?:\\{2})*)/.source + '(?:' + pattern + ')');
2442	}
2443
2444
2445	var tableCell = /(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source;
2446	var tableRow = /\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g, function () { return tableCell; });
2447	var tableLine = /\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source;
2448
2449
2450	Prism.languages.markdown = Prism.languages.extend('markup', {});
2451	Prism.languages.insertBefore('markdown', 'prolog', {
2452		'front-matter-block': {
2453			pattern: /(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,
2454			lookbehind: true,
2455			greedy: true,
2456			inside: {
2457				'punctuation': /^---|---$/,
2458				'front-matter': {
2459					pattern: /\S+(?:\s+\S+)*/,
2460					alias: ['yaml', 'language-yaml'],
2461					inside: Prism.languages.yaml
2462				}
2463			}
2464		},
2465		'blockquote': {
2466			// > ...
2467			pattern: /^>(?:[\t ]*>)*/m,
2468			alias: 'punctuation'
2469		},
2470		'table': {
2471			pattern: RegExp('^' + tableRow + tableLine + '(?:' + tableRow + ')*', 'm'),
2472			inside: {
2473				'table-data-rows': {
2474					pattern: RegExp('^(' + tableRow + tableLine + ')(?:' + tableRow + ')*$'),
2475					lookbehind: true,
2476					inside: {
2477						'table-data': {
2478							pattern: RegExp(tableCell),
2479							inside: Prism.languages.markdown
2480						},
2481						'punctuation': /\|/
2482					}
2483				},
2484				'table-line': {
2485					pattern: RegExp('^(' + tableRow + ')' + tableLine + '$'),
2486					lookbehind: true,
2487					inside: {
2488						'punctuation': /\||:?-{3,}:?/
2489					}
2490				},
2491				'table-header-row': {
2492					pattern: RegExp('^' + tableRow + '$'),
2493					inside: {
2494						'table-header': {
2495							pattern: RegExp(tableCell),
2496							alias: 'important',
2497							inside: Prism.languages.markdown
2498						},
2499						'punctuation': /\|/
2500					}
2501				}
2502			}
2503		},
2504		'code': [
2505			{
2506				// Prefixed by 4 spaces or 1 tab and preceded by an empty line
2507				pattern: /((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,
2508				lookbehind: true,
2509				alias: 'keyword'
2510			},
2511			{
2512				// ```optional language
2513				// code block
2514				// ```
2515				pattern: /^```[\s\S]*?^```$/m,
2516				greedy: true,
2517				inside: {
2518					'code-block': {
2519						pattern: /^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,
2520						lookbehind: true
2521					},
2522					'code-language': {
2523						pattern: /^(```).+/,
2524						lookbehind: true
2525					},
2526					'punctuation': /```/
2527				}
2528			}
2529		],
2530		'title': [
2531			{
2532				// title 1
2533				// =======
2534
2535				// title 2
2536				// -------
2537				pattern: /\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,
2538				alias: 'important',
2539				inside: {
2540					punctuation: /==+$|--+$/
2541				}
2542			},
2543			{
2544				// # title 1
2545				// ###### title 6
2546				pattern: /(^\s*)#.+/m,
2547				lookbehind: true,
2548				alias: 'important',
2549				inside: {
2550					punctuation: /^#+|#+$/
2551				}
2552			}
2553		],
2554		'hr': {
2555			// ***
2556			// ---
2557			// * * *
2558			// -----------
2559			pattern: /(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,
2560			lookbehind: true,
2561			alias: 'punctuation'
2562		},
2563		'list': {
2564			// * item
2565			// + item
2566			// - item
2567			// 1. item
2568			pattern: /(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,
2569			lookbehind: true,
2570			alias: 'punctuation'
2571		},
2572		'url-reference': {
2573			// [id]: http://example.com "Optional title"
2574			// [id]: http://example.com 'Optional title'
2575			// [id]: http://example.com (Optional title)
2576			// [id]: <http://example.com> "Optional title"
2577			pattern: /!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,
2578			inside: {
2579				'variable': {
2580					pattern: /^(!?\[)[^\]]+/,
2581					lookbehind: true
2582				},
2583				'string': /(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,
2584				'punctuation': /^[\[\]!:]|[<>]/
2585			},
2586			alias: 'url'
2587		},
2588		'bold': {
2589			// **strong**
2590			// __strong__
2591
2592			// allow one nested instance of italic text using the same delimiter
2593			pattern: createInline(/\b__(?:(?!_)<inner>|_(?:(?!_)<inner>)+_)+__\b|\*\*(?:(?!\*)<inner>|\*(?:(?!\*)<inner>)+\*)+\*\*/.source),
2594			lookbehind: true,
2595			greedy: true,
2596			inside: {
2597				'content': {
2598					pattern: /(^..)[\s\S]+(?=..$)/,
2599					lookbehind: true,
2600					inside: {} // see below
2601				},
2602				'punctuation': /\*\*|__/
2603			}
2604		},
2605		'italic': {
2606			// *em*
2607			// _em_
2608
2609			// allow one nested instance of bold text using the same delimiter
2610			pattern: createInline(/\b_(?:(?!_)<inner>|__(?:(?!_)<inner>)+__)+_\b|\*(?:(?!\*)<inner>|\*\*(?:(?!\*)<inner>)+\*\*)+\*/.source),
2611			lookbehind: true,
2612			greedy: true,
2613			inside: {
2614				'content': {
2615					pattern: /(^.)[\s\S]+(?=.$)/,
2616					lookbehind: true,
2617					inside: {} // see below
2618				},
2619				'punctuation': /[*_]/
2620			}
2621		},
2622		'strike': {
2623			// ~~strike through~~
2624			// ~strike~
2625			// eslint-disable-next-line regexp/strict
2626			pattern: createInline(/(~~?)(?:(?!~)<inner>)+\2/.source),
2627			lookbehind: true,
2628			greedy: true,
2629			inside: {
2630				'content': {
2631					pattern: /(^~~?)[\s\S]+(?=\1$)/,
2632					lookbehind: true,
2633					inside: {} // see below
2634				},
2635				'punctuation': /~~?/
2636			}
2637		},
2638		'code-snippet': {
2639			// `code`
2640			// ``code``
2641			pattern: /(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,
2642			lookbehind: true,
2643			greedy: true,
2644			alias: ['code', 'keyword']
2645		},
2646		'url': {
2647			// [example](http://example.com "Optional title")
2648			// [example][id]
2649			// [example] [id]
2650			pattern: createInline(/!?\[(?:(?!\])<inner>)+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\])<inner>)+\])/.source),
2651			lookbehind: true,
2652			greedy: true,
2653			inside: {
2654				'operator': /^!/,
2655				'content': {
2656					pattern: /(^\[)[^\]]+(?=\])/,
2657					lookbehind: true,
2658					inside: {} // see below
2659				},
2660				'variable': {
2661					pattern: /(^\][ \t]?\[)[^\]]+(?=\]$)/,
2662					lookbehind: true
2663				},
2664				'url': {
2665					pattern: /(^\]\()[^\s)]+/,
2666					lookbehind: true
2667				},
2668				'string': {
2669					pattern: /(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,
2670					lookbehind: true
2671				}
2672			}
2673		}
2674	});
2675
2676	['url', 'bold', 'italic', 'strike'].forEach(function (token) {
2677		['url', 'bold', 'italic', 'strike', 'code-snippet'].forEach(function (inside) {
2678			if (token !== inside) {
2679				Prism.languages.markdown[token].inside.content.inside[inside] = Prism.languages.markdown[inside];
2680			}
2681		});
2682	});
2683
2684	Prism.hooks.add('after-tokenize', function (env) {
2685		if (env.language !== 'markdown' && env.language !== 'md') {
2686			return;
2687		}
2688
2689		function walkTokens(tokens) {
2690			if (!tokens || typeof tokens === 'string') {
2691				return;
2692			}
2693
2694			for (var i = 0, l = tokens.length; i < l; i++) {
2695				var token = tokens[i];
2696
2697				if (token.type !== 'code') {
2698					walkTokens(token.content);
2699					continue;
2700				}
2701
2702				/*
2703				 * Add the correct `language-xxxx` class to this code block. Keep in mind that the `code-language` token
2704				 * is optional. But the grammar is defined so that there is only one case we have to handle:
2705				 *
2706				 * token.content = [
2707				 *     <span class="punctuation">```</span>,
2708				 *     <span class="code-language">xxxx</span>,
2709				 *     '\n', // exactly one new lines (\r or \n or \r\n)
2710				 *     <span class="code-block">...</span>,
2711				 *     '\n', // exactly one new lines again
2712				 *     <span class="punctuation">```</span>
2713				 * ];
2714				 */
2715
2716				var codeLang = token.content[1];
2717				var codeBlock = token.content[3];
2718
2719				if (codeLang && codeBlock &&
2720					codeLang.type === 'code-language' && codeBlock.type === 'code-block' &&
2721					typeof codeLang.content === 'string') {
2722
2723					// this might be a language that Prism does not support
2724
2725					// do some replacements to support C++, C#, and F#
2726					var lang = codeLang.content.replace(/\b#/g, 'sharp').replace(/\b\+\+/g, 'pp');
2727					// only use the first word
2728					lang = (/[a-z][\w-]*/i.exec(lang) || [''])[0].toLowerCase();
2729					var alias = 'language-' + lang;
2730
2731					// add alias
2732					if (!codeBlock.alias) {
2733						codeBlock.alias = [alias];
2734					} else if (typeof codeBlock.alias === 'string') {
2735						codeBlock.alias = [codeBlock.alias, alias];
2736					} else {
2737						codeBlock.alias.push(alias);
2738					}
2739				}
2740			}
2741		}
2742
2743		walkTokens(env.tokens);
2744	});
2745
2746	Prism.hooks.add('wrap', function (env) {
2747		if (env.type !== 'code-block') {
2748			return;
2749		}
2750
2751		var codeLang = '';
2752		for (var i = 0, l = env.classes.length; i < l; i++) {
2753			var cls = env.classes[i];
2754			var match = /language-(.+)/.exec(cls);
2755			if (match) {
2756				codeLang = match[1];
2757				break;
2758			}
2759		}
2760
2761		var grammar = Prism.languages[codeLang];
2762
2763		if (!grammar) {
2764			if (codeLang && codeLang !== 'none' && Prism.plugins.autoloader) {
2765				var id = 'md-' + new Date().valueOf() + '-' + Math.floor(Math.random() * 1e16);
2766				env.attributes['id'] = id;
2767
2768				Prism.plugins.autoloader.loadLanguages(codeLang, function () {
2769					var ele = document.getElementById(id);
2770					if (ele) {
2771						ele.innerHTML = Prism.highlight(ele.textContent, Prism.languages[codeLang], codeLang);
2772					}
2773				});
2774			}
2775		} else {
2776			env.content = Prism.highlight(textContent(env.content), grammar, codeLang);
2777		}
2778	});
2779
2780	var tagPattern = RegExp(Prism.languages.markup.tag.pattern.source, 'gi');
2781
2782	/**
2783	 * A list of known entity names.
2784	 *
2785	 * This will always be incomplete to save space. The current list is the one used by lowdash's unescape function.
2786	 *
2787	 * @see {@link https://github.com/lodash/lodash/blob/2da024c3b4f9947a48517639de7560457cd4ec6c/unescape.js#L2}
2788	 */
2789	var KNOWN_ENTITY_NAMES = {
2790		'amp': '&',
2791		'lt': '<',
2792		'gt': '>',
2793		'quot': '"',
2794	};
2795
2796	// IE 11 doesn't support `String.fromCodePoint`
2797	var fromCodePoint = String.fromCodePoint || String.fromCharCode;
2798
2799	/**
2800	 * Returns the text content of a given HTML source code string.
2801	 *
2802	 * @param {string} html
2803	 * @returns {string}
2804	 */
2805	function textContent(html) {
2806		// remove all tags
2807		var text = html.replace(tagPattern, '');
2808
2809		// decode known entities
2810		text = text.replace(/&(\w{1,8}|#x?[\da-f]{1,8});/gi, function (m, code) {
2811			code = code.toLowerCase();
2812
2813			if (code[0] === '#') {
2814				var value;
2815				if (code[1] === 'x') {
2816					value = parseInt(code.slice(2), 16);
2817				} else {
2818					value = Number(code.slice(1));
2819				}
2820
2821				return fromCodePoint(value);
2822			} else {
2823				var known = KNOWN_ENTITY_NAMES[code];
2824				if (known) {
2825					return known;
2826				}
2827
2828				// unable to decode
2829				return m;
2830			}
2831		});
2832
2833		return text;
2834	}
2835
2836	Prism.languages.md = Prism.languages.markdown;
2837
2838}(Prism$1));
2839
2840Prism$1.languages.c = Prism$1.languages.extend('clike', {
2841	'comment': {
2842		pattern: /\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,
2843		greedy: true
2844	},
2845	'string': {
2846		// https://en.cppreference.com/w/c/language/string_literal
2847		pattern: /"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,
2848		greedy: true
2849	},
2850	'class-name': {
2851		pattern: /(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,
2852		lookbehind: true
2853	},
2854	'keyword': /\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,
2855	'function': /\b[a-z_]\w*(?=\s*\()/i,
2856	'number': /(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,
2857	'operator': />>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/
2858});
2859
2860Prism$1.languages.insertBefore('c', 'string', {
2861	'char': {
2862		// https://en.cppreference.com/w/c/language/character_constant
2863		pattern: /'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,
2864		greedy: true
2865	}
2866});
2867
2868Prism$1.languages.insertBefore('c', 'string', {
2869	'macro': {
2870		// allow for multiline macro definitions
2871		// spaces after the # character compile fine with gcc
2872		pattern: /(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,
2873		lookbehind: true,
2874		greedy: true,
2875		alias: 'property',
2876		inside: {
2877			'string': [
2878				{
2879					// highlight the path of the include statement as a string
2880					pattern: /^(#\s*include\s*)<[^>]+>/,
2881					lookbehind: true
2882				},
2883				Prism$1.languages.c['string']
2884			],
2885			'char': Prism$1.languages.c['char'],
2886			'comment': Prism$1.languages.c['comment'],
2887			'macro-name': [
2888				{
2889					pattern: /(^#\s*define\s+)\w+\b(?!\()/i,
2890					lookbehind: true
2891				},
2892				{
2893					pattern: /(^#\s*define\s+)\w+\b(?=\()/i,
2894					lookbehind: true,
2895					alias: 'function'
2896				}
2897			],
2898			// highlight macro directives as keywords
2899			'directive': {
2900				pattern: /^(#\s*)[a-z]+/,
2901				lookbehind: true,
2902				alias: 'keyword'
2903			},
2904			'directive-hash': /^#/,
2905			'punctuation': /##|\\(?=[\r\n])/,
2906			'expression': {
2907				pattern: /\S[\s\S]*/,
2908				inside: Prism$1.languages.c
2909			}
2910		}
2911	}
2912});
2913
2914Prism$1.languages.insertBefore('c', 'function', {
2915	// highlight predefined macros as constants
2916	'constant': /\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/
2917});
2918
2919delete Prism$1.languages.c['boolean'];
2920
2921(function (Prism) {
2922
2923	var string = /(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;
2924
2925	Prism.languages.css = {
2926		'comment': /\/\*[\s\S]*?\*\//,
2927		'atrule': {
2928			pattern: RegExp('@[\\w-](?:' + /[^;{\s"']|\s+(?!\s)/.source + '|' + string.source + ')*?' + /(?:;|(?=\s*\{))/.source),
2929			inside: {
2930				'rule': /^@[\w-]+/,
2931				'selector-function-argument': {
2932					pattern: /(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,
2933					lookbehind: true,
2934					alias: 'selector'
2935				},
2936				'keyword': {
2937					pattern: /(^|[^\w-])(?:and|not|only|or)(?![\w-])/,
2938					lookbehind: true
2939				}
2940				// See rest below
2941			}
2942		},
2943		'url': {
2944			// https://drafts.csswg.org/css-values-3/#urls
2945			pattern: RegExp('\\burl\\((?:' + string.source + '|' + /(?:[^\\\r\n()"']|\\[\s\S])*/.source + ')\\)', 'i'),
2946			greedy: true,
2947			inside: {
2948				'function': /^url/i,
2949				'punctuation': /^\(|\)$/,
2950				'string': {
2951					pattern: RegExp('^' + string.source + '$'),
2952					alias: 'url'
2953				}
2954			}
2955		},
2956		'selector': {
2957			pattern: RegExp('(^|[{}\\s])[^{}\\s](?:[^{};"\'\\s]|\\s+(?![\\s{])|' + string.source + ')*(?=\\s*\\{)'),
2958			lookbehind: true
2959		},
2960		'string': {
2961			pattern: string,
2962			greedy: true
2963		},
2964		'property': {
2965			pattern: /(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,
2966			lookbehind: true
2967		},
2968		'important': /!important\b/i,
2969		'function': {
2970			pattern: /(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,
2971			lookbehind: true
2972		},
2973		'punctuation': /[(){};:,]/
2974	};
2975
2976	Prism.languages.css['atrule'].inside.rest = Prism.languages.css;
2977
2978	var markup = Prism.languages.markup;
2979	if (markup) {
2980		markup.tag.addInlined('style', 'css');
2981		markup.tag.addAttribute('style', 'css');
2982	}
2983
2984}(Prism$1));
2985
2986Prism$1.languages.objectivec = Prism$1.languages.extend('c', {
2987	'string': {
2988		pattern: /@?"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,
2989		greedy: true
2990	},
2991	'keyword': /\b(?:asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|in|inline|int|long|register|return|self|short|signed|sizeof|static|struct|super|switch|typedef|typeof|union|unsigned|void|volatile|while)\b|(?:@interface|@end|@implementation|@protocol|@class|@public|@protected|@private|@property|@try|@catch|@finally|@throw|@synthesize|@dynamic|@selector)\b/,
2992	'operator': /-[->]?|\+\+?|!=?|<<?=?|>>?=?|==?|&&?|\|\|?|[~^%?*\/@]/
2993});
2994
2995delete Prism$1.languages.objectivec['class-name'];
2996
2997Prism$1.languages.objc = Prism$1.languages.objectivec;
2998
2999Prism$1.languages.sql = {
3000	'comment': {
3001		pattern: /(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/|#).*)/,
3002		lookbehind: true
3003	},
3004	'variable': [
3005		{
3006			pattern: /@(["'`])(?:\\[\s\S]|(?!\1)[^\\])+\1/,
3007			greedy: true
3008		},
3009		/@[\w.$]+/
3010	],
3011	'string': {
3012		pattern: /(^|[^@\\])("|')(?:\\[\s\S]|(?!\2)[^\\]|\2\2)*\2/,
3013		greedy: true,
3014		lookbehind: true
3015	},
3016	'identifier': {
3017		pattern: /(^|[^@\\])`(?:\\[\s\S]|[^`\\]|``)*`/,
3018		greedy: true,
3019		lookbehind: true,
3020		inside: {
3021			'punctuation': /^`|`$/
3022		}
3023	},
3024	'function': /\b(?:AVG|COUNT|FIRST|FORMAT|LAST|LCASE|LEN|MAX|MID|MIN|MOD|NOW|ROUND|SUM|UCASE)(?=\s*\()/i, // Should we highlight user defined functions too?
3025	'keyword': /\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR(?:ACTER|SET)?|CHECK(?:POINT)?|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMNS?|COMMENT|COMMIT(?:TED)?|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS(?:TABLE)?|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|CYCLE|DATA(?:BASES?)?|DATE(?:TIME)?|DAY|DBCC|DEALLOCATE|DEC|DECI
3025MAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITERS?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE|ELSE(?:IF)?|ENABLE|ENCLOSED|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPED?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|HOUR|IDENTITY(?:COL|_INSERT)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|INVOKER|ISOLATION|ITERATE|JOIN|KEYS?|KILL|LANGUAGE|LAST|LEAVE|LEFT|LEVEL|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|LOOP|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MINUTE|MODE|MODIFIES|MODIFY|MONTH|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREPARE|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READS?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEAT(?:ABLE)?|REPLACE|REPLICATION|REQUIRE|RESIGNAL|RESTORE|RESTRICT|RETURN(?:ING|S)?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SECOND|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|SQL|START(?:ING)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNLOCK|UNPIVOT|UNSIGNED|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?|YEAR)\b/i,
3026	'boolean': /\b(?:FALSE|NULL|TRUE)\b/i,
3027	'number': /\b0x[\da-f]+\b|\b\d+(?:\.\d*)?|\B\.\d+\b/i,
3028	'operator': /[-+*\/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,
3029	'punctuation': /[;[\]()`,.]/
3030};
3031
3032(function (Prism) {
3033
3034	var powershell = Prism.languages.powershell = {
3035		'comment': [
3036			{
3037				pattern: /(^|[^`])<#[\s\S]*?#>/,
3038				lookbehind: true
3039			},
3040			{
3041				pattern: /(^|[^`])#.*/,
3042				lookbehind: true
3043			}
3044		],
3045		'string': [
3046			{
3047				pattern: /"(?:`[\s\S]|[^`"])*"/,
3048				greedy: true,
3049				inside: null // see below
3050			},
3051			{
3052				pattern: /'(?:[^']|'')*'/,
3053				greedy: true
3054			}
3055		],
3056		// Matches name spaces as well as casts, attribute decorators. Force starting with letter to avoid matching array indices
3057		// Supports two levels of nested brackets (e.g. `[OutputType([System.Collections.Generic.List[int]])]`)
3058		'namespace': /\[[a-z](?:\[(?:\[[^\]]*\]|[^\[\]])*\]|[^\[\]])*\]/i,
3059		'boolean': /\$(?:false|true)\b/i,
3060		'variable': /\$\w+\b/,
3061		// Cmdlets and aliases. Aliases should come last, otherwise "write" gets preferred over "write-host" for example
3062		// Get-Command | ?{ $_.ModuleName -match "Microsoft.PowerShell.(Util|Core|Management)" }
3063		// Get-Alias | ?{ $_.ReferencedCommand.Module.Name -match "Microsoft.PowerShell.(Util|Core|Management)" }
3064		'function': [
3065			/\b(?:Add|Approve|Assert|Backup|Block|Checkpoint|Clear|Close|Compare|Complete|Compress|Confirm|Connect|Convert|ConvertFrom|ConvertTo|Copy|Debug|Deny|Disable|Disconnect|Dismount|Edit|Enable|Enter|Exit|Expand|Export|Find|ForEach|Format|Get|Grant|Group|Hide|Import|Initialize|Install|Invoke|Join|Limit|Lock|Measure|Merge|Move|New|Open|Optimize|Out|Ping|Pop|Protect|Publish|Push|Read|Receive|Redo|Register|Remove|Rename|Repair|Request|Reset|Resize|Resolve|Restart|Restore|Resume|Revoke|Save|Search|Select|Send|Set|Show|Skip|Sort|Split|Start|Step|Stop|Submit|Suspend|Switch|Sync|Tee|Test|Trace|Unblock|Undo|Uninstall|Unlock|Unprotect|Unpublish|Unregister|Update|Use|Wait|Watch|Where|Write)-[a-z]+\b/i,
3066			/\b(?:ac|cat|chdir|clc|cli|clp|clv|compare|copy|cp|cpi|cpp|cvpa|dbp|del|diff|dir|ebp|echo|epal|epcsv|epsn|erase|fc|fl|ft|fw|gal|gbp|gc|gci|gcs|gdr|gi|gl|gm|gp|gps|group|gsv|gu|gv|gwmi|iex|ii|ipal|ipcsv|ipsn|irm|iwmi|iwr|kill|lp|ls|measure|mi|mount|move|mp|mv|nal|ndr|ni|nv|ogv|popd|ps|pushd|pwd|rbp|rd|rdr|ren|ri|rm|rmdir|rni|rnp|rp|rv|rvpa|rwmi|sal|saps|sasv|sbp|sc|select|set|shcm|si|sl|sleep|sls|sort|sp|spps|spsv|start|sv|swmi|tee|trcm|type|write)\b/i
3067		],
3068		// per http://technet.microsoft.com/en-us/library/hh847744.aspx
3069		'keyword': /\b(?:Begin|Break|Catch|Class|Continue|Data|Define|Do|DynamicParam|Else|ElseIf|End|Exit|Filter|Finally|For|ForEach|From|Function|If|InlineScript|Parallel|Param|Process|Return|Sequence|Switch|Throw|Trap|Try|Until|Using|Var|While|Workflow)\b/i,
3070		'operator': {
3071			pattern: /(^|\W)(?:!|-(?:b?(?:and|x?or)|as|(?:Not)?(?:Contains|In|Like|Match)|eq|ge|gt|is(?:Not)?|Join|le|lt|ne|not|Replace|sh[lr])\b|-[-=]?|\+[+=]?|[*\/%]=?)/i,
3072			lookbehind: true
3073		},
3074		'punctuation': /[|{}[\];(),.]/
3075	};
3076
3077	// Variable interpolation inside strings, and nested expressions
3078	powershell.string[0].inside = {
3079		'function': {
3080			// Allow for one level of nesting
3081			pattern: /(^|[^`])\$\((?:\$\([^\r\n()]*\)|(?!\$\()[^\r\n)])*\)/,
3082			lookbehind: true,
3083			inside: powershell
3084		},
3085		'boolean': powershell.boolean,
3086		'variable': powershell.variable,
3087	};
3088
3089}(Prism$1));
3090
3091var prismPython = {};
3092
3093var hasRequiredPrismPython;
3094
3095function requirePrismPython () {
3096	if (hasRequiredPrismPython) return prismPython;
3097	hasRequiredPrismPython = 1;
3098	Prism$1.languages.python = {
3099		'comment': {
3100			pattern: /(^|[^\\])#.*/,
3101			lookbehind: true,
3102			greedy: true
3103		},
3104		'string-interpolation': {
3105			pattern: /(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,
3106			greedy: true,
3107			inside: {
3108				'interpolation': {
3109					// "{" <expression> <optional "!s", "!r", or "!a"> <optional ":" format specifier> "}"
3110					pattern: /((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,
3111					lookbehind: true,
3112					inside: {
3113						'format-spec': {
3114							pattern: /(:)[^:(){}]+(?=\}$)/,
3115							lookbehind: true
3116						},
3117						'conversion-option': {
3118							pattern: /![sra](?=[:}]$)/,
3119							alias: 'punctuation'
3120						},
3121						rest: null
3122					}
3123				},
3124				'string': /[\s\S]+/
3125			}
3126		},
3127		'triple-quoted-string': {
3128			pattern: /(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,
3129			greedy: true,
3130			alias: 'string'
3131		},
3132		'string': {
3133			pattern: /(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,
3134			greedy: true
3135		},
3136		'function': {
3137			pattern: /((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,
3138			lookbehind: true
3139		},
3140		'class-name': {
3141			pattern: /(\bclass\s+)\w+/i,
3142			lookbehind: true
3143		},
3144		'decorator': {
3145			pattern: /(^[\t ]*)@\w+(?:\.\w+)*/m,
3146			lookbehind: true,
3147			alias: ['annotation', 'punctuation'],
3148			inside: {
3149				'punctuation': /\./
3150			}
3151		},
3152		'keyword': /\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,
3153		'builtin': /\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,
3154		'boolean': /\b(?:False|None|True)\b/,
3155		'number': /\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,
3156		'operator': /[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,
3157		'punctuation': /[{}[\];(),.:]/
3158	};
3159
3160	Prism$1.languages.python['string-interpolation'].inside['interpolation'].inside.rest = Prism$1.languages.python;
3161
3162	Prism$1.languages.py = Prism$1.languages.python;
3163	return prismPython;
3164}
3165
3166requirePrismPython();
3167
3168var prismRust = {};
3169
3170var hasRequiredPrismRust;
3171
3172function requirePrismRust () {
3173	if (hasRequiredPrismRust) return prismRust;
3174	hasRequiredPrismRust = 1;
3175	(function (Prism) {
3176
3177		var multilineComment = /\/\*(?:[^*/]|\*(?!\/)|\/(?!\*)|<self>)*\*\//.source;
3178		for (var i = 0; i < 2; i++) {
3179			// support 4 levels of nested comments
3180			multilineComment = multilineComment.replace(/<self>/g, function () { return multilineComment; });
3181		}
3182		multilineComment = multilineComment.replace(/<self>/g, function () { return /[^\s\S]/.source; });
3183
3184
3185		Prism.languages.rust = {
3186			'comment': [
3187				{
3188					pattern: RegExp(/(^|[^\\])/.source + multilineComment),
3189					lookbehind: true,
3190					greedy: true
3191				},
3192				{
3193					pattern: /(^|[^\\:])\/\/.*/,
3194					lookbehind: true,
3195					greedy: true
3196				}
3197			],
3198			'string': {
3199				pattern: /b?"(?:\\[\s\S]|[^\\"])*"|b?r(#*)"(?:[^"]|"(?!\1))*"\1/,
3200				greedy: true
3201			},
3202			'char': {
3203				pattern: /b?'(?:\\(?:x[0-7][\da-fA-F]|u\{(?:[\da-fA-F]_*){1,6}\}|.)|[^\\\r\n\t'])'/,
3204				greedy: true
3205			},
3206			'attribute': {
3207				pattern: /#!?\[(?:[^\[\]"]|"(?:\\[\s\S]|[^\\"])*")*\]/,
3208				greedy: true,
3209				alias: 'attr-name',
3210				inside: {
3211					'string': null // see below
3212				}
3213			},
3214
3215			// Closure params should not be confused with bitwise OR |
3216			'closure-params': {
3217				pattern: /([=(,:]\s*|\bmove\s*)\|[^|]*\||\|[^|]*\|(?=\s*(?:\{|->))/,
3218				lookbehind: true,
3219				greedy: true,
3220				inside: {
3221					'closure-punctuation': {
3222						pattern: /^\||\|$/,
3223						alias: 'punctuation'
3224					},
3225					rest: null // see below
3226				}
3227			},
3228
3229			'lifetime-annotation': {
3230				pattern: /'\w+/,
3231				alias: 'symbol'
3232			},
3233
3234			'fragment-specifier': {
3235				pattern: /(\$\w+:)[a-z]+/,
3236				lookbehind: true,
3237				alias: 'punctuation'
3238			},
3239			'variable': /\$\w+/,
3240
3241			'function-definition': {
3242				pattern: /(\bfn\s+)\w+/,
3243				lookbehind: true,
3244				alias: 'function'
3245			},
3246			'type-definition': {
3247				pattern: /(\b(?:enum|struct|trait|type|union)\s+)\w+/,
3248				lookbehind: true,
3249				alias: 'class-name'
3250			},
3251			'module-declaration': [
3252				{
3253					pattern: /(\b(?:crate|mod)\s+)[a-z][a-z_\d]*/,
3254					lookbehind: true,
3255					alias: 'namespace'
3256				},
3257				{
3258					pattern: /(\b(?:crate|self|super)\s*)::\s*[a-z][a-z_\d]*\b(?:\s*::(?:\s*[a-z][a-z_\d]*\s*::)*)?/,
3259					lookbehind: true,
3260					alias: 'namespace',
3261					inside: {
3262						'punctuation': /::/
3263					}
3264				}
3265			],
3266			'keyword': [
3267				// https://github.com/rust-lang/reference/blob/master/src/keywords.md
3268				/\b(?:Self|abstract|as|async|await|become|box|break|const|continue|crate|do|dyn|else|enum|extern|final|fn|for|if|impl|in|let|loop|macro|match|mod|move|mut|override|priv|pub|ref|return|self|static|struct|super|trait|try|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\b/,
3269				// primitives and str
3270				// https://doc.rust-lang.org/stable/rust-by-example/primitives.html
3271				/\b(?:bool|char|f(?:32|64)|[ui](?:8|16|32|64|128|size)|str)\b/
3272			],
3273
3274			// functions can technically start with an upper-case letter, but this will introduce a lot of false positives
3275			// and Rust's naming conventions recommend snake_case anyway.
3276			// https://doc.rust-lang.org/1.0.0/style/style/naming/README.html
3277			'function': /\b[a-z_]\w*(?=\s*(?:::\s*<|\())/,
3278			'macro': {
3279				pattern: /\b\w+!/,
3280				alias: 'property'
3281			},
3282			'constant': /\b[A-Z_][A-Z_\d]+\b/,
3283			'class-name': /\b[A-Z]\w*\b/,
3284
3285			'namespace': {
3286				pattern: /(?:\b[a-z][a-z_\d]*\s*::\s*)*\b[a-z][a-z_\d]*\s*::(?!\s*<)/,
3287				inside: {
3288					'punctuation': /::/
3289				}
3290			},
3291
3292			// Hex, oct, bin, dec numbers with visual separators and type suffix
3293			'number': /\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(?:(?:\d(?:_?\d)*)?\.)?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)(?:_?(?:f32|f64|[iu](?:8|16|32|64|size)?))?\b/,
3294			'boolean': /\b(?:false|true)\b/,
3295			'punctuation': /->|\.\.=|\.{1,3}|::|[{}[\];(),:]/,
3296			'operator': /[-+*\/%!^]=?|=[=>]?|&[&=]?|\|[|=]?|<<?=?|>>?=?|[@?]/
3297		};
3298
3299		Prism.languages.rust['closure-params'].inside.rest = Prism.languages.rust;
3300		Prism.languages.rust['attribute'].inside['string'] = Prism.languages.rust['string'];
3301
3302	}(Prism$1));
3303	return prismRust;
3304}
3305
3306requirePrismRust();
3307
3308Prism$1.languages.swift = {
3309	'comment': {
3310		// Nested comments are supported up to 2 levels
3311		pattern: /(^|[^\\:])(?:\/\/.*|\/\*(?:[^/*]|\/(?!\*)|\*(?!\/)|\/\*(?:[^*]|\*(?!\/))*\*\/)*\*\/)/,
3312		lookbehind: true,
3313		greedy: true
3314	},
3315	'string-literal': [
3316		// https://docs.swift.org/swift-book/LanguageGuide/StringsAndCharacters.html
3317		{
3318			pattern: RegExp(
3319				/(^|[^"#])/.source
3320				+ '(?:'
3321				// single-line string
3322				+ /"(?:\\(?:\((?:[^()]|\([^()]*\))*\)|\r\n|[^(])|[^\\\r\n"])*"/.source
3323				+ '|'
3324				// multi-line string
3325				+ /"""(?:\\(?:\((?:[^()]|\([^()]*\))*\)|[^(])|[^\\"]|"(?!""))*"""/.source
3326				+ ')'
3327				+ /(?!["#])/.source
3328			),
3329			lookbehind: true,
3330			greedy: true,
3331			inside: {
3332				'interpolation': {
3333					pattern: /(\\\()(?:[^()]|\([^()]*\))*(?=\))/,
3334					lookbehind: true,
3335					inside: null // see below
3336				},
3337				'interpolation-punctuation': {
3338					pattern: /^\)|\\\($/,
3339					alias: 'punctuation'
3340				},
3341				'punctuation': /\\(?=[\r\n])/,
3342				'string': /[\s\S]+/
3343			}
3344		},
3345		{
3346			pattern: RegExp(
3347				/(^|[^"#])(#+)/.source
3348				+ '(?:'
3349				// single-line string
3350				+ /"(?:\\(?:#+\((?:[^()]|\([^()]*\))*\)|\r\n|[^#])|[^\\\r\n])*?"/.source
3351				+ '|'
3352				// multi-line string
3353				+ /"""(?:\\(?:#+\((?:[^()]|\([^()]*\))*\)|[^#])|[^\\])*?"""/.source
3354				+ ')'
3355				+ '\\2'
3356			),
3357			lookbehind: true,
3358			greedy: true,
3359			inside: {
3360				'interpolation': {
3361					pattern: /(\\#+\()(?:[^()]|\([^()]*\))*(?=\))/,
3362					lookbehind: true,
3363					inside: null // see below
3364				},
3365				'interpolation-punctuation': {
3366					pattern: /^\)|\\#+\($/,
3367					alias: 'punctuation'
3368				},
3369				'string': /[\s\S]+/
3370			}
3371		},
3372	],
3373
3374	'directive': {
3375		// directives with conditions
3376		pattern: RegExp(
3377			/#/.source
3378			+ '(?:'
3379			+ (
3380				/(?:elseif|if)\b/.source
3381				+ '(?:[ \t]*'
3382				// This regex is a little complex. It's equivalent to this:
3383				//   (?:![ \t]*)?(?:\b\w+\b(?:[ \t]*<round>)?|<round>)(?:[ \t]*(?:&&|\|\|))?
3384				// where <round> is a general parentheses expression.
3385				+ /(?:![ \t]*)?(?:\b\w+\b(?:[ \t]*\((?:[^()]|\([^()]*\))*\))?|\((?:[^()]|\([^()]*\))*\))(?:[ \t]*(?:&&|\|\|))?/.source
3386				+ ')+'
3387			)
3388			+ '|'
3389			+ /(?:else|endif)\b/.source
3390			+ ')'
3391		),
3392		alias: 'property',
3393		inside: {
3394			'directive-name': /^#\w+/,
3395			'boolean': /\b(?:false|true)\b/,
3396			'number': /\b\d+(?:\.\d+)*\b/,
3397			'operator': /!|&&|\|\||[<>]=?/,
3398			'punctuation': /[(),]/
3399		}
3400	},
3401	'literal': {
3402		pattern: /#(?:colorLiteral|column|dsohandle|file(?:ID|Literal|Path)?|function|imageLiteral|line)\b/,
3403		alias: 'constant'
3404	},
3405	'other-directive': {
3406		pattern: /#\w+\b/,
3407		alias: 'property'
3408	},
3409
3410	'attribute': {
3411		pattern: /@\w+/,
3412		alias: 'atrule'
3413	},
3414
3415	'function-definition': {
3416		pattern: /(\bfunc\s+)\w+/,
3417		lookbehind: true,
3418		alias: 'function'
3419	},
3420	'label': {
3421		// https://docs.swift.org/swift-book/LanguageGuide/ControlFlow.html#ID141
3422		pattern: /\b(break|continue)\s+\w+|\b[a-zA-Z_]\w*(?=\s*:\s*(?:for|repeat|while)\b)/,
3423		lookbehind: true,
3424		alias: 'important'
3425	},
3426
3427	'keyword': /\b(?:Any|Protocol|Self|Type|actor|as|assignment|associatedtype|associativity|async|await|break|case|catch|class|continue|convenience|default|defer|deinit|didSet|do|dynamic|else|enum|extension|fallthrough|fileprivate|final|for|func|get|guard|higherThan|if|import|in|indirect|infix|init|inout|internal|is|isolated|lazy|left|let|lowerThan|mutating|none|nonisolated|nonmutating|open|operator|optional|override|postfix|precedencegroup|prefix|private|protocol|public|repeat|required|rethrows|return|right|safe|self|set|some|static|struct|subscript|super|switch|throw|throws|try|typealias|unowned|unsafe|var|weak|where|while|willSet)\b/,
3428	'boolean': /\b(?:false|true)\b/,
3429	'nil': {
3430		pattern: /\bnil\b/,
3431		alias: 'constant'
3432	},
3433
3434	'short-argument': /\$\d+\b/,
3435	'omit': {
3436		pattern: /\b_\b/,
3437		alias: 'keyword'
3438	},
3439	'number': /\b(?:[\d_]+(?:\.[\de_]+)?|0x[a-f0-9_]+(?:\.[a-f0-9p_]+)?|0b[01_]+|0o[0-7_]+)\b/i,
3440
3441	// A class name must start with an upper-case letter and be either 1 letter long or contain a lower-case letter.
3442	'class-name': /\b[A-Z](?:[A-Z_\d]*[a-z]\w*)?\b/,
3443	'function': /\b[a-z_]\w*(?=\s*\()/i,
3444	'constant': /\b(?:[A-Z_]{2,}|k[A-Z][A-Za-z_]+)\b/,
3445
3446	// Operators are generic in Swift. Developers can even create new operators (e.g. +++).
3447	// https://docs.swift.org/swift-book/ReferenceManual/zzSummaryOfTheGrammar.html#ID481
3448	// This regex only supports ASCII operators.
3449	'operator': /[-+*/%=!<>&|^~?]+|\.[.\-+*/%=!<>&|^~?]+/,
3450	'punctuation': /[{}[\]();,.:\\]/
3451};
3452
3453Prism$1.languages.swift['string-literal'].forEach(function (rule) {
3454	rule.inside['interpolation'].inside = Prism$1.languages.swift;
3455});
3456
3457var prismTypescript = {};
3458
3459var hasRequiredPrismTypescript;
3460
3461function requirePrismTypescript () {
3462	if (hasRequiredPrismTypescript) return prismTypescript;
3463	hasRequiredPrismTypescript = 1;
3464	(function (Prism) {
3465
3466		Prism.languages.typescript = Prism.languages.extend('javascript', {
3467			'class-name': {
3468				pattern: /(\b(?:class|extends|implements|instanceof|interface|new|type)\s+)(?!keyof\b)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?:\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,
3469				lookbehind: true,
3470				greedy: true,
3471				inside: null // see below
3472			},
3473			'builtin': /\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/,
3474		});
3475
3476		// The keywords TypeScript adds to JavaScript
3477		Prism.languages.typescript.keyword.push(
3478			/\b(?:abstract|declare|is|keyof|readonly|require)\b/,
3479			// keywords that have to be followed by an identifier
3480			/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,
3481			// This is for `import type *, {}`
3482			/\btype\b(?=\s*(?:[\{*]|$))/
3483		);
3484
3485		// doesn't work with TS because TS is too complex
3486		delete Prism.languages.typescript['parameter'];
3487		delete Prism.languages.typescript['literal-property'];
3488
3489		// a version of typescript specifically for highlighting types
3490		var typeInside = Prism.languages.extend('typescript', {});
3491		delete typeInside['class-name'];
3492
3493		Prism.languages.typescript['class-name'].inside = typeInside;
3494
3495		Prism.languages.insertBefore('typescript', 'function', {
3496			'decorator': {
3497				pattern: /@[$\w\xA0-\uFFFF]+/,
3498				inside: {
3499					'at': {
3500						pattern: /^@/,
3501						alias: 'operator'
3502					},
3503					'function': /^[\s\S]+/
3504				}
3505			},
3506			'generic-function': {
3507				// e.g. foo<T extends "bar" | "baz">( ...
3508				pattern: /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,
3509				greedy: true,
3510				inside: {
3511					'function': /^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,
3512					'generic': {
3513						pattern: /<[\s\S]+/, // everything after the first <
3514						alias: 'class-name',
3515						inside: typeInside
3516					}
3517				}
3518			}
3519		});
3520
3521		Prism.languages.ts = Prism.languages.typescript;
3522
3523	}(Prism$1));
3524	return prismTypescript;
3525}
3526
3527requirePrismTypescript();
3528
3529var prismJava = {};
3530
3531var hasRequiredPrismJava;
3532
3533function requirePrismJava () {
3534	if (hasRequiredPrismJava) return prismJava;
3535	hasRequiredPrismJava = 1;
3536	(function (Prism) {
3537
3538		var keywords = /\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|non-sealed|null|open|opens|package|permits|private|protected|provides|public|record(?!\s*[(){}[\]<>=%~.:,;?+\-*/&|^])|requires|return|sealed|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/;
3539
3540		// full package (optional) + parent classes (optional)
3541		var classNamePrefix = /(?:[a-z]\w*\s*\.\s*)*(?:[A-Z]\w*\s*\.\s*)*/.source;
3542
3543		// based on the java naming conventions
3544		var className = {
3545			pattern: RegExp(/(^|[^\w.])/.source + classNamePrefix + /[A-Z](?:[\d_A-Z]*[a-z]\w*)?\b/.source),
3546			lookbehind: true,
3547			inside: {
3548				'namespace': {
3549					pattern: /^[a-z]\w*(?:\s*\.\s*[a-z]\w*)*(?:\s*\.)?/,
3550					inside: {
3551						'punctuation': /\./
3552					}
3553				},
3554				'punctuation': /\./
3555			}
3556		};
3557
3558		Prism.languages.java = Prism.languages.extend('clike', {
3559			'string': {
3560				pattern: /(^|[^\\])"(?:\\.|[^"\\\r\n])*"/,
3561				lookbehind: true,
3562				greedy: true
3563			},
3564			'class-name': [
3565				className,
3566				{
3567					// variables, parameters, and constructor references
3568					// this to support class names (or generic parameters) which do not contain a lower case letter (also works for methods)
3569					pattern: RegExp(/(^|[^\w.])/.source + classNamePrefix + /[A-Z]\w*(?=\s+\w+\s*[;,=()]|\s*(?:\[[\s,]*\]\s*)?::\s*new\b)/.source),
3570					lookbehind: true,
3571					inside: className.inside
3572				},
3573				{
vendor: 11,608 bytes, lines 3574-3934
3574					// class names based on keyword
3575					// this to support class names (or generic parameters) which do not contain a lower case letter (also works for methods)
3576					pattern: RegExp(/(\b(?:class|enum|extends|implements|instanceof|interface|new|record|throws)\s+)/.source + classNamePrefix + /[A-Z]\w*\b/.source),
3577					lookbehind: true,
3578					inside: className.inside
3579				}
3580			],
3581			'keyword': keywords,
3582			'function': [
3583				Prism.languages.clike.function,
3584				{
3585					pattern: /(::\s*)[a-z_]\w*/,
3586					lookbehind: true
3587				}
3588			],
3589			'number': /\b0b[01][01_]*L?\b|\b0x(?:\.[\da-f_p+-]+|[\da-f_]+(?:\.[\da-f_p+-]+)?)\b|(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfl]?/i,
3590			'operator': {
3591				pattern: /(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m,
3592				lookbehind: true
3593			},
3594			'constant': /\b[A-Z][A-Z_\d]+\b/
3595		});
3596
3597		Prism.languages.insertBefore('java', 'string', {
3598			'triple-quoted-string': {
3599				// http://openjdk.java.net/jeps/355#Description
3600				pattern: /"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/,
3601				greedy: true,
3602				alias: 'string'
3603			},
3604			'char': {
3605				pattern: /'(?:\\.|[^'\\\r\n]){1,6}'/,
3606				greedy: true
3607			}
3608		});
3609
3610		Prism.languages.insertBefore('java', 'class-name', {
3611			'annotation': {
3612				pattern: /(^|[^.])@\w+(?:\s*\.\s*\w+)*/,
3613				lookbehind: true,
3614				alias: 'punctuation'
3615			},
3616			'generics': {
3617				pattern: /<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&))*>)*>)*>)*>/,
3618				inside: {
3619					'class-name': className,
3620					'keyword': keywords,
3621					'punctuation': /[<>(),.:]/,
3622					'operator': /[?&|]/
3623				}
3624			},
3625			'import': [
3626				{
3627					pattern: RegExp(/(\bimport\s+)/.source + classNamePrefix + /(?:[A-Z]\w*|\*)(?=\s*;)/.source),
3628					lookbehind: true,
3629					inside: {
3630						'namespace': className.inside.namespace,
3631						'punctuation': /\./,
3632						'operator': /\*/,
3633						'class-name': /\w+/
3634					}
3635				},
3636				{
3637					pattern: RegExp(/(\bimport\s+static\s+)/.source + classNamePrefix + /(?:\w+|\*)(?=\s*;)/.source),
3638					lookbehind: true,
3639					alias: 'static',
3640					inside: {
3641						'namespace': className.inside.namespace,
3642						'static': /\b\w+$/,
3643						'punctuation': /\./,
3644						'operator': /\*/,
3645						'class-name': /\w+/
3646					}
3647				}
3648			],
3649			'namespace': {
3650				pattern: RegExp(
3651					/(\b(?:exports|import(?:\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\s+)(?!<keyword>)[a-z]\w*(?:\.[a-z]\w*)*\.?/
3652						.source.replace(/<keyword>/g, function () { return keywords.source; })),
3653				lookbehind: true,
3654				inside: {
3655					'punctuation': /\./,
3656				}
3657			}
3658		});
3659	}(Prism$1));
3660	return prismJava;
3661}
3662
3663requirePrismJava();
3664
3665var prismCpp = {};
3666
3667var hasRequiredPrismCpp;
3668
3669function requirePrismCpp () {
3670	if (hasRequiredPrismCpp) return prismCpp;
3671	hasRequiredPrismCpp = 1;
3672	(function (Prism) {
3673
3674		var keyword = /\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/;
3675		var modName = /\b(?!<keyword>)\w+(?:\s*\.\s*\w+)*\b/.source.replace(/<keyword>/g, function () { return keyword.source; });
3676
3677		Prism.languages.cpp = Prism.languages.extend('c', {
3678			'class-name': [
3679				{
3680					pattern: RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!<keyword>)\w+/.source
3681						.replace(/<keyword>/g, function () { return keyword.source; })),
3682					lookbehind: true
3683				},
3684				// This is intended to capture the class name of method implementations like:
3685				//   void foo::bar() const {}
3686				// However! The `foo` in the above example could also be a namespace, so we only capture the class name if
3687				// it starts with an uppercase letter. This approximation should give decent results.
3688				/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,
3689				// This will capture the class name before destructors like:
3690				//   Foo::~Foo() {}
3691				/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,
3692				// This also intends to capture the class name of method implementations but here the class has template
3693				// parameters, so it can't be a namespace (until C++ adds generic namespaces).
3694				/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/
3695			],
3696			'keyword': keyword,
3697			'number': {
3698				pattern: /(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,
3699				greedy: true
3700			},
3701			'operator': />>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,
3702			'boolean': /\b(?:false|true)\b/
3703		});
3704
3705		Prism.languages.insertBefore('cpp', 'string', {
3706			'module': {
3707				// https://en.cppreference.com/w/cpp/language/modules
3708				pattern: RegExp(
3709					/(\b(?:import|module)\s+)/.source +
3710					'(?:' +
3711					// header-name
3712					/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source +
3713					'|' +
3714					// module name or partition or both
3715					/<mod-name>(?:\s*:\s*<mod-name>)?|:\s*<mod-name>/.source.replace(/<mod-name>/g, function () { return modName; }) +
3716					')'
3717				),
3718				lookbehind: true,
3719				greedy: true,
3720				inside: {
3721					'string': /^[<"][\s\S]+/,
3722					'operator': /:/,
3723					'punctuation': /\./
3724				}
3725			},
3726			'raw-string': {
3727				pattern: /R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,
3728				alias: 'string',
3729				greedy: true
3730			}
3731		});
3732
3733		Prism.languages.insertBefore('cpp', 'keyword', {
3734			'generic-function': {
3735				pattern: /\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,
3736				inside: {
3737					'function': /^\w+/,
3738					'generic': {
3739						pattern: /<[\s\S]+/,
3740						alias: 'class-name',
3741						inside: Prism.languages.cpp
3742					}
3743				}
3744			}
3745		});
3746
3747		Prism.languages.insertBefore('cpp', 'operator', {
3748			'double-colon': {
3749				pattern: /::/,
3750				alias: 'punctuation'
3751			}
3752		});
3753
3754		Prism.languages.insertBefore('cpp', 'class-name', {
3755			// the base clause is an optional list of parent classes
3756			// https://en.cppreference.com/w/cpp/language/class
3757			'base-clause': {
3758				pattern: /(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,
3759				lookbehind: true,
3760				greedy: true,
3761				inside: Prism.languages.extend('cpp', {})
3762			}
3763		});
3764
3765		Prism.languages.insertBefore('inside', 'double-colon', {
3766			// All untokenized words that are not namespaces should be class names
3767			'class-name': /\b[a-z_]\w*\b(?!\s*::)/i
3768		}, Prism.languages.cpp['base-clause']);
3769
3770	}(Prism$1));
3771	return prismCpp;
3772}
3773
3774requirePrismCpp();
3775
3776(function (Prism) {
3777
3778	/**
3779	 * Returns the placeholder for the given language id and index.
3780	 *
3781	 * @param {string} language
3782	 * @param {string|number} index
3783	 * @returns {string}
3784	 */
3785	function getPlaceholder(language, index) {
3786		return '___' + language.toUpperCase() + index + '___';
3787	}
3788
3789	Object.defineProperties(Prism.languages['markup-templating'] = {}, {
3790		buildPlaceholders: {
3791			/**
3792			 * Tokenize all inline templating expressions matching `placeholderPattern`.
3793			 *
3794			 * If `replaceFilter` is provided, only matches of `placeholderPattern` for which `replaceFilter` returns
3795			 * `true` will be replaced.
3796			 *
3797			 * @param {object} env The environment of the `before-tokenize` hook.
3798			 * @param {string} language The language id.
3799			 * @param {RegExp} placeholderPattern The matches of this pattern will be replaced by placeholders.
3800			 * @param {(match: string) => boolean} [replaceFilter]
3801			 */
3802			value: function (env, language, placeholderPattern, replaceFilter) {
3803				if (env.language !== language) {
3804					return;
3805				}
3806
3807				var tokenStack = env.tokenStack = [];
3808
3809				env.code = env.code.replace(placeholderPattern, function (match) {
3810					if (typeof replaceFilter === 'function' && !replaceFilter(match)) {
3811						return match;
3812					}
3813					var i = tokenStack.length;
3814					var placeholder;
3815
3816					// Check for existing strings
3817					while (env.code.indexOf(placeholder = getPlaceholder(language, i)) !== -1) {
3818						++i;
3819					}
3820
3821					// Create a sparse array
3822					tokenStack[i] = match;
3823
3824					return placeholder;
3825				});
3826
3827				// Switch the grammar to markup
3828				env.grammar = Prism.languages.markup;
3829			}
3830		},
3831		tokenizePlaceholders: {
3832			/**
3833			 * Replace placeholders with proper tokens after tokenizing.
3834			 *
3835			 * @param {object} env The environment of the `after-tokenize` hook.
3836			 * @param {string} language The language id.
3837			 */
3838			value: function (env, language) {
3839				if (env.language !== language || !env.tokenStack) {
3840					return;
3841				}
3842
3843				// Switch the grammar back
3844				env.grammar = Prism.languages[language];
3845
3846				var j = 0;
3847				var keys = Object.keys(env.tokenStack);
3848
3849				function walkTokens(tokens) {
3850					for (var i = 0; i < tokens.length; i++) {
3851						// all placeholders are replaced already
3852						if (j >= keys.length) {
3853							break;
3854						}
3855
3856						var token = tokens[i];
3857						if (typeof token === 'string' || (token.content && typeof token.content === 'string')) {
3858							var k = keys[j];
3859							var t = env.tokenStack[k];
3860							var s = typeof token === 'string' ? token : token.content;
3861							var placeholder = getPlaceholder(language, k);
3862
3863							var index = s.indexOf(placeholder);
3864							if (index > -1) {
3865								++j;
3866
3867								var before = s.substring(0, index);
3868								var middle = new Prism.Token(language, Prism.tokenize(t, env.grammar), 'language-' + language, t);
3869								var after = s.substring(index + placeholder.length);
3870
3871								var replacement = [];
3872								if (before) {
3873									replacement.push.apply(replacement, walkTokens([before]));
3874								}
3875								replacement.push(middle);
3876								if (after) {
3877									replacement.push.apply(replacement, walkTokens([after]));
3878								}
3879
3880								if (typeof token === 'string') {
3881									tokens.splice.apply(tokens, [i, 1].concat(replacement));
3882								} else {
3883									token.content = replacement;
3884								}
3885							}
3886						} else if (token.content /* && typeof token.content !== 'string' */) {
3887							walkTokens(token.content);
3888						}
3889					}
3890
3891					return tokens;
3892				}
3893
3894				walkTokens(env.tokens);
3895			}
3896		}
3897	});
3898
3899}(Prism$1));
3900
3901var prismRuby = {};
3902
3903var hasRequiredPrismRuby;
3904
3905function requirePrismRuby () {
3906	if (hasRequiredPrismRuby) return prismRuby;
3907	hasRequiredPrismRuby = 1;
3908	(function (Prism) {
3909		Prism.languages.ruby = Prism.languages.extend('clike', {
3910			'comment': {
3911				pattern: /#.*|^=begin\s[\s\S]*?^=end/m,
3912				greedy: true
3913			},
3914			'class-name': {
3915				pattern: /(\b(?:class|module)\s+|\bcatch\s+\()[\w.\\]+|\b[A-Z_]\w*(?=\s*\.\s*new\b)/,
3916				lookbehind: true,
3917				inside: {
3918					'punctuation': /[.\\]/
3919				}
3920			},
3921			'keyword': /\b(?:BEGIN|END|alias|and|begin|break|case|class|def|define_method|defined|do|each|else|elsif|end|ensure|extend|for|if|in|include|module|new|next|nil|not|or|prepend|private|protected|public|raise|redo|require|rescue|retry|return|self|super|then|throw|undef|unless|until|when|while|yield)\b/,
3922			'operator': /\.{2,3}|&\.|===|<?=>|[!=]?~|(?:&&|\|\||<<|>>|\*\*|[+\-*/%<>!^&|=])=?|[?:]/,
3923			'punctuation': /[(){}[\].,;]/,
3924		});
3925
3926		Prism.languages.insertBefore('ruby', 'operator', {
3927			'double-colon': {
3928				pattern: /::/,
3929				alias: 'punctuation'
3930			},
3931		});
3932
3933		var interpolation = {
3934			pattern: /((?:^|[^\\])(?:\\{2}
3934)*)#\{(?:[^{}]|\{[^{}]*\})*\}/,
3935			lookbehind: true,
3936			inside: {
3937				'content': {
3938					pattern: /^(#\{)[\s\S]+(?=\}$)/,
3939					lookbehind: true,
3940					inside: Prism.languages.ruby
3941				},
3942				'delimiter': {
3943					pattern: /^#\{|\}$/,
3944					alias: 'punctuation'
3945				}
3946			}
3947		};
3948
3949		delete Prism.languages.ruby.function;
3950
3951		var percentExpression = '(?:' + [
3952			/([^a-zA-Z0-9\s{(\[<=])(?:(?!\1)[^\\]|\\[\s\S])*\1/.source,
3953			/\((?:[^()\\]|\\[\s\S]|\((?:[^()\\]|\\[\s\S])*\))*\)/.source,
3954			/\{(?:[^{}\\]|\\[\s\S]|\{(?:[^{}\\]|\\[\s\S])*\})*\}/.source,
3955			/\[(?:[^\[\]\\]|\\[\s\S]|\[(?:[^\[\]\\]|\\[\s\S])*\])*\]/.source,
3956			/<(?:[^<>\\]|\\[\s\S]|<(?:[^<>\\]|\\[\s\S])*>)*>/.source
3957		].join('|') + ')';
3958
3959		var symbolName = /(?:"(?:\\.|[^"\\\r\n])*"|(?:\b[a-zA-Z_]\w*|[^\s\0-\x7F]+)[?!]?|\$.)/.source;
3960
3961		Prism.languages.insertBefore('ruby', 'keyword', {
3962			'regex-literal': [
3963				{
3964					pattern: RegExp(/%r/.source + percentExpression + /[egimnosux]{0,6}/.source),
3965					greedy: true,
3966					inside: {
3967						'interpolation': interpolation,
3968						'regex': /[\s\S]+/
3969					}
3970				},
3971				{
3972					pattern: /(^|[^/])\/(?!\/)(?:\[[^\r\n\]]+\]|\\.|[^[/\\\r\n])+\/[egimnosux]{0,6}(?=\s*(?:$|[\r\n,.;})#]))/,
3973					lookbehind: true,
3974					greedy: true,
3975					inside: {
3976						'interpolation': interpolation,
3977						'regex': /[\s\S]+/
3978					}
3979				}
3980			],
3981			'variable': /[@$]+[a-zA-Z_]\w*(?:[?!]|\b)/,
3982			'symbol': [
3983				{
3984					pattern: RegExp(/(^|[^:]):/.source + symbolName),
3985					lookbehind: true,
3986					greedy: true
3987				},
3988				{
3989					pattern: RegExp(/([\r\n{(,][ \t]*)/.source + symbolName + /(?=:(?!:))/.source),
3990					lookbehind: true,
3991					greedy: true
3992				},
3993			],
3994			'method-definition': {
3995				pattern: /(\bdef\s+)\w+(?:\s*\.\s*\w+)?/,
3996				lookbehind: true,
3997				inside: {
3998					'function': /\b\w+$/,
3999					'keyword': /^self\b/,
4000					'class-name': /^\w+/,
4001					'punctuation': /\./
4002				}
4003			}
4004		});
4005
4006		Prism.languages.insertBefore('ruby', 'string', {
4007			'string-literal': [
4008				{
4009					pattern: RegExp(/%[qQiIwWs]?/.source + percentExpression),
4010					greedy: true,
4011					inside: {
4012						'interpolation': interpolation,
4013						'string': /[\s\S]+/
4014					}
4015				},
4016				{
4017					pattern: /("|')(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|(?!\1)[^\\#\r\n])*\1/,
4018					greedy: true,
4019					inside: {
4020						'interpolation': interpolation,
4021						'string': /[\s\S]+/
4022					}
4023				},
4024				{
4025					pattern: /<<[-~]?([a-z_]\w*)[\r\n](?:.*[\r\n])*?[\t ]*\1/i,
4026					alias: 'heredoc-string',
4027					greedy: true,
4028					inside: {
4029						'delimiter': {
4030							pattern: /^<<[-~]?[a-z_]\w*|\b[a-z_]\w*$/i,
4031							inside: {
4032								'symbol': /\b\w+/,
4033								'punctuation': /^<<[-~]?/
4034							}
4035						},
4036						'interpolation': interpolation,
4037						'string': /[\s\S]+/
4038					}
4039				},
4040				{
4041					pattern: /<<[-~]?'([a-z_]\w*)'[\r\n](?:.*[\r\n])*?[\t ]*\1/i,
4042					alias: 'heredoc-string',
4043					greedy: true,
4044					inside: {
4045						'delimiter': {
4046							pattern: /^<<[-~]?'[a-z_]\w*'|\b[a-z_]\w*$/i,
4047							inside: {
4048								'symbol': /\b\w+/,
4049								'punctuation': /^<<[-~]?'|'$/,
4050							}
4051						},
4052						'string': /[\s\S]+/
4053					}
4054				}
4055			],
4056			'command-literal': [
4057				{
4058					pattern: RegExp(/%x/.source + percentExpression),
4059					greedy: true,
4060					inside: {
4061						'interpolation': interpolation,
4062						'command': {
4063							pattern: /[\s\S]+/,
4064							alias: 'string'
4065						}
4066					}
4067				},
4068				{
4069					pattern: /`(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|[^\\`#\r\n])*`/,
4070					greedy: true,
4071					inside: {
4072						'interpolation': interpolation,
4073						'command': {
4074							pattern: /[\s\S]+/,
4075							alias: 'string'
4076						}
4077					}
4078				}
4079			]
4080		});
4081
4082		delete Prism.languages.ruby.string;
4083
4084		Prism.languages.insertBefore('ruby', 'number', {
4085			'builtin': /\b(?:Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Fixnum|Float|Hash|IO|Integer|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|Stat|String|Struct|Symbol|TMS|Thread|ThreadGroup|Time|TrueClass)\b/,
4086			'constant': /\b[A-Z][A-Z0-9_]*(?:[?!]|\b)/
4087		});
4088
4089		Prism.languages.rb = Prism.languages.ruby;
4090	}(Prism$1));
4091	return prismRuby;
4092}
4093
4094requirePrismRuby();
4095
4096var prismPhp = {};
4097
4098var hasRequiredPrismPhp;
4099
4100function requirePrismPhp () {
4101	if (hasRequiredPrismPhp) return prismPhp;
4102	hasRequiredPrismPhp = 1;
4103	(function (Prism) {
4104		var comment = /\/\*[\s\S]*?\*\/|\/\/.*|#(?!\[).*/;
4105		var constant = [
4106			{
4107				pattern: /\b(?:false|true)\b/i,
4108				alias: 'boolean'
4109			},
4110			{
4111				pattern: /(::\s*)\b[a-z_]\w*\b(?!\s*\()/i,
4112				greedy: true,
4113				lookbehind: true,
4114			},
4115			{
4116				pattern: /(\b(?:case|const)\s+)\b[a-z_]\w*(?=\s*[;=])/i,
4117				greedy: true,
4118				lookbehind: true,
4119			},
4120			/\b(?:null)\b/i,
4121			/\b[A-Z_][A-Z0-9_]*\b(?!\s*\()/,
4122		];
4123		var number = /\b0b[01]+(?:_[01]+)*\b|\b0o[0-7]+(?:_[0-7]+)*\b|\b0x[\da-f]+(?:_[\da-f]+)*\b|(?:\b\d+(?:_\d+)*\.?(?:\d+(?:_\d+)*)?|\B\.\d+)(?:e[+-]?\d+)?/i;
4124		var operator = /<?=>|\?\?=?|\.{3}|\??->|[!=]=?=?|::|\*\*=?|--|\+\+|&&|\|\||<<|>>|[?~]|[/^|%*&<>.+-]=?/;
4125		var punctuation = /[{}\[\](),:;]/;
4126
4127		Prism.languages.php = {
4128			'delimiter': {
4129				pattern: /\?>$|^<\?(?:php(?=\s)|=)?/i,
vendor: 10,661 bytes, lines 4130-4477
4130				alias: 'important'
4131			},
4132			'comment': comment,
4133			'variable': /\$+(?:\w+\b|(?=\{))/,
4134			'package': {
4135				pattern: /(namespace\s+|use\s+(?:function\s+)?)(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,
4136				lookbehind: true,
4137				inside: {
4138					'punctuation': /\\/
4139				}
4140			},
4141			'class-name-definition': {
4142				pattern: /(\b(?:class|enum|interface|trait)\s+)\b[a-z_]\w*(?!\\)\b/i,
4143				lookbehind: true,
4144				alias: 'class-name'
4145			},
4146			'function-definition': {
4147				pattern: /(\bfunction\s+)[a-z_]\w*(?=\s*\()/i,
4148				lookbehind: true,
4149				alias: 'function'
4150			},
4151			'keyword': [
4152				{
4153					pattern: /(\(\s*)\b(?:array|bool|boolean|float|int|integer|object|string)\b(?=\s*\))/i,
4154					alias: 'type-casting',
4155					greedy: true,
4156					lookbehind: true
4157				},
4158				{
4159					pattern: /([(,?]\s*)\b(?:array(?!\s*\()|bool|callable|(?:false|null)(?=\s*\|)|float|int|iterable|mixed|object|self|static|string)\b(?=\s*\$)/i,
4160					alias: 'type-hint',
4161					greedy: true,
4162					lookbehind: true
4163				},
4164				{
4165					pattern: /(\)\s*:\s*(?:\?\s*)?)\b(?:array(?!\s*\()|bool|callable|(?:false|null)(?=\s*\|)|float|int|iterable|mixed|never|object|self|static|string|void)\b/i,
4166					alias: 'return-type',
4167					greedy: true,
4168					lookbehind: true
4169				},
4170				{
4171					pattern: /\b(?:array(?!\s*\()|bool|float|int|iterable|mixed|object|string|void)\b/i,
4172					alias: 'type-declaration',
4173					greedy: true
4174				},
4175				{
4176					pattern: /(\|\s*)(?:false|null)\b|\b(?:false|null)(?=\s*\|)/i,
4177					alias: 'type-declaration',
4178					greedy: true,
4179					lookbehind: true
4180				},
4181				{
4182					pattern: /\b(?:parent|self|static)(?=\s*::)/i,
4183					alias: 'static-context',
4184					greedy: true
4185				},
4186				{
4187					// yield from
4188					pattern: /(\byield\s+)from\b/i,
4189					lookbehind: true
4190				},
4191				// `class` is always a keyword unlike other keywords
4192				/\bclass\b/i,
4193				{
4194					// https://www.php.net/manual/en/reserved.keywords.php
4195					//
4196					// keywords cannot be preceded by "->"
4197					// the complex lookbehind means `(?<!(?:->|::)\s*)`
4198					pattern: /((?:^|[^\s>:]|(?:^|[^-])>|(?:^|[^:]):)\s*)\b(?:abstract|and|array|as|break|callable|case|catch|clone|const|continue|declare|default|die|do|echo|else|elseif|empty|enddeclare|endfor|endforeach|endif|endswitch|endwhile|enum|eval|exit|extends|final|finally|fn|for|foreach|function|global|goto|if|implements|include|include_once|instanceof|insteadof|interface|isset|list|match|namespace|never|new|or|parent|print|private|protected|public|readonly|require|require_once|return|self|static|switch|throw|trait|try|unset|use|var|while|xor|yield|__halt_compiler)\b/i,
4199					lookbehind: true
4200				}
4201			],
4202			'argument-name': {
4203				pattern: /([(,]\s*)\b[a-z_]\w*(?=\s*:(?!:))/i,
4204				lookbehind: true
4205			},
4206			'class-name': [
4207				{
4208					pattern: /(\b(?:extends|implements|instanceof|new(?!\s+self|\s+static))\s+|\bcatch\s*\()\b[a-z_]\w*(?!\\)\b/i,
4209					greedy: true,
4210					lookbehind: true
4211				},
4212				{
4213					pattern: /(\|\s*)\b[a-z_]\w*(?!\\)\b/i,
4214					greedy: true,
4215					lookbehind: true
4216				},
4217				{
4218					pattern: /\b[a-z_]\w*(?!\\)\b(?=\s*\|)/i,
4219					greedy: true
4220				},
4221				{
4222					pattern: /(\|\s*)(?:\\?\b[a-z_]\w*)+\b/i,
4223					alias: 'class-name-fully-qualified',
4224					greedy: true,
4225					lookbehind: true,
4226					inside: {
4227						'punctuation': /\\/
4228					}
4229				},
4230				{
4231					pattern: /(?:\\?\b[a-z_]\w*)+\b(?=\s*\|)/i,
4232					alias: 'class-name-fully-qualified',
4233					greedy: true,
4234					inside: {
4235						'punctuation': /\\/
4236					}
4237				},
4238				{
4239					pattern: /(\b(?:extends|implements|instanceof|new(?!\s+self\b|\s+static\b))\s+|\bcatch\s*\()(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,
4240					alias: 'class-name-fully-qualified',
4241					greedy: true,
4242					lookbehind: true,
4243					inside: {
4244						'punctuation': /\\/
4245					}
4246				},
4247				{
4248					pattern: /\b[a-z_]\w*(?=\s*\$)/i,
4249					alias: 'type-declaration',
4250					greedy: true
4251				},
4252				{
4253					pattern: /(?:\\?\b[a-z_]\w*)+(?=\s*\$)/i,
4254					alias: ['class-name-fully-qualified', 'type-declaration'],
4255					greedy: true,
4256					inside: {
4257						'punctuation': /\\/
4258					}
4259				},
4260				{
4261					pattern: /\b[a-z_]\w*(?=\s*::)/i,
4262					alias: 'static-context',
4263					greedy: true
4264				},
4265				{
4266					pattern: /(?:\\?\b[a-z_]\w*)+(?=\s*::)/i,
4267					alias: ['class-name-fully-qualified', 'static-context'],
4268					greedy: true,
4269					inside: {
4270						'punctuation': /\\/
4271					}
4272				},
4273				{
4274					pattern: /([(,?]\s*)[a-z_]\w*(?=\s*\$)/i,
4275					alias: 'type-hint',
4276					greedy: true,
4277					lookbehind: true
4278				},
4279				{
4280					pattern: /([(,?]\s*)(?:\\?\b[a-z_]\w*)+(?=\s*\$)/i,
4281					alias: ['class-name-fully-qualified', 'type-hint'],
4282					greedy: true,
4283					lookbehind: true,
4284					inside: {
4285						'punctuation': /\\/
4286					}
4287				},
4288				{
4289					pattern: /(\)\s*:\s*(?:\?\s*)?)\b[a-z_]\w*(?!\\)\b/i,
4290					alias: 'return-type',
4291					greedy: true,
4292					lookbehind: true
4293				},
4294				{
4295					pattern: /(\)\s*:\s*(?:\?\s*)?)(?:\\?\b[a-z_]\w*)+\b(?!\\)/i,
4296					alias: ['class-name-fully-qualified', 'return-type'],
4297					greedy: true,
4298					lookbehind: true,
4299					inside: {
4300						'punctuation': /\\/
4301					}
4302				}
4303			],
4304			'constant': constant,
4305			'function': {
4306				pattern: /(^|[^\\\w])\\?[a-z_](?:[\w\\]*\w)?(?=\s*\()/i,
4307				lookbehind: true,
4308				inside: {
4309					'punctuation': /\\/
4310				}
4311			},
4312			'property': {
4313				pattern: /(->\s*)\w+/,
4314				lookbehind: true
4315			},
4316			'number': number,
4317			'operator': operator,
4318			'punctuation': punctuation
4319		};
4320
4321		var string_interpolation = {
4322			pattern: /\{\$(?:\{(?:\{[^{}]+\}|[^{}]+)\}|[^{}])+\}|(^|[^\\{])\$+(?:\w+(?:\[[^\r\n\[\]]+\]|->\w+)?)/,
4323			lookbehind: true,
4324			inside: Prism.languages.php
4325		};
4326
4327		var string = [
4328			{
4329				pattern: /<<<'([^']+)'[\r\n](?:.*[\r\n])*?\1;/,
4330				alias: 'nowdoc-string',
4331				greedy: true,
4332				inside: {
4333					'delimiter': {
4334						pattern: /^<<<'[^']+'|[a-z_]\w*;$/i,
4335						alias: 'symbol',
4336						inside: {
4337							'punctuation': /^<<<'?|[';]$/
4338						}
4339					}
4340				}
4341			},
4342			{
4343				pattern: /<<<(?:"([^"]+)"[\r\n](?:.*[\r\n])*?\1;|([a-z_]\w*)[\r\n](?:.*[\r\n])*?\2;)/i,
4344				alias: 'heredoc-string',
4345				greedy: true,
4346				inside: {
4347					'delimiter': {
4348						pattern: /^<<<(?:"[^"]+"|[a-z_]\w*)|[a-z_]\w*;$/i,
4349						alias: 'symbol',
4350						inside: {
4351							'punctuation': /^<<<"?|[";]$/
4352						}
4353					},
4354					'interpolation': string_interpolation
4355				}
4356			},
4357			{
4358				pattern: /`(?:\\[\s\S]|[^\\`])*`/,
4359				alias: 'backtick-quoted-string',
4360				greedy: true
4361			},
4362			{
4363				pattern: /'(?:\\[\s\S]|[^\\'])*'/,
4364				alias: 'single-quoted-string',
4365				greedy: true
4366			},
4367			{
4368				pattern: /"(?:\\[\s\S]|[^\\"])*"/,
4369				alias: 'double-quoted-string',
4370				greedy: true,
4371				inside: {
4372					'interpolation': string_interpolation
4373				}
4374			}
4375		];
4376
4377		Prism.languages.insertBefore('php', 'variable', {
4378			'string': string,
4379			'attribute': {
4380				pattern: /#\[(?:[^"'\/#]|\/(?![*/])|\/\/.*$|#(?!\[).*$|\/\*(?:[^*]|\*(?!\/))*\*\/|"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*')+\](?=\s*[a-z$#])/im,
4381				greedy: true,
4382				inside: {
4383					'attribute-content': {
4384						pattern: /^(#\[)[\s\S]+(?=\]$)/,
4385						lookbehind: true,
4386						// inside can appear subset of php
4387						inside: {
4388							'comment': comment,
4389							'string': string,
4390							'attribute-class-name': [
4391								{
4392									pattern: /([^:]|^)\b[a-z_]\w*(?!\\)\b/i,
4393									alias: 'class-name',
4394									greedy: true,
4395									lookbehind: true
4396								},
4397								{
4398									pattern: /([^:]|^)(?:\\?\b[a-z_]\w*)+/i,
4399									alias: [
4400										'class-name',
4401										'class-name-fully-qualified'
4402									],
4403									greedy: true,
4404									lookbehind: true,
4405									inside: {
4406										'punctuation': /\\/
4407									}
4408								}
4409							],
4410							'constant': constant,
4411							'number': number,
4412							'operator': operator,
4413							'punctuation': punctuation
4414						}
4415					},
4416					'delimiter': {
4417						pattern: /^#\[|\]$/,
4418						alias: 'punctuation'
4419					}
4420				}
4421			},
4422		});
4423
4424		Prism.hooks.add('before-tokenize', function (env) {
4425			if (!/<\?/.test(env.code)) {
4426				return;
4427			}
4428
4429			var phpPattern = /<\?(?:[^"'/#]|\/(?![*/])|("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|(?:\/\/|#(?!\[))(?:[^?\n\r]|\?(?!>))*(?=$|\?>|[\r\n])|#\[|\/\*(?:[^*]|\*(?!\/))*(?:\*\/|$))*?(?:\?>|$)/g;
4430			Prism.languages['markup-templating'].buildPlaceholders(env, 'php', phpPattern);
4431		});
4432
4433		Prism.hooks.add('after-tokenize', function (env) {
4434			Prism.languages['markup-templating'].tokenizePlaceholders(env, 'php');
4435		});
4436
4437	}(Prism$1));
4438	return prismPhp;
4439}
4440
4441requirePrismPhp();
4442
4443Prism$1.languages.go = Prism$1.languages.extend('clike', {
4444	'string': {
4445		pattern: /(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,
4446		lookbehind: true,
4447		greedy: true
4448	},
4449	'keyword': /\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,
4450	'boolean': /\b(?:_|false|iota|nil|true)\b/,
4451	'number': [
4452		// binary and octal integers
4453		/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,
4454		// hexadecimal integers and floats
4455		/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,
4456		// decimal integers and floats
4457		/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i
4458	],
4459	'operator': /[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,
4460	'builtin': /\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/
4461});
4462
4463Prism$1.languages.insertBefore('go', 'string', {
4464	'char': {
4465		pattern: /'(?:\\.|[^'\\\r\n]){0,10}'/,
4466		greedy: true
4467	}
4468});
4469
4470delete Prism$1.languages.go['class-name'];
4471
4472(function (Prism) {
4473	// $ set | grep '^[A-Z][^[:space:]]*=' | cut -d= -f1 | tr '\n' '|'
4474	// + LC_ALL, RANDOM, REPLY, SECONDS.
4475	// + make sure PS1..4 are here as they are not always set,
4476	// - some useless things.
4477	var envVars = '\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_
4477CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b';
4478
4479	var commandAfterHeredoc = {
4480		pattern: /(^(["']?)\w+\2)[ \t]+\S.*/,
4481		lookbehind: true,
4482		alias: 'punctuation', // this looks reasonably well in all themes
4483		inside: null // see below
4484	};
4485
4486	var insideString = {
4487		'bash': commandAfterHeredoc,
4488		'environment': {
4489			pattern: RegExp('\\$' + envVars),
4490			alias: 'constant'
4491		},
4492		'variable': [
4493			// [0]: Arithmetic Environment
4494			{
4495				pattern: /\$?\(\([\s\S]+?\)\)/,
4496				greedy: true,
4497				inside: {
4498					// If there is a $ sign at the beginning highlight $(( and )) as variable
4499					'variable': [
4500						{
4501							pattern: /(^\$\(\([\s\S]+)\)\)/,
4502							lookbehind: true
4503						},
4504						/^\$\(\(/
4505					],
4506					'number': /\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,
4507					// Operators according to https://www.gnu.org/software/bash/manual/bashref.html#Shell-Arithmetic
4508					'operator': /--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/,
4509					// If there is no $ sign at the beginning highlight (( and )) as punctuation
4510					'punctuation': /\(\(?|\)\)?|,|;/
4511				}
4512			},
4513			// [1]: Command Substitution
4514			{
4515				pattern: /\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,
4516				greedy: true,
4517				inside: {
4518					'variable': /^\$\(|^`|\)$|`$/
4519				}
4520			},
4521			// [2]: Brace expansion
4522			{
4523				pattern: /\$\{[^}]+\}/,
4524				greedy: true,
4525				inside: {
4526					'operator': /:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,
4527					'punctuation': /[\[\]]/,
4528					'environment': {
4529						pattern: RegExp('(\\{)' + envVars),
4530						lookbehind: true,
4531						alias: 'constant'
4532					}
4533				}
4534			},
4535			/\$(?:\w+|[#?*!@$])/
4536		],
4537		// Escape sequences from echo and printf's manuals, and escaped quotes.
4538		'entity': /\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{1,2})/
4539	};
4540
4541	Prism.languages.bash = {
4542		'shebang': {
4543			pattern: /^#!\s*\/.*/,
4544			alias: 'important'
4545		},
4546		'comment': {
4547			pattern: /(^|[^"{\\$])#.*/,
4548			lookbehind: true
4549		},
4550		'function-name': [
4551			// a) function foo {
4552			// b) foo() {
4553			// c) function foo() {
4554			// but not “foo {”
4555			{
4556				// a) and c)
4557				pattern: /(\bfunction\s+)[\w-]+(?=(?:\s*\(?:\s*\))?\s*\{)/,
4558				lookbehind: true,
4559				alias: 'function'
4560			},
4561			{
4562				// b)
4563				pattern: /\b[\w-]+(?=\s*\(\s*\)\s*\{)/,
4564				alias: 'function'
4565			}
4566		],
4567		// Highlight variable names as variables in for and select beginnings.
4568		'for-or-select': {
4569			pattern: /(\b(?:for|select)\s+)\w+(?=\s+in\s)/,
4570			alias: 'variable',
4571			lookbehind: true
4572		},
4573		// Highlight variable names as variables in the left-hand part
4574		// of assignments (“=” and “+=”).
4575		'assign-left': {
4576			pattern: /(^|[\s;|&]|[<>]\()\w+(?:\.\w+)*(?=\+?=)/,
4577			inside: {
4578				'environment': {
4579					pattern: RegExp('(^|[\\s;|&]|[<>]\\()' + envVars),
4580					lookbehind: true,
4581					alias: 'constant'
4582				}
4583			},
4584			alias: 'variable',
4585			lookbehind: true
4586		},
4587		// Highlight parameter names as variables
4588		'parameter': {
4589			pattern: /(^|\s)-{1,2}(?:\w+:[+-]?)?\w+(?:\.\w+)*(?=[=\s]|$)/,
4590			alias: 'variable',
4591			lookbehind: true
4592		},
4593		'string': [
4594			// Support for Here-documents https://en.wikipedia.org/wiki/Here_document
4595			{
4596				pattern: /((?:^|[^<])<<-?\s*)(\w+)\s[\s\S]*?(?:\r?\n|\r)\2/,
4597				lookbehind: true,
4598				greedy: true,
4599				inside: insideString
4600			},
4601			// Here-document with quotes around the tag
4602			// → No expansion (so no “inside”).
4603			{
4604				pattern: /((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,
4605				lookbehind: true,
4606				greedy: true,
4607				inside: {
4608					'bash': commandAfterHeredoc
4609				}
4610			},
4611			// “Normal” string
4612			{
4613				// https://www.gnu.org/software/bash/manual/html_node/Double-Quotes.html
4614				pattern: /(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/,
4615				lookbehind: true,
4616				greedy: true,
4617				inside: insideString
4618			},
4619			{
4620				// https://www.gnu.org/software/bash/manual/html_node/Single-Quotes.html
4621				pattern: /(^|[^$\\])'[^']*'/,
4622				lookbehind: true,
4623				greedy: true
4624			},
4625			{
4626				// https://www.gnu.org/software/bash/manual/html_node/ANSI_002dC-Quoting.html
4627				pattern: /\$'(?:[^'\\]|\\[\s\S])*'/,
4628				greedy: true,
4629				inside: {
4630					'entity': insideString.entity
4631				}
4632			}
4633		],
4634		'environment': {
4635			pattern: RegExp('\\$?' + envVars),
4636			alias: 'constant'
4637		},
4638		'variable': insideString.variable,
4639		'function': {
4640			pattern: /(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cargo|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|docker|docker-compose|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|
4640ifup|import|install|ip|java|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|node|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|podman|podman-compose|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|sysctl|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,
4641			lookbehind: true
4642		},
4643		'keyword': {
4644			pattern: /(^|[\s;|&]|[<>]\()(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)(?=$|[)\s;|&])/,
4645			lookbehind: true
4646		},
4647		// https://www.gnu.org/software/bash/manual/html_node/Shell-Builtin-Commands.html
4648		'builtin': {
4649			pattern: /(^|[\s;|&]|[<>]\()(?:\.|:|alias|bind|break|builtin|caller|cd|command|continue|declare|echo|enable|eval|exec|exit|export|getopts|hash|help|let|local|logout|mapfile|printf|pwd|read|readarray|readonly|return|set|shift|shopt|source|test|times|trap|type|typeset|ulimit|umask|unalias|unset)(?=$|[)\s;|&])/,
4650			lookbehind: true,
4651			// Alias added to make those easier to distinguish from strings.
4652			alias: 'class-name'
4653		},
4654		'boolean': {
4655			pattern: /(^|[\s;|&]|[<>]\()(?:false|true)(?=$|[)\s;|&])/,
4656			lookbehind: true
4657		},
4658		'file-descriptor': {
4659			pattern: /\B&\d\b/,
4660			alias: 'important'
4661		},
4662		'operator': {
4663			// Lots of redirections here, but not just that.
4664			pattern: /\d?<>|>\||\+=|=[=~]?|!=?|<<[<-]?|[&\d]?>>|\d[<>]&?|[<>][&=]?|&[>&]?|\|[&|]?/,
4665			inside: {
4666				'file-descriptor': {
4667					pattern: /^\d/,
4668					alias: 'important'
4669				}
4670			}
4671		},
4672		'punctuation': /\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,
4673		'number': {
4674			pattern: /(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,
4675			lookbehind: true
4676		}
4677	};
4678
4679	commandAfterHeredoc.inside = Prism.languages.bash;
4680
4681	/* Patterns in command substitution. */
4682	var toBeCopied = [
4683		'comment',
4684		'function-name',
4685		'for-or-select',
4686		'assign-left',
4687		'parameter',
4688		'string',
4689		'environment',
4690		'function',
4691		'keyword',
4692		'builtin',
4693		'boolean',
4694		'file-descriptor',
4695		'operator',
4696		'punctuation',
4697		'number'
4698	];
4699	var inside = insideString.variable[1].inside;
4700	for (var i = 0; i < toBeCopied.length; i++) {
4701		inside[toBeCopied[i]] = Prism.languages.bash[toBeCopied[i]];
4702	}
4703
4704	Prism.languages.sh = Prism.languages.bash;
4705	Prism.languages.shell = Prism.languages.bash;
4706}(Prism$1));
4707
4708// https://www.json.org/json-en.html
4709Prism$1.languages.json = {
4710	'property': {
4711		pattern: /(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,
4712		lookbehind: true,
4713		greedy: true
4714	},
4715	'string': {
4716		pattern: /(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,
4717		lookbehind: true,
4718		greedy: true
4719	},
4720	'comment': {
4721		pattern: /\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,
4722		greedy: true
4723	},
4724	'number': /-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,
4725	'punctuation': /[{}[\],]/,
4726	'operator': /:/,
4727	'boolean': /\b(?:false|true)\b/,
4728	'null': {
4729		pattern: /\bnull\b/,
4730		alias: 'keyword'
4731	}
4732};
4733
4734Prism$1.languages.webmanifest = Prism$1.languages.json;
4735
4736(function (Prism) {
4737	Prism.languages.kotlin = Prism.languages.extend('clike', {
4738		'keyword': {
4739			// The lookbehind prevents wrong highlighting of e.g. kotlin.properties.get
4740			pattern: /(^|[^.])\b(?:abstract|actual|annotation|as|break|by|catch|class|companion|const|constructor|continue|crossinline|data|do|dynamic|else|enum|expect|external|final|finally|for|fun|get|if|import|in|infix|init|inline|inner|interface|internal|is|lateinit|noinline|null|object|open|operator|out|override|package|private|protected|public|reified|return|sealed|set|super|suspend|tailrec|this|throw|to|try|typealias|val|var|vararg|when|where|while)\b/,
4741			lookbehind: true
4742		},
4743		'function': [
4744			{
4745				pattern: /(?:`[^\r\n`]+`|\b\w+)(?=\s*\()/,
4746				greedy: true
4747			},
4748			{
4749				pattern: /(\.)(?:`[^\r\n`]+`|\w+)(?=\s*\{)/,
4750				lookbehind: true,
4751				greedy: true
4752			}
4753		],
4754		'number': /\b(?:0[xX][\da-fA-F]+(?:_[\da-fA-F]+)*|0[bB][01]+(?:_[01]+)*|\d+(?:_\d+)*(?
4754:\.\d+(?:_\d+)*)?(?:[eE][+-]?\d+(?:_\d+)*)?[fFL]?)\b/,
4755		'operator': /\+[+=]?|-[-=>]?|==?=?|!(?:!|==?)?|[\/*%<>]=?|[?:]:?|\.\.|&&|\|\||\b(?:and|inv|or|shl|shr|ushr|xor)\b/
4756	});
4757
4758	delete Prism.languages.kotlin['class-name'];
4759
4760	var interpolationInside = {
4761		'interpolation-punctuation': {
4762			pattern: /^\$\{?|\}$/,
4763			alias: 'punctuation'
4764		},
4765		'expression': {
4766			pattern: /[\s\S]+/,
4767			inside: Prism.languages.kotlin
4768		}
4769	};
4770
4771	Prism.languages.insertBefore('kotlin', 'string', {
4772		// https://kotlinlang.org/spec/expressions.html#string-interpolation-expressions
4773		'string-literal': [
4774			{
4775				pattern: /"""(?:[^$]|\$(?:(?!\{)|\{[^{}]*\}))*?"""/,
4776				alias: 'multiline',
4777				inside: {
4778					'interpolation': {
4779						pattern: /\$(?:[a-z_]\w*|\{[^{}]*\})/i,
4780						inside: interpolationInside
4781					},
4782					'string': /[\s\S]+/
4783				}
4784			},
4785			{
4786				pattern: /"(?:[^"\\\r\n$]|\\.|\$(?:(?!\{)|\{[^{}]*\}))*"/,
4787				alias: 'singleline',
4788				inside: {
4789					'interpolation': {
4790						pattern: /((?:^|[^\\])(?:\\{2})*)\$(?:[a-z_]\w*|\{[^{}]*\})/i,
4791						lookbehind: true,
4792						inside: interpolationInside
4793					},
4794					'string': /[\s\S]+/
4795				}
4796			}
4797		],
4798		'char': {
4799			// https://kotlinlang.org/spec/expressions.html#character-literals
4800			pattern: /'(?:[^'\\\r\n]|\\(?:.|u[a-fA-F0-9]{0,4}))'/,
4801			greedy: true
4802		}
4803	});
4804
4805	delete Prism.languages.kotlin['string'];
4806
4807	Prism.languages.insertBefore('kotlin', 'keyword', {
4808		'annotation': {
4809			pattern: /\B@(?:\w+:)?(?:[A-Z]\w*|\[[^\]]+\])/,
4810			alias: 'builtin'
4811		}
4812	});
4813
4814	Prism.languages.insertBefore('kotlin', 'function', {
4815		'label': {
4816			pattern: /\b\w+@|@\w+\b/,
4817			alias: 'symbol'
4818		}
4819	});
4820
4821	Prism.languages.kt = Prism.languages.kotlin;
4822	Prism.languages.kts = Prism.languages.kotlin;
4823}(Prism$1));
4824
4825// Configure Prism for manual highlighting mode
4826// This must be set before importing prismjs
4827window.Prism ||= {};
4828window.Prism.manual = true;
4829
4830/*! @license DOMPurify 3.4.13 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.4.13/LICENSE */
4831
4832function _arrayLikeToArray(r, a) {
4833  (null == a || a > r.length) && (a = r.length);
4834  for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
4835  return n;
4836}
4837function _arrayWithHoles(r) {
4838  if (Array.isArray(r)) return r;
4839}
4840function _iterableToArrayLimit(r, l) {
4841  var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
4842  if (null != t) {
4843    var e,
4844      n,
4845      i,
4846      u,
4847      a = [],
4848      f = true,
4849      o = false;
4850    try {
4851      if (i = (t = t.call(r)).next, 0 === l) ; else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0
vendor: 8,931 bytes, lines 4851-5124
4851);
4852    } catch (r) {
4853      o = true, n = r;
4854    } finally {
4855      try {
4856        if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
4857      } finally {
4858        if (o) throw n;
4859      }
4860    }
4861    return a;
4862  }
4863}
4864function _nonIterableRest() {
4865  throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
4866}
4867function _slicedToArray(r, e) {
4868  return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
4869}
4870function _unsupportedIterableToArray(r, a) {
4871  if (r) {
4872    if ("string" == typeof r) return _arrayLikeToArray(r, a);
4873    var t = {}.toString.call(r).slice(8, -1);
4874    return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
4875  }
4876}
4877
4878const entries = Object.entries,
4879  setPrototypeOf = Object.setPrototypeOf,
4880  isFrozen = Object.isFrozen,
4881  getPrototypeOf = Object.getPrototypeOf,
4882  getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
4883let freeze = Object.freeze,
4884  seal = Object.seal,
4885  create = Object.create; // eslint-disable-line import/no-mutable-exports
4886let _ref = typeof Reflect !== 'undefined' && Reflect,
4887  apply = _ref.apply,
4888  construct = _ref.construct;
4889if (!freeze) {
4890  freeze = function freeze(x) {
4891    return x;
4892  };
4893}
4894if (!seal) {
4895  seal = function seal(x) {
4896    return x;
4897  };
4898}
4899if (!apply) {
4900  apply = function apply(func, thisArg) {
4901    for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
4902      args[_key - 2] = arguments[_key];
4903    }
4904    return func.apply(thisArg, args);
4905  };
4906}
4907if (!construct) {
4908  construct = function construct(Func) {
4909    for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
4910      args[_key2 - 1] = arguments[_key2];
4911    }
4912    return new Func(...args);
4913  };
4914}
4915const arrayForEach = unapply(Array.prototype.forEach);
4916const arrayLastIndexOf = unapply(Array.prototype.lastIndexOf);
4917const arrayPop = unapply(Array.prototype.pop);
4918const arrayPush = unapply(Array.prototype.push);
4919const arraySplice = unapply(Array.prototype.splice);
4920const arrayIsArray = Array.isArray;
4921const stringToLowerCase = unapply(String.prototype.toLowerCase);
4922const stringToString = unapply(String.prototype.toString);
4923const stringMatch = unapply(String.prototype.match);
4924const stringReplace = unapply(String.prototype.replace);
4925const stringIndexOf = unapply(String.prototype.indexOf);
4926const stringTrim = unapply(String.prototype.trim);
4927const numberToString = unapply(Number.prototype.toString);
4928const booleanToString = unapply(Boolean.prototype.toString);
4929const bigintToString = typeof BigInt === 'undefined' ? null : unapply(BigInt.prototype.toString);
4930const symbolToString = typeof Symbol === 'undefined' ? null : unapply(Symbol.prototype.toString);
4931const objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty);
4932const objectToString = unapply(Object.prototype.toString);
4933const regExpTest = unapply(RegExp.prototype.test);
4934const typeErrorCreate = unconstruct(TypeError);
4935/**
4936 * Creates a new function that calls the given function with a specified thisArg and arguments.
4937 *
4938 * @param func - The function to be wrapped and called.
4939 * @returns A new function that calls the given function with a specified thisArg and arguments.
4940 */
4941function unapply(func) {
4942  return function (thisArg) {
4943    if (thisArg instanceof RegExp) {
4944      thisArg.lastIndex = 0;
4945    }
4946    for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
4947      args[_key3 - 1] = arguments[_key3];
4948    }
4949    return apply(func, thisArg, args);
4950  };
4951}
4952/**
4953 * Creates a new function that constructs an instance of the given constructor function with the provided arguments.
4954 *
4955 * @param func - The constructor function to be wrapped and called.
4956 * @returns A new function that constructs an instance of the given constructor function with the provided arguments.
4957 */
4958function unconstruct(Func) {
4959  return function () {
4960    for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
4961      args[_key4] = arguments[_key4];
4962    }
4963    return construct(Func, args);
4964  };
4965}
4966/**
4967 * Add properties to a lookup table
4968 *
4969 * @param set - The set to which elements will be added.
4970 * @param array - The array containing elements to be added to the set.
4971 * @param transformCaseFunc - An optional function to transform the case of each element before adding to the set.
4972 * @returns The modified set with added elements.
4973 */
4974function addToSet(set, array) {
4975  let transformCaseFunc = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : stringToLowerCase;
4976  if (setPrototypeOf) {
4977    // Make 'in' and truthy checks like Boolean(set.constructor)
4978    // independent of any properties defined on Object.prototype.
4979    // Prevent prototype setters from intercepting set as a this value.
4980    setPrototypeOf(set, null);
4981  }
4982  if (!arrayIsArray(array)) {
4983    return set;
4984  }
4985  let l = array.length;
4986  while (l--) {
4987    let element = array[l];
4988    if (typeof element === 'string') {
4989      const lcElement = transformCaseFunc(element);
4990      if (lcElement !== element) {
4991        // Config presets (e.g. tags.js, attrs.js) are immutable.
4992        if (!isFrozen(array)) {
4993          array[l] = lcElement;
4994        }
4995        element = lcElement;
4996      }
4997    }
4998    set[element] = true;
4999  }
5000  return set;
5001}
5002/**
5003 * Clean up an array to harden against CSPP
5004 *
5005 * @param array - The array to be cleaned.
5006 * @returns The cleaned version of the array
5007 */
5008function cleanArray(array) {
5009  for (let index = 0; index < array.length; index++) {
5010    const isPropertyExist = objectHasOwnProperty(array, index);
5011    if (!isPropertyExist) {
5012      array[index] = null;
5013    }
5014  }
5015  return array;
5016}
5017/**
5018 * Shallow clone an object
5019 *
5020 * @param object - The object to be cloned.
5021 * @returns A new object that copies the original.
5022 */
5023function clone(object) {
5024  const newObject = create(null);
5025  for (const _ref2 of entries(object)) {
5026    var _ref3 = _slicedToArray(_ref2, 2);
5027    const property = _ref3[0];
5028    const value = _ref3[1];
5029    const isPropertyExist = objectHasOwnProperty(object, property);
5030    if (isPropertyExist) {
5031      if (arrayIsArray(value)) {
5032        newObject[property] = cleanArray(value);
5033      } else if (value && typeof value === 'object' && value.constructor === Object) {
5034        newObject[property] = clone(value);
5035      } else {
5036        newObject[property] = value;
5037      }
5038    }
5039  }
5040  return newObject;
5041}
5042/**
5043 * Convert non-node values into strings without depending on direct property access.
5044 *
5045 * @param value - The value to stringify.
5046 * @returns A string representation of the provided value.
5047 */
5048function stringifyValue(value) {
5049  switch (typeof value) {
5050    case 'string':
5051      {
5052        return value;
5053      }
5054    case 'number':
5055      {
5056        return numberToString(value);
5057      }
5058    case 'boolean':
5059      {
5060        return booleanToString(value);
5061      }
5062    case 'bigint':
5063      {
5064        return bigintToString ? bigintToString(value) : '0';
5065      }
5066    case 'symbol':
5067      {
5068        return symbolToString ? symbolToString(value) : 'Symbol()';
5069      }
5070    case 'undefined':
5071      {
5072        return objectToString(value);
5073      }
5074    case 'function':
5075    case 'object':
5076      {
5077        if (value === null) {
5078          return objectToString(value);
5079        }
5080        const valueAsRecord = value;
5081        const valueToString = lookupGetter(valueAsRecord, 'toString');
5082        if (typeof valueToString === 'function') {
5083          const stringified = valueToString(valueAsRecord);
5084          return typeof stringified === 'string' ? stringified : objectToString(stringified);
5085        }
5086        return objectToString(value);
5087      }
5088    default:
5089      {
5090        return objectToString(value);
5091      }
5092  }
5093}
5094/**
5095 * This method automatically checks if the prop is function or getter and behaves accordingly.
5096 *
5097 * @param object - The object to look up the getter function in its prototype chain.
5098 * @param prop - The property name for which to find the getter function.
5099 * @returns The getter function found in the prototype chain or a fallback function.
5100 */
5101function lookupGetter(object, prop) {
5102  while (object !== null) {
5103    const desc = getOwnPropertyDescriptor(object, prop);
5104    if (desc) {
5105      if (desc.get) {
5106        return unapply(desc.get);
5107      }
5108      if (typeof desc.value === 'function') {
5109        return unapply(desc.value);
5110      }
5111    }
5112    object = getPrototypeOf(object);
5113  }
5114  function fallbackValue() {
5115    return null;
5116  }
5117  return fallbackValue;
5118}
5119function isRegex(value) {
5120  try {
5121    regExpTest(value, '');
5122    return true;
5123  } catch (_unused) {
5124    return false;
vendor: 8,255 bytes, lines 5125-5155
5125  }
5126}
5127
5128const html$1 = freeze(['a', 'abbr', 'acronym', 'address', 'area', 'article', 'aside', 'audio', 'b', 'bdi', 'bdo', 'big', 'blink', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'content', 'data', 'datalist', 'dd', 'decorator', 'del', 'details', 'dfn', 'dialog', 'dir', 'div', 'dl', 'dt', 'element', 'em', 'fieldset', 'figcaption', 'figure', 'font', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'main', 'map', 'mark', 'marquee', 'menu', 'menuitem', 'meter', 'nav', 'nobr', 'ol', 'optgroup', 'option', 'output', 'p', 'picture', 'pre', 'progress', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'search', 'section', 'select', 'shadow', 'slot', 'small', 'source', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'tr', 'track', 'tt', 'u', 'ul', 'var', 'video', 'wbr']);
5129const svg$1 = freeze(['svg', 'a', 'altglyph', 'altglyphdef', 'altglyphitem', 'animatecolor', 'animatemotion', 'animatetransform', 'circle', 'clippath', 'defs', 'desc', 'ellipse', 'enterkeyhint', 'exportparts', 'filter', 'font', 'g', 'glyph', 'glyphref', 'hkern', 'image', 'inputmode', 'line', 'lineargradient', 'marker', 'mask', 'metadata', 'mpath', 'part', 'path', 'pattern', 'polygon', 'polyline', 'radialgradient', 'rect', 'stop', 'style', 'switch', 'symbol', 'text', 'textpath', 'title', 'tref', 'tspan', 'view', 'vkern']);
5130const svgFilters = freeze(['feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight', 'feDropShadow', 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode', 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence']);
5131// List of SVG elements that are disallowed by default.
5132// We still need to know them so that we can do namespace
5133// checks properly in case one wants to add them to
5134// allow-list.
5135const svgDisallowed = freeze(['animate', 'color-profile', 'cursor', 'discard', 'font-face', 'font-face-format', 'font-face-name', 'font-face-src', 'font-face-uri', 'foreignobject', 'hatch', 'hatchpath', 'mesh', 'meshgradient', 'meshpatch', 'meshrow', 'missing-glyph', 'script', 'set', 'solidcolor', 'unknown', 'use']);
5136const mathMl$1 = freeze(['math', 'menclose', 'merror', 'mfenced', 'mfrac', 'mglyph', 'mi', 'mlabeledtr', 'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded', 'mphantom', 'mroot', 'mrow', 'ms', 'mspace', 'msqrt', 'mstyle', 'msub', 'msup', 'msubsup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder', 'munderover', 'mprescripts']);
5137// Similarly to SVG, we want to know all MathML elements,
5138// even those that we disallow by default.
5139const mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']);
5140const text = freeze(['#text']);
5141
5142const html = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', 'command', 'commandfor', 'controls', 'controlslist', 'coords', 'crossorigin', 'datetime', 'decoding', 'default', 'dir', 'disabled', 'disablepictureinpicture', 'disableremoteplayback', 'download', 'draggable', 'enctype', 'enterkeyhint', 'exportparts', 'face', 'for', 'headers', 'height', 'hidden', 'high', 'href', 'hreflang', 'id', 'inert', 'inputmode', 'integrity', 'ismap', 'kind', 'label', 'lang', 'list', 'loading', 'loop', 'low', 'max', 'maxlength', 'media', 'method', 'min', 'minlength', 'multiple', 'muted', 'name', 'nonce', 'noshade', 'novalidate', 'nowrap', 'open', 'optimum', 'part', 'pattern', 'placeholder', 'playsinline', 'popover', 'popovertarget', 'popovertargetaction', 'poster', 'preload', 'pubdate', 'radiogroup', 'readonly', 'rel', 'required', 'rev', 'reversed', 'role', 'rows', 'rowspan', 'spellcheck', 'scope', 'selected', 'shape', 'size', 'sizes', 'slot', 'span', 'srclang', 'start', 'src', 'srcset', 'step', 'style', 'summary', 'tabindex', 'title', 'translate', 'type', 'usemap', 'valign', 'value', 'width', 'wrap', 'xmlns']);
5143const svg = freeze(['accent-height', 'accumulate', 'additive', 'alignment-baseline', 'amplitude', 'ascent', 'attributename', 'attributetype', 'azimuth', 'basefrequency', 'baseline-shift', 'begin', 'bias', 'by', 'class', 'clip', 'clippathunits', 'clip-path', 'clip-rule', 'color', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'cx', 'cy', 'd', 'dx', 'dy', 'diffuseconstant', 'direction', 'display', 'divisor', 'dominant-baseline', 'dur', 'edgemode', 'elevation', 'end', 'exponent', 'fill', 'fill-opacity', 'fill-rule', 'filter', 'filterunits', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'fx', 'fy', 'g1', 'g2', 'glyph-name', 'glyphref', 'gradientunits', 'gradienttransform', 'height', 'href', 'id', 'image-rendering', 'in', 'in2', 'intercept', 'k', 'k1', 'k2', 'k3', 'k4', 'kerning', 'keypoints', 'keysplines', 'keytimes', 'lang', 'lengthadjust', 'letter-spacing', 'kernelmatrix', 'kernelunitlength', 'lighting-color', 'local', 'marker-end', 'marker-mid', 'marker-start', 'markerheight', 'markerunits', 'markerwidth', 'maskcontentunits', 'maskunits', 'max', 'mask', 'mask-type', 'media', 'method', 'mode', 'min', 'name', 'numoctaves', 'offset', 'operator', 'opacity', 'order', 'orient', 'orientation', 'origin', 'overflow', 'paint-order', 'path', 'pathlength', 'patterncontentunits', 'patterntransform', 'patternunits', 'points', 'preservealpha', 'preserveaspectratio', 'primitiveunits', 'r', 'rx', 'ry', 'radius', 'refx', 'refy', 'repeatcount', 'repeatdur', 'restart', 'result', 'rotate', 'scale', 'seed', 'shape-rendering', 'slope', 'specularconstant', 'specularexponent', 'spreadmethod', 'startoffset', 'stddeviation', 'stitchtiles', 'stop-color', 'stop-opacity', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke', 'stroke-width', 'style', 'surfacescale', 'systemlanguage', 'tabindex', 'tablevalues', 'targetx', 'targety', 'transform', 'transform-origin', 'text-anchor', 'text-decoration', 'text-orientation', 'text-rendering', 'textlength', 'type', 'u1', 'u2', 'unicode', 'values', 'viewbox', 'visibility', 'version', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'width', 'word-spacing', 'wrap', 'writing-mode', 'xchannelselector', 'ychannelselector', 'x', 'x1', 'x2', 'xmlns', 'y', 'y1', 'y2', 'z', 'zoomandpan']);
5144const mathMl = freeze(['accent', 'accentunder', 'align', 'bevelled', 'close', 'columnalign', 'columnlines', 'columnspacing', 'columnspan', 'denomalign', 'depth', 'dir', 'display', 'displaystyle', 'encoding', 'fence', 'frame', 'height', 'href', 'id', 'largeop', 'length', 'linethickness', 'lquote', 'lspace', 'mathbackground', 'mathcolor', 'mathsize', 'mathvariant', 'maxsize', 'minsize', 'movablelimits', 'notation', 'numalign', 'open', 'rowalign', 'rowlines', 'rowspacing', 'rowspan', 'rspace', 'rquote', 'scriptlevel', 'scriptminsize', 'scriptsizemultiplier', 'selection', 'separator', 'separators', 'stretchy', 'subscriptshift', 'supscriptshift', 'symmetric', 'voffset', 'width', 'xmlns']);
5145const xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']);
5146
5147const MUSTACHE_EXPR = seal(/{{[\w\W]*|^[\w\W]*}}/g);
5148const ERB_EXPR = seal(/<%[\w\W]*|^[\w\W]*%>/g);
5149const TMPLIT_EXPR = seal(/\${[\w\W]*/g);
5150const DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]+$/); // eslint-disable-line no-useless-escape
5151const ARIA_ATTR = seal(/^aria-[\-\w]+$/); // eslint-disable-line no-useless-escape
5152const IS_ALLOWED_URI = seal(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i // eslint-disable-line no-useless-escape
5153);
5154const IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i);
5155const ATTR_WHITESPACE
vendor: 9,242 bytes, lines 5155-5359
5155$1 = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g // eslint-disable-line no-control-regex
5156);
5157const DOCTYPE_NAME = seal(/^html$/i);
5158const CUSTOM_ELEMENT = seal(/^[a-z][.\w]*(-[.\w]+)+$/i);
5159// Markup-significant character probes used by _sanitizeElements.
5160// Shared module-level instances are safe despite the sticky /g flags:
5161// unapply() resets lastIndex for RegExp receivers before every call.
5162const ELEMENT_MARKUP_PROBE = seal(/<[/\w!]/g);
5163const COMMENT_MARKUP_PROBE = seal(/<[/\w]/g);
5164const FALLBACK_TAG_CLOSE = seal(/<\/no(script|embed|frames)/i);
5165const SELF_CLOSING_TAG = seal(/\/>/i);
5166
5167// https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType
5168const NODE_TYPE = {
5169  element: 1,
5170  attribute: 2,
5171  text: 3,
5172  cdataSection: 4,
5173  entityReference: 5,
5174  // Deprecated
5175  entityNode: 6,
5176  // Deprecated
5177  processingInstruction: 7,
5178  comment: 8,
5179  document: 9,
5180  documentType: 10,
5181  documentFragment: 11,
5182  notation: 12 // Deprecated
5183};
5184const getGlobal = function getGlobal() {
5185  return typeof window === 'undefined' ? null : window;
5186};
5187/**
5188 * Creates a no-op policy for internal use only.
5189 * Don't export this function outside this module!
5190 * @param trustedTypes The policy factory.
5191 * @param purifyHostElement The Script element used to load DOMPurify (to determine policy name suffix).
5192 * @return The policy created (or null, if Trusted Types
5193 * are not supported or creating the policy failed).
5194 */
5195const _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, purifyHostElement) {
5196  if (typeof trustedTypes !== 'object' || typeof trustedTypes.createPolicy !== 'function') {
5197    return null;
5198  }
5199  // Allow the callers to control the unique policy name
5200  // by adding a data-tt-policy-suffix to the script element with the DOMPurify.
5201  // Policy creation with duplicate names throws in Trusted Types.
5202  let suffix = null;
5203  const ATTR_NAME = 'data-tt-policy-suffix';
5204  if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) {
5205    suffix = purifyHostElement.getAttribute(ATTR_NAME);
5206  }
5207  const policyName = 'dompurify' + (suffix ? '#' + suffix : '');
5208  try {
5209    return trustedTypes.createPolicy(policyName, {
5210      createHTML(html) {
5211        return html;
5212      },
5213      createScriptURL(scriptUrl) {
5214        return scriptUrl;
5215      }
5216    });
5217  } catch (_) {
5218    // Policy creation failed (most likely another DOMPurify script has
5219    // already run). Skip creating the policy, as this will only cause errors
5220    // if TT are enforced.
5221    console.warn('TrustedTypes policy ' + policyName + ' could not be created.');
5222    return null;
5223  }
5224};
5225const _createHooksMap = function _createHooksMap() {
5226  return {
5227    afterSanitizeAttributes: [],
5228    afterSanitizeElements: [],
5229    afterSanitizeShadowDOM: [],
5230    beforeSanitizeAttributes: [],
5231    beforeSanitizeElements: [],
5232    beforeSanitizeShadowDOM: [],
5233    uponSanitizeAttribute: [],
5234    uponSanitizeElement: [],
5235    uponSanitizeShadowNode: []
5236  };
5237};
5238/**
5239 * Resolve a set-valued configuration option: a fresh set built from
5240 * cfg[key] when it is an own array property (seeded with a clone of
5241 * options.base when given, case-normalized via options.transform),
5242 * the fallback set otherwise.
5243 *
5244 * @param cfg the cloned, prototype-free configuration object
5245 * @param key the configuration property to read
5246 * @param fallback the set to use when the option is absent or not an array
5247 * @param options transform and optional base set to merge into
5248 * @returns the resolved set
5249 */
5250const _resolveSetOption = function _resolveSetOption(cfg, key, fallback, options) {
5251  return objectHasOwnProperty(cfg, key) && arrayIsArray(cfg[key]) ? addToSet(options.base ? clone(options.base) : {}, cfg[key], options.transform) : fallback;
5252};
5253function createDOMPurify() {
5254  let window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal();
5255  const DOMPurify = root => createDOMPurify(root);
5256  DOMPurify.version = '3.4.13';
5257  DOMPurify.removed = [];
5258  if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document || !window.Element) {
5259    // Not running in a browser, provide a factory function
5260    // so that you can pass your own Window
5261    DOMPurify.isSupported = false;
5262    return DOMPurify;
5263  }
5264  let document = window.document;
5265  const originalDocument = document;
5266  const currentScript = originalDocument.currentScript;
5267  window.DocumentFragment;
5268    const HTMLTemplateElement = window.HTMLTemplateElement,
5269    Node = window.Node,
5270    Element = window.Element,
5271    NodeFilter = window.NodeFilter,
5272    _window$NamedNodeMap = window.NamedNodeMap;
5273    _window$NamedNodeMap === void 0 ? window.NamedNodeMap || window.MozNamedAttrMap : _window$NamedNodeMap;
5274    window.HTMLFormElement;
5275    const DOMParser = window.DOMParser,
5276    trustedTypes = window.trustedTypes;
5277  const ElementPrototype = Element.prototype;
5278  const cloneNode = lookupGetter(ElementPrototype, 'cloneNode');
5279  const remove = lookupGetter(ElementPrototype, 'remove');
5280  const getNextSibling = lookupGetter(ElementPrototype, 'nextSibling');
5281  const getChildNodes = lookupGetter(ElementPrototype, 'childNodes');
5282  const getParentNode = lookupGetter(ElementPrototype, 'parentNode');
5283  const getShadowRoot = lookupGetter(ElementPrototype, 'shadowRoot');
5284  const getAttributes = lookupGetter(ElementPrototype, 'attributes');
5285  const getNodeType = Node && Node.prototype ? lookupGetter(Node.prototype, 'nodeType') : null;
5286  const getNodeName = Node && Node.prototype ? lookupGetter(Node.prototype, 'nodeName') : null;
5287  const getOwnerDocument = Node && Node.prototype ? lookupGetter(Node.prototype, 'ownerDocument') : null;
5288  // As per issue #47, the web-components registry is inherited by a
5289  // new document created via createHTMLDocument. As per the spec
5290  // (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries)
5291  // a new empty registry is used when creating a template contents owner
5292  // document, so we use that as our parent document to ensure nothing
5293  // is inherited.
5294  if (typeof HTMLTemplateElement === 'function') {
5295    const template = document.createElement('template');
5296    if (template.content && template.content.ownerDocument) {
5297      document = template.content.ownerDocument;
5298    }
5299  }
5300  let trustedTypesPolicy;
5301  let emptyHTML = '';
5302  // The instance's own internal Trusted Types policy. Unlike a caller-supplied
5303  // `TRUSTED_TYPES_POLICY`, this is created at most once — Trusted Types throws
5304  // on duplicate policy names — and is the only policy allowed to persist
5305  // across configurations and survive `clearConfig()`.
5306  let defaultTrustedTypesPolicy;
5307  let defaultTrustedTypesPolicyResolved = false;
5308  // Tracks whether we are already inside a call to the configured Trusted Types
5309  // policy (`createHTML` or `createScriptURL`). If a supplied policy callback
5310  // itself calls `DOMPurify.sanitize` (the cause of #1422), `sanitize` would
5311  // re-enter the policy and recurse until the stack overflows. We detect that
5312  // re-entry and throw a clear, actionable error instead. The guard is shared
5313  // across both callbacks, because either one re-entering `sanitize` triggers
5314  // the same unbounded recursion.
5315  let IN_TRUSTED_TYPES_POLICY = 0;
5316  const _assertNotInTrustedTypesPolicy = function _assertNotInTrustedTypesPolicy() {
5317    if (IN_TRUSTED_TYPES_POLICY > 0) {
5318      throw typeErrorCreate('A configured TRUSTED_TYPES_POLICY callback (createHTML or ' + 'createScriptURL) must not call DOMPurify.sanitize, as that causes ' + 'infinite recursion. Do not pass a policy whose callbacks wrap ' + 'DOMPurify as TRUSTED_TYPES_POLICY; see the "DOMPurify and Trusted ' + 'Types" section of the README.');
5319    }
5320  };
5321  const _createTrustedHTML = function _createTrustedHTML(html) {
5322    _assertNotInTrustedTypesPolicy();
5323    IN_TRUSTED_TYPES_POLICY++;
5324    try {
5325      return trustedTypesPolicy.createHTML(html);
5326    } finally {
5327      IN_TRUSTED_TYPES_POLICY--;
5328    }
5329  };
5330  const _createTrustedScriptURL = function _createTrustedScriptURL(scriptUrl) {
5331    _assertNotInTrustedTypesPolicy();
5332    IN_TRUSTED_TYPES_POLICY++;
5333    try {
5334      return trustedTypesPolicy.createScriptURL(scriptUrl);
5335    } finally {
5336      IN_TRUSTED_TYPES_POLICY--;
5337    }
5338  };
5339  // Lazily resolve (and cache) the instance's internal default policy.
5340  // Resolution is attempted at most once: a successful `createPolicy` cannot be
5341  // repeated (Trusted Types throws on duplicate names), and a failed or
5342  // unsupported attempt must not be retried on every parse.
5343  const _getDefaultTrustedTypesPolicy = function _getDefaultTrustedTypesPolicy() {
5344    if (!defaultTrustedTypesPolicyResolved) {
5345      defaultTrustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, currentScript);
5346      defaultTrustedTypesPolicyResolved = true;
5347    }
5348    return defaultTrustedTypesPolicy;
5349  };
5350  const _document = document,
5351    implementation = _document.implementation,
5352    createNodeIterator = _document.createNodeIterator,
5353    createDocumentFragment = _document.createDocumentFragment,
5354    getElementsByTagName = _document.getElementsByTagName;
5355  const importNode = originalDocument.importNode;
5356  let hooks = _createHooksMap();
5357  /**
5358   * Expose whether this browser supports running the full DOMPurify.
5359   */
5360  DOMPurify.isSupported = typeof entries === 'function' && typeof getParentNode === 'function' && implementation && implementation.createHTMLDocument !== undefined;
5361  const MUSTACHE_EXPR$1 = MUSTACHE_EXPR,
5362    ERB_EXPR$1 = ERB_EXPR,
5363    TMPLIT_EXPR$1 = TMPLIT_EXPR,
5364    DATA_ATTR$1 = DATA_ATTR,
5365    ARIA_ATTR$1 = ARIA_ATTR,
5366    IS_SCRIPT_OR_DATA$1 = IS_SCRIPT_OR_DATA,
5367    ATTR_WHITESPACE$1$1 = ATTR_WHITESPACE$1
vendor: 25,707 bytes, lines 5367-5894
5367,
5368    CUSTOM_ELEMENT$1 = CUSTOM_ELEMENT;
5369  let IS_ALLOWED_URI$1 = IS_ALLOWED_URI;
5370  /**
5371   * We consider the elements and attributes below to be safe. Ideally
5372   * don't add any new ones but feel free to remove unwanted ones.
5373   */
5374  /* allowed element names */
5375  let ALLOWED_TAGS = null;
5376  const DEFAULT_ALLOWED_TAGS = addToSet({}, [...html$1, ...svg$1, ...svgFilters, ...mathMl$1, ...text]);
5377  /* Allowed attribute names */
5378  let ALLOWED_ATTR = null;
5379  const DEFAULT_ALLOWED_ATTR = addToSet({}, [...html, ...svg, ...mathMl, ...xml]);
5380  /*
5381   * Configure how DOMPurify should handle custom elements and their attributes as well as customized built-in elements.
5382   * @property {RegExp|Function|null} tagNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any custom elements)
5383   * @property {RegExp|Function|null} attributeNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any attributes not on the allow list)
5384   * @property {boolean} allowCustomizedBuiltInElements allow custom elements derived from built-ins if they pass CUSTOM_ELEMENT_HANDLING.tagNameCheck. Default: `false`.
5385   */
5386  let CUSTOM_ELEMENT_HANDLING = Object.seal(create(null, {
5387    tagNameCheck: {
5388      writable: true,
5389      configurable: false,
5390      enumerable: true,
5391      value: null
5392    },
5393    attributeNameCheck: {
5394      writable: true,
5395      configurable: false,
5396      enumerable: true,
5397      value: null
5398    },
5399    allowCustomizedBuiltInElements: {
5400      writable: true,
5401      configurable: false,
5402      enumerable: true,
5403      value: false
5404    }
5405  }));
5406  /* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */
5407  let FORBID_TAGS = null;
5408  /* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */
5409  let FORBID_ATTR = null;
5410  /* Config object to store ADD_TAGS/ADD_ATTR functions (when used as functions) */
5411  const EXTRA_ELEMENT_HANDLING = Object.seal(create(null, {
5412    tagCheck: {
5413      writable: true,
5414      configurable: false,
5415      enumerable: true,
5416      value: null
5417    },
5418    attributeCheck: {
5419      writable: true,
5420      configurable: false,
5421      enumerable: true,
5422      value: null
5423    }
5424  }));
5425  /* Decide if ARIA attributes are okay */
5426  let ALLOW_ARIA_ATTR = true;
5427  /* Decide if custom data attributes are okay */
5428  let ALLOW_DATA_ATTR = true;
5429  /* Decide if unknown protocols are okay */
5430  let ALLOW_UNKNOWN_PROTOCOLS = false;
5431  /* Decide if self-closing tags in attributes are allowed.
5432   * Usually removed due to a mXSS issue in jQuery 3.0 */
5433  let ALLOW_SELF_CLOSE_IN_ATTR = true;
5434  /* Output should be safe for common template engines.
5435   * This means, DOMPurify removes data attributes, mustaches and ERB
5436   */
5437  let SAFE_FOR_TEMPLATES = false;
5438  /* Output should be safe even for XML used within HTML and alike.
5439   * This means, DOMPurify removes comments when containing risky content.
5440   */
5441  let SAFE_FOR_XML = true;
5442  /* Decide if document with <html>... should be returned */
5443  let WHOLE_DOCUMENT = false;
5444  /* Track whether config is already set on this instance of DOMPurify. */
5445  let SET_CONFIG = false;
5446  /* Pristine allowlist bindings captured at setConfig() time. On the
5447   * persistent-config path sanitize() restores the sets from these before
5448   * the per-walk hook clone-guard, so a hook's in-call widening cannot
5449   * carry across calls. Null until setConfig() is called; reset by
5450   * clearConfig(). */
5451  let SET_CONFIG_ALLOWED_TAGS = null;
5452  let SET_CONFIG_ALLOWED_ATTR = null;
5453  /* Decide if all elements (e.g. style, script) must be children of
5454   * document.body. By default, browsers might move them to document.head */
5455  let FORCE_BODY = false;
5456  /* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html
5457   * string (or a TrustedHTML object if Trusted Types are supported).
5458   * If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead
5459   */
5460  let RETURN_DOM = false;
5461  /* Decide if a DOM `DocumentFragment` should be returned, instead of a html
5462   * string  (or a TrustedHTML object if Trusted Types are supported) */
5463  let RETURN_DOM_FRAGMENT = false;
5464  /* Try to return a Trusted Type object instead of a string, return a string in
5465   * case Trusted Types are not supported  */
5466  let RETURN_TRUSTED_TYPE = false;
5467  /* Output should be free from DOM clobbering attacks?
5468   * This sanitizes markups named with colliding, clobberable built-in DOM APIs.
5469   */
5470  let SANITIZE_DOM = true;
5471  /* Achieve full DOM Clobbering protection by isolating the namespace of named
5472   * properties and JS variables, mitigating attacks that abuse the HTML/DOM spec rules.
5473   *
5474   * HTML/DOM spec rules that enable DOM Clobbering:
5475   *   - Named Access on Window (§7.3.3)
5476   *   - DOM Tree Accessors (§3.1.5)
5477   *   - Form Element Parent-Child Relations (§4.10.3)
5478   *   - Iframe srcdoc / Nested WindowProxies (§4.8.5)
5479   *   - HTMLCollection (§4.2.10.2)
5480   *
5481   * Namespace isolation is implemented by prefixing `id` and `name` attributes
5482   * with a constant string, i.e., `user-content-`
5483   */
5484  let SANITIZE_NAMED_PROPS = false;
5485  const SANITIZE_NAMED_PROPS_PREFIX = 'user-content-';
5486  /* Keep element content when removing element? */
5487  let KEEP_CONTENT = true;
5488  /* If a `Node` is passed to sanitize(), then performs sanitization in-place instead
5489   * of importing it into a new Document and returning a sanitized copy */
5490  let IN_PLACE = false;
5491  /* Allow usage of profiles like html, svg and mathMl */
5492  let USE_PROFILES = {};
5493  /* Tags to ignore content of when KEEP_CONTENT is true */
5494  let FORBID_CONTENTS = null;
5495  const DEFAULT_FORBID_CONTENTS = addToSet({}, ['annotation-xml', 'audio', 'colgroup', 'desc', 'foreignobject', 'head', 'iframe', 'math', 'mi', 'mn', 'mo', 'ms', 'mtext', 'noembed', 'noframes', 'noscript', 'plaintext', 'script',
5496  // <selectedcontent> mirrors the selected <option>'s subtree, cloned by
5497  // the UA (customizable <select>) — including any on* handlers — and the
5498  // engine re-mirrors synchronously whenever a removal changes which
5499  // option/selectedcontent is current, even inside DOMPurify's inert
5500  // DOMParser document. Hoisting its children on removal re-inserts a fresh
5501  // mirror target ahead of the walk, which the engine refills, looping
5502  // forever (DoS) and amplifying output. Dropping its content on removal
5503  // (rather than hoisting) breaks that cascade; the content is a duplicate
5504  // of the option, which is sanitized on its own. See campaign-3 F1/F6.
5505  'selectedcontent', 'style', 'svg', 'template', 'thead', 'title', 'video', 'xmp']);
5506  /* Tags that are safe for data: URIs */
5507  let DATA_URI_TAGS = null;
5508  const DEFAULT_DATA_URI_TAGS = addToSet({}, ['audio', 'video', 'img', 'source', 'image', 'track']);
5509  /* Attributes safe for values like "javascript:" */
5510  let URI_SAFE_ATTRIBUTES = null;
5511  const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ['alt', 'class', 'for', 'id', 'label', 'name', 'pattern', 'placeholder', 'role', 'summary', 'title', 'value', 'style', 'xmlns']);
5512  const MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
5513  const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
5514  const HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';
5515  /* Document namespace */
5516  let NAMESPACE = HTML_NAMESPACE;
5517  let IS_EMPTY_INPUT = false;
5518  /* Allowed XHTML+XML namespaces */
5519  let ALLOWED_NAMESPACES = null;
5520  const DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE], stringToString);
5521  const DEFAULT_MATHML_TEXT_INTEGRATION_POINTS = freeze(['mi', 'mo', 'mn', 'ms', 'mtext']);
5522  let MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, DEFAULT_MATHML_TEXT_INTEGRATION_POINTS);
5523  const DEFAULT_HTML_INTEGRATION_POINTS = freeze(['annotation-xml']);
5524  let HTML_INTEGRATION_POINTS = addToSet({}, DEFAULT_HTML_INTEGRATION_POINTS);
5525  // Certain elements are allowed in both SVG and HTML
5526  // namespace. We need to specify them explicitly
5527  // so that they don't get erroneously deleted from
5528  // HTML namespace.
5529  const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, ['title', 'style', 'font', 'a', 'script']);
5530  /* Parsing of strict XHTML documents */
5531  let PARSER_MEDIA_TYPE = null;
5532  const SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html'];
5533  const DEFAULT_PARSER_MEDIA_TYPE = 'text/html';
5534  let transformCaseFunc = null;
5535  /* Keep a reference to config to pass to hooks */
5536  let CONFIG = null;
5537  /* Ideally, do not touch anything below this line */
5538  /* ______________________________________________ */
5539  const formElement = document.createElement('form');
5540  const isRegexOrFunction = function isRegexOrFunction(testValue) {
5541    return testValue instanceof RegExp || testValue instanceof Function;
5542  };
5543  /**
5544   * _parseConfig
5545   *
5546   * @param cfg optional config literal
5547   */
5548  // eslint-disable-next-line complexity
5549  const _parseConfig = function _parseConfig() {
5550    let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
5551    if (CONFIG && CONFIG === cfg) {
5552      return;
5553    }
5554    /* Shield configuration object from tampering */
5555    if (!cfg || typeof cfg !== 'object') {
5556      cfg = {};
5557    }
5558    /* Shield configuration object from prototype pollution */
5559    cfg = clone(cfg);
5560    PARSER_MEDIA_TYPE =
5561    // eslint-disable-next-line unicorn/prefer-includes
5562    SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? DEFAULT_PARSER_MEDIA_TYPE : cfg.PARSER_MEDIA_TYPE;
5563    // HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is.
5564    transformCaseFunc = PARSER_MEDIA_TYPE === 'application/xhtml+xml' ? stringToString : stringToLowerCase;
5565    /* Set configuration parameters */
5566    ALLOWED_TAGS = _resolveSetOption(cfg, 'ALLOWED_TAGS', DEFAULT_ALLOWED_TAGS, {
5567      transform: transformCaseFunc
5568    });
5569    ALLOWED_ATTR = _resolveSetOption(cfg, 'ALLOWED_ATTR', DEFAULT_ALLOWED_ATTR, {
5570      transform: transformCaseFunc
5571    });
5572    ALLOWED_NAMESPACES = _resolveSetOption(cfg, 'ALLOWED_NAMESPACES', DEFAULT_ALLOWED_NAMESPACES, {
5573      transform: stringToString
5574    });
5575    URI_SAFE_ATTRIBUTES = _resolveSetOption(cfg, 'ADD_URI_SAFE_ATTR', DEFAULT_URI_SAFE_ATTRIBUTES, {
5576      transform: transformCaseFunc,
5577      base: DEFAULT_URI_SAFE_ATTRIBUTES
5578    });
5579    DATA_URI_TAGS = _resolveSetOption(cfg, 'ADD_DATA_URI_TAGS', DEFAULT_DATA_URI_TAGS, {
5580      transform: transformCaseFunc,
5581      base: DEFAULT_DATA_URI_TAGS
5582    });
5583    FORBID_CONTENTS = _resolveSetOption(cfg, 'FORBID_CONTENTS', DEFAULT_FORBID_CONTENTS, {
5584      transform: transformCaseFunc
5585    });
5586    FORBID_TAGS = _resolveSetOption(cfg, 'FORBID_TAGS', clone({}), {
5587      transform: transformCaseFunc
5588    });
5589    FORBID_ATTR = _resolveSetOption(cfg, 'FORBID_ATTR', clone({}), {
5590      transform: transformCaseFunc
5591    });
5592    USE_PROFILES = objectHasOwnProperty(cfg, 'USE_PROFILES') ? cfg.USE_PROFILES && typeof cfg.USE_PROFILES === 'object' ? clone(cfg.USE_PROFILES) : cfg.USE_PROFILES : false;
5593    ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true
5594    ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true
5595    ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false
5596    ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false; // Default true
5597    SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false
5598    SAFE_FOR_XML = cfg.SAFE_FOR_XML !== false; // Default true
5599    WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false
5600    RETURN_DOM = cfg.RETURN_DOM || false; // Default false
5601    RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false
5602    RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false
5603    FORCE_BODY = cfg.FORCE_BODY || false; // Default false
5604    SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true
5605    SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false; // Default false
5606    KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true
5607    IN_PLACE = cfg.IN_PLACE || false; // Default false
5608    IS_ALLOWED_URI$1 = isRegex(cfg.ALLOWED_URI_REGEXP) ? cfg.ALLOWED_URI_REGEXP : IS_ALLOWED_URI; // Default regexp
5609    NAMESPACE = typeof cfg.NAMESPACE === 'string' ? cfg.NAMESPACE : HTML_NAMESPACE; // Default HTML namespace
5610    MATHML_TEXT_INTEGRATION_POINTS = objectHasOwnProperty(cfg, 'MATHML_TEXT_INTEGRATION_POINTS') && cfg.MATHML_TEXT_INTEGRATION_POINTS && typeof cfg.MATHML_TEXT_INTEGRATION_POINTS === 'object' ? clone(cfg.MATHML_TEXT_INTEGRATION_POINTS) : addToSet({}, DEFAULT_MATHML_TEXT_INTEGRATION_POINTS); // Default built-in map
5611    HTML_INTEGRATION_POINTS = objectHasOwnProperty(cfg, 'HTML_INTEGRATION_POINTS') && cfg.HTML_INTEGRATION_POINTS && typeof cfg.HTML_INTEGRATION_POINTS === 'object' ? clone(cfg.HTML_INTEGRATION_POINTS) : addToSet({}, DEFAULT_HTML_INTEGRATION_POINTS); // Default built-in map
5612    const customElementHandling = objectHasOwnProperty(cfg, 'CUSTOM_ELEMENT_HANDLING') && cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING === 'object' ? clone(cfg.CUSTOM_ELEMENT_HANDLING) : create(null);
5613    CUSTOM_ELEMENT_HANDLING = create(null);
5614    if (objectHasOwnProperty(customElementHandling, 'tagNameCheck') && isRegexOrFunction(customElementHandling.tagNameCheck)) {
5615      CUSTOM_ELEMENT_HANDLING.tagNameCheck = customElementHandling.tagNameCheck; // Default undefined
5616    }
5617    if (objectHasOwnProperty(customElementHandling, 'attributeNameCheck') && isRegexOrFunction(customElementHandling.attributeNameCheck)) {
5618      CUSTOM_ELEMENT_HANDLING.attributeNameCheck = customElementHandling.attributeNameCheck; // Default undefined
5619    }
5620    if (objectHasOwnProperty(customElementHandling, 'allowCustomizedBuiltInElements') && typeof customElementHandling.allowCustomizedBuiltInElements === 'boolean') {
5621      CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = customElementHandling.allowCustomizedBuiltInElements; // Default undefined
5622    }
5623    seal(CUSTOM_ELEMENT_HANDLING);
5624    if (SAFE_FOR_TEMPLATES) {
5625      ALLOW_DATA_ATTR = false;
5626    }
5627    if (RETURN_DOM_FRAGMENT) {
5628      RETURN_DOM = true;
5629    }
5630    /* Parse profile info */
5631    if (USE_PROFILES) {
5632      ALLOWED_TAGS = addToSet({}, text);
5633      ALLOWED_ATTR = create(null);
5634      if (USE_PROFILES.html === true) {
5635        addToSet(ALLOWED_TAGS, html$1);
5636        addToSet(ALLOWED_ATTR, html);
5637      }
5638      if (USE_PROFILES.svg === true) {
5639        addToSet(ALLOWED_TAGS, svg$1);
5640        addToSet(ALLOWED_ATTR, svg);
5641        addToSet(ALLOWED_ATTR, xml);
5642      }
5643      if (USE_PROFILES.svgFilters === true) {
5644        addToSet(ALLOWED_TAGS, svgFilters);
5645        addToSet(ALLOWED_ATTR, svg);
5646        addToSet(ALLOWED_ATTR, xml);
5647      }
5648      if (USE_PROFILES.mathMl === true) {
5649        addToSet(ALLOWED_TAGS, mathMl$1);
5650        addToSet(ALLOWED_ATTR, mathMl);
5651        addToSet(ALLOWED_ATTR, xml);
5652      }
5653    }
5654    /* Always reset function-based ADD_TAGS / ADD_ATTR checks to prevent
5655     * leaking across calls when switching from function to array config */
5656    EXTRA_ELEMENT_HANDLING.tagCheck = null;
5657    EXTRA_ELEMENT_HANDLING.attributeCheck = null;
5658    /* Merge configuration parameters */
5659    if (objectHasOwnProperty(cfg, 'ADD_TAGS')) {
5660      if (typeof cfg.ADD_TAGS === 'function') {
5661        EXTRA_ELEMENT_HANDLING.tagCheck = cfg.ADD_TAGS;
5662      } else if (arrayIsArray(cfg.ADD_TAGS)) {
5663        if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) {
5664          ALLOWED_TAGS = clone(ALLOWED_TAGS);
5665        }
5666        addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc);
5667      }
5668    }
5669    if (objectHasOwnProperty(cfg, 'ADD_ATTR')) {
5670      if (typeof cfg.ADD_ATTR === 'function') {
5671        EXTRA_ELEMENT_HANDLING.attributeCheck = cfg.ADD_ATTR;
5672      } else if (arrayIsArray(cfg.ADD_ATTR)) {
5673        if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) {
5674          ALLOWED_ATTR = clone(ALLOWED_ATTR);
5675        }
5676        addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc);
5677      }
5678    }
5679    if (objectHasOwnProperty(cfg, 'ADD_URI_SAFE_ATTR') && arrayIsArray(cfg.ADD_URI_SAFE_ATTR)) {
5680      addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc);
5681    }
5682    if (objectHasOwnProperty(cfg, 'FORBID_CONTENTS') && arrayIsArray(cfg.FORBID_CONTENTS)) {
5683      if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {
5684        FORBID_CONTENTS = clone(FORBID_CONTENTS);
5685      }
5686      addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc);
5687    }
5688    if (objectHasOwnProperty(cfg, 'ADD_FORBID_CONTENTS') && arrayIsArray(cfg.ADD_FORBID_CONTENTS)) {
5689      if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) {
5690        FORBID_CONTENTS = clone(FORBID_CONTENTS);
5691      }
5692      addToSet(FORBID_CONTENTS, cfg.ADD_FORBID_CONTENTS, transformCaseFunc);
5693    }
5694    /* Add #text in case KEEP_CONTENT is set to true */
5695    if (KEEP_CONTENT) {
5696      ALLOWED_TAGS['#text'] = true;
5697    }
5698    /* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */
5699    if (WHOLE_DOCUMENT) {
5700      addToSet(ALLOWED_TAGS, ['html', 'head', 'body']);
5701    }
5702    /* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */
5703    if (ALLOWED_TAGS.table) {
5704      addToSet(ALLOWED_TAGS, ['tbody']);
5705      delete FORBID_TAGS.tbody;
5706    }
5707    // Re-derive the active Trusted Types policy from this configuration on
5708    // every parse. The active policy must never be sticky closure state that
5709    // outlives the config that set it: a caller-supplied policy left in place
5710    // after `clearConfig()` — or after a later call that supplied none, or
5711    // `TRUSTED_TYPES_POLICY: null` — could sign a subsequent "default"
5712    // `RETURN_TRUSTED_TYPE` result with a foreign, possibly unsafe policy.
5713    // See GHSA-vxr8-fq34-vvx9.
5714    if (cfg.TRUSTED_TYPES_POLICY) {
5715      if (typeof cfg.TRUSTED_TYPES_POLICY.createHTML !== 'function') {
5716        throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');
5717      }
5718      if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== 'function') {
5719        throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');
5720      }
5721      // A caller-supplied policy applies to this configuration only.
5722      const previousTrustedTypesPolicy = trustedTypesPolicy;
5723      trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY;
5724      // Sign local variables required by `sanitize`. If the supplied policy's
5725      // `createHTML` is circular (i.e. it calls `DOMPurify.sanitize`), this
5726      // throws via the re-entrancy guard. Restore the previous policy first so
5727      // the instance is not left in a poisoned state. See #1422.
5728      try {
5729        emptyHTML = _createTrustedHTML('');
5730      } catch (error) {
5731        trustedTypesPolicy = previousTrustedTypesPolicy;
5732        throw error;
5733      }
5734    } else if (cfg.TRUSTED_TYPES_POLICY === null) {
5735      // Explicit opt-out for this call: perform no Trusted Types signing and
5736      // create nothing (so a strict `trusted-types` CSP that disallows a
5737      // `dompurify` policy can still call `sanitize` from inside its own
5738      // policy — see #1422). Resetting to `undefined` rather than a sticky
5739      // `null` also drops any previously retained caller policy, so it cannot
5740      // resurface on a later call, while still allowing the next config-less
5741      // call to restore the internal default policy. See GHSA-vxr8-fq34-vvx9.
5742      trustedTypesPolicy = undefined;
5743      emptyHTML = '';
5744    } else {
5745      // No policy supplied: keep the currently active policy if one is set — a
5746      // previously supplied policy is intentionally sticky across config-less
5747      // calls — otherwise fall back to the instance's own internal policy,
5748      // created at most once. (A policy supplied for a *single* call still
5749      // lingers by design; what must not linger is a policy whose configuration
5750      // has been torn down via `clearConfig()`, which restores the default.)
5751      if (trustedTypesPolicy === undefined) {
5752        trustedTypesPolicy = _getDefaultTrustedTypesPolicy();
5753      }
5754      // Sign internal variables only when a policy is active. A falsy policy
5755      // (Trusted Types unsupported, creation failed, or an explicit opt-out)
5756      // leaves `emptyHTML` as a plain string, so we never call `.createHTML` on
5757      // a non-policy and throw. See #1422.
5758      if (trustedTypesPolicy && typeof emptyHTML === 'string') {
5759        emptyHTML = _createTrustedHTML('');
5760      }
5761    }
5762    // Prevent further manipulation of configuration.
5763    // Not available in IE8, Safari 5, etc.
5764    if (freeze) {
5765      freeze(cfg);
5766    }
5767    CONFIG = cfg;
5768  };
5769  /* Keep track of all possible SVG and MathML tags
5770   * so that we can perform the namespace checks
5771   * correctly. */
5772  const ALL_SVG_TAGS = addToSet({}, [...svg$1, ...svgFilters, ...svgDisallowed]);
5773  const ALL_MATHML_TAGS = addToSet({}, [...mathMl$1, ...mathMlDisallowed]);
5774  /**
5775   * Namespace rules for an element in the SVG namespace.
5776   *
5777   * @param tagName the element's lowercase tag name
5778   * @param parent the (possibly simulated) parent node
5779   * @param parentTagName the parent's lowercase tag name
5780   * @returns true if a spec-compliant parser could produce this element
5781   */
5782  const _checkSvgNamespace = function _checkSvgNamespace(tagName, parent, parentTagName) {
5783    // The only way to switch from HTML namespace to SVG
5784    // is via <svg>. If it happens via any other tag, then
5785    // it should be killed.
5786    if (parent.namespaceURI === HTML_NAMESPACE) {
5787      return tagName === 'svg';
5788    }
5789    // The only way to switch from MathML to SVG is via <svg>
5790    // if the parent is either <annotation-xml> or a MathML
5791    // text integration point.
5792    if (parent.namespaceURI === MATHML_NAMESPACE) {
5793      return tagName === 'svg' && (parentTagName === 'annotation-xml' || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]);
5794    }
5795    // We only allow elements that are defined in SVG
5796    // spec. All others are disallowed in SVG namespace.
5797    return Boolean(ALL_SVG_TAGS[tagName]);
5798  };
5799  /**
5800   * Namespace rules for an element in the MathML namespace.
5801   *
5802   * @param tagName the element's lowercase tag name
5803   * @param parent the (possibly simulated) parent node
5804   * @param parentTagName the parent's lowercase tag name
5805   * @returns true if a spec-compliant parser could produce this element
5806   */
5807  const _checkMathMlNamespace = function _checkMathMlNamespace(tagName, parent, parentTagName) {
5808    // The only way to switch from HTML namespace to MathML
5809    // is via <math>. If it happens via any other tag, then
5810    // it should be killed.
5811    if (parent.namespaceURI === HTML_NAMESPACE) {
5812      return tagName === 'math';
5813    }
5814    // The only way to switch from SVG to MathML is via
5815    // <math> and HTML integration points
5816    if (parent.namespaceURI === SVG_NAMESPACE) {
5817      return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName];
5818    }
5819    // We only allow elements that are defined in MathML
5820    // spec. All others are disallowed in MathML namespace.
5821    return Boolean(ALL_MATHML_TAGS[tagName]);
5822  };
5823  /**
5824   * Namespace rules for an element in the HTML namespace.
5825   *
5826   * @param tagName the element's lowercase tag name
5827   * @param parent the (possibly simulated) parent node
5828   * @param parentTagName the parent's lowercase tag name
5829   * @returns true if a spec-compliant parser could produce this element
5830   */
5831  const _checkHtmlNamespace = function _checkHtmlNamespace(tagName, parent, parentTagName) {
5832    // The only way to switch from SVG to HTML is via
5833    // HTML integration points, and from MathML to HTML
5834    // is via MathML text integration points
5835    if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) {
5836      return false;
5837    }
5838    if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) {
5839      return false;
5840    }
5841    // We disallow tags that are specific for MathML
5842    // or SVG and should never appear in HTML namespace
5843    return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]);
5844  };
5845  /**
5846   * @param element a DOM element whose namespace is being checked
5847   * @returns Return false if the element has a
5848   *  namespace that a spec-compliant parser would never
5849   *  return. Return true otherwise.
5850   */
5851  const _checkValidNamespace = function _checkValidNamespace(element) {
5852    let parent = getParentNode(element);
5853    // In JSDOM, if we're inside shadow DOM, then parentNode
5854    // can be null. We just simulate parent in this case.
5855    if (!parent || !parent.tagName) {
5856      parent = {
5857        namespaceURI: NAMESPACE,
5858        tagName: 'template'
5859      };
5860    }
5861    const tagName = stringToLowerCase(element.tagName);
5862    const parentTagName = stringToLowerCase(parent.tagName);
5863    if (!ALLOWED_NAMESPACES[element.namespaceURI]) {
5864      return false;
5865    }
5866    if (element.namespaceURI === SVG_NAMESPACE) {
5867      return _checkSvgNamespace(tagName, parent, parentTagName);
5868    }
5869    if (element.namespaceURI === MATHML_NAMESPACE) {
5870      return _checkMathMlNamespace(tagName, parent, parentTagName);
5871    }
5872    if (element.namespaceURI === HTML_NAMESPACE) {
5873      return _checkHtmlNamespace(tagName, parent, parentTagName);
5874    }
5875    // For XHTML and XML documents that support custom namespaces
5876    if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && ALLOWED_NAMESPACES[element.namespaceURI]) {
5877      return true;
5878    }
5879    // The code should never reach this place (this means
5880    // that the element somehow got namespace that is not
5881    // HTML, SVG, MathML or allowed via ALLOWED_NAMESPACES).
5882    // Return false just in case.
5883    return false;
5884  };
5885  /**
5886   * _forceRemove
5887   *
5888   * @param node a DOM node
5889   */
5890  const _forceRemove = function _forceRemove(node) {
5891    arrayPush(DOMPurify.removed, {
5892      element: node
5893    });
5894    try {
vendor: 12,552 bytes, lines 5895-6182
5895      // eslint-disable-next-line unicorn/prefer-dom-node-remove
5896      getParentNode(node).removeChild(node);
5897    } catch (_) {
5898      /* The normal detach failed — this is reached for a parentless node
5899         (getParentNode() is null, so .removeChild throws). Element.prototype
5900         .remove() is itself a spec no-op on a parentless node, so a recorded
5901         "removal" would otherwise hand the caller back an intact,
5902         payload-bearing node (e.g. a detached IN_PLACE root the mXSS canary or
5903         the style-with-element-child rule decided to kill). Fail closed by
5904         throwing — exactly as a clobbered root does at the IN_PLACE entry —
5905         rather than trying to "neutralize" the node via its own methods.
5906         Neutralizing would mean calling getAttributeNames()/removeAttribute()
5907         on the node, both of which a <form> root can clobber via a named child
5908         (and _isClobbered does not even probe getAttributeNames), so the
5909         neutralize step could itself be silently defeated, leaving the payload
5910         intact. A throw touches only the cached, clobber-safe remove() and
5911         getParentNode(). Generalizes GHSA-r47g-fvhr-h676 (clobbered-form root)
5912         to every root-kill reason. REPORT-3.
5913                This lives inside the catch, so it never fires for a normally-removed
5914         in-tree node: those have a parent, removeChild() succeeds, and the
5915         catch is not entered. Only a kept (parentless) root reaches here. */
5916      remove(node);
5917      if (!getParentNode(node)) {
5918        throw typeErrorCreate('a node selected for removal could not be detached from its tree ' + 'and cannot be safely returned; refusing to sanitize in place');
5919      }
5920    }
5921  };
5922  /**
5923   * _neutralizeRoot
5924   *
5925   * Fail-closed teardown of an in-place root after the sanitize walk aborts
5926   * (campaign-3 F2). An internal throw mid-walk — e.g. a page-registered
5927   * custom element's reaction detaches a node so `_forceRemove`'s deliberate
5928   * parentless guard throws, or any other re-entrant engine mutation — would
5929   * otherwise leave the caller's *live* tree half-sanitized, with everything
5930   * after the abort point still carrying its handlers. There is no safe way
5931   * to resume the walk (the tree mutated under us), so we strip the root bare:
5932   * remove every child and every attribute, then let the caller's catch see
5933   * the original error. Clobber-safe (cached `remove`/`childNodes`/`attributes`
5934   * getters; the root was already clobber-pre-flighted at the IN_PLACE entry).
5935   *
5936   * @param root the in-place root to empty
5937   */
5938  const _neutralizeRoot = function _neutralizeRoot(root) {
5939    /* Strip every disallowed attribute (on* handlers included) off the whole
5940       subtree BEFORE detaching anything. Detaching first would hand back
5941       handler-bearing originals (e.g. an already-loading `<img onerror>`)
5942       whose queued resource event still fires in page scope after we throw.
5943       Clobber-safe reads; a doomed clobbered node's own attributes are
5944       irrelevant while its non-clobbered descendants are reached and scrubbed. */
5945    _neutralizeSubtree(root);
5946    const childNodes = getChildNodes(root);
5947    if (childNodes) {
5948      const snapshot = [];
5949      arrayForEach(childNodes, child => {
5950        arrayPush(snapshot, child);
5951      });
5952      arrayForEach(snapshot, child => {
5953        try {
5954          remove(child);
5955        } catch (_) {
5956          /* Best-effort teardown; a still-attached child is handled below */
5957        }
5958      });
5959    }
5960    const attributes = getAttributes(root);
5961    if (attributes) {
5962      for (let i = attributes.length - 1; i >= 0; --i) {
5963        const attribute = attributes[i];
5964        const name = attribute && attribute.name;
5965        if (typeof name === 'string') {
5966          try {
5967            root.removeAttribute(name);
5968          } catch (_) {
5969            /* Clobbered removeAttribute — ignore (fail-closed best effort) */
5970          }
5971        }
5972      }
5973    }
5974  };
5975  /**
5976   * _removeAttribute
5977   *
5978   * @param name an Attribute name
5979   * @param element a DOM node
5980   */
5981  const _removeAttribute = function _removeAttribute(name, element) {
5982    try {
5983      arrayPush(DOMPurify.removed, {
5984        attribute: element.getAttributeNode(name),
5985        from: element
5986      });
5987    } catch (_) {
5988      arrayPush(DOMPurify.removed, {
5989        attribute: null,
5990        from: element
5991      });
5992    }
5993    element.removeAttribute(name);
5994    // We void attribute values for unremovable "is" attributes
5995    if (name === 'is') {
5996      if (RETURN_DOM || RETURN_DOM_FRAGMENT) {
5997        try {
5998          _forceRemove(element);
5999        } catch (_) {}
6000      } else {
6001        try {
6002          element.setAttribute(name, '');
6003        } catch (_) {}
6004      }
6005    }
6006  };
6007  /**
6008   * _stripDisallowedAttributes
6009   *
6010   * Removes every attribute the active configuration does not allow from a
6011   * single element, using the same allowlist as the main attribute pass (so
6012   * `on*` handlers go, but no `/^on/` blocklist is introduced). Used only to
6013   * neutralise nodes that are being discarded from an in-place tree.
6014   *
6015   * @param element the element to strip
6016   */
6017  const _stripDisallowedAttributes = function _stripDisallowedAttributes(element) {
6018    const attributes = getAttributes(element);
6019    if (!attributes) {
6020      return;
6021    }
6022    for (let i = attributes.length - 1; i >= 0; --i) {
6023      const attribute = attributes[i];
6024      const name = attribute && attribute.name;
6025      if (typeof name !== 'string' || ALLOWED_ATTR[transformCaseFunc(name)]) {
6026        continue;
6027      }
6028      try {
6029        element.removeAttribute(name);
6030      } catch (_) {
6031        /* Clobbered removeAttribute on a doomed node — ignore */
6032      }
6033    }
6034  };
6035  /**
6036   * _neutralizeSubtree
6037   *
6038   * Completes the audit-5 F1 fix across every removal path. The KEEP_CONTENT
6039   * move-hoist neutralises only disallowed-tag removals; clobber, mXSS-canary,
6040   * namespace, comment, processing-instruction and KEEP_CONTENT:false removals
6041   * all drop their subtree wholesale via `_forceRemove`. On the IN_PLACE path
6042   * those dropped nodes are detached from the caller's LIVE tree but a
6043   * handler-bearing original among them (an `<img onerror>`/`<video>` that was
6044   * loading) keeps its queued resource event, which fires in page scope after
6045   * sanitize returns. This walks a removed subtree and strips every attribute
6046   * the active configuration does not allow — so `on*` handlers are cancelled
6047   * through the SAME allowlist that governs kept nodes, not a separate `/^on/`
6048   * blocklist. Run synchronously before sanitize returns, i.e. before any
6049   * queued event can fire. Hook-free by design: these nodes leave the output,
6050   * so firing attribute hooks for them would be surprising. Clobber-safe reads;
6051   * a doomed clobbered node may shadow `removeAttribute` (its own attributes are
6052   * irrelevant — it is discarded — while its non-clobbered descendants, e.g.
6053   * the `<img>`, are reached and scrubbed).
6054   *
6055   * @param root the root of a removed subtree to neutralise
6056   */
6057  const _neutralizeSubtree = function _neutralizeSubtree(root) {
6058    const stack = [root];
6059    while (stack.length > 0) {
6060      const node = stack.pop();
6061      const nodeType = getNodeType ? getNodeType(node) : node.nodeType;
6062      if (nodeType === NODE_TYPE.element) {
6063        _stripDisallowedAttributes(node);
6064      }
6065      const childNodes = getChildNodes(node);
6066      if (childNodes) {
6067        for (let i = childNodes.length - 1; i >= 0; --i) {
6068          stack.push(childNodes[i]);
6069        }
6070      }
6071    }
6072  };
6073  /**
6074   * _neutralizePatchLinkage
6075   *
6076   * IN_PLACE entry pre-pass (declarative-partial-updates / streaming
6077   * hardening, https://github.com/WICG/declarative-partial-updates).
6078   *
6079   * The main walk strips patch linkage (`for`/`patchsrc`) and removes range
6080   * markers (PIs / markup comments) node-by-node, in document order, AS it
6081   * reaches each node. On a live in-place root that leaves a window: from the
6082   * moment the root is connected until the walk arrives at a given node, that
6083   * node's linkage is live. A patch applied on connection/stream can fire as
6084   * a microtask during the walk and inject or teleport an unsanitized DOM
6085   * range into a region the iterator has already passed and will not revisit,
6086   * so the post-return "tree is sanitized" contract is violated. Sweep the
6087   * whole tree once up front and sever every linkage before the walk begins,
6088   * closing that window.
6089   *
6090   * This CANNOT undo a patch that already fired before sanitize ran — that is
6091   * the irreducible "do not IN_PLACE a live-connected attacker tree" caveat —
6092   * but it closes everything from sanitize-start onward. Gated on SAFE_FOR_XML
6093   * to group with the rest of the declarative-partial-updates handling and
6094   * stay overridable, consistent with the codebase.
6095   *
6096   * Clobber-safe traversal (cached childNodes getter); per-node try/catch so a
6097   * clobbered root cannot defeat the sweep of its non-clobbered descendants.
6098   *
6099   * NOTE (pending real-Chrome confirmation, see test/declarative-patch-probe
6100   * .html Q1): this mirrors the existing policy of keeping `for` on
6101   * <label>/<output>. If the shipping feature can drive a patch through a
6102   * surviving `for`-on-label/output + `id` pair, this pre-pass and the
6103   * attribute check at _isBasicCustomElement's caller must additionally drop
6104   * that pair on the IN_PLACE path. Left as-is until the taxonomy is verified.
6105   *
6106   * @param root the in-place root to sweep
6107   */
6108  const _neutralizePatchLinkage = function _neutralizePatchLinkage(root) {
6109    if (!SAFE_FOR_XML) {
6110      return;
6111    }
6112    const stack = [root];
6113    while (stack.length > 0) {
6114      const node = stack.pop();
6115      const nodeType = getNodeType ? getNodeType(node) : node.nodeType;
6116      /* Remove range markers (the target side of a patch linkage): every
6117         processing instruction, and any markup-bearing comment. */
6118      if (nodeType === NODE_TYPE.processingInstruction || nodeType === NODE_TYPE.comment && regExpTest(COMMENT_MARKUP_PROBE, node.data)) {
6119        try {
6120          remove(node);
6121        } catch (_) {
6122          /* Best-effort */
6123        }
6124        continue;
6125      }
6126      /* Strip patch-source attributes (the source side) off elements. */
6127      if (nodeType === NODE_TYPE.element) {
6128        const element = node;
6129        const lcTag = transformCaseFunc(getNodeName ? getNodeName(node) : node.nodeName);
6130        try {
6131          if (element.hasAttribute && element.hasAttribute('patchsrc')) {
6132            element.removeAttribute('patchsrc');
6133          }
6134          if (element.hasAttribute && element.hasAttribute('for') && lcTag !== 'label' && lcTag !== 'output') {
6135            element.removeAttribute('for');
6136          }
6137        } catch (_) {
6138          /* Clobbered removeAttribute/hasAttribute on a doomed node — ignore */
6139        }
6140      }
6141      const childNodes = getChildNodes(node);
6142      if (childNodes) {
6143        for (let i = childNodes.length - 1; i >= 0; --i) {
6144          stack.push(childNodes[i]);
6145        }
6146      }
6147    }
6148  };
6149  /**
6150   * _initDocument
6151   *
6152   * @param dirty - a string of dirty markup
6153   * @return a DOM, filled with the dirty markup
6154   */
6155  const _initDocument = function _initDocument(dirty) {
6156    /* Create a HTML document */
6157    let doc = null;
6158    let leadingWhitespace = null;
6159    if (FORCE_BODY) {
6160      dirty = '<remove></remove>' + dirty;
6161    } else {
6162      /* If FORCE_BODY isn't used, leading whitespace needs to be preserved manually */
6163      const matches = stringMatch(dirty, /^[\r\n\t ]+/);
6164      leadingWhitespace = matches && matches[0];
6165    }
6166    if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && NAMESPACE === HTML_NAMESPACE) {
6167      // Root of XHTML doc must contain xmlns declaration (see https://www.w3.org/TR/xhtml1/normative.html#strict)
6168      dirty = '<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>' + dirty + '</body></html>';
6169    }
6170    const dirtyPayload = trustedTypesPolicy ? _createTrustedHTML(dirty) : dirty;
6171    /*
6172     * Use the DOMParser API by default, fallback later if needs be
6173     * DOMParser not work for svg when has multiple root element.
6174     */
6175    if (NAMESPACE === HTML_NAMESPACE) {
6176      try {
6177        doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE);
6178      } catch (_) {}
6179    }
6180    /* Use createHTMLDocument in case DOMParser is not available */
6181    if (!doc || !doc.documentElement) {
6182      doc = implementation.createDocument(NAMESPACE, 'template', null);
vendor: 10,704 bytes, lines 6183-6396
6183      try {
6184        doc.documentElement.innerHTML = IS_EMPTY_INPUT ? emptyHTML : dirtyPayload;
6185      } catch (_) {
6186        // Syntax error if dirtyPayload is invalid xml
6187      }
6188    }
6189    const body = doc.body || doc.documentElement;
6190    if (dirty && leadingWhitespace) {
6191      body.insertBefore(document.createTextNode(leadingWhitespace), body.childNodes[0] || null);
6192    }
6193    /* Work on whole document or just its body */
6194    if (NAMESPACE === HTML_NAMESPACE) {
6195      return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0];
6196    }
6197    return WHOLE_DOCUMENT ? doc.documentElement : body;
6198  };
6199  /**
6200   * Creates a NodeIterator object that you can use to traverse filtered lists of nodes or elements in a document.
6201   *
6202   * @param root The root element or node to start traversing on.
6203   * @return The created NodeIterator
6204   */
6205  const _createNodeIterator = function _createNodeIterator(root) {
6206    /* Read ownerDocument through the cached Node.prototype getter, never the
6207       direct property. HTMLFormElement has [LegacyOverrideBuiltIns], so a
6208       clobbering child (<input name="ownerDocument"> or a form-associated
6209       external input) shadows the prototype getter and makes a direct read
6210       return that <input>. createNodeIterator.call(<input>, ...) then throws
6211       "Illegal invocation", and on the IN_PLACE path that throw lands before
6212       the walk's fail-closed barrier - leaving the caller's live tree, with
6213       any already-armed handler in it, un-neutralized. The cached getter
6214       returns the real Document regardless of the clobber. */
6215    const doc = getOwnerDocument ? getOwnerDocument(root) : root.ownerDocument;
6216    return createNodeIterator.call(doc || root, root,
6217    // eslint-disable-next-line no-bitwise
6218    NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT | NodeFilter.SHOW_PROCESSING_INSTRUCTION | NodeFilter.SHOW_CDATA_SECTION, null);
6219  };
6220  /**
6221   * Replace template expression syntax (mustache, ERB, template
6222   * literal) with a space; shared by all SAFE_FOR_TEMPLATES scrub
6223   * sites. Order matters: mustache, then ERB, then template literal.
6224   *
6225   * @param value the string to scrub
6226   * @returns the scrubbed string
6227   */
6228  const _stripTemplateExpressions = function _stripTemplateExpressions(value) {
6229    value = stringReplace(value, MUSTACHE_EXPR$1, ' ');
6230    value = stringReplace(value, ERB_EXPR$1, ' ');
6231    value = stringReplace(value, TMPLIT_EXPR$1, ' ');
6232    return value;
6233  };
6234  /**
6235   * Strip template-engine expressions ({{...}}, ${...}, <%...%>) from the
6236   * character data of an element subtree. Used as the final safety net for
6237   * SAFE_FOR_TEMPLATES on every DOM-returning code path so that expressions
6238   * which only form after text-node normalization (e.g. fragments split across
6239   * stripped elements) cannot survive into a template-evaluating framework.
6240   *
6241   * Walks text/comment/CDATA/processing-instruction nodes and mutates `.data`
6242   * in place rather than round-tripping through innerHTML. This preserves
6243   * descendant node references (important for IN_PLACE callers), avoids a
6244   * serialize/reparse cycle, and reads literal character data — which means
6245   * `<%...%>` in text content matches the ERB regex against its real bytes
6246   * instead of the HTML-entity-escaped form innerHTML would produce.
6247   *
6248   * Attribute values are not visited here; SAFE_FOR_TEMPLATES handling for
6249   * attributes is performed during the per-node `_sanitizeAttributes` pass.
6250   *
6251   * @param node The root element whose character data should be scrubbed.
6252   */
6253  const _scrubTemplateExpressions2 = function _scrubTemplateExpressions(node) {
6254    var _node$querySelectorAl;
6255    node.normalize();
6256    /* Clobber-safe ownerDocument read, same reasoning as _createNodeIterator:
6257       under SAFE_FOR_TEMPLATES this runs on the live IN_PLACE root, which may
6258       carry a form-named-getter override of ownerDocument. */
6259    const doc = getOwnerDocument ? getOwnerDocument(node) : node.ownerDocument;
6260    const walker = createNodeIterator.call(doc || node, node,
6261    // eslint-disable-next-line no-bitwise
6262    NodeFilter.SHOW_TEXT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_CDATA_SECTION | NodeFilter.SHOW_PROCESSING_INSTRUCTION, null);
6263    let currentNode = walker.nextNode();
6264    while (currentNode) {
6265      currentNode.data = _stripTemplateExpressions(currentNode.data);
6266      currentNode = walker.nextNode();
6267    }
6268    // NodeIterator does not descend into <template>.content per the DOM spec,
6269    // so we must explicitly recurse into each template's content fragment,
6270    // mirroring the approach used by _sanitizeShadowDOM.
6271    const templates = (_node$querySelectorAl = node.querySelectorAll) === null || _node$querySelectorAl === void 0 ? void 0 : _node$querySelectorAl.call(node, 'template');
6272    if (templates) {
6273      arrayForEach(templates, tmpl => {
6274        if (_isDocumentFragment(tmpl.content)) {
6275          _scrubTemplateExpressions2(tmpl.content);
6276        }
6277      });
6278    }
6279  };
6280  /**
6281   * _isClobbered
6282   *
6283   * Detect DOM-clobbering on HTMLFormElement nodes. Form is the only HTML
6284   * interface with [LegacyOverrideBuiltIns]; a descendant element with a
6285   * `name` attribute matching a prototype property shadows that property
6286   * on direct reads. We use this check at the IN_PLACE entry-point and
6287   * during attribute sanitization to refuse clobbered forms.
6288   *
6289   * @param element element to check for clobbering attacks
6290   * @return true if clobbered, false if safe
6291   */
6292  const _isClobbered = function _isClobbered(element) {
6293    // Realm-independent tag-name probe. If we can't determine the tag
6294    // name at all, we can't reason about clobbering — return false
6295    // (the caller's other defences still apply).
6296    const realTagName = getNodeName ? getNodeName(element) : null;
6297    if (typeof realTagName !== 'string') {
6298      return false;
6299    }
6300    if (transformCaseFunc(realTagName) !== 'form') {
6301      return false;
6302    }
6303    return typeof element.nodeName !== 'string' || typeof element.textContent !== 'string' || typeof element.removeChild !== 'function' ||
6304    // Realm-safe NamedNodeMap detection: equality against the cached
6305    // prototype getter. Clobbered .attributes (e.g. <input name="attributes">)
6306    // makes the direct read diverge from the cached read; a clean form
6307    // (same-realm OR foreign-realm) has both reads pointing at the same
6308    // canonical NamedNodeMap.
6309    element.attributes !== getAttributes(element) || typeof element.removeAttribute !== 'function' || typeof element.setAttribute !== 'function' || typeof element.namespaceURI !== 'string' || typeof element.insertBefore !== 'function' || typeof element.hasChildNodes !== 'function' ||
6310    // NodeType clobbering probe. Cached Node.prototype.nodeType getter
6311    // returns the integer 1 for any Element regardless of realm; direct
6312    // read on a clobbered form (e.g. <input name="nodeType">) returns
6313    // the named child element. Cheap addition — nodeType is read from
6314    // an internal slot, no serialization cost — and removes a residual
6315    // clobbering surface used by several mXSS / PI / comment branches
6316    // in _sanitizeElements that compare currentNode.nodeType directly.
6317    element.nodeType !== getNodeType(element) ||
6318    // HTMLFormElement has [LegacyOverrideBuiltIns]: a descendant named
6319    // "childNodes" shadows the prototype getter. Direct reads of
6320    // form.childNodes from a clobbered form return the named child
6321    // instead of the real NodeList, so any walk that reads it directly
6322    // skips the form's real children. Compare the direct read to the
6323    // cached Node.prototype getter — when the form's named-property
6324    // getter intercepts the read, the two values differ and we flag
6325    // the form. This catches every clobbering child type (input,
6326    // select, etc.) regardless of whether the named child happens to
6327    // carry a numeric .length, which a typeof-based probe would miss
6328    // (e.g. HTMLSelectElement.length is a defined unsigned-long).
6329    element.childNodes !== getChildNodes(element);
6330  };
6331  /**
6332   * Checks whether the given value is a DocumentFragment from any realm.
6333   *
6334   * The realm-independent replacement reads `nodeType` through the cached
6335   * Node.prototype getter and compares to the DOCUMENT_FRAGMENT_NODE
6336   * constant (11). nodeType is a numeric value resolved from the node's
6337   * internal slot, identical across realms for the same kind of node.
6338   *
6339   * @param value object to check
6340   * @return true if value is a DocumentFragment-shaped node from any realm
6341   */
6342  const _isDocumentFragment = function _isDocumentFragment(value) {
6343    if (!getNodeType || typeof value !== 'object' || value === null) {
6344      return false;
6345    }
6346    try {
6347      return getNodeType(value) === NODE_TYPE.documentFragment;
6348    } catch (_) {
6349      return false;
6350    }
6351  };
6352  /**
6353   * Checks whether the given object is a DOM node, including nodes that
6354   * originate from a different window/realm (e.g. an iframe's
6355   * contentDocument). The previous `value instanceof Node` check was
6356   * realm-bound: nodes from a different window failed it, causing
6357   * sanitize() to silently stringify them and reset IN_PLACE to false,
6358   * returning the original node unsanitized. See GHSA-4w3q-35jp-p934.
6359   *
6360   * @param value object to check whether it's a DOM node
6361   * @return true if value is a DOM node from any realm
6362   */
6363  const _isNode = function _isNode(value) {
6364    if (!getNodeType || typeof value !== 'object' || value === null) {
6365      return false;
6366    }
6367    try {
6368      return typeof getNodeType(value) === 'number';
6369    } catch (_) {
6370      return false;
6371    }
6372  };
6373  function _executeHooks(hooks, currentNode, data) {
6374    if (hooks.length === 0) {
6375      return;
6376    }
6377    arrayForEach(hooks, hook => {
6378      hook.call(DOMPurify, currentNode, data, CONFIG);
6379    });
6380  }
6381  /**
6382   * Structural-threat checks that condemn a node regardless of the
6383   * allowlists: mXSS via namespace confusion, risky CSS construction,
6384   * processing instructions, markup-bearing comments. Pure predicate;
6385   * the caller removes. Check order is load-bearing.
6386   *
6387   * @param currentNode the node to inspect
6388   * @param tagName the node's transformCaseFunc'd tag name
6389   * @return true if the node must be removed
6390   */
6391  const _isUnsafeNode = function _isUnsafeNode(currentNode, tagName) {
6392    /* Detect mXSS attempts abusing namespace confusion */
6393    if (SAFE_FOR_XML && currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(ELEMENT_MARKUP_PROBE, currentNode.textContent) && regExpTest(ELEMENT_MARKUP_PROBE, currentNode.innerHTML)) {
6394      return true;
6395    }
6396    /* Remove r
vendor: 1,737 bytes, lines 6396-6431
6396isky CSS construction leading to mXSS */
6397    if (SAFE_FOR_XML && currentNode.namespaceURI === HTML_NAMESPACE && tagName === 'style' && _isNode(currentNode.firstElementChild)) {
6398      return true;
6399    }
6400    /* Remove any occurrence of processing instructions */
6401    if (currentNode.nodeType === NODE_TYPE.processingInstruction) {
6402      return true;
6403    }
6404    /* Remove any kind of possibly harmful comments */
6405    if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(COMMENT_MARKUP_PROBE, currentNode.data)) {
6406      return true;
6407    }
6408    return false;
6409  };
6410  /**
6411   * Handle a node whose tag is forbidden or not allowlisted: keep
6412   * allowed custom elements (false return exits _sanitizeElements
6413   * early - the namespace and fallback-tag removal checks are
6414   * intentionally skipped for kept custom elements), else hoist
6415   * content per KEEP_CONTENT and remove.
6416   *
6417   * A kept custom element is the ONLY case in which this function
6418   * returns false, so the caller uses that return value to run the
6419   * afterSanitizeElements hook on the kept element and keep the
6420   * element-hook lifecycle consistent with normal allowlisted
6421   * elements (GHSA-c2j3-45gr-mqc4).
6422   *
6423   * @param currentNode the disallowed node
6424   * @param tagName the node's transformCaseFunc'd tag name
6425   * @return true if the node was removed, false if kept
6426   */
6427  const _sanitizeDisallowedNode = function _sanitizeDisallowedNode(currentNode, tagName, root) {
6428    /* Check if we have a custom element to handle */
6429    if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) {
6430      if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) {
6431        return false;
6432      }
6433      if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) {
6434        return false;
6435      }
6436    }
6437    /* Keep content except for bad-listed elements.
6438         Use the cached prototype getters exclusively — the previous code
6439         had `|| currentNode.parentNode` / `|| currentNode.childNodes`
6440         fallbacks, but the cached getters always return the canonical
6441         value (or null for a real parent-less node), so the fallback
6442         path was dead in safe cases and a clobbering surface in unsafe
6443         ones. Falsy cached results stay falsy; the `if (childNodes &&
6444         parentNode)` check already gates correctly. */
6445    if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) {
6446      const parentNode = getParentNode(currentNode);
6447      const childNodes = getChildNodes(currentNode);
6448      if (childNodes && parentNode) {
6449        const childCount = childNodes.length;
6450        /* Hoist by moving each child up one level rather than deep-cloning
6451             it. Moving transfers every descendant exactly once, so a chain of
6452             nested disallowed elements costs O(n) instead of the O(n^2) that
6453             re-cloning the shrinking subtree at each level produced; it also
6454             empties the removed original, so `DOMPurify.removed` no longer
6455             pins whole subtrees. Moving preserves the in-place guarantee too:
6456             an original carrying already-queued resource events (`<img
6457             onerror>`, `<video>`/`<audio>` error, lazy/`onload`, …) is
6458             relocated and sanitised rather than left detached but still armed.
6459                      The sole case that must clone is removing the walk root itself.
6460             The result is serialised from the root's subtree, so a restrictive
6461             ALLOWED_TAGS that strips the root (`body` on the string path) must
6462             leave the content inside it, which only cloning does. In IN_PLACE
6463             the root is pre-validated as an allowed tag and so is never removed
6464             here, so that path always takes the move branch.
6465                      `childNodes` is live; a tail-to-head walk keeps `childNodes[i]`
6466             valid whether we move (drops the trailing entry) or clone (leaves
6467             the list intact). */
6468        for (let i = childCount - 1; i >= 0; --i) {
6469          const hoisted = currentNode === root ? cloneNode(childNodes[i], true) : childNodes[i];
6470          parentNode.insertBefore(hoisted, getNextSibling(currentNode));
6471        }
6472      }
6473    }
6474    _forceRemove(currentNode);
6475    return true;
6476  };
6477  /**
6478   * Fork a hook-mutable allowlist off its shared binding the first time a
6479   * (possibly lazily-installed) uponSanitize* hook is about to see it, so the
6480   * hook cannot widen the per-instance default or the setConfig binding by
6481   * reference and leak past the call. Returns the set unchanged once it is
6482   * already call-local, so repeated calls across elements are idempotent.
6483   *
6484   * @param hookList the uponSanitize* hook array for this event
6485   * @param set the current ALLOWED_TAGS / ALLOWED_ATTR binding
6486   * @param defaultSet the per-instance DEFAULT_ALLOWED_* constant
6487   * @param setConfigSet the captured setConfig() binding, or null
6488   * @return a call-local clone if a hook is present and set is still shared,
6489   *   else set unchanged
6490   */
6491  const _forkSharedAllowlist = function _forkSharedAllowlist(hookList, set, defaultSet, setConfigSet) {
6492    if (hookList.length === 0) {
6493      return set;
6494    }
6495    return set === defaultSet || set === setConfigSet ? clone(set) : set;
6496  };
6497  /**
6498   * _sanitizeElements
6499   *
6500   * @protect nodeName
6501   * @protect textContent
6502   * @protect removeChild
6503   * @param currentNode to check for permission to exist
6504   * @return true if node was killed, false if left alive
6505   */
6506  // eslint-disable-next-line complexity
6507  const _sanitizeElements = function _sanitizeElements(currentNode, root) {
6508    /* Execute a hook if present */
6509    _executeHooks(hooks.beforeSanitizeElements, currentNode, null);
6510    /* A hook may have detached the node - treat it as removed (see the
6511       detached-node comment after the uponSanitizeElement hook below). On
6512       the IN_PLACE path, neutralize the detached subtree first so a queued
6513       resource handler on it cannot fire in page scope after we return. */
6514    if (currentNode !== root && getParentNode(currentNode) === null) {
6515      if (IN_PLACE) {
6516        _neutralizeSubtree(currentNode);
6517      }
6518      return true;
6519    }
6520    /* Check if element is clobbered or can clobber */
6521    if (_isClobbered(currentNode)) {
6522      _forceRemove(currentNode);
6523      return true;
6524    }
6525    /* Now let's check the element's type and name */
6526    const tagName = transformCaseFunc(getNodeName ? getNodeName(currentNode) : currentNode.nodeName);
6527    /* Close the pre-walk clone-guard's timing gap: an uponSanitizeElement
6528       hook may have been installed after that guard sampled the hook arrays
6529       (e.g. lazily from beforeSanitizeElements), leaving ALLOWED_TAGS still
6530       aliasing a shared binding that a widening hook would mutate by
6531       reference. Fork it before exposing it to the hook. */
6532    ALLOWED_TAGS = _forkSharedAllowlist(hooks.uponSanitizeElement, ALLOWED_TAGS, DEFAULT_ALLOWED_TAGS, SET_CONFIG_ALLOWED_TAGS);
6533    /* Execute a hook if present */
6534    _executeHooks(hooks.uponSanitizeElement, currentNode, {
6535      tagName,
6536      allowedTags: ALLOWED_TAGS
6537    });
6538    /* A hook may have detached the node from the tree — a long-standing
6539       user pattern (issue #469; draw.io-style foreignObject filtering).
6540       Per the cached, unclobberable parentNode getter the node is
6541       genuinely out of the tree, so it can reach neither the serialized
6542       output nor an IN_PLACE live tree; treat it as removed and stop
6543       processing it. Without this guard, the unsafe-node / namespace
6544       checks below would call _forceRemove on a parentless node and hit
6545       the REPORT-3 fail-closed throw — which exists for nodes DOMPurify
6546       wants gone but *cannot* detach (clobbered / parentless roots), the
6547       opposite of a node that is already safely gone. The walk root is
6548       exempt: a detached IN_PLACE root is legitimate input and must still
6549       be fully sanitized, and a kill-decision on it must keep hitting the
6550       REPORT-3 throw. Nodes detached by hooks stay the hook's
6551       responsibility for placement: they are not recorded in
6552       DOMPurify.removed, so the post-walk IN_PLACE pass (which iterates
6553       DOMPurify.removed) does not reach them. But a hook-detached subtree
6554       can still hold a queued resource-event handler - e.g. an <img onload>
6555       that began loading when the caller built the live tree - which fires
6556       in page scope after sanitize returns even though the handler never
6557       reached the returned tree. That is the audit-5 F1 hazard, and the
6558       documented node.remove() hook pattern walks straight into it. So on
6559       the IN_PLACE path we neutralize the detached subtree inline here,
6560       stripping its non-allow-listed attributes before returning, exactly
6561       as the post-walk pass does for _forceRemove'd subtrees. */
6562    if (currentNode !== root && getParentNode(currentNode) === null) {
6563      if (IN_PLACE) {
6564        _neutralizeSubtree(currentNode);
6565      }
6566      return true;
6567    }
6568    /* Remove mXSS vectors, processing instructions and risky comments */
6569    if (_isUnsafeNode(currentNode, tagName)) {
6570      _forceRemove(currentNode);
6571      return true;
6572    }
6573    /* Remove element if anything forbids its presence */
6574    if (FORBID_TAGS[tagName] || !(EXTRA_ELEMENT_HANDLING.tagCheck instanceof Function && EXTRA_ELEMENT_HANDLING.tagCheck(tagName)) && !ALLOWED_TAGS[tagName]) {
6575      const removed = _sanitizeDisallowedNode(currentNode, tagName, root
vendor: 7,065 bytes, lines 6575-6685
6575);
6576      /* A false return means the node is a custom element kept via
6577         CUSTOM_ELEMENT_HANDLING - the only keep path through
6578         _sanitizeDisallowedNode. Run afterSanitizeElements on it so the
6579         element-hook lifecycle matches normal allowlisted elements: a
6580         security policy applied in this hook (e.g. stripping an attribute
6581         from every surviving element) must not silently skip kept custom
6582         elements (GHSA-c2j3-45gr-mqc4). This mirrors the normal-element
6583         tail below - the hook runs, then the walker's subsequent
6584         _sanitizeAttributes pass sanitizes the element's attributes. The
6585         deliberately skipped namespace and fallback-tag removal checks stay
6586         skipped; they are removal decisions, not the hook contract. */
6587      if (removed === false) {
6588        _executeHooks(hooks.afterSanitizeElements, currentNode, null);
6589      }
6590      return removed;
6591    }
6592    /* Check whether element has a valid namespace.
6593       Realm-safe check (GHSA-hpcv-96wg-7vj8): use the cached Node.prototype
6594       nodeType getter rather than `instanceof Element`, which is realm-
6595       bound and short-circuits to false for any node minted in a different
6596       realm — letting a foreign-realm element with a forbidden namespace
6597       slip past the namespace check entirely. */
6598    const nt = getNodeType ? getNodeType(currentNode) : currentNode.nodeType;
6599    if (nt === NODE_TYPE.element && !_checkValidNamespace(currentNode)) {
6600      _forceRemove(currentNode);
6601      return true;
6602    }
6603    /* Make sure that older browsers don't get fallback-tag mXSS */
6604    if ((tagName === 'noscript' || tagName === 'noembed' || tagName === 'noframes') && regExpTest(FALLBACK_TAG_CLOSE, currentNode.innerHTML)) {
6605      _forceRemove(currentNode);
6606      return true;
6607    }
6608    /* Sanitize element content to be template-safe */
6609    if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) {
6610      /* Get the element's text content */
6611      const content = _stripTemplateExpressions(currentNode.textContent);
6612      if (currentNode.textContent !== content) {
6613        arrayPush(DOMPurify.removed, {
6614          element: currentNode.cloneNode()
6615        });
6616        currentNode.textContent = content;
6617      }
6618    }
6619    /* Execute a hook if present */
6620    _executeHooks(hooks.afterSanitizeElements, currentNode, null);
6621    return false;
6622  };
6623  /**
6624   * _isValidAttribute
6625   *
6626   * @param lcTag Lowercase tag name of containing element.
6627   * @param lcName Lowercase attribute name.
6628   * @param value Attribute value.
6629   * @return Returns true if `value` is valid, otherwise false.
6630   */
6631  // eslint-disable-next-line complexity
6632  const _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) {
6633    /* FORBID_ATTR must always win, even if ADD_ATTR predicate would allow it */
6634    if (FORBID_ATTR[lcName]) {
6635      return false;
6636    }
6637    /* Reject declarative-partial-updates patch-linkage attributes
6638       (https://github.com/WICG/declarative-partial-updates).
6639            Empirical note (Chrome 150, verified — see
6640       test/declarative-patch-probe-v3.html): expansion is NOT applied after
6641       sanitization. For the string path it fires during sanitize()'s own
6642       parse, so the walk sees and sanitizes the fully materialized expanded
6643       tree — teleports into MathML/SVG integration points included; a
6644       weaponized `<template for>`->`<img onerror>` comes back with the handler
6645       stripped. For the IN_PLACE path it fires on connection, before the walk.
6646       Either way DOMPurify is NOT blind to the patch.
6647            This removal is therefore defense-in-depth rather than the sole barrier:
6648       it prevents live linkage from surviving into the OUTPUT and re-expanding
6649       in the caller's context, and keeps behaviour deterministic if a future
6650       engine defers expansion. `for` is legitimate only on <label>/<output>;
6651       anywhere else (notably <template for>) it links the element to a patch
6652       target and teleports or removes an arbitrary DOM range by id/marker name.
6653       `patchsrc` fetches remote markup and is treated as a script-loading
6654       mechanism (CSP). Gated on SAFE_FOR_XML so the removal groups with the
6655       other structural-threat checks and stays overridable, consistent with
6656       the rest of the codebase. PI range markers are already removed by
6657       _isUnsafeNode. */
6658    if (SAFE_FOR_XML && lcName === 'patchsrc') {
6659      return false;
6660    }
6661    if (SAFE_FOR_XML && lcName === 'for' && lcTag !== 'label' && lcTag !== 'output') {
6662      return false;
6663    }
6664    /* Make sure attribute cannot clobber */
6665    if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) {
6666      return false;
6667    }
6668    const nameIsPermitted = ALLOWED_ATTR[lcName] || EXTRA_ELEMENT_HANDLING.attributeCheck instanceof Function && EXTRA_ELEMENT_HANDLING.attributeCheck(lcName, lcTag);
6669    /* Allow valid data-* attributes: At least one character after "-"
6670        (https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes)
6671        XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804)
6672        We don't need to check the value; it's always URI safe. */
6673    if (ALLOW_DATA_ATTR && regExpTest(DATA_ATTR$1, lcName)) ; else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR$1, lcName)) ; else if (!nameIsPermitted) {
6674      if (
6675      // First condition does a very basic check if a) it's basically a valid custom element tagname AND
6676      // b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
6677      // and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck
6678      _isBasicCustomElement(lcTag) && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, lcTag) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(lcTag)) && (CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.attributeNameCheck, lcName) || CUSTOM_ELEMENT_HANDLING.attributeNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.attributeNameCheck(lcName, lcTag)) ||
6679      // Alternative, second condition checks if it's an `is`-attribute, AND
6680      // the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck
6681      lcName === 'is' && CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements && (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, value) || CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(value))) ; else {
6682        return false;
6683      }
6684      /* Check value is safe. First, is attr inert? If so, is safe */
6685    } else if (URI_SAFE_ATTRIBUTES[lcName]) ; else if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE$1
vendor: 4,485 bytes, lines 6685-6782
6685$1, ''))) ; else if ((lcName === 'src' || lcName === 'xlink:href' || lcName === 'href') && lcTag !== 'script' && stringIndexOf(value, 'data:') === 0 && DATA_URI_TAGS[lcTag]) ; else if (ALLOW_UNKNOWN_PROTOCOLS && !regExpTest(IS_SCRIPT_OR_DATA$1, stringReplace(value, ATTR_WHITESPACE$1$1, ''))) ; else if (value) {
6686      return false;
6687    } else ;
6688    return true;
6689  };
6690  /* Names the HTML spec reserves from valid-custom-element-name; these must
6691   * never be treated as basic custom elements even when a permissive
6692   * CUSTOM_ELEMENT_HANDLING.tagNameCheck is configured. */
6693  const RESERVED_CUSTOM_ELEMENT_NAMES = addToSet({}, ['annotation-xml', 'color-profile', 'font-face', 'font-face-format', 'font-face-name', 'font-face-src', 'font-face-uri', 'missing-glyph']);
6694  /**
6695   * _isBasicCustomElement
6696   * checks if at least one dash is included in tagName, and it's not the first char
6697   * for more sophisticated checking see https://github.com/sindresorhus/validate-element-name
6698   *
6699   * @param tagName name of the tag of the node to sanitize
6700   * @returns Returns true if the tag name meets the basic criteria for a custom element, otherwise false.
6701   */
6702  const _isBasicCustomElement = function _isBasicCustomElement(tagName) {
6703    return !RESERVED_CUSTOM_ELEMENT_NAMES[stringToLowerCase(tagName)] && regExpTest(CUSTOM_ELEMENT$1, tagName);
6704  };
6705  /**
6706   * Wrap an attribute value in the matching Trusted Types object when
6707   * the active policy requires it. Namespaced attributes pass through
6708   * unchanged (no TT support yet, see
6709   * https://bugs.chromium.org/p/chromium/issues/detail?id=1305293).
6710   *
6711   * @param lcTag lowercase tag name of the containing element
6712   * @param lcName lowercase attribute name
6713   * @param namespaceURI the attribute's namespace, if any
6714   * @param value the attribute value to wrap
6715   * @return the value, wrapped when Trusted Types demand it
6716   */
6717  const _applyTrustedTypesToAttribute = function _applyTrustedTypesToAttribute(lcTag, lcName, namespaceURI, value) {
6718    if (trustedTypesPolicy && typeof trustedTypes === 'object' && typeof trustedTypes.getAttributeType === 'function' && !namespaceURI) {
6719      switch (trustedTypes.getAttributeType(lcTag, lcName)) {
6720        case 'TrustedHTML':
6721          {
6722            return _createTrustedHTML(value);
6723          }
6724        case 'TrustedScriptURL':
6725          {
6726            return _createTrustedScriptURL(value);
6727          }
6728      }
6729    }
6730    return value;
6731  };
6732  /**
6733   * Write a modified attribute value back onto the element. On
6734   * success, re-probe for clobbering introduced by the new value and
6735   * remove the element when found; otherwise pop the removal entry
6736   * recorded by the earlier _removeAttribute (long-standing pairing
6737   * with the SANITIZE_NAMED_PROPS path - do not "fix" casually). On
6738   * failure, remove the attribute instead.
6739   *
6740   * @param currentNode the element carrying the attribute
6741   * @param name the attribute name as present on the element
6742   * @param namespaceURI the attribute's namespace, if any
6743   * @param value the new attribute value
6744   */
6745  const _setAttributeValue = function _setAttributeValue(currentNode, name, namespaceURI, value) {
6746    try {
6747      if (namespaceURI) {
6748        currentNode.setAttributeNS(namespaceURI, name, value);
6749      } else {
6750        /* Fallback to setAttribute() for browser-unrecognized namespaces e.g. "x-schema". */
6751        currentNode.setAttribute(name, value);
6752      }
6753      if (_isClobbered(currentNode)) {
6754        _forceRemove(currentNode);
6755      } else {
6756        arrayPop(DOMPurify.removed);
6757      }
6758    } catch (_) {
6759      _removeAttribute(name, currentNode);
6760    }
6761  };
6762  /**
6763   * _sanitizeAttributes
6764   *
6765   * @protect attributes
6766   * @protect nodeName
6767   * @protect removeAttribute
6768   * @protect setAttribute
6769   *
6770   * @param currentNode to sanitize
6771   */
6772  const _sanitizeAttributes = function _sanitizeAttributes(currentNode) {
6773    /* Execute a hook if present */
6774    _executeHooks(hooks.beforeSanitizeAttributes, currentNode, null);
6775    const attributes = currentNode.attributes;
6776    /* Check if we have attributes; if not we might have a text node */
6777    if (!attributes || _isClobbered(currentNode)) {
6778      return;
6779    }
6780    /* Same lazy-install guard as uponSanitizeElement (see there): fork the
6781       attribute allowlist off its shared binding before a hook can see it. */
6782    ALLOWED_ATTR = _forkSharedAllowlist(hooks.uponSanitizeAttribute, ALLOWED_ATTR, DEFAULT_ALLOWED_ATTR, SET_CONFIG_ALLOWED_ATTR);
vendor: 5,961 bytes, lines 6782-6917
6782
6783    const hookEvent = {
6784      attrName: '',
6785      attrValue: '',
6786      keepAttr: true,
6787      allowedAttributes: ALLOWED_ATTR,
6788      forceKeepAttr: undefined
6789    };
6790    let l = attributes.length;
6791    const lcTag = transformCaseFunc(currentNode.nodeName);
6792    /* Go backwards over all attributes; safely remove bad ones */
6793    while (l--) {
6794      const attr = attributes[l];
6795      const name = attr.name,
6796        namespaceURI = attr.namespaceURI,
6797        attrValue = attr.value;
6798      const lcName = transformCaseFunc(name);
6799      const initValue = attrValue;
6800      let value = name === 'value' ? initValue : stringTrim(initValue);
6801      /* Execute a hook if present */
6802      hookEvent.attrName = lcName;
6803      hookEvent.attrValue = value;
6804      hookEvent.keepAttr = true;
6805      hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set
6806      _executeHooks(hooks.uponSanitizeAttribute, currentNode, hookEvent);
6807      value = hookEvent.attrValue;
6808      /* Full DOM Clobbering protection via namespace isolation,
6809       * Prefix id and name attributes with `user-content-`
6810       */
6811      if (SANITIZE_NAMED_PROPS && (lcName === 'id' || lcName === 'name') && stringIndexOf(value, SANITIZE_NAMED_PROPS_PREFIX) !== 0) {
6812        // Remove the attribute with this value
6813        _removeAttribute(name, currentNode);
6814        // Prefix the value and later re-create the attribute with the sanitized value
6815        value = SANITIZE_NAMED_PROPS_PREFIX + value;
6816      }
6817      // Else: already prefixed, leave the attribute alone — the prefix is
6818      // itself the clobbering protection, and re-applying it is incorrect.
6819      /* Work around a security issue with comments inside attributes */
6820      if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|script|title|xmp|textarea|noscript|iframe|noembed|noframes)/i, value)) {
6821        _removeAttribute(name, currentNode);
6822        continue;
6823      }
6824      /* Make sure we cannot easily use animated hrefs, even if animations are allowed */
6825      if (lcName === 'attributename' && stringMatch(value, 'href')) {
6826        _removeAttribute(name, currentNode);
6827        continue;
6828      }
6829      /* Did the hooks force-keep the attribute? */
6830      if (hookEvent.forceKeepAttr) {
6831        continue;
6832      }
6833      /* Did the hooks approve of the attribute? */
6834      if (!hookEvent.keepAttr) {
6835        _removeAttribute(name, currentNode);
6836        continue;
6837      }
6838      /* Work around a security issue in jQuery 3.0 */
6839      if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(SELF_CLOSING_TAG, value)) {
6840        _removeAttribute(name, currentNode);
6841        continue;
6842      }
6843      /* Sanitize attribute content to be template-safe */
6844      if (SAFE_FOR_TEMPLATES) {
6845        value = _stripTemplateExpressions(value);
6846      }
6847      /* Is `value` valid for this attribute? */
6848      if (!_isValidAttribute(lcTag, lcName, value)) {
6849        _removeAttribute(name, currentNode);
6850        continue;
6851      }
6852      /* Handle attributes that require Trusted Types */
6853      value = _applyTrustedTypesToAttribute(lcTag, lcName, namespaceURI, value);
6854      /* Handle invalid data-* attribute set by try-catching it */
6855      if (value !== initValue) {
6856        _setAttributeValue(currentNode, name, namespaceURI, value);
6857      }
6858    }
6859    /* Execute a hook if present */
6860    _executeHooks(hooks.afterSanitizeAttributes, currentNode, null);
6861  };
6862  /**
6863   * _sanitizeShadowDOM
6864   *
6865   * @param fragment to iterate over recursively
6866   */
6867  const _sanitizeShadowDOM2 = function _sanitizeShadowDOM(fragment) {
6868    let shadowNode = null;
6869    const shadowIterator = _createNodeIterator(fragment);
6870    /* Execute a hook if present */
6871    _executeHooks(hooks.beforeSanitizeShadowDOM, fragment, null);
6872    while (shadowNode = shadowIterator.nextNode()) {
6873      /* Execute a hook if present */
6874      _executeHooks(hooks.uponSanitizeShadowNode, shadowNode, null);
6875      /* Sanitize tags and elements */
6876      _sanitizeElements(shadowNode, fragment);
6877      /* Check attributes next */
6878      _sanitizeAttributes(shadowNode);
6879      /* Deep shadow DOM detected.
6880         Realm-safe check (GHSA-hpcv-96wg-7vj8): use nodeType against the
6881         DOCUMENT_FRAGMENT_NODE constant rather than instanceof, so we
6882         recurse into <template>.content from foreign realms too. */
6883      if (_isDocumentFragment(shadowNode.content)) {
6884        _sanitizeShadowDOM2(shadowNode.content);
6885      }
6886      /* An element iterated here may itself host an attached
6887         shadow root. The default NodeIterator does not enter shadow
6888         trees, so a shadow root nested inside template.content was
6889         previously reached by no walk at all (the pre-pass at
6890         _sanitizeAttachedShadowRoots descends via childNodes, which
6891         doesn't enter template.content; the template-content recursion
6892         above iterates the content but never inspected shadowRoot).
6893         Walk it explicitly. The nodeType guard avoids reading
6894         shadowRoot off text / comment / CDATA / PI nodes that the
6895         iterator also surfaces. */
6896      const shadowNodeType = getNodeType ? getNodeType(shadowNode) : shadowNode.nodeType;
6897      if (shadowNodeType === NODE_TYPE.element) {
6898        const innerSr = getShadowRoot(shadowNode);
6899        if (_isDocumentFragment(innerSr)) {
6900          _sanitizeAttachedShadowRoots(innerSr);
6901          _sanitizeShadowDOM2(innerSr);
6902        }
6903      }
6904    }
6905    /* Execute a hook if present */
6906    _executeHooks(hooks.afterSanitizeShadowDOM, fragment, null);
6907  };
6908  /**
6909   * _sanitizeAttachedShadowRoots
6910   *
6911   * Walks `root` and feeds every attached shadow root we encounter into
6912   * the existing _sanitizeShadowDOM pipeline. The default node iterator
6913   * does not descend into shadow trees, so nodes inside an attached
6914   * shadow root would otherwise be skipped entirely.
6915   *
6916   * Two real input paths put attached shadow roots in front of us:
6917   *   1. IN_PLACE on a DOM node that already has shadow roots attached.
vendor: 3,953 bytes, lines 6918-7007
6918   *   2. DOM-node input where importNode(dirty, true) deep-clones the
6919   *      shadow root because it was created with `clonable: true`.
6920   *
6921   * This pass runs once, up front, so the main iteration loop (and the
6922   * existing _sanitizeShadowDOM template-content recursion) stay
6923   * untouched — string-input paths are not affected.
6924   *
6925   * @param root the subtree root to walk for attached shadow roots
6926   */
6927  const _sanitizeAttachedShadowRoots = function _sanitizeAttachedShadowRoots(root) {
6928    /* Iterative (explicit stack) rather than per-child recursion. DOM APIs
6929       impose no depth cap, so an attacker-shaped tree (JSON/CRDT/editor data
6930       built straight into the DOM — the IN_PLACE surface) deeper than the JS
6931       call-stack budget would otherwise overflow native recursion here and
6932       throw at the IN_PLACE entry pre-pass, before a single node is
6933       sanitized, leaving the caller's live tree untouched (fail-open). See
6934       campaign-3 F4. A heap stack keeps depth off the call stack.
6935            Each work item is either a node to descend into, or a deferred
6936       `_sanitizeShadowDOM` for an already-walked shadow root. The deferred
6937       form preserves the original post-order discipline: a shadow root's
6938       nested shadow roots are discovered before the outer shadow is
6939       sanitized (which may remove hosts). Pushes are in reverse of the
6940       desired processing order (LIFO): template content, then children, then
6941       the shadow-sanitize, then the shadow walk — so the order matches the
6942       previous recursion exactly. */
6943    const stack = [{
6944      node: root,
6945      shadow: null
6946    }];
6947    while (stack.length > 0) {
6948      const item = stack.pop();
6949      /* Deferred shadow-DOM sanitisation: runs after its subtree was walked. */
6950      if (item.shadow) {
6951        _sanitizeShadowDOM2(item.shadow);
6952        continue;
6953      }
6954      const node = item.node;
6955      const nodeType = getNodeType ? getNodeType(node) : node.nodeType;
6956      const isElement = nodeType === NODE_TYPE.element;
6957      /* (pushed last → processed first) Children, snapshotted in reverse so
6958         the first child is processed first. Snapshotting matters because a
6959         hook may detach siblings mid-walk. */
6960      const childNodes = getChildNodes(node);
6961      if (childNodes) {
6962        for (let i = childNodes.length - 1; i >= 0; --i) {
6963          stack.push({
6964            node: childNodes[i],
6965            shadow: null
6966          });
6967        }
6968      }
6969      /* (pushed before children → processed after them, matching the old
6970         "template content last" order) When the node is a <template>,
6971         descend into its content. */
6972      if (isElement) {
6973        const rootName = getNodeName ? getNodeName(node) : null;
6974        if (typeof rootName === 'string' && transformCaseFunc(rootName) === 'template') {
6975          const content = node.content;
6976          if (_isDocumentFragment(content)) {
6977            stack.push({
6978              node: content,
6979              shadow: null
6980            });
6981          }
6982        }
6983      }
6984      /* Shadow root (processed first): walk its subtree, then sanitise it.
6985         Realm-safe check (GHSA-hpcv-96wg-7vj8): nodeType-based detection
6986         rather than `instanceof DocumentFragment`, which is realm-bound and
6987         silently skipped foreign-realm shadow roots (e.g.
6988         iframe.contentDocument attachShadow). */
6989      if (isElement) {
6990        const sr = getShadowRoot(node);
6991        if (_isDocumentFragment(sr)) {
6992          /* Push the deferred sanitise first so it pops after the shadow
6993             walk we push next, i.e. nested shadow roots are discovered
6994             before this one is sanitised. */
6995          stack.push({
6996            node: null,
6997            shadow: sr
6998          }, {
6999            node: sr,
7000            shadow: null
7001          });
7002        }
7003      }
7004    }
7005  };
7006  // eslint-disable-next-line complexity
7007  DOMPurify.sanitize = function (dirty) {
vendor: 5,221 bytes, lines 7008-7105
7008    let cfg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
7009    let body = null;
7010    let importedNode = null;
7011    let currentNode = null;
7012    let returnNode = null;
7013    /* Make sure we have a string to sanitize.
7014      DO NOT return early, as this will return the wrong type if
7015      the user has requested a DOM object rather than a string */
7016    IS_EMPTY_INPUT = !dirty;
7017    if (IS_EMPTY_INPUT) {
7018      dirty = '<!-->';
7019    }
7020    /* Stringify, in case dirty is an object */
7021    if (typeof dirty !== 'string' && !_isNode(dirty)) {
7022      dirty = stringifyValue(dirty);
7023      if (typeof dirty !== 'string') {
7024        throw typeErrorCreate('dirty is not a string, aborting');
7025      }
7026    }
7027    /* Return dirty HTML if DOMPurify cannot run */
7028    if (!DOMPurify.isSupported) {
7029      return dirty;
7030    }
7031    /* Assign config vars */
7032    if (SET_CONFIG) {
7033      /* Persistent setConfig() path: _parseConfig is skipped, so the sets are
7034       * not re-derived per call. Restore them from the pristine bindings
7035       * captured at setConfig() time so a previous call's hook clone (mutated
7036       * below) does not carry over. */
7037      ALLOWED_TAGS = SET_CONFIG_ALLOWED_TAGS;
7038      ALLOWED_ATTR = SET_CONFIG_ALLOWED_ATTR;
7039    } else {
7040      _parseConfig(cfg);
7041    }
7042    /* Clone the hook-mutable allowlists before the walk whenever an
7043     * uponSanitize* hook is registered. The hook event exposes ALLOWED_TAGS
7044     * and ALLOWED_ATTR by reference (as allowedTags / allowedAttributes), so
7045     * a hook that widens them would otherwise mutate the shared set
7046     * permanently: across later calls and across every element. Cloning per
7047     * walk keeps documented in-call widening working while scoping it to the
7048     * call. A single guard for both config paths - the per-call path rebinds
7049     * the sets in _parseConfig each call, the persistent path restores them
7050     * from the captured bindings just above - so the two cannot diverge. */
7051    if (hooks.uponSanitizeElement.length > 0 || hooks.uponSanitizeAttribute.length > 0) {
7052      ALLOWED_TAGS = clone(ALLOWED_TAGS);
7053    }
7054    if (hooks.uponSanitizeAttribute.length > 0) {
7055      ALLOWED_ATTR = clone(ALLOWED_ATTR);
7056    }
7057    /* Clean up removed elements */
7058    DOMPurify.removed = [];
7059    /* Resolve IN_PLACE for this call without mutating persistent config.
7060       Writing the IN_PLACE closure variable here leaks under setConfig(),
7061       where _parseConfig is skipped on later calls: a single string call would
7062       disable in-place mode for every subsequent node call, returning a
7063       sanitized copy while leaving the caller's node — which in-place callers
7064       keep using and whose return value they ignore — unsanitized. REPORT-2. */
7065    const inPlace = IN_PLACE && typeof dirty !== 'string' && _isNode(dirty);
7066    if (inPlace) {
7067      /* Declarative-partial-updates / streaming pre-pass: sever every patch
7068         linkage across the live tree BEFORE the walk, so no patch can fire
7069         mid-walk and inject into an already-processed region. Runs first, so
7070         it also covers the forbidden/clobbered roots that throw below. */
7071      _neutralizePatchLinkage(dirty);
7072      /* Do some early pre-sanitization to avoid unsafe root nodes.
7073         Read nodeName through the cached prototype getter — a clobbering
7074         child named "nodeName" on the form root would otherwise shadow
7075         the property and let this check skip the root-allowlist
7076         validation entirely. */
7077      const nn = getNodeName ? getNodeName(dirty) : dirty.nodeName;
7078      if (typeof nn === 'string') {
7079        const tagName = transformCaseFunc(nn);
7080        if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) {
7081          /* Fail closed on a live root: neutralize handlers/children before
7082             throwing, exactly as the mid-walk abort path does. */
7083          _neutralizeRoot(dirty);
7084          throw typeErrorCreate('root node is forbidden and cannot be sanitized in-place');
7085        }
7086      }
7087      /* Pre-flight the root through _isClobbered. The iterator-driven
7088         removal path can not detach a parent-less root: _forceRemove
7089         falls through to Element.prototype.remove(), which per spec
7090         is a no-op on a node with no parent. A clobbered root would
7091         then survive the main loop with its attributes uninspected,
7092         because _sanitizeAttributes early-returns on _isClobbered. The
7093         result would be an attacker-controlled form, complete with any
7094         event-handler attributes the caller passed in, handed back to
7095         the application unsanitized. Refuse to sanitize such a root
7096         the same way we refuse a forbidden tag. GHSA-r47g-fvhr-h676. */
7097      if (_isClobbered(dirty)) {
7098        /* Fail closed on a live clobbered root before throwing.
7099           _neutralizeRoot's reads are clobber-safe (cached getters); the
7100           form's non-clobbered descendants, e.g. an armed <img>, are scrubbed. */
7101        _neutralizeRoot(dirty);
7102        throw typeErrorCreate('root node is clobbered and cannot be sanitized in-place');
7103      }
7104      /* Sanitize attached shadow roots before the main iterator runs.
7105         The iterator does not descend into shadow trees. Same fail-closed
vendor: 5,016 bytes, lines 7106-7210
7106         barrier as the main walk (campaign-3 F2): a custom-element reaction
7107         inside a shadow root could abort this pre-pass before the walk runs,
7108         which would otherwise leave the entire live tree unsanitized. */
7109      try {
7110        _sanitizeAttachedShadowRoots(dirty);
7111      } catch (error) {
7112        _neutralizeRoot(dirty);
7113        throw error;
7114      }
7115    } else if (_isNode(dirty)) {
7116      /* If dirty is a DOM element, append to an empty document to avoid
7117         elements being stripped by the parser */
7118      body = _initDocument('<!---->');
7119      importedNode = body.ownerDocument.importNode(dirty, true);
7120      if (importedNode.nodeType === NODE_TYPE.element && importedNode.nodeName === 'BODY') {
7121        /* Node is already a body, use as is */
7122        body = importedNode;
7123      } else if (importedNode.nodeName === 'HTML') {
7124        body = importedNode;
7125      } else {
7126        // eslint-disable-next-line unicorn/prefer-dom-node-append
7127        body.appendChild(importedNode);
7128      }
7129      /* Clonable shadow roots are deep-cloned by importNode(); sanitize
7130         them before the main iterator runs, since the iterator does not
7131         descend into shadow trees. The walk routes every read through a
7132         cached prototype getter so clobbering descendants on a form root
7133         cannot hide a shadow host from this pass. */
7134      _sanitizeAttachedShadowRoots(importedNode);
7135    } else {
7136      /* Exit directly if we have nothing to do */
7137      if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT &&
7138      // eslint-disable-next-line unicorn/prefer-includes
7139      dirty.indexOf('<') === -1) {
7140        return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? _createTrustedHTML(dirty) : dirty;
7141      }
7142      /* Initialize the document to work on */
7143      body = _initDocument(dirty);
7144      /* Check we have a DOM node from the data */
7145      if (!body) {
7146        return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : '';
7147      }
7148    }
7149    /* Remove first element node (ours) if FORCE_BODY is set */
7150    if (body && FORCE_BODY) {
7151      _forceRemove(body.firstChild);
7152    }
7153    /* Get node iterator */
7154    const walkRoot = inPlace ? dirty : body;
7155    /* Now start iterating over the created document.
7156       The walk runs inside an exception barrier (campaign-3 F2): a re-entrant
7157       engine/custom-element mutation can detach a node mid-walk so
7158       `_forceRemove`'s parentless guard throws, aborting the loop. Without the
7159       barrier the caller's in-place tree would be left half-sanitized with the
7160       unvisited tail still armed. _createNodeIterator itself is inside the
7161       barrier too: constructing the iterator dereferences the root's document,
7162       and any failure there (e.g. an exotic/clobbered root) must still fail
7163       closed rather than skip the neutralize. On any throw we fail closed -
7164       strip the in-place root bare - then rethrow so the existing throw
7165       contract is preserved. (String/DOM-copy paths never return the partial
7166       body, so the propagating throw is already fail-closed there.) */
7167    try {
7168      const nodeIterator = _createNodeIterator(walkRoot);
7169      while (currentNode = nodeIterator.nextNode()) {
7170        /* Sanitize tags and elements */
7171        _sanitizeElements(currentNode, walkRoot);
7172        /* Check attributes next */
7173        _sanitizeAttributes(currentNode);
7174        /* Shadow DOM detected, sanitize it.
7175           Realm-safe check (GHSA-hpcv-96wg-7vj8): nodeType-based detection
7176           instead of instanceof, so foreign-realm <template>.content is
7177           walked correctly. */
7178        if (_isDocumentFragment(currentNode.content)) {
7179          _sanitizeShadowDOM2(currentNode.content);
7180        }
7181      }
7182    } catch (error) {
7183      if (inPlace) {
7184        _neutralizeRoot(dirty);
7185        /* Nodes _forceRemove'd earlier in the aborted walk are already
7186           detached from the root, so _neutralizeRoot's subtree pass does not
7187           reach them. Defuse them too, mirroring the success-path loop below. */
7188        arrayForEach(DOMPurify.removed, entry => {
7189          if (entry.element) {
7190            _neutralizeSubtree(entry.element);
7191          }
7192        });
7193      }
7194      throw error;
7195    }
7196    /* If we sanitized `dirty` in-place, return it. */
7197    if (inPlace) {
7198      /* Fail-closed completion of the audit-5 F1 fix: every node removed from
7199         the caller's live tree is detached but may still hold a queued
7200         resource-event handler that fires in page scope after we return. The
7201         move-hoist covers only disallowed-tag KEEP_CONTENT removals; strip the
7202         non-allow-listed attributes off every other removed subtree (clobber,
7203         mXSS, namespace, comments, KEEP_CONTENT:false, …) so those handlers are
7204         cancelled before any event can fire. Runs synchronously, pre-return. */
7205      arrayForEach(DOMPurify.removed, entry => {
7206        if (entry.element) {
7207          _neutralizeSubtree(entry.element);
7208        }
7209      });
7210      if (SAFE_FOR_TEMPLATES) {
vendor: 4,041 bytes, lines 7211-7315
7211        _scrubTemplateExpressions2(dirty);
7212      }
7213      return dirty;
7214    }
7215    /* Return sanitized string or DOM */
7216    if (RETURN_DOM) {
7217      if (SAFE_FOR_TEMPLATES) {
7218        _scrubTemplateExpressions2(body);
7219      }
7220      if (RETURN_DOM_FRAGMENT) {
7221        returnNode = createDocumentFragment.call(body.ownerDocument);
7222        while (body.firstChild) {
7223          // eslint-disable-next-line unicorn/prefer-dom-node-append
7224          returnNode.appendChild(body.firstChild);
7225        }
7226      } else {
7227        returnNode = body;
7228      }
7229      if (ALLOWED_ATTR.shadowroot || ALLOWED_ATTR.shadowrootmode) {
7230        /*
7231          AdoptNode() is not used because internal state is not reset
7232          (e.g. the past names map of a HTMLFormElement), this is safe
7233          in theory but we would rather not risk another attack vector.
7234          The state that is cloned by importNode() is explicitly defined
7235          by the specs.
7236        */
7237        returnNode = importNode.call(originalDocument, returnNode, true);
7238      }
7239      return returnNode;
7240    }
7241    let serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML;
7242    /* Serialize doctype if allowed */
7243    if (WHOLE_DOCUMENT && ALLOWED_TAGS['!doctype'] && body.ownerDocument && body.ownerDocument.doctype && body.ownerDocument.doctype.name && regExpTest(DOCTYPE_NAME, body.ownerDocument.doctype.name)) {
7244      serializedHTML = '<!DOCTYPE ' + body.ownerDocument.doctype.name + '>\n' + serializedHTML;
7245    }
7246    /* Sanitize final string template-safe */
7247    if (SAFE_FOR_TEMPLATES) {
7248      serializedHTML = _stripTemplateExpressions(serializedHTML);
7249    }
7250    return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? _createTrustedHTML(serializedHTML) : serializedHTML;
7251  };
7252  DOMPurify.setConfig = function () {
7253    let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
7254    _parseConfig(cfg);
7255    SET_CONFIG = true;
7256    SET_CONFIG_ALLOWED_TAGS = ALLOWED_TAGS;
7257    SET_CONFIG_ALLOWED_ATTR = ALLOWED_ATTR;
7258  };
7259  DOMPurify.clearConfig = function () {
7260    CONFIG = null;
7261    SET_CONFIG = false;
7262    SET_CONFIG_ALLOWED_TAGS = null;
7263    SET_CONFIG_ALLOWED_ATTR = null;
7264    // Drop any caller-supplied Trusted Types policy so it cannot poison later
7265    // `RETURN_TRUSTED_TYPE` output. The internal default policy (cached, and
7266    // never recreated — Trusted Types throws on duplicate names) is restored by
7267    // the next `_parseConfig`. See GHSA-vxr8-fq34-vvx9.
7268    trustedTypesPolicy = defaultTrustedTypesPolicy;
7269    emptyHTML = '';
7270  };
7271  DOMPurify.isValidAttribute = function (tag, attr, value) {
7272    /* Initialize shared config vars if necessary. */
7273    if (!CONFIG) {
7274      _parseConfig({});
7275    }
7276    const lcTag = transformCaseFunc(tag);
7277    const lcName = transformCaseFunc(attr);
7278    return _isValidAttribute(lcTag, lcName, value);
7279  };
7280  DOMPurify.addHook = function (entryPoint, hookFunction) {
7281    if (typeof hookFunction !== 'function') {
7282      return;
7283    }
7284    /* Reject unknown entry points. Without this, a non-hook key (e.g.
7285     * '__proto__') indexes off the prototype chain rather than a real
7286     * hook array, and arrayPush then writes to Object.prototype. Guard
7287     * with an own-property check against the known hook names. */
7288    if (!objectHasOwnProperty(hooks, entryPoint)) {
7289      return;
7290    }
7291    arrayPush(hooks[entryPoint], hookFunction);
7292  };
7293  DOMPurify.removeHook = function (entryPoint, hookFunction) {
7294    if (!objectHasOwnProperty(hooks, entryPoint)) {
7295      return undefined;
7296    }
7297    if (hookFunction !== undefined) {
7298      const index = arrayLastIndexOf(hooks[entryPoint], hookFunction);
7299      return index === -1 ? undefined : arraySplice(hooks[entryPoint], index, 1)[0];
7300    }
7301    return arrayPop(hooks[entryPoint]);
7302  };
7303  DOMPurify.removeHooks = function (entryPoint) {
7304    if (!objectHasOwnProperty(hooks, entryPoint)) {
7305      return;
7306    }
7307    hooks[entryPoint] = [];
7308  };
7309  DOMPurify.removeAllHooks = function () {
7310    hooks = _createHooksMap();
7311  };
7312  return DOMPurify;
7313}
7314var purify = createDOMPurify();
7315
7316/**
7317 * Copyright (c) Meta Platforms, Inc. and affiliates.
7318 *
7319 * This source code is licensed under the MIT license found in the
7320 * LICENSE file in the root directory of this source tree.
7321 *
7322 */
7323
7324function t(t,...e){const n=new URL("https://lexical.dev/docs/error"),r=new URLSearchParams;r.append("code",t);for(const t of e)r.append("v",t);throw n.search=r.toString(),Error(`Minified Lexical error #${t}; visit ${n.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}function e(t,...e){const n=new URL("https://lexical.dev/docs/error"),r=new URLSearchParams;r.append("code",t);for(const t of e)r.append("v",t);n.search=r.toString(),console.warn(`Minified Lexical warning #${t}; visit ${n.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`);}const n="undefined"!=typeof window&&void 0!==window.document&&void 0!==window.document.createElement,r$1=n&&"documentMode"in document?document.documentMode:null,i=n&&/Mac|iPod|iPhone|iPad/.test(navigator.platform),o$1=n&&/^(?!.*Seamonkey)(?=.*Firefox).*/i.test(navigator.userAgent),s$1=!(!n||!("InputEvent"in window)||r$1)&&"getTargetRanges"in new window.InputEvent("input"),l=n&&/iPad|iPhone|iPod/.test(navigator.userAgent)&&!window.MSStream,c=n&&/Android/.test(navigator.userAgent),a$1=n&&/Version\/[\d.]+.*Safari/.test(navigator.userAgent)&&!c,u=n&&/^(?=.*Chrome).*/i.test(navigator.userAgent),f=n&&c&&u,d$1=n&&/AppleWebKit\/[\d.]+/.test(navigator.userAgent)&&i&&!u,h$1=0,g=1,_$3=2,p=1,y$1=2,m$1=4,x$1=8,C$4=16,S$1=32,v$1=64,k$3=128,T$2=2047,N$3=1,b$3=2,w$3=3,E$4=4,O$4=5,M$5=6,A$3=a$1||l||d$1?"\xa0":"\u200b",D$4="\n\n",P$3=o$1?"\xa0":A$3,F$7="\u0591-\u07ff\ufb1d-\ufdfd\ufe70-\ufefc",L$5="A-Za-z\xc0-\xd6\xd8-\xf6\xf8-\u02b8\u0300-\u0590\u0800-\u1fff\u200e\u2c00-\ufb1c\ufe00-\ufe6f\ufefd-\uffff",I$6=new RegExp("^[^"+L$5+"]*["+F$7+"]"),K$4=new RegExp("^[^"+F$7+"]*["+L$5+"]"),z$7={bold:1,capitalize:1024,code:16,highlight:k$3,italic:2,lowercase:256,strikethrough:4,subscript:32,superscript:64,underline:8,uppercase:512},R$4={directionless:1,unmergeable:2},B$5={center:2,end:6,justify:4,left:1,right:3,start:5}
7324,W$5={[b$3]:"center",[M$5]:"end",[E$4]:"justify",[N$3]:"left",[w$3]:"right",[O$4]:"start"},$$4={normal:0,segmented:2,token:1},J$7={[h$1]:"normal",[_$3]:"segmented",[g]:"token"},j$7="$",U$6="$config";let V$7 = class V{_front=new Set;_back=new Set;_cache;get size(){return this._front.size+this._back.size}addBack(t){return delete this._cache,this._front.has(t)||this._back.add(t),this}addFront(t){return delete this._cache,this._back.has(t)||this._front.add(t),this}delete(t){return delete this._cache,this._front.delete(t)||this._back.delete(t)}toArray(){const t=Array.from(this._front).reverse();for(const e of this._back)t.push(e);return t}toReadonlyArray(){return this._cache=this._cache||this.toArray(),this._cache}[Symbol.iterator](){return this.toReadonlyArray()[Symbol.iterator]()}};function Y$5(t,e,n,r,i,o){let s=t.getFirstChild();for(;null!==s;){const t=s.__key;s.__parent===e&&(Wi(s)&&Y$5(s,t,n,r,i,o),n.has(t)||o.delete(t),i.push(t)),s=s.getNextSibling();}}let q$7=false,H$7=0;function G$a(t){H$7=t.timeStamp;}function X$6(t,e,n){const r="BR"===t.nodeName,i=e.__lexicalLineBreak;return i&&(t===i||r&&t.previousSibling===i)||r&&void 0!==Ho(t,n)}function Q$9(t,e,n){const r=Js(Ps(n));let i=null,o=null;null!==r&&r.anchorNode===t&&(i=r.anchorOffset,o=r.focusOffset);const s=t.nodeValue;null!==s&&cs(e,s,i,o,false);}function Z$5(t,e,n){if(Fr(t)){const e=t.anchor.getNode();if(e.is(n)&&t.format!==e.getFormat())return  false}return Ko(e)&&n.isAttached()}function tt$4(t,e,n,r){for(let i=t;i&&!cl(i);i=bs(i)){const t=Ho(i,e);if(void 0!==t){const e=Yo(t,n);if(e)return ji(e)||!Ys(i)?void 0:[i,e]}else if(i===r)return [r,ts(n)]}}function et$2(t,e,n){q$7=true;const r=performance.now()-H$7>100;try{Ki(t,()=>{const i=Qr()||function(t){return t.getEditorState().read(()=>{const t=Qr();return null!==t?t.clone():null})}(t),s=new Map,l=t.getRootElement(),c=t._editorState,a=t._blockCursorElement;let u=!1,f="";for(let n=0;n<e.length;n++){const d=e[n],h=d.type,g=d.target,_=tt$4(g,t,c,l);if(!_)continue;const[p,y]=_;if("characterData"===h)r&&Tr(y)&&Ko(g)&&Z$5(i,g,y)&&Q$9(g,y,t);else if("childList"===h){u=!0;const e=d.addedNodes;for(let n=0;n<e.length;n++){const r=e[n],i=qo(r),s=r.parentNode;if(null!=s&&r!==a&&null===i&&!X$6(r,s,t)){if(o$1){const t=(Ys(r)?r.innerText:null)||r.nodeValue;t&&(f+=t);}s.removeChild(r);}}const n=d.removedNodes,r=n.length;if(r>0){let e=0;for(let i=0;i<r;i++){const r=n[i];(X$6(r,g,t)||a===r)&&(g.appendChild(r),e++);}r!==e&&s.set(p,y);}}}if(s.size>0)for(const[e,n]of s)n.reconcileObservedMutation(e,t);const d=n.takeRecords();if(d.length>0){for(let e=0;e<d.length;e++){const n=d[e],r=n.addedNodes,i=n.target;for(let e=0;e<r.length;e++){const n=r[e],o=n.parentNode;null==o||"BR"!==n.nodeName||X$6(n,i,t)||o.removeChild(n);}}n.takeRecords();}null!==i&&(u&&es(i),o$1&&ks(t)&&i.insertRawText(f));});}finally{q$7=false;}}function nt$4(t){const e=t._observer;if(null!==e){et$2(t,e.takeRecords(),e);}}function rt$4(t){!function(t){0===H$7&&Ps(t).addEventListener("textInput",G$a,true);}(t),t._observer=new MutationObserver((e,n)=>{et$2(t,e,n);});}let it$2 = class it{key;parse;unparse;isEqual;defaultValue;resetOnCopyNode;constructor(t,e){this.key=t,this.parse=e.parse.bind(e),this.unparse=(e.unparse||gt$3).bind(e),this.isEqual=(e.isEqual||Object.is).bind(e),this.defaultValue=this.parse(void 0),this.resetOnCopyNode=e.resetOnCopyNode||false;}};function ot$3(t,e){return new it$2(t,e)}function st$2(t,e,n="latest"){const r=("latest"===n?t.getLatest():t).__state;return r?r.getValue(e):e.defaultValue}function lt$3(t,e,n){const r=st$2(t,n,"direct"),i=st$2(e,n,"direct");return n.isEqual(r,i)?null:[r,i]}function ct$2(t,e,n){let r;if(xi(),"function"==typeof n){const i=t.getLatest(),o=st$2(i,e);if(r=n(o),e.isEqual(o,r))return i}else r=n;const i=t.getWritable();return ft$2(i).updateFromKnown(e,r),i}function at$3(t){const e=new Map,n=new Set;for(let r="function"==typeof t?t:t.replace;r.prototype&&void 0!==r.prototype.getType;r=Object.getPrototypeOf(r)){const{ownNodeConfig:t}=ul(r);if(t&&t.stateConfigs)for(const r of t.stateConfigs){let t;"stateConfig"in r?(t=r.stateConfig,r.flat&&n.add(t.key)):t=r,e.set(t.key,t);}}return {flatKeys:n,sharedConfigMap:e}}let ut$3 = class ut{node;knownState;unknownState;sharedNodeState;size;constructor(t,e,n=void 0,r=new Map,i=void 0){this.node=t,this.sharedNodeState=e,this.unknownState=n,this.knownState=r;const{sharedConfigMap:o}=this.sharedNodeState,s=void 0!==i?i:function(t,e,n){let r=n.size;if(e)for(const i in e){const e=t.get(i);e&&n.has(e)||r++;}return r}(o,n,r);this.size=s;}getValue(t){const e=this.knownState.get(t);if(void 0!==e)return e;this.sharedNodeState.sharedConfigMap.set(t.key,t);let n=t.defaultValue;if(this.unknownState&&t.key in this.unknownState){const e=this.unknownState[t.key];void 0!==e&&(n=t.parse(e)),this.updateFromKnown(t,n);}return n}getInternalState(){return [this.unknownState,this.knownState]}toJSON(){const t={...this.unknownState},e={};for(const[e,n]of this.knownState)e.isEqual(n,e.defaultValue)?delete t[e.key]:t[e.key]=e.unparse(n);for(const n of this.sharedNodeState.flatKeys)n in t&&(e[n]=t[n],delete t[n]);return ht$3(t)&&(e.$=t),e}getWritable(t){if(this.node===t)return this;const{sharedNodeState:e,unknownState:n}=this,r=new Map(this.knownState);return new ut(t,e,function(t,e,n){let r;if(n)for(const[i,o]of Object.entries(n)){const n=t.get(i);n?e.has(n)||e.set(n,n.parse(o)):(r=r||{},r[i]=o);}return r}(e.sharedConfigMap,r,n),r,this.size)}resetOnCopyNode(){for(const t of this.knownState.keys())t.resetOnCopyNode&&this.knownState.set(t,t.defaultValue);return this}updateFromKnown(t,e){const n=t.key;this.sharedNodeState.sharedConfigMap.set(n,t);const{knownState:r,unknownState:i}=this;r.has(t)||i&&n in i||(i&&(delete i[n],this.unknownState=ht$3(i)),this.size++),r.set(t,e);}updateFromUnknown(t,e){const n=this.sharedNodeState.sharedConfigMap.get(t);n?this.updateFromKnown(n,n.parse(e)):(this.unknownState=this.unknownState||{},t in this.unknownState||this.size++,this.unknownState[t]=e);}updateFromJSON(t){const{knownState:e}=this;for(const t of e.keys())e.set(t,t.defaultValue);if(this.size=e.size,this.unknownState=void 0,t)for(const[e,n]of Object.entries(t))this.updateFromUnknown(e,n);}};function ft$2(t){const e=t.getWritable(),n=e.__state?e.__state.getWritable(e):new ut$3(e,dt$3(e));return e.__state=n,n}function dt$3(t){return t.__state?t.__state.sharedNodeState:No(Zs(),t.getType()).sharedNodeState}function ht$3(t){if(t)for(const e in t)return t}function gt$3(t){return t}
7324function _t$3(t,e,n){for(const[r,i]of e.knownState){if(t.has(r.key))continue;t.add(r.key);const e=n?n.getValue(r):r.defaultValue;if(e!==i&&!r.isEqual(e,i))return  true}return  false}function pt$3(t,e,n){const{unknownState:r}=e,i=n?n.unknownState:void 0;if(r)for(const[e,n]of Object.entries(r)){if(t.has(e))continue;t.add(e);if(n!==(i?i[e]:void 0))return  true}return  false}function yt$6(t,e){const n=t.__state;return n&&n.node===t?n.getWritable(e):n}function mt$3(t,e){const n=t.__mode,r=t.__format,i=t.__style,o=e.__mode,s=e.__format,l=e.__style,c=t.__state,a=e.__state;return (null===n||n===o)&&(null===r||r===s)&&(null===i||i===l)&&(null===t.__state||c===a||function(t,e){if(t===e)return  true;const n=new Set;return !(t&&_t$3(n,t,e)||e&&_t$3(n,e,t)||t&&pt$3(n,t,e)||e&&pt$3(n,e,t))}(c,a))}function xt$3(t,e){const n=t.mergeWithSibling(e),r=vi()._normalizedNodes;return r.add(t.__key),r.add(e.__key),n}function Ct$2(t){let e,n,r=t;if(""!==r.__text||!r.isSimpleText()||r.isUnmergeable()){for(;null!==(e=r.getPreviousSibling())&&Tr(e)&&e.isSimpleText()&&!e.isUnmergeable();){if(""!==e.__text){if(mt$3(e,r)){r=xt$3(e,r);break}break}e.remove();}for(;null!==(n=r.getNextSibling())&&Tr(n)&&n.isSimpleText()&&!n.isUnmergeable();){if(""!==n.__text){if(mt$3(r,n)){r=xt$3(r,n);break}break}n.remove();}}else r.remove();}function St$3(t){return vt$3(t.anchor),vt$3(t.focus),t}function vt$3(t){for(;"element"===t.type;){const e=t.getNode(),n=t.offset;let r,i;if(n===e.getChildrenSize()?(r=e.getChildAtIndex(n-1),i=true):(r=e.getChildAtIndex(n),i=false),Tr(r)){t.set(r.__key,i?r.getTextContentSize():0,"text",true);break}if(!Wi(r))break;t.set(r.__key,i?r.getChildrenSize():0,"element",true);}}let kt$3,Tt$5,Nt$3,bt$3,wt$3,Et$4,Ot$4,Mt$3,At$3,Dt$5,Pt$4,Ft$3="",Lt$4=null,It$2=null,Kt$3=false,zt$5=false;function Rt$4(t,e){const n=Ot$4.get(t);if(null!==e){const n=ne$5(t);n.parentNode===e&&e.removeChild(n);}if(Mt$3.has(t)||Tt$5._keyToDOMMap.delete(t),Wi(n)){const t=hl(n,Ot$4);Bt$4(t,0,t.length-1,null);} void 0!==n&&xs(Dt$5,Nt$3,bt$3,n,"destroyed");}function Bt$4(t,e,n,r){for(let i=e;i<=n;++i){const e=t[i];void 0!==e&&Rt$4(e,r);}}function Wt$4(t,e){t.setProperty("text-align",e);}const $t$3="40px";function Jt$4(t,e){const n=kt$3.theme.indent;if("string"==typeof n){const r=t.classList.contains(n);e>0&&!r?t.classList.add(n):e<1&&r&&t.classList.remove(n);}if(0===e)return void t.style.setProperty("padding-inline-start","");const r=getComputedStyle(Tt$5._rootElement||t).getPropertyValue("--lexical-indent-base-value")||$t$3;t.style.setProperty("padding-inline-start",`calc(${e} * ${r})`);}function jt$3(t,e){const n=t.style;0===e?Wt$4(n,""):1===e?Wt$4(n,"left"):2===e?Wt$4(n,"center"):3===e?Wt$4(n,"right"):4===e?Wt$4(n,"justify"):5===e?Wt$4(n,"start"):6===e&&Wt$4(n,"end");}function Ut$4(t,e){const n=function(t){const e=t.__dir;if(null!==e)return e;if(Vi(t))return null;const n=t.getParentOrThrow();return Vi(n)&&null===n.__dir?"auto":null}(e);null!==n?t.dir=n:t.removeAttribute("dir");}function Vt$3(e,n){const r=Mt$3.get(e);void 0===r&&t(60);const i=Pt$4.$createDOM(r,Tt$5);if(function(t,e,n){const r=n._keyToDOMMap;((function(t,e,n){const r=`__lexicalKey_${e._key}`;t[r]=n;}))(e,n,t),r.set(t,e);}(e,i,Tt$5),Tr(r)?i.setAttribute("data-lexical-text","true"):ji(r)&&i.setAttribute("data-lexical-decorator","true"),Wi(r)){const t=r.__indent,e=r.__size;if(Ut$4(i,r),0!==t&&Jt$4(i,t),0!==e){const t=e-1;Yt$3(hl(r,Mt$3),r,0,t,Pt$4.$getDOMSlot(r,i,Tt$5));}const n=r.__format;0!==n&&jt$3(i,n),r.isInline()||Ht$4(null,r,i);}else {const t=r.getTextContent();if(ji(r)){const t=r.decorate(Tt$5,kt$3);null!==t&&Qt$3(e,t),i.contentEditable="false";}Ft$3+=t;}return null!==n&&n.insertChild(i),Pt$4.$decorateDOM(r,null,i,Tt$5),xs(Dt$5,Nt$3,bt$3,r,"created"),i}function Yt$3(t,e,n,r,i){const o=Ft$3;Ft$3="";let s=n;for(;s<=r;++s){Vt$3(t[s],i);const e=Mt$3.get(t[s]);null!==e&&Tr(e)?null===Lt$4&&(Lt$4=e.getFormat(),It$2=e.getStyle()):Wi(e)&&s<r&&!e.isInline()&&(Ft$3+=D$4);}i.element.__lexicalTextContent=Ft$3,Ft$3=o+Ft$3;}function qt$4(t,e){if(t){const n=t.__last;if(n){const t=e.get(n);if(t)return sr(t)?"line-break":ji(t)&&t.isInline()?"decorator":null}return "empty"}return null}function Ht$4(t,e,n){const r=qt$4(t,Ot$4),i=qt$4(e,Mt$3);r!==i&&Pt$4.$getDOMSlot(e,n,Tt$5).setManagedLineBreak(i);}function Gt$3(e,n,r){var i;Lt$4=null,It$2=null,function(e,n,r){const i=Ft$3,o=e.__size,s=n.__size;Ft$3="";const l=r.element;if(1===o&&1===s){const t=e.__first,r=n.__first;if(t===r)Xt$4(t,l);else {const e=ne$5(t),n=Vt$3(r,null);try{l.replaceChild(n,e);}catch(i){if("object"==typeof i&&null!=i){const o=`${i.toString()} Parent: ${l.tagName}, new child: {tag: ${n.tagName} key: ${r}}, old child: {tag: ${e.tagName}, key: ${t}}.`;throw new Error(o)}throw i}Rt$4(t,null);}const i=Mt$3.get(r);Tr(i)&&null===Lt$4&&(Lt$4=i.getFormat(),It$2=i.getStyle());}else {const i=hl(e,Ot$4),c=hl(n,Mt$3);if(i.length!==o&&t(227),c.length!==s&&t(228),0===o)0!==s&&Yt$3(c,0,0,s-1,r);
7324else if(0===s){if(0!==o){const t=null==r.after&&null==r.before&&null==r.element.__lexicalLineBreak;Bt$4(i,0,o-1,t?null:l),t&&(l.textContent="");}}else !function(t,e,n,r,i,o){const s=r-1,l=i-1;let c,a,u=o.getFirstChild(),f=0,d=0;for(;f<=s&&d<=l;){const t=e[f],r=n[d];if(t===r)u=Zt$3(Xt$4(r,o.element)),f++,d++;else {if(void 0===a&&(a=te$5(n,d)),void 0===c)c=te$5(e,f);else if(!c.has(t)){f++;continue}if(!a.has(t)){u=Zt$3(ne$5(t)),Rt$4(t,o.element),f++,c.delete(t);continue}if(c.has(r)){const t=Ns(Tt$5,r);t!==u&&o.withBefore(u).insertChild(t),u=Zt$3(Xt$4(r,o.element)),f++,d++;}else Vt$3(r,o.withBefore(u)),d++;}const i=Mt$3.get(r);null!==i&&Tr(i)?null===Lt$4&&(Lt$4=i.getFormat(),It$2=i.getStyle()):Wi(i)&&d<=l&&!i.isInline()&&(Ft$3+=D$4);}const h=f>s,g=d>l;if(h&&!g){const t=n[l+1],e=void 0===t?null:Tt$5.getElementByKey(t);Yt$3(n,0,d,l,o.withBefore(e));}else g&&!h&&Bt$4(e,f,s,o.element);}(0,i,c,o,s,r);}l.__lexicalTextContent=Ft$3,Ft$3=i+Ft$3;}(e,n,Pt$4.$getDOMSlot(n,r,Tt$5)),i=n,null==Lt$4||Lt$4===i.__textFormat||zt$5||i.setTextFormat(Lt$4),function(t){null==It$2||It$2===t.__textStyle||zt$5||t.setTextStyle(It$2);}(n);}function Xt$4(e,n){const r=Ot$4.get(e);let i=Mt$3.get(e);void 0!==r&&void 0!==i||t(61);const o=Kt$3||Et$4.has(e)||wt$3.has(e),s=Ns(Tt$5,e);if(r===i&&!o){let t;if(Wi(r)){const e=s.__lexicalTextContent;"string"==typeof e?t=e:(t=r.getTextContent(),s.__lexicalTextContent=t);}else t=r.getTextContent();return Ft$3+=t,s}if(r!==i&&o&&xs(Dt$5,Nt$3,bt$3,i,"updated"),Pt$4.$updateDOM(i,r,s,Tt$5)){const r=Vt$3(e,null);return null===n&&t(62),n.replaceChild(r,s),Rt$4(e,null),r}if(Wi(r)){Wi(i)||t(334,e);const n=i.__indent;(Kt$3||n!==r.__indent)&&Jt$4(s,n);const l=i.__format;if((Kt$3||l!==r.__format)&&jt$3(s,l),o)Gt$3(r,i,s),Vi(i)||i.isInline()||Ht$4(r,i,s);else {const t=s.__lexicalTextContent;let e;"string"==typeof t?e=t:(e=r.getTextContent(),s.__lexicalTextContent=e),Ft$3+=e;}if((Kt$3||i.__dir!==r.__dir)&&(Ut$4(s,i),Vi(i)&&!Kt$3))for(const t of i.getChildren())if(Wi(t)){Ut$4(Ns(Tt$5,t.getKey()),t);}}else {const t=i.getTextContent();if(ji(i)){const t=i.decorate(Tt$5,kt$3);null!==t&&Qt$3(e,t);}Ft$3+=t;}if(!zt$5&&Vi(i)&&i.__cachedText!==Ft$3){const t=i.getWritable();t.__cachedText=Ft$3,i=t;}return Pt$4.$decorateDOM(i,r,s,Tt$5),s}function Qt$3(t,e){let n=Tt$5._pendingDecorators;const r=Tt$5._decorators;if(null===n){if(r[t]===e)return;n=Xo(Tt$5);}n[t]=e;}function Zt$3(t){let e=t.nextSibling;return null!==e&&e===Tt$5._blockCursorElement&&(e=e.nextSibling),e}function te$5(t,e){const n=new Set;for(let r=e;r<t.length;r++)n.add(t[r]);return n}function ee$4(t,e,n,r,i,o){Ft$3="",Kt$3=2===r,Tt$5=n,kt$3=n._config,Pt$4=n._config.dom||po,Nt$3=n._nodes,bt$3=Tt$5._listeners.mutation,wt$3=i,Et$4=o,Ot$4=t._nodeMap,Mt$3=e._nodeMap,zt$5=e._readOnly,At$3=new Map(n._keyToDOMMap);const s=new Map;return Dt$5=s,Xt$4("root",null),Tt$5=void 0,Nt$3=void 0,wt$3=void 0,Et$4=void 0,Ot$4=void 0,Mt$3=void 0,kt$3=void 0,At$3=void 0,Dt$5=void 0,Pt$4=po,s}function ne$5(e){const n=At$3.get(e);return void 0===n&&t(75,e),n}function re$5(t){return {type:t}}const ie$4=re$5("SELECTION_CHANGE_COMMAND"),oe$6=re$5("SELECTION_INSERT_CLIPBOARD_NODES_COMMAND"),se$5=re$5("CLICK_COMMAND"),le$3=re$5("BEFORE_INPUT_COMMAND"),ce$4=re$5("INPUT_COMMAND"),ae$4=re$5("COMPOSITION_START_COMMAND"),ue$4=re$5("COMPOSITION_END_COMMAND"),fe$4=re$5("DELETE_CHARACTER_COMMAND"),de$4=re$5("INSERT_LINE_BREAK_COMMAND"),he$3=re$5("INSERT_PARAGRAPH_COMMAND"),ge$3=re$5("CONTROLLED_TEXT_INSERTION_COMMAND"),_e$2=re$5("PASTE_COMMAND"),pe$3=re$5("REMOVE_TEXT_COMMAND"),ye$2=re$5("DELETE_WORD_COMMAND"),me$3=re$5("DELETE_LINE_COMMAND"),xe=re$5("FORMAT_TEXT_COMMAND"),Ce$2=re$5("UNDO_COMMAND"),Se$2=re$5("REDO_COMMAND"),ve$2=re$5("KEYDOWN_COMMAND"),ke$2=re$5("KEY_ARROW_RIGHT_COMMAND"),Te$2=re$5("MOVE_TO_END"),Ne$1=re$5("KEY_ARROW_LEFT_COMMAND"),be$1=re$5("MOVE_TO_START"),we$1=re$5("KEY_ARROW_UP_COMMAND"),Ee$3=re$5("KEY_ARROW_DOWN_COMMAND"),Oe$2=re$5("KEY_ENTER_COMMAND"),Me$2=re$5("KEY_SPACE_COMMAND"),Ae$3=re$5("KEY_BACKSPACE_COMMAND"),De$2=re$5("KEY_ESCAPE_COMMAND"),Pe$2=re$5("KEY_DELETE_COMMAND"),Fe$2=re$5("KEY_TAB_COMMAND"),Le$2=re$5("INSERT_TAB_COMMAND"),Ie$3=re$5("INDENT_CONTENT_COMMAND"),Ke$2=re$5("OUTDENT_CONTENT_COMMAND"),ze$2=re$5("DROP_COMMAND"),Re$1=re$5("FORMAT_ELEMENT_COMMAND"),Be$2=re$5("DRAGSTART_COMMAND"),We$2=re$5("DRAGOVER_COMMAND"),$e$2=re$5("DRAGEND_COMMAND"),Je$2=re$5("COPY_COMMAND"),je$2=re$5("CUT_COMMAND"),Ue$2=re$5("SELECT_ALL_COMMAND"),Ve$2=re$5("CLEAR_EDITOR_COMMAND"),Ye$1=re$5("CLEAR_HISTORY_COMMAND"),qe$2=re$5("CAN_REDO_COMMAND"),He$2=re$5("CAN_UNDO_COMMAND"),Ge$2=re$5("FOCUS_COMMAND"),Xe$2=re$5("BLUR_COMMAND"),Qe$1=re$5("KEY_MODIFIER_COMMAND"),Ze$1=Object.freeze({}),tn$1=[["keydown",function(t,e){if(en$1=t.timeStamp,nn$1=t.key,e.isComposing())return;Ts(e,ve$2,t);}],["pointerdown",function(t,e){const n=t.target,r=t.pointerType;qs(n)&&"touch"!==r&&"pen"!==r&&0===t.button&&Ki(e,()=>{Eo(n)||(an$1=true);});}],["compositionstart",function(t,e){Ts(e,ae$4,t);}],["compositionend",function(t,e){o$1?fn$1=true:l||!a$1&&!d$1?Ts(e,ue$4,t):(dn$1=true,hn$1=t.data);}],["input",function(t,e){t.stopPropagation(),Ki(e,()=>{e.dispatchCommand(ce$4,t);},{event:t}),on$1=null;}],["click",function(t,e){Ki(e,()=>{const n=Qr(),r=Js(Ps(e)),i=Zr();
7324if(r)if(Fr(n)){const e=n.anchor,o=e.getNode();if("element"===e.type&&0===e.offset&&n.isCollapsed()&&!Vi(o)&&1===Zo().getChildrenSize()&&o.getTopLevelElementOrThrow().isEmpty()&&null!==i&&n.is(i))r.removeAllRanges(),n.dirty=true;else if(3===t.detail&&!n.isCollapsed()){if(o!==n.focus.getNode()){const t=dl(o,t=>Wi(t)&&!t.isInline());Wi(t)&&t.select(0);}}}else if("touch"===t.pointerType||"pen"===t.pointerType){const n=r.anchorNode;if(Ys(n)||Ko(n)){es(Xr(i,r,e,t));}}Ts(e,se$5,t);});}],["cut",Ze$1],["copy",Ze$1],["dragstart",Ze$1],["dragover",Ze$1],["dragend",Ze$1],["paste",Ze$1],["focus",Ze$1],["blur",Ze$1],["drop",Ze$1]];s$1&&tn$1.push(["beforeinput",(t,e)=>function(t,e){const n=t.inputType;if("deleteCompositionText"===n||o$1&&ks(e))return;if("insertCompositionText"===n)return;Ts(e,le$3,t);}(t,e)]);let en$1=0,nn$1=null,rn$1=0,on$1=null;const sn$1=new WeakMap,ln$1=new WeakMap;let cn$1=false,an$1=false,un$1=false,fn$1=false,dn$1=false,hn$1="",gn$1=null,_n$1=[0,"",0,"root",0];function pn$1(t,e,n,r,i){const o=t.anchor,l=t.focus,c=o.getNode(),a=vi(),u=Js(Ps(a)),f=null!==u?u.anchorNode:null,d=o.key,h=a.getElementByKey(d),g=n.length;return d!==l.key||!Tr(c)||(!i&&(!s$1||rn$1<r+50)||c.isDirty()&&g<2||rs(n))&&o.offset!==l.offset&&!c.isComposing()||Io(c)||c.isDirty()&&g>1||(i||!s$1)&&null!==h&&!c.isComposing()&&f!==Ro(h)||null!==u&&null!==e&&(!e.collapsed||e.startContainer!==u.anchorNode||e.startOffset!==u.anchorOffset)||!c.isComposing()&&(c.getFormat()!==t.format||c.getStyle()!==t.style)||function(t,e){if(e.isSegmented())return  true;if(!t.isCollapsed())return  false;const n=t.anchor.offset,r=e.getParentOrThrow(),i=Lo(e);return 0===n?!e.canInsertTextBefore()||!r.canInsertTextBefore()&&!e.isComposing()||i||function(t){const e=t.getPreviousSibling();return (Tr(e)||Wi(e)&&e.isInline())&&!e.canInsertTextAfter()}(e):n===e.getTextContentSize()&&(!e.canInsertTextAfter()||!r.canInsertTextAfter()&&!e.isComposing()||i)}(t,c)}function yn$1(t,e){return Ko(t)&&null!==t.nodeValue&&0!==e&&e!==t.nodeValue.length}function mn$1(e,n,r){const{anchorNode:i,anchorOffset:o,focusNode:s,focusOffset:l}=e;cn$1&&(cn$1=false,yn$1(i,o)&&yn$1(s,l)&&!gn$1)||Ki(n,()=>{if(!r)return void es(null);if(!Mo(n,i,s))return;let c=Qr();if(gn$1&&Fr(c)&&c.isCollapsed()){const t=c.anchor,e=gn$1.anchor;(t.key===e.key&&t.offset===e.offset+1||1===t.offset&&e.getNode().is(t.getNode().getPreviousSibling()))&&(c=gn$1.clone(),es(c));}if(gn$1=null,Fr(c)){const r=c.anchor,i=r.getNode();if(c.isCollapsed()){"Range"===e.type&&e.anchorNode===e.focusNode&&(c.dirty=true);const o=Ps(n).event,s=o?o.timeStamp:performance.now(),[l,a,u,f,d]=_n$1,h=Zo(),g=false===n.isComposing()&&""===h.getTextContent();if(s<d+200&&r.offset===u&&r.key===f)xn$1(c,l,a);else if("text"===r.type)Tr(i)||t(141),Cn$1(c,i);else if("element"===r.type&&!g){Wi(i)||t(259);const e=r.getNode();e.isEmpty()?function(t,e){const n=e.getTextFormat(),r=e.getTextStyle();xn$1(t,n,r);}(c,e):xn$1(c,c.format,"");}}else {const t=r.key,e=c.focus.key,n=c.getNodes(),i=n.length,s=c.isBackward(),a=s?l:o,u=s?o:l,f=s?e:t,d=s?t:e;let h=2047,g=false;for(let t=0;t<i;t++){const e=n[t],r=e.getTextContentSize();if(Tr(e)&&0!==r&&!(0===t&&e.__key===f&&a===r||t===i-1&&e.__key===d&&0===u)&&(g=true,h&=e.getFormat(),0===h))break}c.format=g?h:0;}}Ts(n,ie$4,void 0);});}function xn$1(t,e,n){t.format===e&&t.style===n||(t.format=e,t.style=n,t.dirty=true);}function Cn$1(t,e){xn$1(t,e.getFormat(),e.getStyle());}function Sn$1(t){if(!t.getTargetRanges)return null;const e=t.getTargetRanges();return 0===e.length?null:e[0]}function vn$1(e){const n=e.inputType,r=Sn$1(e),i=vi(),o=Qr();if("deleteContentBackward"===n){if(null===o){const t=Zr();if(!Fr(t))return  true;es(t.clone());}if(Fr(o)){const n=o.anchor.key===o.focus.key;if(s=e.timeStamp,"MediaLast"===nn$1&&s<en$1+30&&i.isComposing()&&n){if(Uo(null),en$1=0,setTimeout(()=>{Ki(i,()=>{Uo(null);});},30),Fr(o)){const e=o.anchor.getNode();e.markDirty(),Tr(e)||t(142),Cn$1(o,e);}}else {Uo(null),e.preventDefault();const t=o.anchor.getNode(),r=t.getTextContent(),s=t.canInsertTextAfter(),l=0===o.anchor.offset&&o.focus.offset===r.length;let c=f&&n&&!l&&s;if(c&&o.isCollapsed()&&(c=!ji(vs(o.anchor,true))),!c){Ts(i,fe$4,true);const t=Qr();f&&Fr(t)&&t.isCollapsed()&&(gn$1=t,setTimeout(()=>gn$1=null));}}return  true}}var s;if(!Fr(o))return  true;const c=e.data;null!==on$1&&ls(false,i,on$1),o.dirty&&null===on$1||!o.isCollapsed()||Vi(o.anchor.getNode())||null===r||o.applyDOMRange(r),on$1=null;const a=o.anchor,u=o.focus,d=a.getNode(),h=u.getNode();if("insertText"===n||"insertTranspose"===n){if("\n"===c)e.preventDefault(),Ts(i,de$4,false);else if(c===D$4)e.preventDefault(),Ts(i,he$3,void 0);else if(null==c&&e.dataTransfer){const t=e.dataTransfer.getData("text/plain");e.preventDefault(),o.insertRawText(t);}else null!=c&&pn$1(o,r,c,e.timeStamp,true)?(e.preventDefault(),Ts(i,ge$3,c)):on$1=c;return rn$1=e.timeStamp,true}switch(e.preventDefault(),n){case "insertFromYank":case "insertFromDrop":case "insertReplacementText":Ts(i,ge$3,e);break;case "insertFromComposition":Uo(null),Ts(i,ge$3,e);break;case "insertLineBreak":Uo(null),Ts(i,de$4,false);break;case "insertParagraph":Uo(null),un$1&&!l?(un$1=false,Ts(i,de$4,false)):Ts(i,he$3,void 0);break;case "insertFromPaste":case "insertFromPasteAsQuotation":Ts(i,_e$2,e);break;case "deleteByComposition":(function(t,e){return t!==e||Wi(t)||Wi(e)||!Lo(t)||!Lo(e)})(d,h)&&Ts(i,pe$3,e);break;case "deleteByDrag":Os(Hn),Ts(i,pe$3,e);break;case "deleteByCut":Ts(i,pe$3,e);break;case "deleteContent":Ts(i,fe$4,false);break;case "deleteWordBackward":Ts(i,ye$2,true);break;
7324case "deleteWordForward":Ts(i,ye$2,false);break;case "deleteHardLineBackward":case "deleteSoftLineBackward":Ts(i,me$3,true);break;case "deleteContentForward":case "deleteHardLineForward":case "deleteSoftLineForward":Ts(i,me$3,false);break;case "formatStrikeThrough":Ts(i,xe,"strikethrough");break;case "formatBold":Ts(i,xe,"bold");break;case "formatItalic":Ts(i,xe,"italic");break;case "formatUnderline":Ts(i,xe,"underline");break;case "historyUndo":Ts(i,Ce$2,void 0);break;case "historyRedo":Ts(i,Se$2,void 0);}return  true}function kn$1(t){if(Ys(t.target)&&Eo(t.target))return  true;const e=vi(),n=Qr(),r=t.data,i=Sn$1(t);if(null!=r&&Fr(n)&&pn$1(n,i,r,t.timeStamp,false)){fn$1&&(bn$1(e,r),fn$1=false);const i=n.anchor.getNode(),l=Js(Ps(e));if(null===l)return  true;const c=n.isBackward(),a=c?n.anchor.offset:n.focus.offset,u=c?n.focus.offset:n.anchor.offset;s$1&&!n.isCollapsed()&&Tr(i)&&null!==l.anchorNode&&i.getTextContent().slice(0,a)+r+i.getTextContent().slice(a+u)===ss(l.anchorNode)||Ts(e,ge$3,r);const d=r.length;o$1&&d>1&&"insertCompositionText"===t.inputType&&!e.isComposing()&&(n.anchor.offset-=d),f&&e.isComposing()&&(en$1=0,Uo(null));}else {ls(false,e,null!==r?r:void 0),fn$1&&(bn$1(e,r||void 0),fn$1=false);}return function(){xi();const t=vi();nt$4(t);}(),true}function Tn$1(t){const e=vi(),n=Qr();if(Fr(n)&&!e.isComposing()){const r=n.anchor,i=n.anchor.getNode();Uo(r.key),Os(Gn),(t.timeStamp<en$1+30||"element"===r.type||!n.isCollapsed()||i.getFormat()!==n.format||Tr(i)&&i.getStyle()!==n.style)&&Ts(e,ge$3,P$3);}return  true}function Nn$1(t){return bn$1(vi(),t.data),Os(Xn),true}function bn$1(t,e){const n=t._compositionKey;if(Uo(null),null!==n&&null!=e){if(""===e){const e=Yo(n),r=Ro(t.getElementByKey(n));if(null!==r&&null!==r.nodeValue&&Tr(e)){const n=Js(Ps(t));let i=null,o=null;null!==n&&n.anchorNode===r&&(i=n.anchorOffset,o=n.focusOffset),cs(e,r.nodeValue,i,o,true);}return}if("\n"===e[e.length-1]){const e=Qr();if(Fr(e)||Ir(e)){if(Fr(e)){const t=e.focus;e.anchor.set(t.key,t.offset,t.type);}return void Ts(t,Oe$2,null)}}}ls(true,t,e);}function wn$1(t){const e=vi();if(null==t.key)return  true;if(dn$1){if(_s(t))return Ki(e,()=>{bn$1(e,hn$1);}),dn$1=false,hn$1="",true;dn$1=false,hn$1="";}if(function(t){return ds(t,"ArrowRight",{shiftKey:"any"})}(t))Ts(e,ke$2,t);else if(function(t){return ds(t,"ArrowRight",hs)}(t))Ts(e,Te$2,t);else if(function(t){return ds(t,"ArrowLeft",{shiftKey:"any"})}(t))Ts(e,Ne$1,t);else if(function(t){return ds(t,"ArrowLeft",hs)}(t))Ts(e,be$1,t);else if(function(t){return ds(t,"ArrowUp",{altKey:"any",shiftKey:"any"})}(t))Ts(e,we$1,t);else if(function(t){return ds(t,"ArrowDown",{altKey:"any",shiftKey:"any"})}(t))Ts(e,Ee$3,t);else if(function(t){return ds(t,"Enter",{altKey:"any",ctrlKey:"any",metaKey:"any",shiftKey:true})}(t))un$1=true,Ts(e,Oe$2,t);else if(function(t){return " "===t.key}(t))Ts(e,Me$2,t);else if(function(t){return i&&ds(t,"o",{ctrlKey:true})}(t))t.preventDefault(),un$1=true,Ts(e,de$4,true);else if(function(t){return ds(t,"Enter",{altKey:"any",ctrlKey:"any",metaKey:"any"})}(t))un$1=false,Ts(e,Oe$2,t);else if(function(t){return ds(t,"Backspace",{shiftKey:"any"})||i&&ds(t,"h",{ctrlKey:true})}(t))_s(t)?Ts(e,Ae$3,t):(t.preventDefault(),Ts(e,fe$4,true));
7324else if(function(t){return "Escape"===t.key}(t))Ts(e,De$2,t);else if(function(t){return ds(t,"Delete",{})||i&&ds(t,"d",{ctrlKey:true})}(t))!function(t){return "Delete"===t.key}(t)?(t.preventDefault(),Ts(e,fe$4,false)):Ts(e,Pe$2,t);else if(function(t){return ds(t,"Backspace",gs)}(t))t.preventDefault(),Ts(e,ye$2,true);else if(function(t){return ds(t,"Delete",gs)}(t))t.preventDefault(),Ts(e,ye$2,false);else if(function(t){return i&&ds(t,"Backspace",{metaKey:true})}(t))t.preventDefault(),Ts(e,me$3,true);else if(function(t){return i&&(ds(t,"Delete",{metaKey:true})||ds(t,"k",{ctrlKey:true}))}(t))t.preventDefault(),Ts(e,me$3,false);else if(function(t){return ds(t,"b",hs)}(t))t.preventDefault(),Ts(e,xe,"bold");else if(function(t){return ds(t,"u",hs)}(t))t.preventDefault(),Ts(e,xe,"underline");else if(function(t){return ds(t,"i",hs)}(t))t.preventDefault(),Ts(e,xe,"italic");else if(function(t){return ds(t,"Tab",{shiftKey:"any"})}(t))Ts(e,Fe$2,t);else if(function(t){return ds(t,"z",hs)}(t))t.preventDefault(),Ts(e,Ce$2,void 0);else if(function(t){if(i)return ds(t,"z",{metaKey:true,shiftKey:true});return ds(t,"y",{ctrlKey:true})||ds(t,"z",{ctrlKey:true,shiftKey:true})}(t))t.preventDefault(),Ts(e,Se$2,void 0);else {const n=e._editorState._selection;null===n||Fr(n)?ps(t)&&(t.preventDefault(),Ts(e,Ue$2,t)):!function(t){return ds(t,"c",hs)}(t)?!function(t){return ds(t,"x",hs)}(t)?ps(t)&&(t.preventDefault(),Ts(e,Ue$2,t)):(t.preventDefault(),Ts(e,je$2,t)):(t.preventDefault(),Ts(e,Je$2,t));}return function(t){return t.ctrlKey||t.shiftKey||t.altKey||t.metaKey}(t)&&e.dispatchCommand(Qe$1,t),true}function En$1(t){let e=t.__lexicalEventHandles;return void 0===e&&(e=[],t.__lexicalEventHandles=e),e}const On$1=new Map;function Mn(t){const e=js(t.target);if(null===e)return;const n=Do(e.anchorNode);if(null===n)return;an$1&&(an$1=false,Ki(n,()=>{const r=Zr(),i=e.anchorNode;if(Ys(i)||Ko(i)){es(Xr(r,e,n,t));}}));const r=is(n),i=r[r.length-1],o=i._key,s=On$1.get(o),l=s||i;l!==n&&mn$1(e,l,false),mn$1(e,n,true),n!==i?On$1.set(o,n):s&&On$1.delete(o);}function An$1(t){t._lexicalHandled=true;}function Dn(t){return  true===t._lexicalHandled}function Fn$1(e){const n=sn$1.get(e);if(void 0===n)return void 0;const r=ln$1.get(n);if(void 0===r)return void 0;const i=r-1;i>=0||t(164),sn$1.delete(e),ln$1.set(n,i),0===i&&n.removeEventListener("selectionchange",Mn);const o=Po(e);Ao(o)?(!function(t){if(null!==t._parentEditor){const e=is(t),n=e[e.length-1]._key;On$1.get(n)===t&&On$1.delete(n);}else On$1.delete(t._key);}(o),e.__lexicalEditor=null):o&&t(198);const s=En$1(e);for(let t=0;t<s.length;t++)s[t]();e.__lexicalEventHandles=[];}function Ln(t,e,n){xi();const r=t.__key,i=t.getParent();if(null===i)return;const o=function(t){const e=Qr();if(!Fr(e)||!Wi(t))return e;const{anchor:n,focus:r}=e,i=n.getNode(),o=r.getNode();As(i,t)&&n.set(t.__key,0,"element");As(o,t)&&r.set(t.__key,0,"element");return e}(t);let s=false;if(Fr(o)&&e){const e=o.anchor,n=o.focus;e.key===r&&(ni(e,t,i,t.getPreviousSibling(),t.getNextSibling()),s=true),n.key===r&&(ni(n,t,i,t.getPreviousSibling(),t.getNextSibling()),s=true);}else Ir(o)&&e&&t.isSelected()&&t.selectPrevious();if(Fr(o)&&e&&!s){const e=t.getIndexWithinParent();Jo(t),ti(o,i,e,-1);}else Jo(t);n||Is(i)||i.canBeEmpty()||!i.isEmpty()||Ln(i,e),e&&o&&Vi(i)&&i.isEmpty()&&i.selectEnd();}function In(t){return t}const Kn$1=Symbol.for("ephemeral");function zn(t){return t[Kn$1]||false}let Rn$1 = class Rn{__type;__key;__parent;__prev;__next;__state;static getType(){const{ownNodeType:e}=ul(this);return void 0===e&&t(64,this.name),e}static clone(e){t(65,this.name);}$config(){return {}}config(t,e){const n=e.extends||Object.getPrototypeOf(this.constructor);return Object.assign(e,{extends:n,type:t}),{[t]:e}}afterCloneFrom(t){this.__key===t.__key?(this.__parent=t.__parent,this.__next=t.__next,this.__prev=t.__prev,this.__state=t.__state):t.__state&&(this.__state=t.__state.getWritable(this));}resetOnCopyNodeFrom(t){this.__state&&(this.__state=this.__state.getWritable(this).resetOnCopyNode());}static importDOM;constructor(t){this.__type=this.constructor.getType(),this.__parent=null,this.__prev=null,this.__next=null,Object.defineProperty(this,"__state",{configurable:true,enumerable:false,value:void 0,writable:true}),$o(this,t);}getType(){return this.__type}isInline(){t(137,this.constructor.name);}isAttached(){let t=this.__key;for(;null!==t;){if("root"===t)return  true;const e=Yo(t);if(null===e)break;t=e.__parent;}return  false}isSelected(t){const e=t||Qr();if(null==e)return  false;
7324const n=e.getNodes().some(t=>t.__key===this.__key);if(Tr(this))return n;if(Fr(e)&&"element"===e.anchor.type&&"element"===e.focus.type){if(e.isCollapsed())return  false;const t=this.getParent();if(ji(this)&&this.isInline()&&t){const n=e.isBackward()?e.focus:e.anchor;if(t.is(n.getNode())&&n.offset===t.getChildrenSize()&&this.is(t.getLastChild()))return  false}}return n}getKey(){return this.__key}getIndexWithinParent(){const t=this.getParent();if(null===t)return  -1;let e=t.getFirstChild(),n=0;for(;null!==e;){if(this.is(e))return n;n++,e=e.getNextSibling();}return  -1}getParent(){const t=this.getLatest().__parent;return null===t?null:Yo(t)}getParentOrThrow(){const e=this.getParent();return null===e&&t(66,this.__key),e}getTopLevelElement(){let e=this;for(;null!==e;){const n=e.getParent();if(Is(n))return Wi(e)||e===this&&ji(e)||t(194),e;e=n;}return null}getTopLevelElementOrThrow(){const e=this.getTopLevelElement();return null===e&&t(67,this.__key),e}getParents(){const t=[];let e=this.getParent();for(;null!==e;)t.push(e),e=e.getParent();return t}getParentKeys(){const t=[];let e=this.getParent();for(;null!==e;)t.push(e.__key),e=e.getParent();return t}getPreviousSibling(){const t=this.getLatest().__prev;return null===t?null:Yo(t)}getPreviousSiblings(){const t=[],e=this.getParent();if(null===e)return t;let n=e.getFirstChild();for(;null!==n&&!n.is(this);)t.push(n),n=n.getNextSibling();return t}getNextSibling(){const t=this.getLatest().__next;return null===t?null:Yo(t)}getNextSiblings(){const t=[];let e=this.getNextSibling();for(;null!==e;)t.push(e),e=e.getNextSibling();return t}getCommonAncestor(t){const e=Wi(this)?this:this.getParent(),n=Wi(t)?t:t.getParent(),r=e&&n?Yl(e,n):null;return r?r.commonAncestor:null}is(t){return null!=t&&this.__key===t.__key}isBefore(e){const n=Yl(this,e);return null!==n&&("descendant"===n.type||("branch"===n.type?-1===jl(n):("same"!==n.type&&"ancestor"!==n.type&&t(279),false)))}isParentOf(t){const e=Yl(this,t);return null!==e&&"ancestor"===e.type}getNodesBetween(e){const n=this.isBefore(e),r=[],i=new Set;let o=this;for(;null!==o;){const s=o.__key;if(i.has(s)||(i.add(s),r.push(o)),o===e)break;const l=Wi(o)?n?o.getFirstChild():o.getLastChild():null;if(null!==l){o=l;continue}const c=n?o.getNextSibling():o.getPreviousSibling();if(null!==c){o=c;continue}const a=o.getParentOrThrow();if(i.has(a.__key)||r.push(a),a===e)break;let u=null,f=a;do{if(null===f&&t(68),u=n?f.getNextSibling():f.getPreviousSibling(),f=f.getParent(),null===f)break;null!==u||i.has(f.__key)||r.push(f);}while(null===u);o=u;}return n||r.reverse(),r}isDirty(){const t=vi()._dirtyLeaves;return null!==t&&t.has(this.__key)}getLatest(){if(zn(this))return this;const e=Yo(this.__key);return null===e&&t(113),e}getWritable(){if(zn(this))return this;xi();const t=Si(),e=vi(),n=t._nodeMap,r=this.__key,i=this.getLatest(),o=e._cloneNotNeeded,s=Qr();if(null!==s&&s.setCachedNodes(null),o.has(r))return jo(i),i;const l=il(i);return o.add(r),jo(l),n.set(r,l),l}getTextContent(){return ""}getTextContentSize(){return this.getTextContent().length}createDOM(e,n){t(70);}updateDOM(e,n,r){t(71);}exportDOM(t){return {element:this.createDOM(t._config,t)}}exportJSON(){const t=this.__state?this.__state.toJSON():void 0;return {type:this.__type,version:1,...t}}static importJSON(e){t(18,this.name);}updateFromJSON(t){return function(t,e){const n=t.getWritable(),r=e.$;let i=r;for(const t of dt$3(n).flatKeys)t in e&&(void 0!==i&&i!==r||(i={...r}),i[t]=e[t]);return (n.__state||i)&&ft$2(t).updateFromJSON(i),n}(this,t)}static transform(){return null}remove(t){Ln(this,true,t);}replace(e,n){xi();let r=Qr();null!==r&&(r=r.clone()),Rs(this,e);const i=this.getLatest(),o=this.__key,s=e.__key,l=e.getWritable(),c=this.getParentOrThrow().getWritable(),a=c.__size;Jo(l);const u=i.getPreviousSibling(),f=i.getNextSibling(),d=i.__prev,h=i.__next,g=i.__parent;if(Ln(i,false,true),null===u)c.__first=s;else {u.getWritable().__next=s;}if(l.__prev=d,null===f)c.__last=s;else {f.getWritable().__prev=s;}if(l.__next=h,l.__parent=g,c.__size=a,n&&(Wi(this)&&Wi(l)||t(139),this.getChildren().forEac
7324h(t=>{l.append(t);})),Fr(r)){es(r);const t=r.anchor,e=r.focus;t.key===o&&Dr(t,l),e.key===o&&Dr(e,l);}return Vo()===o&&Uo(s),l}insertAfter(t,e=true){xi(),Rs(this,t);const n=this.getWritable(),r=t.getWritable(),i=r.getParent(),o=Qr();let s=false,l=false;if(null!==i){const e=t.getIndexWithinParent();if(Jo(r),Fr(o)){const t=i.__key,n=o.anchor,r=o.focus;s="element"===n.type&&n.key===t&&n.offset===e+1,l="element"===r.type&&r.key===t&&r.offset===e+1;}}const c=this.getNextSibling(),a=this.getParentOrThrow().getWritable(),u=r.__key,f=n.__next;if(null===c)a.__last=u;else {c.getWritable().__prev=u;}if(a.__size++,n.__next=u,r.__next=f,r.__prev=n.__key,r.__parent=n.__parent,e&&Fr(o)){const t=this.getIndexWithinParent();ti(o,a,t+1);const e=a.__key;s&&o.anchor.set(e,t+2,"element"),l&&o.focus.set(e,t+2,"element");}return t}insertBefore(t,e=true){xi(),Rs(this,t);const n=this.getWritable(),r=t.getWritable(),i=r.__key;Jo(r);const o=this.getPreviousSibling(),s=this.getParentOrThrow().getWritable(),l=n.__prev,c=this.getIndexWithinParent();if(null===o)s.__first=i;else {o.getWritable().__next=i;}s.__size++,n.__prev=i,r.__prev=l,r.__next=n.__key,r.__parent=n.__parent;const a=Qr();if(e&&Fr(a)){ti(a,this.getParentOrThrow(),c);}return t}isParentRequired(){return  false}createParentElementNode(){return eo()}selectStart(){return this.selectPrevious()}selectEnd(){return this.selectNext(0,0)}selectPrevious(t,e){xi();const n=this.getPreviousSibling(),r=this.getParentOrThrow();if(null===n)return r.select(0,0);if(Wi(n))return n.select();if(!Tr(n)){const t=n.getIndexWithinParent()+1;return r.select(t,t)}return n.select(t,e)}selectNext(t,e){xi();const n=this.getNextSibling(),r=this.getParentOrThrow();if(null===n)return r.select();if(Wi(n))return n.select(0,0);if(!Tr(n)){const t=n.getIndexWithinParent();return r.select(t,t)}return n.select(t,e)}markDirty(){this.getWritable();}reconcileObservedMutation(t,e){this.markDirty();}};function Bn(t){return t instanceof Rn$1}const Wn$1="historic",$n$1="history-push",Jn="history-merge",jn="paste",Un="collaboration",Vn="skip-collab",Yn="skip-scroll-into-view",qn="skip-dom-selection",Hn="skip-selection-focus",Gn="composition-start",Xn="composition-end",Qn=/\s*!important\s*$/i;function Zn(t){const e={};if(!t)return e;let n="",r="",i=null,o=false,s=false,l=false,c=0;for(let a=0;a<t.length;a++){const u=t[a];if(o)"*"===u&&"/"===t[a+1]&&(o=false,a++);else if(s)l?r+=u:n+=u,s=false;else if(null===i)if("/"!==u||"*"!==t[a+1])if('"'!==u&&"'"!==u)if("("!==u)if(")"!==u)if(l||":"!==u||0!==c){if(";"===u&&0===c){const t=n.trim(),i=r.trim();""!==t&&""!==i&&(e[t]=i),n="",r="",l=false;continue}l?r+=u:n+=u;}else l=true;else c=Math.max(0,c-1),l?r+=u:n+=u;else c++,l?r+=u:n+=u;else i=u,l?r+=u:n+=u;else o=true,a++;else l?r+=u:n+=u,"\\"===u?s=true:u===i&&(i=null);}const a=n.trim(),u=r.trim();return ""!==a&&""!==u&&(e[a]=u),e}function tr(t,e,n){const r=Qn.test(n)?"important":"",i=""===r?n:n.replace(Qn,"").trim();t.setProperty(e,i,r);}function er(t,e){for(const n in e){const r=e[n];null==r?t.removeProperty(n):tr(t,n,r);}}function nr(t,e,n=""){if(e===n)return;const r=Zn(n),i=Zn(e);for(const e in i)delete r[e],tr(t,e,i[e]);for(const e in r)t.removeProperty(e);}class rr extends Rn$1{static getType(){return "linebreak"}static clone(t){return new rr(t.__key)}constructor(t){super(t);}getTextContent(){return "\n"}createDOM(){return document.createElement("br")}updateDOM(){return  false}isInline(){return  true}static importDOM(){return {br:t=>function(t){const e=t.parentElement;if(null!==e&&Xs(e)){const n=e.firstChild;if(n===t||n.nextSibling===t&&lr(n)){const n=e.lastChild;if(n===t||n.previousSibling===t&&lr(n))return  true}}return  false}(t)||function(t){const e=t.parentElement;if(null!==e&&Xs(e)){const n=e.firstChild;if(n===t||n.nextSibling===t&&lr(n))return  false;const r=e.lastChild;if(r===t||r.previousSibling===t&&lr(r))return  true}return  false}(t)?null:{conversion:ir,priority:0}}}static importJSON(t){return or().updateFromJSON(t)}}function ir(t){return {node:or()}}function or(){return zs(new rr)}function sr(t){return t instanceof rr}function lr(t){return Ko(t)&&/^( |\t|\r?\n)+$/.test(t.textContent||"")}function cr(t,e){return 16&e?"code":e&k$3?"mark":32&e?"sub":64&e?"sup":null}function ar(t,e){return 1&e?"strong":2&e?"em":"span"}function ur(t,e,n,r,i){const o=r.classList;let s=ms(i,"base");void 0!==s&&o.add(...s),s=ms(i,"underlineStrikethrough");let l=false;const c=8&e&&4&e;void 0!==s&&(8&n&&4&n?(l=true,c||o.add(...s)):c&&o.remove(...s));for(const t in z$7){const r=z$7[t];if(s=ms(i,t),void 0!==s)if(n&r){if(l&&("underline"===t||"strikethrough"===t)){e&r&&o.remove(...s);continue}(0===(e&r)||c&&"underline"===t||"strikethrough"===t)&&o.add(...s);}else e&r&&o.remove(...s);}}function fr(t,e,n){const r=e.firstChild,i=n.isComposing(),s=t+(i?A$3:"");if(null==r)e.textContent=s;else {const t=r.nodeValue;if(t!==s)if(i||o$1){const[e,n,i]=function(t,e){const n=t.length,r=e.length;let i=0,o=0;for(;i<n&&i<r&&t[i]===e[i];)i++;for(;o+i<n&&o+i<r&&t[n-o-1]===e[r-o-1];)o++;return [i,n-i-o,e.slice(i,r-o)]}(t,s);0!==n&&r.deleteData(e,n),r.insertData(e,i);}else r.nodeValue=s;}}function dr(t,e,n,r,i,o){fr(i,t,e);const s=o.theme.text;void 0!==s&&ur(0,0,r,t,s);}function hr(t,e){const n=document.createElement(e);return n.appendChild(t),n}class gr extends Rn$1{__text;__format;__style;__mode;__detail;static getType(){return "text"}static clone(t){return new gr(t.__text,t.__key)}afterCloneFrom(t){super.afterCloneFrom(t),this.__text=t.__text,this.__format=t.__format,this.__style=t.__style,this.__mode=t.__mode,this.__detail=t.__detail;}constructor(t="",e){super(e),this.__text=t,this.__format=0,this.__style="",this.__mode=0,this.__detail=0;}getFormat(){return this.getLatest().__format}getDetail(){return this.getLatest().__detail}getMode(){const t=this.getLatest();return J$7[t.__mode]}getStyle(){return this.getLatest().__style}isToken(){return 1===this.getLatest().__mode}isComposing(){return this.__key===Vo()}isSegmented(){return 2===this.getLatest().__mode}isDirectionless(){return !!(1&this.getLatest().__detail)}isUnmergeable(){return !!(2&this.getLatest().__detail)}hasFormat(t){const e=z$7[t];return 0!==(this.getFormat()&e)}isSimpleText(){return "text"===this.__type&&0===this.__mode}getTextContent(){return this.getLatest().__text}getFormatFlags(t,e){return Bo(this.getLatest().__format,t,e)}canHaveFormat(){return  true}isInline(){return  true}createDOM(t,e){const n=this.__format,r=cr(0,n),i=ar(0,n),o=null===r?i:r,s=document.createElement(o);let l=s;
7324this.hasFormat("code")&&s.setAttribute("spellcheck","false"),null!==r&&(l=document.createElement(i),s.appendChild(l));dr(l,this,0,n,this.__text,t);const c=this.__style;return ""!==c&&nr(s.style,c),s}updateDOM(e,n,r){const i=this.__text,o=e.__format,s=this.__format,l=cr(0,o),c=cr(0,s),a=ar(0,o),u=ar(0,s);if((null===l?a:l)!==(null===c?u:c))return  true;if(l===c&&a!==u){const e=n.firstChild;null==e&&t(48);const o=document.createElement(u);return dr(o,this,0,s,i,r),n.replaceChild(o,e),false}let f=n;null!==c&&null!==l&&(f=n.firstChild,null==f&&t(49)),fr(i,f,this);const d=r.theme.text;void 0!==d&&o!==s&&ur(0,o,s,f,d);const h=e.__style,g=this.__style;return h!==g&&nr(n.style,g,h),false}static importDOM(){return {"#text":()=>({conversion:xr,priority:0}),b:()=>({conversion:pr,priority:0}),code:()=>({conversion:vr,priority:0}),em:()=>({conversion:vr,priority:0}),i:()=>({conversion:vr,priority:0}),mark:()=>({conversion:vr,priority:0}),s:()=>({conversion:vr,priority:0}),span:()=>({conversion:_r,priority:0}),strong:()=>({conversion:vr,priority:0}),sub:()=>({conversion:vr,priority:0}),sup:()=>({conversion:vr,priority:0}),u:()=>({conversion:vr,priority:0})}}static importJSON(t){return kr().updateFromJSON(t)}updateFromJSON(t){return super.updateFromJSON(t).setTextContent(t.text).setFormat(t.format).setDetail(t.detail).setMode(t.mode).setStyle(t.style)}exportDOM(e){let{element:n}=super.exportDOM(e);return Ys(n)||t(132),n.style.whiteSpace="pre-wrap",this.hasFormat("lowercase")?n.style.textTransform="lowercase":this.hasFormat("uppercase")?n.style.textTransform="uppercase":this.hasFormat("capitalize")&&(n.style.textTransform="capitalize"),this.hasFormat("bold")&&(n=hr(n,"b")),this.hasFormat("italic")&&(n=hr(n,"i")),this.hasFormat("strikethrough")&&(n=hr(n,"s")),this.hasFormat("underline")&&(n=hr(n,"u")),{element:n}}exportJSON(){return {detail:this.getDetail(),format:this.getFormat(),mode:this.getMode(),style:this.getStyle(),text:this.getTextContent(),...super.exportJSON()}}selectionTransform(t,e){}setFormat(t){const e=this.getWritable();return e.__format="string"==typeof t?z$7[t]:t,e}setDetail(t){const e=this.getWritable();return e.__detail="string"==typeof t?R$4[t]:t,e}setStyle(t){const e=this.getWritable();return e.__style=t,e}toggleFormat(t){const e=Bo(this.getFormat(),t,null);return this.setFormat(e)}toggleDirectionless(){const t=this.getWritable();return t.__detail^=1,t}toggleUnmergeable(){const t=this.getWritable();return t.__detail^=2,t}setMode(t){const e=$$4[t];if(this.__mode===e)return this;const n=this.getWritable();return n.__mode=e,n}setTextContent(t){if(this.__text===t)return this;const e=this.getWritable();return e.__text=t,e}select(t,e){xi();let n=t,r=e;const i=Qr(),o=this.getTextContent(),s=this.__key;if("string"==typeof o){const t=o.length;void 0===n&&(n=t),void 0===r&&(r=t);}else n=0,r=0;if(!Fr(i))return Yr(s,n,s,r,"text","text");{const t=Vo();t!==i.anchor.key&&t!==i.focus.key||Uo(s),i.setTextNodeRange(this,n,this,r);}return i}selectStart(){return this.select(0,0)}selectEnd(){const t=this.getTextContentSize();return this.select(t,t)}spliceText(t,e,n,r){const i=this.getWritable(),o=i.__text,s=n.length;let l=t;l<0&&(l=s+l,l<0&&(l=0));const c=Qr();if(r&&Fr(c)){const e=t+s;c.setTextNodeRange(i,e,i,e);}const a=o.slice(0,l)+n+o.slice(l+e);return i.__text=a,i}canInsertTextBefore(){return  true}canInsertTextAfter(){return  true}splitText(...t){xi();const e=this.getLatest(),n=e.getTextContent();if(""===n)return [];const r=e.__key,i=Vo(),o=n.length;t.sort((t,e)=>t-e),t.push(o);const s=[],l=t.length;for(let e=0,r=0;e<o&&r<=l;r++){const i=t[r];i>e&&(s.push(n.slice(e,i)),e=i);}const c=s.length;if(1===c)return [e];const a=s[0],u=e.getParent();let f;const d=e.getFormat(),h=e.getStyle(),g=e.__detail;let _=false,p=null,y=null;const m=Qr();if(Fr(m)){const[t,e]=m.isBackward()?[m.focus,m.anchor]:[m.anchor,m.focus];"text"===t.type&&t.key===r&&(p=t),"text"===e.type&&e.key===r&&(y=e);}e.isSegmented()?(f=kr(a),f.__format=d,f.__style=h,f.__detail=g,f.__state=yt$6(e,f),_=true):f=e.setTextContent(a);const x=[f];for(let t=1;t<c;t++){const n=kr(s[t]);n.__format=d,n.__style=h,n.__detail=g,n.__state=yt$6(e,n);const o=n.__key;i===r&&Uo(o),x.push(n);}const C=p?p.offset:null,S=y?y.offset:null;let v=0;for(const t of x){if(!p&&!y)break;const e=v+t.getTextContentSize();if(null!==p&&null!==C&&C<=e&&C>=v&&(p.set(t.getKey(),C-v,"text"),C<e&&(p=null)),null!==y&&null!==S&&S<=e&&S>=v){y.set(t.getKey(),S-v,"text");break}v=e;}if(null!==u){!function(t){const e=t.getPreviousSibling(),n=t.getNextSibling();null!==e&&jo(e);null!==n&&jo(n);}(this);const t=u.getWritable(),e=this.getIndexWithinParent();_?(t.splice(e,0,x),this.remove()):t.splice(e,1,x),Fr(m)&&ti(m,u,e,c-1);}return x}mergeWithSibling(e){const n=e===this.getPreviousSibling();n||e===this.getNextSibling()||t(50);const r=this.__key,i=e.__key,o=this.__text,s=o.length;Vo()===i&&Uo(r);const l=Qr();if(Fr(l)){const t=l.anchor,o=l.focus;null!==t&&t.key===i&&ri(t,n,r,e,s),null!==o&&o.key===i&&ri(o,n,r,e,s);}const c=e.__text,a=n?c+o:o+c;this.setTextContent(a);const u=this.getWritable();return e.remove(),u}isTextEntity(){return  false}}function _r(t){return {forChild:Nr(t.style),node:null}}function pr(t){const e=t,n="normal"===e.style.fontWeight;return {forChild:Nr(e.style,n?void 0:"bold"),node:null}}const yr=new WeakMap;function mr(t){if(!Ys(t))return  false;if("PRE"===t.nodeName)return  true;const e=t.style.whiteSpace;return "string"==typeof e&&e.startsWith("pre")}function xr(e){const n=e;null===e.parentElement&&t(129);let r=n.textContent||"";if(null!==function(t){let e,n=t.parentNode;const r=[t];for(;null!==n&&void 0===(e=yr.get(n))&&!mr(n);)r.push(n),n=n.parentNode;const i=void 0===e?n:e;for(let t=0;t<r.length;t++)yr.set(r[t],i);return i}(n)){const t=r.split(/(\r?\n|\t)/),e=[],n=t.length;for(let r=0;r<n;r++){const n=t[r];"\n"===n||"\r\n"===n?e.push(or()):"\t"===n?e.push(wr()):""!==n&&e.push(kr(n));}return {node:e}}if(r=r.replace(/\r/g,"").replace(/[ \t\n]+/g," "),""===r)return {node:null};if(" "===r[0]){let t=n,e=true;for(;null!==t&&null!==(t=Cr(t,false));){const n=t.textContent||"";if(n.length>0){/[ \t\n]$/.test(n)&&(r=r.slice(1)),e=false;break}}e&&(r=r.slice(1));}if(" "===r[r.length-1]){let t=n,e=true;for(;null!==t&&null!==(t=Cr(t,true));){if((t.textContent||"").replace(/^( |\t|\r?\n)+/,"").length>0){e=false;break}}e&&(r=r.slice(0,r.length-1));}return ""===r?{node:null}
7324:{node:kr(r)}}function Cr(t,e){let n=t;for(;;){let t;for(;null===(t=e?n.nextSibling:n.previousSibling);){const t=n.parentElement;if(null===t)return null;n=t;}if(n=t,Ys(n)){const t=n.style.display;if(""===t&&!Gs(n)||""!==t&&!t.startsWith("inline"))return null}let r=n;for(;null!==(r=e?n.firstChild:n.lastChild);)n=r;if(Ko(n))return n;if("BR"===n.nodeName)return null}}const Sr={code:"code",em:"italic",i:"italic",mark:"highlight",s:"strikethrough",strong:"bold",sub:"subscript",sup:"superscript",u:"underline"};function vr(t){const e=Sr[t.nodeName.toLowerCase()];return void 0===e?{node:null}:{forChild:Nr(t.style,e),node:null}}function kr(t=""){return zs(new gr(t))}function Tr(t){return t instanceof gr}function Nr(t,e){const n=t.fontWeight,r=t.textDecoration.split(" "),i="700"===n||"bold"===n,o=r.includes("line-through"),s="italic"===t.fontStyle,l=r.includes("underline"),c=t.verticalAlign;return t=>Tr(t)?(i&&!t.hasFormat("bold")&&t.toggleFormat("bold"),o&&!t.hasFormat("strikethrough")&&t.toggleFormat("strikethrough"),s&&!t.hasFormat("italic")&&t.toggleFormat("italic"),l&&!t.hasFormat("underline")&&t.toggleFormat("underline"),"sub"!==c||t.hasFormat("subscript")||t.toggleFormat("subscript"),"super"!==c||t.hasFormat("superscript")||t.toggleFormat("superscript"),e&&!t.hasFormat(e)&&t.toggleFormat(e),t):t}class br extends gr{static getType(){return "tab"}static clone(t){return new br(t.__key)}constructor(t){super("\t",t),this.__detail=2;}static importDOM(){return null}createDOM(t){const e=super.createDOM(t),n=ms(t.theme,"tab");if(void 0!==n){e.classList.add(...n);}return e}static importJSON(t){return wr().updateFromJSON(t)}setTextContent(t){return "\t"!==t&&""!==t&&e(126),super.setTextContent("\t")}spliceText(e,n,r,i){return ""===r&&0===n||"\t"===r&&1===n||t(286),this}setDetail(e){return 2!==e&&t(127),this}setMode(e){return "normal"!==e&&t(128),this}canInsertTextBefore(){return  false}canInsertTextAfter(){return  false}}function wr(){return zs(new br)}function Er(t){return t instanceof br}class Or{key;offset;type;_selection;constructor(t,e,n){this._selection=null,this.key=t,this.offset=e,this.type=n;}is(t){return this.key===t.key&&this.offset===t.offset&&this.type===t.type}isBefore(t){if(this.key===t.key)return this.offset<t.offset;return Jl(rc(ql(this,"next")),rc(ql(t,"next")))<0}getNode(){const e=Yo(this.key);return null===e&&t(20),e}set(t,e,n,r){const i=this._selection,o=this.key;r&&this.key===t&&this.offset===e&&this.type===n||(this.key=t,this.offset=e,this.type=n,mi()||(Vo()===o&&Uo(t),null!==i&&(i.setCachedNodes(null),i.dirty=true)));}}function Mr(t,e,n){return new Or(t,e,n)}function Ar(t,e){let n=e.__key,r=t.offset,i="element";if(Tr(e)){i="text";const t=e.getTextContentSize();r>t&&(r=t);}else if(!Wi(e)){const t=e.getNextSibling();if(Tr(t))n=t.__key,r=0,i="text";else {const t=e.getParent();t&&(n=t.__key,r=e.getIndexWithinParent()+1);}}t.set(n,r,i);}function Dr(t,e){if(Wi(e)){const n=e.getLastDescendant();Wi(n)||Tr(n)?Ar(t,n):Ar(t,e);}else Ar(t,e);}class Pr{_nodes;_cachedNodes;dirty;constructor(t){this._cachedNodes=null,this._nodes=t,this.dirty=false;}getCachedNodes(){return this._cachedNodes}setCachedNodes(t){this._cachedNodes=t;}is(t){if(!Ir(t))return  false;const e=this._nodes,n=t._nodes;return e.size===n.size&&Array.from(e).every(t=>n.has(t))}isCollapsed(){return  false}isBackward(){return  false}getStartEndPoints(){return null}add(t){this.dirty=true,this._nodes.add(t),this._cachedNodes=null;}delete(t){this.dirty=true,this._nodes.delete(t),this._cachedNodes=null;}clear(){this.dirty=true,this._nodes.clear(),this._cachedNodes=null;}has(t){return this._nodes.has(t)}clone(){return new Pr(new Set(this._nodes))}extract(){return this.getNodes()}insertRawText(t){}insertText(){}insertNodes(t){const e=this.getNodes(),n=e.length,r=e[n-1];let i;if(Tr(r))i=r.select();else {const t=r.getIndexWithinParent()+1;i=r.getParentOrThrow().select(t,t);}i.insertNodes(t);for(let t=0;t<n;t++)e[t].remove();}getNodes(){const t=this._cachedNodes;if(null!==t)return t;const e=this._nodes,n=[];for(const t of e){const e=Yo(t);null!==e&&n.push(e);}return mi()||(this._cachedNodes=n),n}getTextContent(){const t=this.getNodes();let e="";for(let n=0;n<t.length;n++)e+=t[n].getTextContent();return e}deleteNodes(){const t=this.getNodes();if((Qr()||Zr())===this&&t[0]){const e=Ol(t[0],"next");Gl(Wl(e,e));}for(const e of t)e.remove();}}function Fr(t){return t instanceof Lr}class Lr{format;style;anchor;focus;_cachedNodes;dirty;constructor(t,e,n,r){this.anchor=t,this.focus=e,t._selection=this,e._selection=this,this._cachedNodes=null,this.format=n,this.style=r,this.dirty=false;}getCachedNodes(){return this._cachedNodes}setCachedNodes(t){this._cachedNodes=t;}is(t){return !!Fr(t)&&(this.anchor.is(t.anchor)&&this.focus.is(t.focus)&&this.format===t.format&&this.style===t.style)}isCollapsed(){return this.anchor.is(this.focus)}getNodes(){const t=this._cachedNodes;if(null!==t)return t;const e=function(t){const e=[],[n,r]=t.getTextSlices();n&&e.push(n.caret.origin);const i=new Set,o=new Set;for(const n of t)if(Nl(n)){const{origin:t}=n;
73240===e.length?i.add(t):(o.add(t),e.push(t));}else {const{origin:t}=n;Wi(t)&&o.has(t)||e.push(t);}r&&e.push(r.caret.origin);if(Tl(t.focus)&&Wi(t.focus.origin)&&null===t.focus.getNodeAtCaret())for(let n=Pl(t.focus.origin,"previous");Nl(n)&&i.has(n.origin)&&!n.origin.isEmpty()&&n.origin.is(e[e.length-1]);n=Ll(n))i.delete(n.origin),e.pop();for(;e.length>1;){const t=e[e.length-1];if(!Wi(t)||o.has(t)||t.isEmpty()||i.has(t))break;e.pop();}if(0===e.length&&t.isCollapsed()){const n=rc(t.anchor),r=rc(t.anchor.getFlipped()),i=t=>vl(t)?t.origin:t.getNodeAtCaret(),o=i(n)||i(r)||(t.anchor.getNodeAtCaret()?n.origin:r.origin);e.push(o);}return e}(sc(Ql(this),"next"));return mi()||(this._cachedNodes=e),e}setTextNodeRange(t,e,n,r){this.anchor.set(t.__key,e,"text"),this.focus.set(n.__key,r,"text");}getTextContent(){const t=this.getNodes();if(0===t.length)return "";const e=t[0],n=t[t.length-1],r=this.anchor,i=this.focus,o=r.isBefore(i),[s,l]=zr(this);let c="",a=true;for(let u=0;u<t.length;u++){const f=t[u];if(Wi(f)&&!f.isInline())a||(c+="\n"),a=!f.isEmpty();else if(a=false,Tr(f)){let t=f.getTextContent();f===e?f===n?"element"===r.type&&"element"===i.type&&i.offset!==r.offset||(t=s<l?t.slice(s,l):t.slice(l,s)):t=o?t.slice(s):t.slice(l):f===n&&(t=o?t.slice(0,l):t.slice(0,s)),c+=t;}else !ji(f)&&!sr(f)||f===n&&this.isCollapsed()||(c+=f.getTextContent());}return c}applyDOMRange(t){const e=vi(),n=e.getEditorState()._selection,r=Ur(t.startContainer,t.startOffset,t.endContainer,t.endOffset,e,n);if(null===r)return;const[i,o]=r;this.anchor.set(i.key,i.offset,i.type,true),this.focus.set(o.key,o.offset,o.type,true),St$3(this);}clone(){const t=this.anchor,e=this.focus;return new Lr(Mr(t.key,t.offset,t.type),Mr(e.key,e.offset,e.type),this.format,this.style)}toggleFormat(t){this.format=Bo(this.format,t,null),this.dirty=true;}setFormat(t){this.format=t,this.dirty=true;}setStyle(t){this.style=t,this.dirty=true;}hasFormat(t){const e=z$7[t];return 0!==(this.format&e)}insertRawText(t){const e=t.split(/(\r?\n|\t)/),n=[],r=e.length;for(let t=0;t<r;t++){const r=e[t];"\n"===r||"\r\n"===r?n.push(or()):"\t"===r?n.push(wr()):n.push(kr(r));}this.insertNodes(n);}insertText(e){const n=this.anchor,r=this.focus,i=this.format,o=this.style;let s=n,l=r;!this.isCollapsed()&&r.isBefore(n)&&(s=r,l=n),"element"===s.type&&function(t,e,n,r){const i=t.getNode(),o=i.getChildAtIndex(t.offset),s=kr();if(s.setFormat(n),s.setStyle(r),no(o))o.splice(0,0,[s]);else {const t=Vi(i)?eo().append(s):s;null===o?i.append(t):o.insertBefore(t);}t.is(e)&&e.set(s.__key,0,"text"),t.set(s.__key,0,"text");}(s,l,i,o),"element"===l.type&&Hl(l,rc(ql(l,"next")));const c=s.offset;let a=l.offset;const u=this.getNodes(),f=u.length;let d=u[0];Tr(d)||t(26);const h=d.getTextContent().length,g=d.getParentOrThrow();let _=u[f-1];if(1===f&&"element"===l.type&&(a=h,l.set(s.key,a,"text")),this.isCollapsed()&&c===h&&(Io(d)||!d.canInsertTextAfter()||!g.canInsertTextAfter()&&null===d.getNextSibling())){let t=d.getNextSibling();if(Tr(t)&&t.canInsertTextBefore()&&!Io(t)||(t=kr(),t.setFormat(i),t.setStyle(o),g.canInsertTextAfter()?d.insertAfter(t):g.insertAfter(t)),t.select(0,0),d=t,""!==e)return void this.insertText(e)}else if(this.isCollapsed()&&0===c&&(Io(d)||!d.canInsertTextBefore()||!g.canInsertTextBefore()&&null===d.getPreviousSibling())){let t=d.getPreviousSibling();if(Tr(t)&&!Io(t)||(t=kr(),t.setFormat(i),g.canInsertTextBefore()?d.insertBefore(t):g.insertBefore(t)),t.select(),d=t,""!==e)return void this.insertText(e)}else if(d.isSegmented()&&c!==h){const t=kr(d.getTextContent());t.setFormat(i),d.replace(t),d=t;}else if(!this.isCollapsed()&&""!==e){const t=_.getParent();if(!g.canInsertTextBefore()||!g.canInsertTextAfter()||Wi(t)&&(!t.canInsertTextBefore()||!t.canInsertTextAfter()))return this.insertText(""),jr(this.anchor,this.focus),void this.insertText(e)}if(1===f){if(Lo(d)){const t=kr(e);return t.select(),void d.replace(t)}const t=d.getFormat(),n=d.getStyle();if(c!==a||t===i&&n===o){if(Er(d)){const t=kr(e);return t.setFormat(i),t.setStyle(o),t.select(),void d.replace(t)}}else {if(""!==d.getTextContent()){const t=kr(e);
7324if(t.setFormat(i),t.setStyle(o),t.select(),0===c)d.insertBefore(t,false);else {const[e]=d.splitText(c);e.insertAfter(t,false);}return void(t.isComposing()&&"text"===this.anchor.type&&(this.anchor.offset-=e.length))}d.setFormat(i),d.setStyle(o);}const r=a-c;d=d.spliceText(c,r,e,true),""===d.getTextContent()?d.remove():"text"===this.anchor.type&&(this.format=t,this.style=n,d.isComposing()&&(this.anchor.offset-=e.length));}else {const t=new Set([...d.getParentKeys(),..._.getParentKeys()]),n=Wi(d)?d:d.getParentOrThrow();let r=Wi(_)?_:_.getParentOrThrow(),i=_;if(!n.is(r)&&r.isInline())do{i=r,r=r.getParentOrThrow();}while(r.isInline());if("text"===l.type&&(0!==a||""===_.getTextContent())||"element"===l.type&&_.getIndexWithinParent()<a)if(Tr(_)&&!Lo(_)&&a!==_.getTextContentSize()){if(_.isSegmented()){const t=kr(_.getTextContent());_.replace(t),_=t;}Vi(l.getNode())||"text"!==l.type||(_=_.spliceText(0,a,"")),t.add(_.__key);}else {const t=_.getParentOrThrow();t.canBeEmpty()||1!==t.getChildrenSize()?_.remove():t.remove();}else t.add(_.__key);const o=r.getChildren(),s=new Set(u),g=n.is(r),p=n.isInline()&&null===d.getNextSibling()?n:d;for(let t=o.length-1;t>=0;t--){const e=o[t];
7324if(e.is(d)||Wi(e)&&e.isParentOf(d))break;e.isAttached()&&(!s.has(e)||e.is(i)?g||p.insertAfter(e,false):e.remove());}if(!g){let e=r,n=null;for(;null!==e;){const r=e.getChildren(),i=r.length;(0===i||r[i-1].is(n))&&(t.delete(e.__key),n=e),e=e.getParent();}}if(Lo(d))if(c===h)d.select();else {const t=kr(e);t.select(),d.replace(t);}else d=d.spliceText(c,h-c,e,true),""===d.getTextContent()?d.remove():"text"===this.anchor.type&&(this.format=d.getFormat(),this.style=d.getStyle(),d.isComposing()&&(this.anchor.offset-=e.length));for(let e=1;e<f;e++){const n=u[e],r=n.__key;t.has(r)||n.remove();}}}removeText(){const t=Qr()===this;Xl(this,nc(Ql(this))),t&&Qr()!==this&&es(this);}formatText(t,e=null){if(this.isCollapsed())return this.toggleFormat(t),void Uo(null);const n=this.getNodes(),r=[];for(const t of n)Tr(t)&&r.push(t);const i=e=>{n.forEach(n=>{if(Wi(n)){const r=n.getFormatFlags(t,e);n.setTextFormat(r);}});},o=r.length;if(0===o)return this.toggleFormat(t),Uo(null),void i(e);const s=this.anchor,l=this.focus,c=this.isBackward(),a=c?l:s,u=c?s:l;let f=0,d=r[0],h="element"===a.type?0:a.offset;if("text"===a.type&&h===d.getTextContentSize()&&(f=1,d=r[1],h=0),null==d)return;const g=d.getFormatFlags(t,e);i(g);const _=o-1;let p=r[_];const y="text"===u.type?u.offset:p.getTextContentSize();if(d.is(p)){if(h===y)return;if(Io(d)||0===h&&y===d.getTextContentSize())d.setFormat(g);else {const t=d.splitText(h,y),e=0===h?t[0]:t[1];e.setFormat(g),"text"===a.type&&a.set(e.__key,0,"text"),"text"===u.type&&u.set(e.__key,y-h,"text");}return void(this.format=g)}0===h||Io(d)||([,d]=d.splitText(h),h=0),d.setFormat(g);const m=p.getFormatFlags(t,g);y>0&&(y===p.getTextContentSize()||Io(p)||([p]=p.splitText(y)),p.setFormat(m));for(let e=f+1;e<_;e++){const n=r[e],i=n.getFormatFlags(t,m);n.setFormat(i);}"text"===a.type&&a.set(d.__key,h,"text"),"text"===u.type&&u.set(p.__key,y,"text"),this.format=g|m;}insertNodes(e){if(0===e.length)return;if(this.isCollapsed()||this.removeText(),"root"===this.anchor.key){this.insertParagraph();const n=Qr();return Fr(n)||t(134),n.insertNodes(e)}const n=(this.isBackward()?this.focus:this.anchor).getNode(),r=dl(n,Qs),i=e[e.length-1];if(Wi(r)&&"__language"in r){if("__language"in e[0])this.insertText(e[0].getTextContent());else {const t=ai(this);r.splice(t,0,e),i.selectEnd();}return}if(!e.some(t=>(Wi(t)||ji(t))&&!t.isInline())){Wi(r)||t(211,n.constructor.name,n.getType());const o=ai(this);return r.splice(o,0,e),void i.selectEnd()}const o=function(t){const e=eo();let n=null;for(let r=0;r<t.length;r++){const i=t[r],o=sr(i);if(o||ji(i)&&i.isInline()||Wi(i)&&i.isInline()||Tr(i)||i.isParentRequired()){if(null===n&&(n=i.createParentElementNode(),e.append(n),o))continue;null!==n&&n.append(i);}else e.append(i),n=null;}return e}(e),s=o.getLastDescendant(),l=o.getChildren(),c=!Wi(r)||!r.isEmpty()?this.insertParagraph():null,a=l[l.length-1];let u=l[0];var f;Wi(f=u)&&Qs(f)&&!f.isEmpty()&&Wi(r)&&(!r.isEmpty()||r.canMergeWhenEmpty())&&(Wi(r)||t(211,n.constructor.name,n.getType()),r.append(...u.getChildren()),u=l[1]),u&&(null===r&&t(212,n.constructor.name,n.getType()),function(e,n){const r=n.getParentOrThrow().getLastChild();let i=n;const o=[n];for(;i!==r;)i.getNextSibling()||t(140),i=i.getNextSibling(),o.push(i);let s=e;for(const t of o)s=s.insertAfter(t);}(r,u));const d=dl(s,Qs);c&&Wi(d)&&(c.canMergeWhenEmpty()||Qs(a))&&(d.append(...c.getChildren()),c.remove()),Wi(r)&&r.isEmpty()&&r.remove(),s.selectEnd();const h=Wi(r)?r.getLastChild():null;sr(h)&&d!==r&&h.remove();}insertParagraph(){if("root"===this.anchor.key){const t=eo();return Zo().splice(this.anchor.offset,0,[t]),t.select(),t}const e=ai(this),n=dl(this.anchor.getNode(),Qs);Wi(n)||t(213);const r=n.getChildAtIndex(e),i=r?[r,...r.getNextSiblings()]:[],o=n.insertNewAfter(this,false);return o?(o.append(...i),o.selectStart(),o):null}insertLineBreak(t){const e=or();if(this.insertNodes([e]),t){const t=e.getParentOrThrow(),n=e.getIndexWithinParent();t.select(n,n);}}extract(){const t=[...this.getNodes()],e=t.length;let n=t[0],r=t[e-1];const[i,o]=zr(this),s=this.isBackward(),[l,c]=s?[this.focus,this.anchor]:[this.anchor,this.focus],[a,u]=s?[o,i]:[i,o];if(0===e)return [];if(1===e){if(Tr(n)&&!this.isCollapsed()){const t=n.splitText(a,u),e=0===a?t[0]:t[1];return e?(l.set(e.getKey(),0,"text"),c.set(e.getKey(),e.getTextContentSize(),"text"),[e]):[]}return [n]}if(Tr(n)&&(a===n.getTextContentSize()?t.shift():0!==a&&([,n]=n.splitText(a),t[0]=n,l.set(n.getKey(),0,"text"))),Tr(r)){const e=r.getTextContent().length;0===u?t.pop():u!==e&&([r]=r.splitText(u),t[t.length-1]=r,c.set(r.getKey(),r.getTextContentSize(),"text"));}return t}modify(t,e,n){if(fi(this,t,e,n))return;const r="move"===t,i=vi(),o=Js(Ps(i));if(!o)return;const s=i._blockCursorElement,l=i._rootElement,c=this.focus.getNode();if(null===l||null===s||!Wi(c)||c.isInline()||c.canBeEmpty()||$s(s,i,l),this.dirty){let t=Ns(i,this.anchor.key),e=Ns(i,this.focus.key);"text"===this.anchor.type&&(t=Ro(t)),"text"===this.focus.type&&(e=Ro(e)),t&&e&&ii(o,t,this.anchor.offset,e,this.focus.offset);}if(function(t,e,n,r){t.modify(e,n,r);}(o,t,e?"backward":"forward",n),o.rangeCount>0){const t=o.getRangeAt(0),n=this.anchor.getNode(),i=Vi(n)?n:Ls(n);if(this.applyDOMRange(t),this.dirty=true,!r){const n=this.getNodes(),r=[];let s=false;for(let t=0;t<n.length;t++){const e=n[t];As(e,i)?r.push(e):s=true;}if(s&&r.length>0)if(e){const t=r[0];Wi(t)?t.selectStart():t.getParentOrThrow().selectStart();}else {const t=r[r.length-1];Wi(t)?t.selectEnd():t.getParentOrThrow().selectEnd();}
7324o.anchorNode===t.startContainer&&o.anchorOffset===t.startOffset||function(t){const e=t.focus,n=t.anchor,r=n.key,i=n.offset,o=n.type;n.set(e.key,e.offset,e.type,true),e.set(r,i,o,true);}(this);}}"lineboundary"===n&&fi(this,t,e,n,"decorators");}forwardDeletion(t,e,n){if(!n&&("element"===t.type&&Wi(e)&&t.offset===e.getChildrenSize()||"text"===t.type&&t.offset===e.getTextContentSize())){const t=e.getParent(),n=e.getNextSibling()||(null===t?null:t.getNextSibling());if(Wi(n)&&n.isShadowRoot())return  true}return  false}deleteCharacter(t){const e=this.isCollapsed();if(this.isCollapsed()){const e=this.anchor;let n=e.getNode();if(this.forwardDeletion(e,n,t))return;const r=Rl(ql(e,t?"previous":"next"));if(r.getTextSlices().every(t=>null===t||0===t.distance)){let t={type:"initial"};for(const e of r.iterNodeCarets("shadowRoot"))if(Nl(e))if(e.origin.isInline());else {if(e.origin.isShadowRoot()){if("merge-block"===t.type)break;if(Wi(r.anchor.origin)&&r.anchor.origin.isEmpty()){const t=rc(e);Xl(this,Wl(t,t)),r.anchor.origin.remove();}return}"merge-next-block"!==t.type&&"merge-block"!==t.type||(t={block:t.block,caret:e,type:"merge-block"});}else {if("merge-block"===t.type)break;if(Tl(e)){if(Wi(e.origin)){if(e.origin.isInline()){if(!e.origin.isParentOf(r.anchor.origin))break}else t={block:e.origin,type:"merge-next-block"};continue}if(ji(e.origin)){if(e.origin.isIsolated());else if("merge-next-block"===t.type&&(e.origin.isKeyboardSelectable()||!e.origin.isInline())&&Wi(r.anchor.origin)&&r.anchor.origin.isEmpty()){r.anchor.origin.remove();const t=Hr();t.add(e.origin.getKey()),es(t);}else e.origin.remove();return}break}}if("merge-block"===t.type){const{caret:e,block:n}=t;return Xl(this,Wl(!e.origin.isEmpty()&&n.isEmpty()?Zl(Ol(n,e.direction)):r.anchor,e)),this.removeText()}}const i=this.focus;if(this.modify("extend",t,"character"),this.isCollapsed()){if(t&&0===e.offset&&Rr(this,e.getNode()))return}else {const r="text"===i.type?i.getNode():null;if(n="text"===e.type?e.getNode():null,null!==r&&r.isSegmented()){const e=i.offset,o=r.getTextContentSize();if(r.is(n)||t&&e!==o||!t&&0!==e)return void Wr(r,t,e)}else if(null!==n&&n.isSegmented()){const i=e.offset,o=n.getTextContentSize();if(n.is(r)||t&&0!==i||!t&&i!==o)return void Wr(n,t,i)}!function(t,e){const n=t.anchor,r=t.focus,i=n.getNode(),o=r.getNode();if(i===o&&"text"===n.type&&"text"===r.type){const t=n.offset,o=r.offset,s=t<o,l=s?t:o,c=s?o:t,a=c-1;if(l!==a){(function(t){return !(rs(t)||Br(t))})(i.getTextContent().slice(l,c))&&(e?r.set(r.key,a,r.type):n.set(n.key,a,n.type));}}}(this,t);}}if(this.removeText(),t&&!e&&this.isCollapsed()&&"element"===this.anchor.type&&0===this.anchor.offset){const t=this.anchor.getNode();t.isEmpty()&&Vi(t.getParent())&&null===t.getPreviousSibling()&&Rr(this,t);}}deleteLine(t){this.isCollapsed()&&this.modify("extend",t,"lineboundary"),this.isCollapsed()?this.deleteCharacter(t):this.removeText();}deleteWord(t){if(this.isCollapsed()){const e=this.anchor,n=e.getNode();if(this.forwardDeletion(e,n,t))return;this.modify("extend",t,"word");}this.isCollapsed()?this.deleteCharacter(t):this.removeText();}isBackward(){return this.focus.isBefore(this.anchor)}getStartEndPoints(){return [this.anchor,this.focus]}}function Ir(t){return t instanceof Pr}function Kr(t){const e=t.offset;if("text"===t.type)return e;const n=t.getNode();return e===n.getChildrenSize()?n.getTextContent().length:0}function zr(t){const e=t.getStartEndPoints();if(null===e)return [0,0];const[n,r]=e;return "element"===n.type&&"element"===r.type&&n.key===r.key&&n.offset===r.offset?[0,0]:[Kr(n),Kr(r)]}function Rr(t,e){for(let n=e;n;n=n.getParent()){if(Wi(n)){if(n.collapseAtStart(t))return  true;if(Is(n))break}if(n.getPreviousSibling())break}return  false}const Br=(()=>{try{const t=new RegExp("\\p{Emoji}","u"),e=t.test.bind(t);if(e("\u2764\ufe0f")&&e("#\ufe0f\u20e3")&&e("\u{1f44d}"))return e}catch(t){}return ()=>false})();function Wr(t,e,n){const r=t,i=r.getTextContent().split(/(?=\s)/g),o=i.length;let s=0,l=0;for(let t=0;t<o;t++){const r=t===o-1;if(l=s,s+=i[t].length,e&&s===n||s>n||r){i.splice(t,1),r&&(l=void 0);break}}const c=i.join("").trim();""===c?r.remove():(r.setTextContent(c),r.select(l,l));}function $r(e,n,r,i){let o,s=n;if(Ys(e)){let l=false;const c=e.childNodes,a=c.length,u=i._blockCursorElement;s===a&&(l=true,s=a-1);let f=c[s],d=false;if(f===u)f=c[s+1],d=true;else if(null!==u){const t=u.parentNode;if(e===t){n>Array.prototype.indexOf.call(t.children,u)&&s--;}}if(o=ns(f),Tr(o))s=Al(o,l?"next":"previous");else {let c=ns(e);if(null===c)return null;if(Wi(c)){const a=i.getElementByKey(c.getKey());null===a&&t(214);const u=tl(i).$getDOMSlot(c,a,i);
7324[c,s]=u.resolveChildIndex(c,a,e,n),Wi(c)||t(215),l&&s>=c.getChildrenSize()&&(s=Math.max(0,c.getChildrenSize()-1));let f=c.getChildAtIndex(s);if(Wi(f)&&function(t,e,n){const r=t.getParent();return null===n||null===r||!r.canBeEmpty()||r!==n.getNode()}(f,0,r)){const t=l?f.getLastDescendant():f.getFirstDescendant();null===t?c=f:(f=t,c=Wi(f)?f:f.getParentOrThrow()),s=0;}Tr(f)?(o=f,c=null,s=Al(f,l?"next":"previous")):f!==c&&l&&!d&&(Wi(c)||t(216),s=Math.min(c.getChildrenSize(),s+1));}else {const t=c.getIndexWithinParent();s=0===n&&ji(c)&&ns(e)===c?t:t+1,c=c.getParentOrThrow();}if(Wi(c))return Mr(c.__key,s,"element")}}else o=ns(e);return Tr(o)?Mr(o.__key,Al(o,s,"clamp"),"text"):null}function Jr(t,e,n){const r=t.offset,i=t.getNode();if(0===r){const r=i.getPreviousSibling(),o=i.getParent();if(e){if((n||!e)&&null===r&&Wi(o)&&o.isInline()){const e=o.getPreviousSibling();Tr(e)&&t.set(e.__key,e.getTextContent().length,"text");}}else Wi(r)&&!n&&r.isInline()?t.set(r.__key,r.getChildrenSize(),"element"):Tr(r)&&t.set(r.__key,r.getTextContent().length,"text");}else if(r===i.getTextContent().length){const r=i.getNextSibling(),o=i.getParent();if(e&&Wi(r)&&r.isInline())t.set(r.__key,0,"element");else if((n||e)&&null===r&&Wi(o)&&o.isInline()&&!o.canInsertTextAfter()){const e=o.getNextSibling();Tr(e)&&t.set(e.__key,0,"text");}}}function jr(t,e,n){if("text"===t.type&&"text"===e.type){const n=t.isBefore(e),r=t.is(e);Jr(t,n,r),Jr(e,!n,r),r&&e.set(t.key,t.offset,t.type);}}function Ur(t,e,n,r,i,o){if(null===t||null===n||!Mo(i,t,n))return null;const s=$r(t,e,Fr(o)?o.anchor:null,i);if(null===s)return null;const l=$r(n,r,Fr(o)?o.focus:null,i);if(null===l)return null;if("element"===s.type&&"element"===l.type){const e=ns(t),r=ns(n);if(ji(e)&&ji(r))return null}return jr(s,l),[s,l]}function Vr(t){return Wi(t)&&!t.isInline()}function Yr(t,e,n,r,i,o){const s=Si(),l=new Lr(Mr(t,e,i),Mr(n,r,o),0,"");return l.dirty=true,s._selection=l,l}function qr(){const t=Mr("root",0,"element"),e=Mr("root",0,"element");return new Lr(t,e,0,"")}function Hr(){return new Pr(new Set)}function Gr(t,e){return Xr(null,t,e,null)}function Xr(t,e,n,r){const i=n._window;if(null===i)return null;const o=r||i.event,s=o?o.type:void 0,l="selectionchange"===s,c=!q$7&&(l||"beforeinput"===s||"compositionstart"===s||"compositionend"===s||"click"===s&&o&&3===o.detail||"drop"===s||void 0===s);let a,u,f,d;if(Fr(t)&&!c)return t.clone();if(null===e)return null;if(a=e.anchorNode,u=e.focusNode,f=e.anchorOffset,d=e.focusOffset,(l||void 0===s)&&Fr(t)&&!Mo(n,a,u))return t.clone();const h=Ur(a,f,u,d,n,t);if(null===h)return null;const[g,_]=h;let p=0,y="";if(Fr(t)){const e=t.anchor;if(g.key===e.key)p=t.format,y=t.style;else {const t=g.getNode();Tr(t)?(p=t.getFormat(),y=t.getStyle()):Wi(t)&&(p=t.getTextFormat(),y=t.getTextStyle());}}return new Lr(g,_,p,y)}function Qr(){return Si()._selection}function Zr(){return vi()._editorState._selection}function ti(t,e,n,r=1){const i=t.anchor,o=t.focus,s=i.getNode(),l=o.getNode();if(!e.is(s)&&!e.is(l))return;const c=e.__key;if(t.isCollapsed()){const e=i.offset;if(n<=e&&r>0||n<e&&r<0){const n=Math.max(0,e+r);i.set(c,n,"element"),o.set(c,n,"element"),ei(t);}}else {const s=t.isBackward(),l=s?o:i,a=l.getNode(),u=s?i:o,f=u.getNode();if(e.is(a)){const t=l.offset;(n<=t&&r>0||n<t&&r<0)&&l.set(c,Math.max(0,t+r),"element");}if(e.is(f)){const t=u.offset;(n<=t&&r>0||n<t&&r<0)&&u.set(c,Math.max(0,t+r),"element");}}ei(t);}function ei(t){const e=t.anchor,n=e.offset,r=t.focus,i=r.offset,o=e.getNode(),s=r.getNode();if(t.isCollapsed()){if(!Wi(o))return;const t=o.getChildrenSize(),i=n>=t,s=i?o.getChildAtIndex(t-1):o.getChildAtIndex(n);if(Tr(s)){let t=0;i&&(t=s.getTextContentSize()),e.set(s.__key,t,"text"),r.set(s.__key,t,"text");}return}if(Wi(o)){const t=o.getChildrenSize(),r=n>=t,i=r?o.getChildAtIndex(t-1):o.getChildAtIndex(n);if(Tr(i)){let t=0;r&&(t=i.getTextContentSize()),e.set(i.__key,t,"text");}}if(Wi(s)){const t=s.getChildrenSize(),e=i>=t,n=e?s.getChildAtIndex(t-1):s.getChildAtIndex(i);if(Tr(n)){let t=0;e&&(t=n.getTextContentSize()),r.set(n.__key,t,"text");}}}function ni(t,e,n,r,i){let o=null,s=0,l=null;null!==r?(o=r.__key,Tr(r)?(s=r.getTextContentSize(),l="text"):Wi(r)&&(s=r.getChildrenSize(),l="element")):null!==i&&(o=i.__key,Tr(i)?l="text":Wi(i)&&(l="element")),null!==o&&null!==l?t.set(o,s,l):(s=e.getIndexWithinParent(),-1===s&&(s=n.getChildrenSize()),t.set(n.__key,s,"element"));}function ri(t,e,n,r,i){"text"===t.type?t.set(n,t.offset+(e?0:i),"text"):t.offset>r.getIndexWithinParent()&&t.set(t.key,t.offset-1,"element");}function ii(t,e,n,r,i){try{t.setBaseAndExtent(e,n,r,i);}catch(t){}}function oi(t,e,n){const r=Ns(t,e.getKey());if(Wi(e)){const i=tl(t).$getDOMSlot(e,r,t);return [i.element,n+i.getFirstChildOffset()]}return [r,n]}function si(t,e,n,r,i,s,l){const c=r.anchorNode,a=r.focusNode,u=r.anchorOffset,f=r.focusOffset,d=document.activeElement;if(i.has(Un)&&d!==s||null!==d&&Oo(d))return;if(!Fr(e))return void(null!==t&&Mo(n,c,a)&&r.removeAllRanges());const h=e.anchor,g=e.focus,_=h.getNode(),p=g.getNode(),[y,m]=oi(n,_,h.offset),[x,C]=oi(n,p,g.offset),S=e.format,v=e.style,k=e.isCollapsed();let T=y,N=x,b=false;var w,E,O,M,A;if(("text"===h.type?(T=Ro(y),b=_.getFormat()!==S||_.getStyle()!==v):Fr(t)&&"text"===t.anchor.type&&(b=true),"text"===g.type&&(N=Ro(x)),null!==T&&null!==N)&&(k&&(null===t||b||Fr(t)&&(t.format!==S||t.style!==v))&&(w=S,E=v,O=m,M=h.key,A=performance.now(),_n$1=[w,E,O,M,A]),u!==m||f!==C||c!==T||a!==N||"Range"===r.type&&k||(null!==d&&s.contains(d)||i.has(Hn)||s.focus({preventScroll:true}),"element"===h.type))){if(ii(r,T,m,N,C),!o$1||!e.isCollapsed()||null===s||i.has(Hn)||null!==document.activeElement&&s.contains(document.activeElement)||s.focus({preventScroll:true}),!i.has(Yn)&&e.isCollapsed()&&null!==s&&s===document.activeElement){const t=Fr(e)&&"element"===e.anchor.type?T.childNodes[m]||null:r.rangeCount>0?r.getRangeAt(0):null;if(null!==t){let e;if(t instanceof Text){const n=document.createRange();n.selectNode(t),e=n.getBoundingClientRect();}else e=t.getBoundingClientRect();!function(t,e,n){const r=ws(n),i=Ds(r);if(null===r||null===i)return;let{top:o,bottom:s}=e,l=0,c=0,a=n;for(;null!==a;){const e=a===r.body;if(e){l=0,c=Ps(t).innerHeight;const e=i.getComputedStyle(r.documentElement),n=parseFloat(e.scrollPaddingTop),o=parseFloat(e.scrollPaddingBottom);
7324isFinite(n)&&(l+=n),isFinite(o)&&(c-=o);}else {const t=a.getBoundingClientRect();l=t.top,c=t.bottom;}let n=0;if(o<l?n=-(l-o):s>c&&(n=s-c),0!==n)if(e)i.scrollBy(0,n);else {const t=a.scrollTop;a.scrollTop+=n;const e=a.scrollTop-t;o-=e,s-=e;}if(e)break;a=bs(a);}}(n,e,s);}}cn$1=true;}}function li(t){let e=Qr()||Zr();null===e&&(e=Zo().selectEnd()),e.insertNodes(t);}function ci(){const t=Qr();return null===t?"":t.getTextContent()}function ai(e){let n=e;e.isCollapsed()||n.removeText();const r=Qr();Fr(r)&&(n=r),Fr(n)||t(161);const i=n.anchor;let o=i.getNode(),s=i.offset;for(;!Qs(o);){const t=o;if([o,s]=ui(o,s),t.is(o))break}return s}function ui(t,e){const n=t.getParent();if(!n){const t=eo();return Zo().append(t),t.select(),[Zo(),0]}if(Tr(t)){const r=t.splitText(e);if(0===r.length)return [n,t.getIndexWithinParent()];const i=0===e?0:1;return [n,r[0].getIndexWithinParent()+i]}if(!Wi(t)||0===e)return [n,t.getIndexWithinParent()];const r=t.getChildAtIndex(e);if(r){const n=new Lr(Mr(t.__key,e,"element"),Mr(t.__key,e,"element"),0,""),i=t.insertNewAfter(n);i&&i.append(r,...r.getNextSiblings());}return [n,t.getIndexWithinParent()+1]}function fi(t,e,n,r,i="decorators-and-blocks"){if("move"===e&&"character"===r&&!t.isCollapsed()){const[e,r]=n===t.isBackward()?[t.focus,t.anchor]:[t.anchor,t.focus];return r.set(e.key,e.offset,e.type),true}const o=ql(t.focus,n?"previous":"next"),s="lineboundary"===r,l="move"===e;let c=o,a="decorators-and-blocks"===i;if(!ic(c)){for(const t of c){a=false;const{origin:e}=t;if(!ji(e)||e.isIsolated()||(c=t,!s||!e.isInline()))break}if(a)for(const t of Rl(o).iterNodeCarets("extend"===e?"shadowRoot":"root")){if(Nl(t))t.origin.isInline()||(c=t);else {if(Wi(t.origin))continue;ji(t.origin)&&!t.origin.isInline()&&(c=t);}break}}if(c===o)return  false;if(l&&!s&&ji(c.origin)&&c.origin.isKeyboardSelectable()){const t=Hr();return t.add(c.origin.getKey()),es(t),true}return c=rc(c),l&&Hl(t.anchor,c),Hl(t.focus,c),a||!s}let di=null,hi=null,gi=false,_i=false,pi=0;const yi={characterData:true,childList:true,subtree:true};function mi(){return gi||null!==di&&di._readOnly}function xi(){gi&&t(13);}function Ci(){pi>99&&t(14);}function Si(){return null===di&&t(195,ki()),di}function vi(){return null===hi&&t(337,ki()),hi}function ki(){let t=0;const e=new Set,n=Co.version;if("undefined"!=typeof window)for(const r of document.querySelectorAll("[contenteditable]")){const i=Po(r);if(Ao(i))t++;else if(i){let t=String(i.constructor.version||"<0.17.1");t===n&&(t+=" (separately built, likely a bundler configuration issue)"),e.add(t);}}let r=` Detected on the page: ${t} compatible editor(s) with version ${n}`;return e.size&&(r+=` and incompatible editors with versions ${Array.from(e).join(", ")}`),r}function Ti(){return hi}function Ni(t,e,n){const r=e.__type,i=No(t,r);let o=n.get(r);void 0===o&&(o=Array.from(i.transforms),n.set(r,o));const s=o.length;for(let t=0;t<s&&(o[t](e),e.isAttached());t++);}function bi(t,e){return void 0!==t&&t.__key!==e&&t.isAttached()}function wi(t,e){if(!e)return;const n=t._updateTags;let r=e;Array.isArray(e)||(r=[e]);for(const t of r)n.add(t);}function Ei(t){return Oi(t,vi()._nodes)}function Oi(e,n){const r=e.type,i=n.get(r);void 0===i&&t(17,r);const o=i.klass;e.type!==o.getType()&&t(18,o.name);const s=o.importJSON(e),l=e.children;if(Wi(s)&&Array.isArray(l))for(let t=0;t<l.length;t++){const e=Oi(l[t],n);s.append(e);}return s}function Mi(t,e,n){const r=di,i=gi,o=hi;di=e,gi=true,hi=t;try{return n()}finally{di=r,gi=i,hi=o;}}function Ai(t,e){const n=t._pendingEditorState,r=t._rootElement,i=t._headless||null===r;if(null===n)return void(t._deferred.length>0&&Fi(t,t._deferred));const o=t._editorState,s=o._selection,l=n._selection,c=0!==t._dirtyType,a=di,u=gi,f=hi,d=t._updating,h=t._observer;let g=null;if(t._pendingEditorState=null,t._editorState=n,!i&&c&&null!==h){hi=t,di=n,gi=false,t._updating=true;try{const e=t._dirtyType,r=t._dirtyElements,i=t._dirtyLeaves;h.disconnect(),g=ee$4(o,n,t,e,r,i);}catch(e){if(e instanceof Error&&t._onError(e),_i)throw e;return go(t,null,r,n),rt$4(t),t._dirtyType=2,_i=true,Ai(t,o),void(_i=false)}finally{h.observe(r,yi),t._updating=d,di=a,gi=u,hi=f;}}n._readOnly||(n._readOnly=true);const _=t._dirtyLeaves,p=t._dirtyElements,y=t._normalizedNodes,m=t._updateTags,x=t._deferred;c&&(t._dirtyType=0,t._cloneNotNeeded.clear(),t._dirtyLeaves=new Set,t._dirtyElements=new Map,t._normalizedNodes=new Set,t._updateTags=new Set),function(t,e){const n=t._decorators;let r=t._pendingDecorators||n;const i=e._nodeMap;let o;
7324for(o in r)i.has(o)||(r===n&&(r=Xo(t)),delete r[o]);}(t,n);const C=i?null:Js(Ps(t));if(t._editable&&null!==C&&(c||null===l||l.dirty||!l.is(s))&&null!==r&&!m.has(qn)){hi=t,di=n;try{if(null!==h&&h.disconnect(),c||null===l||l.dirty){const e=t._blockCursorElement;null!==e&&$s(e,t,r),si(s,l,t,C,m,r);}!function(t,e,n){let r=t._blockCursorElement;if(Fr(n)&&n.isCollapsed()&&"element"===n.anchor.type&&e.contains(document.activeElement)){const i=n.anchor,o=i.getNode(),s=i.offset;let l=!1,c=null;if(s===o.getChildrenSize()){Ws(o.getChildAtIndex(s-1))&&(l=!0);}else {const e=o.getChildAtIndex(s);if(null!==e&&Ws(e)){const n=e.getPreviousSibling();(null===n||Ws(n))&&(l=!0,c=t.getElementByKey(e.__key));}}if(l){const n=t.getElementByKey(o.__key);return null===r&&(t._blockCursorElement=r=function(t){const e=t.theme,n=document.createElement("div");n.contentEditable="false",n.setAttribute("data-lexical-cursor","true");let r=e.blockCursor;if(void 0!==r){if("string"==typeof r){const t=yc(r);r=e.blockCursor=t;}void 0!==r&&n.classList.add(...r);}return n}(t._config)),e.style.caretColor="transparent",void(null===c?n.appendChild(r):n.insertBefore(r,c))}}null!==r&&$s(r,t,e);}(t,r,l);}finally{null!==h&&h.observe(r,yi),hi=f,di=a;}}null!==g&&function(t,e,n,r,i){const o=Array.from(t._listeners.mutation),s=o.length;for(let t=0;t<s;t++){const[s,l]=o[t];for(const t of l){const o=e.get(t);void 0!==o&&s(o,{dirtyLeaves:r,prevEditorState:i,updateTags:n});}}}(t,g,m,_,o),Fr(l)||null===l||null!==s&&s.is(l)||t.dispatchCommand(ie$4,void 0);const S=t._pendingDecorators;null!==S&&(t._decorators=S,t._pendingDecorators=null,Di("decorator",t,true,S)),function(t,e,n){const r=Qo(e),i=Qo(n);r!==i&&Di("textcontent",t,true,i);}(t,e||o,n),Di("update",t,true,{dirtyElements:p,dirtyLeaves:_,editorState:n,mutatedNodes:g,normalizedNodes:y,prevEditorState:e||o,tags:m}),Fi(t,x),function(t){const e=t._updates;if(0!==e.length){const n=e.shift();if(n){const[e,r]=n;Ii(t,e,r);}}}(t);}function Di(t,e,n,...r){const i=e._updating;e._updating=n;try{const n=e._listeners[t],i=Array.from(n);for(const[t,e]of i){e&&e();const i=t(...r);n.has(t)?n.set(t,i):i&&i();}}finally{e._updating=i;}}function Pi(t,e,n,r){const i=is(t);let o;for(let t=4;t>=0;t--)for(let s=0;s<i.length;s++){const l=i[s];if(s>0&&l._updating){o=l;break}const c=l._commands.get(e);if(void 0!==c){const e=c[t];if(e.size>0){let t=false;if(Ki(l,()=>{for(const i of e)if(i(n,r))return void(t=true)}),t)return t}}}return o&&o.update(()=>{Pi(o,e,n,r);}),false}function Fi(t,e){if(t._deferred=[],0!==e.length){const n=t._updating;t._updating=true;try{for(let t=0;t<e.length;t++)e[t]();}finally{t._updating=n;}}}function Li(e,n){const r=e._updates;let i=n||false;for(;0!==r.length;){const n=r.shift();if(n){const[r,o]=n,s=e._pendingEditorState;let l;void 0!==o&&(l=o.onUpdate,o.skipTransforms&&(i=true),o.discrete&&(null===s&&t(191),s._flushSync=true),l&&e._deferred.push(l),wi(e,o.tag)),null==s?Ii(e,r,o):r();}}return i}function Ii(e,n,r){const i=e._updateTags;let o,s=false,l=false;void 0!==r&&(o=r.onUpdate,wi(e,r.tag),s=r.skipTransforms||false,l=r.discrete||false),o&&e._deferred.push(o);const c=e._editorState;let a=e._pendingEditorState,u=false;(null===a||a._readOnly)&&(a=e._pendingEditorState=Yi(a||c),u=true),a._flushSync=l;const f=di,d=gi,h=hi,g=e._updating;di=a,gi=false,e._updating=true,hi=e;const _=e._headless||null===e.getRootElement();vo(null);try{u&&(_?null!==c._selection&&(a._selection=c._selection.clone()):a._selection=function(t,e){const n=t.getEditorState()._selection,r=Js(Ps(t));return Fr(n)||null==n?Xr(n,r,t,e):n.clone()}(e,r&&r.event||null));const i=e._compositionKey;n(),s=Li(e,s),function(t,e){const n=e.getEditorState()._selection,r=t._selection;if(Fr(r)){const t=r.anchor,e=r.focus;let i;if("text"===t.type&&(i=t.getNode(),i.selectionTransform(n,r)),"text"===e.type){const t=e.getNode();i!==t&&t.selectionTransform(n,r);}}}(a,e),0!==e._dirtyType&&(s?function(t,e){const n=e._dirtyLeaves,r=t._nodeMap;for(const t of n){const e=r.get(t);Tr(e)&&e.isAttached()&&e.isSimpleText()&&!e.isUnmergeable()&&Ct$2(e);}}(a,e):function(t,e){const n=e._dirtyLeaves,r=e._dirtyElements,i=t._nodeMap,o=Vo(),s=new Map;let l=n,c=l.size,a=r,u=a.size;
7324for(;c>0||u>0;){if(c>0){e._dirtyLeaves=new Set;for(const t of l){const r=i.get(t);Tr(r)&&r.isAttached()&&r.isSimpleText()&&!r.isUnmergeable()&&Ct$2(r),void 0!==r&&bi(r,o)&&Ni(e,r,s),n.add(t);}if(l=e._dirtyLeaves,c=l.size,c>0){pi++;continue}}e._dirtyLeaves=new Set,e._dirtyElements=new Map,a.delete("root")&&a.set("root",!0);for(const t of a){const n=t[0],l=t[1];if(r.set(n,l),!l)continue;const c=i.get(n);void 0!==c&&bi(c,o)&&Ni(e,c,s);}l=e._dirtyLeaves,c=l.size,a=e._dirtyElements,u=a.size,pi++;}e._dirtyLeaves=n,e._dirtyElements=r;}(a,e),Li(e),function(t,e,n,r){const i=t._nodeMap,o=e._nodeMap,s=[];for(const[t]of r){const e=o.get(t);void 0!==e&&(e.isAttached()||(Wi(e)&&Y$5(e,t,i,o,s,r),i.has(t)||r.delete(t),s.push(t)));}for(const t of s)o.delete(t);for(const t of n){const e=o.get(t);void 0===e||e.isAttached()||(i.has(t)||n.delete(t),o.delete(t));}}(c,a,e._dirtyLeaves,e._dirtyElements));i!==e._compositionKey&&(a._flushSync=!0);const o=a._selection;if(Fr(o)){const e=a._nodeMap,n=o.anchor.key,r=o.focus.key;void 0!==e.get(n)&&void 0!==e.get(r)||t(19);}else Ir(o)&&0===o._nodes.size&&(a._selection=null);}catch(t){return t instanceof Error&&e._onError(t),e._pendingEditorState=c,e._dirtyType=2,e._cloneNotNeeded.clear(),e._dirtyLeaves=new Set,e._dirtyElements.clear(),void Ai(e)}finally{di=f,gi=d,hi=h,e._updating=g,pi=0;}const p=0!==e._dirtyType||e._deferred.length>0||function(t,e){const n=e.getEditorState()._selection,r=t._selection;if(null!==r){if(r.dirty||!r.is(n))return  true}else if(null!==n)return  true;return  false}(a,e);p?a._flushSync?(a._flushSync=false,Ai(e)):u&&wo(()=>{Ai(e);}):(a._flushSync=false,u&&(i.clear(),e._deferred=[],e._pendingEditorState=null));}function Ki(t,e,n){hi===t&&void 0===n?e():Ii(t,e,n);}class zi{element;before;after;constructor(t,e,n){this.element=t,this.before=e||null,this.after=n||null;}withBefore(t){return new zi(this.element,t,this.after)}withAfter(t){return new zi(this.element,this.before,t)}withElement(t){return this.element===t?this:new zi(t,this.before,this.after)}insertChild(e){const n=this.before||this.getManagedLineBreak();return null!==n&&n.parentElement!==this.element&&t(222),this.element.insertBefore(e,n),this}removeChild(e){return e.parentElement!==this.element&&t(223),this.element.removeChild(e),this}replaceChild(e,n){return n.parentElement!==this.element&&t(224),this.element.replaceChild(e,n),this}getFirstChild(){const t=this.after?this.after.nextSibling:this.element.firstChild;return t===this.before||t===this.getManagedLineBreak()?null:t}getManagedLineBreak(){return this.element.__lexicalLineBreak||null}setManagedLineBreak(t){if(null===t)this.removeManagedLineBreak();else {const e="decorator"===t&&(d$1||l||a$1);this.insertManagedLineBreak(e);}}removeManagedLineBreak(){const t=this.getManagedLineBreak();if(t){const e=this.element,n="IMG"===t.nodeName?t.nextSibling:null;n&&e.removeChild(n),e.removeChild(t),e.__lexicalLineBreak=void 0;}}insertManagedLineBreak(t){const e=this.getManagedLineBreak();if(e){if(t===("IMG"===e.nodeName))return;this.removeManagedLineBreak();}const n=this.element,r=this.before,i=document.createElement("br");if(n.insertBefore(i,r),t){const t=document.createElement("img");t.setAttribute("data-lexical-linebreak","true"),t.style.setProperty("display","inline","important"),t.style.setProperty("border","0px","important"),t.style.setProperty("margin","0px","important"),t.alt="",n.insertBefore(t,i),n.__lexicalLineBreak=t;}else n.__lexicalLineBreak=i;}getFirstChildOffset(){let t=0;for(let e=this.after;null!==e;e=e.previousSibling)t++;return t}resolveChildIndex(t,e,n,r){if(n===this.element){const e=this.getFirstChildOffset();return [t,Math.min(e+t.getChildrenSize(),Math.max(e,r))]}const i=Ri(e,n);i.push(r);const o=Ri(e,this.element);let s=t.getIndexWithinParent();for(let t=0;t<o.length;t++){const e=i[t],n=o[t];if(void 0===e||e<n)break;if(e>n){s+=1;break}}return [t.getParentOrThrow(),s]}}function Ri(e,n){const r=[];let i=n;for(;i!==e&&null!==i;i=i.parentNode){let t=0;for(let e=i.previousSibling;null!==e;e=e.previousSibling)t++;r.push(t);}return i!==e&&t(225),r.reverse()}class Bi extends Rn$1{__first;__last;__size;__format;__style;__indent;__dir;__textFormat;__textStyle;constructor(t){super(t),this.__first=null,this.__last=null,this.__size=0,this.__format=0,this.__style="",this.__indent=0,this.__dir=null,this.__textFormat=0,this.__textStyle="";}afterCloneFrom(t){super.afterCloneFrom(t),this.__key===t.__key&&(this.__first=t.__first,this.__last=t.__last,this.__size=t.__size),this.__indent=t.__indent,this.__format=t.__format,this.__style=t.__style,this.__dir=t.__dir,this.__textFormat=t.__textFormat,this.__textStyle=t.__textStyle;}getFormat(){return this.getLatest().__format}getFormatType(){const t=this.getFormat();return W$5[t]||""}getStyle(){return this.getLatest().__style}getIndent(){return this.getLatest().__indent}getChildren(){const t=[];let e=this.getFirstChild();for(;null!==e;)t.push(e),e=e.getNextSibling();return t}getChildrenKeys(){const t=[];let e=this.getFirstChild();for(;null!==e;)t.push(e.__key),e=e.getNextSibling();return t}getChildrenSize(){return this.getLatest().__size}isEmpty(){return 0===this.getChildrenSize()}isDirty(){const t=vi()._dirtyElements;return null!==t&&t.has(this.__key)}isLastChild(){const t=this.getLatest(),e=this.getParentOrThrow().getLastChild();return null!==e&&e.is(t)}getAllTextNodes(){const t=[];let e=this.getFirstChild();for(;null!==e;){if(Tr(e)&&t.push(e),Wi(e)){const n=e.getAllTextNodes();t.push(...n);}e=e.getNextSibling();}return t}getFirstDescendant(){let t=this.getFirstChild();for(;Wi(t);){const e=t.getFirstChild();if(null===e)break;t=e;}return t}getLastDescendant(){let t=this.getLastChild();for(;Wi(t);){const e=t.getLastChild();if(null===e)break;t=e;}return t}getDescendantByIndex(t){const e=this.getChildren(),n=e.length;if(t>
vendor: 2,106 bytes, line 7324
7324=n){const t=e[n-1];return Wi(t)&&t.getLastDescendant()||t||null}const r=e[t];return Wi(r)&&r.getFirstDescendant()||r||null}getFirstChild(){const t=this.getLatest().__first;return null===t?null:Yo(t)}getFirstChildOrThrow(){const e=this.getFirstChild();return null===e&&t(45,this.__key),e}getLastChild(){const t=this.getLatest().__last;return null===t?null:Yo(t)}getLastChildOrThrow(){const e=this.getLastChild();return null===e&&t(96,this.__key),e}getChildAtIndex(t){const e=this.getChildrenSize();let n,r;if(t<e/2){for(n=this.getFirstChild(),r=0;null!==n&&r<=t;){if(r===t)return n;n=n.getNextSibling(),r++;}return null}for(n=this.getLastChild(),r=e-1;null!==n&&r>=t;){if(r===t)return n;n=n.getPreviousSibling(),r--;}return null}getTextContent(){let t="";const e=this.getChildren(),n=e.length;for(let r=0;r<n;r++){const i=e[r];t+=i.getTextContent(),Wi(i)&&r!==n-1&&!i.isInline()&&(t+=D$4);}return t}getTextContentSize(){let t=0;const e=this.getChildren(),n=e.length;for(let r=0;r<n;r++){const i=e[r];t+=i.getTextContentSize(),Wi(i)&&r!==n-1&&!i.isInline()&&(t+=2);}return t}getDirection(){return this.getLatest().__dir}getTextFormat(){return this.getLatest().__textFormat}hasFormat(t){if(""!==t){const e=B$5[t];return 0!==(this.getFormat()&e)}return  false}hasTextFormat(t){const e=z$7[t];return 0!==(this.getTextFormat()&e)}getFormatFlags(t,e){return Bo(this.getLatest().__textFormat,t,e)}getTextStyle(){return this.getLatest().__textStyle}select(t,e){xi();const n=Qr();let r=t,i=e;const o=this.getChildrenSize();if(!this.canBeEmpty())if(0===t&&0===e){const t=this.getFirstChild();if(Tr(t)||Wi(t))return t.select(0,0)}else if(!(void 0!==t&&t!==o||void 0!==e&&e!==o)){const t=this.getLastChild();if(Tr(t)||Wi(t))return t.select()} void 0===r&&(r=o),void 0===i&&(i=o);const s=this.__key;return Fr(n)?(n.anchor.set(s,r,"element"),n.focus.set(s,i,"element"),n.dirty=true,n):Yr(s,r,s,i,"element","element")}selectStart(){const t=this.getFirstDescendant();return t?t.selectStart():this.select()}selectEnd(){const t=this.getLastDescendant();return t?t.selectEnd():this.select()}clear(){const t=this.getWritable();
7324return this.getChildren().forEach(t=>t.remove()),t}append(...t){return this.splice(this.getChildrenSize(),0,t)}setDirection(t){const e=this.getWritable();return e.__dir=t,e}setFormat(t){return this.getWritable().__format=""!==t&&B$5[t]||0,this}setStyle(t){return this.getWritable().__style=t||"",this}setTextFormat(t){const e=this.getWritable();return e.__textFormat=t,e}setTextStyle(t){const e=this.getWritable();return e.__textStyle=t,e}setIndent(t){return this.getWritable().__indent=t,this}splice(e,n,r){zn(this)&&t(324,this.__key,this.__type);const i=this.getChildrenSize(),o=this.getWritable();e+n<=i||t(226,String(e),String(n),String(i));const s=o.__key,l=[],c=[],a=this.getChildAtIndex(e+n);let u=null,f=i-n+r.length;if(0!==e)if(e===i)u=this.getLastChild();else {const t=this.getChildAtIndex(e);null!==t&&(u=t.getPreviousSibling());}if(n>0){let e=null===u?this.getFirstChild():u.getNextSibling();for(let r=0;r<n;r++){null===e&&t(100);const n=e.getNextSibling(),r=e.__key;Jo(e.getWritable()),c.push(r),e=n;}}let d=u;for(const e of r){null!==d&&e.is(d)&&(u=d=d.getPreviousSibling());const n=e.getWritable();n.__parent===s&&f--,Jo(n);const r=e.__key;if(null===d)o.__first=r,n.__prev=null;else {const t=d.getWritable();t.__next=r,n.__prev=t.__key;}e.__key===s&&t(76),n.__parent=s,l.push(r),d=e;}if(e+n===i){if(null!==d){d.getWritable().__next=null,o.__last=d.__key;}}else if(null!==a){const t=a.getWritable();if(null!==d){const e=d.getWritable();t.__prev=d.__key,e.__next=a.__key;}else t.__prev=null;}if(o.__size=f,c.length){const t=Qr();if(Fr(t)){const e=new Set(c),n=new Set(l),{anchor:r,focus:i}=t;$i(r,e,n)&&ni(r,r.getNode(),this,u,a),$i(i,e,n)&&ni(i,i.getNode(),this,u,a),0!==f||this.canBeEmpty()||Is(this)||this.remove();}}return o}getDOMSlot(t){return new zi(t)}exportDOM(t){const{element:e}=super.exportDOM(t);if(Ys(e)){const t=this.getIndent();t>0&&(e.style.paddingInlineStart=40*t+"px");const n=this.getDirection();n&&(e.dir=n);}return {element:e}}exportJSON(){const t={children:[],direction:this.getDirection(),format:this.getFormatType(),indent:this.getIndent(),...super.exportJSON()},e=this.getTextFormat(),n=this.getTextStyle();return 0===e&&""===n||Is(this)||this.getChildren().some(Tr)||(0!==e&&(t.textFormat=e),""!==n&&(t.textStyle=n)),t}updateFromJSON(t){return super.updateFromJSON(t).setFormat(t.format).setIndent(t.indent).setDirection(t.direction).setTextFormat(t.textFormat||0).setTextStyle(t.textStyle||"")}insertNewAfter(t,e){return null}canIndent(){return  true}collapseAtStart(t){return  false}excludeFromCopy(t){return  false}canReplaceWith(t){return  true}canInsertAfter(t){return  true}canBeEmpty(){return  true}canInsertTextBefore(){return  true}canInsertTextAfter(){return  true}isInline(){return  false}isShadowRoot(){return  false}canMergeWith(t){return  false}extractWithChild(t,e,n){return  false}canMergeWhenEmpty(){return  false}reconcileObservedMutation(t,e){const n=tl(e).$getDOMSlot(this,t,e);let r=n.getFirstChild();for(let t=this.getFirstChild();t;t=t.getNextSibling()){const i=e.getElementByKey(t.getKey());null!==i&&(null==r?(n.insertChild(i),r=i):r!==i&&n.replaceChild(i,r),r=r.nextSibling);}}}function Wi(t){return t instanceof Bi}function $i(t,e,n){let r=t.getNode();for(;r;){const t=r.__key;if(e.has(t)&&!n.has(t))return  true;r=r.getParent();}return  false}class Ji extends Rn$1{decorate(t,e){return null}isIsolated(){return  false}isInline(){return  true}isKeyboardSelectable(){return  true}}function ji(t){return t instanceof Ji}class Ui extends Bi{__cachedText;static getType(){return "root"}static clone(){return new Ui}constructor(){super("root"),this.__cachedText=null;}getTopLevelElementOrThrow(){t(51);}getTextContent(){const t=this.__cachedText;return !mi()&&0!==vi()._dirtyType||null===t?super.getTextContent():t}remove(){t(52);}replace(e){t(53);}insertBefore(e){t(54);}insertAfter(e){t(55);}updateDOM(t,e){return  false}splice(e,n,r){for(const e of r)Wi(e)||ji(e)||t(282);return super.splice(e,n,r)}static importJSON(t){return Zo().updateFromJSON(t)}collapseAtStart(){return  true}}function Vi(t){return t instanceof Ui}function Yi(t){return new Xi(new Map(t._nodeMap))}function qi(){return new Xi(new Map([["root",new Ui]]))}function Hi(e){const n=e.exportJSON(),r=e.constructor;if(n.type!==r.getType()&&t(130,r.name),Wi(e)){const i=n.children;Array.isArray(i)||t(59,r.name);const o=e.getChildren();for(let t=0;t<o.length;t++){const e=Hi(o[t]);i.push(e);}}return n}function Gi(t){return t instanceof Xi}class Xi{_nodeMap;_selection;_flushSync;_readOnly;constructor(t,e){this._nodeMap=t,this._selection=e||null,this._flushSync=false,this._readOnly=false;}isEmpty(){return 1===this._nodeMap.size&&null===this._selection}read(t,e){return Mi(e&&e.editor||null,this,t)}clone(t){const e=new Xi(this._nodeMap,void 0===t?this._selection:t);return e._readOnly=true,e}toJSON(){return Mi(null,this,()=>({root:Hi(Zo())}))}}class Qi extends Bi{static getType(){return "artificial"}createDOM(t){return document.createElement("div")}}class Zi extends Bi{static getType(){return "paragraph"}static clone(t){return new Zi(t.__key)}createDOM(t){const e=document.createElement("p"),n=ms(t.theme,"paragraph");if(void 0!==n){e.classList.add(...n);}return e}updateDOM(t,e,n){return  false}static importDOM(){return {p:t=>({conversion:to,priority:0})}}exportDOM(t){const{element:e}=super.exportDOM(t);if(Ys(e)){this.isEmpty()&&e.append(document.createElement("br"));const t=this.getFormatType();t&&(e.style.textAlign=t);}return {element:e}}static importJSON(t){return eo().updateFromJSON(t)}exportJSON(){const t=super.exportJSON();if(void 0===t.textFormat||void 0===t.textStyle){const e=this.getChildren().find(Tr);e?(t.textFormat=e.getFormat(),t.textStyle=e.getStyle()):(t.textFormat=this.getTextFormat(),t.textStyle=this.getTextStyle());}return t}insertNewAfter(t,e){const n=eo();n.setTextFormat(t.format),n.setTextStyle(t.style);const r=this.getDirection();return n.setDirection(r),n.setFormat(this.getFormatType()),n.setStyle(this.getStyle()),this.insertAfter(n,e),n}collapseAtStart(){const t=this.getChildren();if(0===t.length||Tr(t[0])&&""===t[0].getTextContent().trim()){if(null!==this.getNextSibling())return this.selectNext(),this.remove(),true;if(null!==this.getPreviousSibling())return this.selectPrevious(),this.remove(),true}return  false}}function to(t){const e=eo();if(t.style&&(e.setFormat(t.style.textAlign),sl(t,e)),""===e.getFormatType()){const n=t.getAttribute("align");n&&n&&n in B$5&&e.setFormat(n);}return {node:e}}function eo(){return zs(new Zi)}function no(t){return t instanceof Zi}const ro=0,io=1,oo=2,so=3,lo=4,co=-8,ao=-7,uo=-6,fo=-5,ho=-4;function go(t,e,n,r){const i=t._keyToDOMMap;i.clear(),t._editorState=qi(),t._pendingEditorState=r,t._compositionKey=null,t._dirtyType=0,t._cloneNotNeeded.clear(),t._dirtyLeaves=new Set,t._dirtyElements.clear(),t._normalizedNodes=new Set,t._updateTags=new Set,t._updates=[],t._blockCursorElement=null;const o=t._observer;null!==o&&(o.disconnect(),t._observer=null),null!==e&&(e.textContent=""),null!==n&&(n.textContent="",i.set("root",n));}function _o(t){const e=new Set,n=new Set;let r=t;for(;r;){const{ownNodeConfig:t}=ul(r),i=r.transform;if(!n.has(i)){n.add(i);const t=r.transform();t&&e.add(t);}if(t){const n=t.$transform;n&&e.add(n),r=t.extends;}else {const t=Object.getPrototypeOf(r);r=t.prototype instanceof Rn$1&&t!==Rn$1?t:void 0;}}return e}const po={$createDOM:(t,e)=>t.createDOM(e._config,e),$decorateDOM:(t,e,n,r)=>{},$exportDOM:(t,e)=>{const n=bo(e,t.getType());return n&&void 0!==n.exportDOM?n.exportDOM(e,t):t.exportDOM(e)},$extractWithChild:(t,e,n,r,i)=>Wi(t)&&t.extractWithChild(e,n,r),$getDOMSlot:(e,n,r)=>(Wi(e)||t(336,e.getKey(),e.getType()),e.getDOMSlot(n)),$shouldExclude:(t,e,n)=>Wi(t)&&t.excludeFromCopy("html"),$shouldInclude:(t,e,n)=>!e||t.isSelected(e),$updateDOM:(t,e,n,r)=>t.updateDOM(e,n,r._config)};function yo(t){const e=t||{},n=Ti(),r=e.theme||{},i=void 0===t?n:e.parentEditor||null,o=e.disableEvents||false,s=qi(),l=e.namespace||(null!==i?i._config.namespace:os()),c=e.editorState,a=[Ui,gr,rr,br,Zi,Qi,...e.nodes||[]],{onError:u,html:f}=e,d=void 0===e.editable||e.editable;let h;if(void 0===t&&null!==n)h=n._nodes;else {h=new Map;for(let t=0;t<a.length;t++){let e=a[t],n=null,r=null;if("function"!=typeof e){const t=e;e=t.replace,n=t.with,r=t.withKlass||null;}ul(e);const i=e.getType(),o=_o(e);h.set(i,{exportDOM:f&&f.export?f.export.get(e):void 0,klass:e,replace:n,replaceWithKlass:r,sharedNodeState:at$3(a[t]),transforms:o});}}const g=new Co(s,i,h,{disableEvents:o,dom:{...po,...t&&t.dom},namespace:l,theme:r},u||console.error,function(t,e){const n=new Map,r=new Set,i=t=>
7324{Object.keys(t).forEach(e=>{let r=n.get(e);void 0===r&&(r=[],n.set(e,r)),r.push(t[e]);});};return t.forEach(t=>{const e=t.klass.importDOM;if(null==e||r.has(e))return;r.add(e);const n=e.call(t.klass);null!==n&&i(n);}),e&&i(e),n}(h,f?f.import:void 0),d,t);return void 0!==c&&(g._pendingEditorState=c,g._dirtyType=2),function(t){t.registerCommand(le$3,vn$1,ro),t.registerCommand(ce$4,kn$1,ro),t.registerCommand(ae$4,Tn$1,ro),t.registerCommand(ue$4,Nn$1,ro),t.registerCommand(ve$2,wn$1,ro);}(g),g}function mo(t,e){const n=t.get(e);t.delete(e),n&&n();}function xo(t,e,n){return t.set(e,n),mo.bind(null,t,e)}class Co{static version;_headless;_parentEditor;_rootElement;_editorState;_pendingEditorState;_compositionKey;_deferred;_keyToDOMMap;_updates;_updating;_listeners;_commands;_nodes;_decorators;_pendingDecorators;_config;_dirtyType;_cloneNotNeeded;_dirtyLeaves;_dirtyElements;_normalizedNodes;_updateTags;_observer;_key;_onError;_htmlConversions;_window;_editable;_blockCursorElement;_createEditorArgs;constructor(t,e,n,r,i,o,s,l){this._createEditorArgs=l,this._parentEditor=e,this._rootElement=null,this._editorState=t,this._pendingEditorState=null,this._compositionKey=null,this._deferred=[],this._keyToDOMMap=new Map,this._updates=[],this._updating=false,this._listeners={decorator:new Map,editable:new Map,mutation:new Map,root:new Map,textcontent:new Map,update:new Map},this._commands=new Map,this._config=r,this._nodes=n,this._decorators={},this._pendingDecorators=null,this._dirtyType=0,this._cloneNotNeeded=new Set,this._dirtyLeaves=new Set,this._dirtyElements=new Map,this._normalizedNodes=new Set,this._updateTags=new Set,this._observer=null,this._key=os(),this._onError=i,this._htmlConversions=o,this._editable=s,this._headless=null!==e&&e._headless,this._window=null,this._blockCursorElement=null;}isComposing(){return null!=this._compositionKey}registerUpdateListener(t){return xo(this._listeners.update,t)}registerEditableListener(t){return xo(this._listeners.editable,t)}registerDecoratorListener(t){return xo(this._listeners.decorator,t)}registerTextContentListener(t){return xo(this._listeners.textcontent,t)}registerRootListener(t){const e=this._listeners.root;return Cc(xo(e,t,t(this._rootElement,null)||void 0),()=>function(t,e,n){const r=t.get(e);r&&r(),t.set(e,e(...n)||void 0);}(e,t,[null,this._rootElement]))}registerCommand(e,n,r){ void 0===r&&t(35);const i=this._commands;i.has(e)||i.set(e,[new V$7,new V$7,new V$7,new V$7,new V$7]);const o=i.get(e);void 0===o&&t(36,String(e));const s=function(t){return 7&t}(r),l=o[s];return s!==r?l.addFront(n):l.addBack(n),()=>{l.delete(n),o.every(t=>0===t.size)&&i.delete(e);}}registerMutationListener(t,e,n){const r=this.resolveRegisteredNodeAfterReplacements(this.getRegisteredNode(t)).klass,i=this._listeners.mutation;let o=i.get(e);void 0===o&&(o=new Set,i.set(e,o)),o.add(r);const s=n&&n.skipInitialization;return void 0!==s&&s||this.initializeMutationListener(e,r),()=>{o.delete(r),0===o.size&&i.delete(e);}}getRegisteredNode(e){const n=this._nodes.get(e.getType());return void 0===n&&t(37,e.name),n}resolveRegisteredNodeAfterReplacements(t){for(;t.replaceWithKlass;)t=this.getRegisteredNode(t.replaceWithKlass);return t}initializeMutationListener(t,e){const n=this._editorState,r=rl(n).get(e.getType());if(!r)return;const i=new Map;for(const t of r.keys())i.set(t,"created");i.size>0&&t(i,{dirtyLeaves:new Set,prevEditorState:n,updateTags:new Set(["registerMutationListener"])});}registerNodeTransformToKlass(t,e){const n=this.getRegisteredNode(t);return n.transforms.add(e),n}registerNodeTransform(t,e){const n=this.registerNodeTransformToKlass(t,e),r=[n],i=n.replaceWithKlass;if(null!=i){const t=this.registerNodeTransformToKlass(i,e);r.push(t);}return function(t,e){const n=rl(t.getEditorState()),r=[];for(const t of e){const e=n.get(t);e&&r.push(e);}if(0===r.length)return;t.update(()=>{for(const t of r)for(const e of t.keys()){const t=Yo(e);t&&t.markDirty();}},null===t._pendingEditorState?{tag:Jn}:void 0);}(this,r.map(t=>t.klass.getType())),()=>{r.forEach(t=>t.transforms.delete(e));}}hasNode(t){return this._nodes.has(t.getType())}hasNodes(t){return t.every(this.hasNode.bind(this))}dispatchCommand(t,e){return Ts(this,t,e)}getDecorators(){return this._decorators}getRootElement(){return this._rootElement}getKey(){return this._key}setRootElement(t){const e=this._rootElement;
7324if(t!==e){const n=ms(this._config.theme,"root"),r=this._pendingEditorState||this._editorState;if(this._rootElement=t,go(this,e,t,r),null!==e&&(this._config.disableEvents||Fn$1(e),null!=n&&e.classList.remove(...n)),null!==t){const e=Ds(t),r=t.style;r.userSelect="text",r.whiteSpace="pre-wrap",r.wordBreak="break-word",t.setAttribute("data-lexical-editor","true"),this._window=e,this._dirtyType=2,rt$4(this),this._updateTags.add(Jn),Ai(this),this._config.disableEvents||function(t,e){const n=t.ownerDocument;sn$1.set(t,n);const r=ln$1.get(n)??0;r<1&&n.addEventListener("selectionchange",Mn),ln$1.set(n,r+1),t.__lexicalEditor=e;const i=En$1(t);for(let n=0;n<tn$1.length;n++){const[r,o]=tn$1[n],s="function"==typeof o?t=>{Dn(t)||(An$1(t),(e.isEditable()||"click"===r)&&o(t,e));}:t=>{if(Dn(t))return;An$1(t);const n=e.isEditable();switch(r){case "cut":return n&&Ts(e,je$2,t);case "copy":return Ts(e,Je$2,t);case "paste":return n&&Ts(e,_e$2,t);case "dragstart":return n&&Ts(e,Be$2,t);case "dragover":return n&&Ts(e,We$2,t);case "dragend":return n&&Ts(e,$e$2,t);case "focus":return n&&Ts(e,Ge$2,t);case "blur":return n&&Ts(e,Xe$2,t);case "drop":return n&&Ts(e,ze$2,t)}};t.addEventListener(r,s),i.push(()=>{t.removeEventListener(r,s);});}}(t,this),null!=n&&t.classList.add(...n);}else this._window=null,this._updateTags.add(Jn),Ai(this);Di("root",this,false,t,e);}}getElementByKey(t){return this._keyToDOMMap.get(t)||null}getEditorState(){return this._editorState}setEditorState(e,n){e.isEmpty()&&t(38);let r=e;r._readOnly&&(r=Yi(e),r._selection=e._selection?e._selection.clone():null),nt$4(this);const i=this._pendingEditorState,o=this._updateTags,s=void 0!==n?n.tag:null;null===i||i.isEmpty()||(null!=s&&o.add(s),Ai(this)),this._pendingEditorState=r,this._dirtyType=2,this._dirtyElements.set("root",false),this._compositionKey=null,null!=s&&o.add(s),this._updating||Ai(this);}parseEditorState(t,e){return function(t,e,n){const r=qi(),i=di,o=gi,s=hi,l=e._dirtyElements,c=e._dirtyLeaves,a=e._cloneNotNeeded,u=e._dirtyType;e._dirtyElements=new Map,e._dirtyLeaves=new Set,e._cloneNotNeeded=new Set,e._dirtyType=0,di=r,gi=false,hi=e,vo(null);try{const i=e._nodes;Oi(t.root,i),n&&n(),r._readOnly=!0;}catch(t){t instanceof Error&&e._onError(t);}finally{e._dirtyElements=l,e._dirtyLeaves=c,e._cloneNotNeeded=a,e._dirtyType=u,di=i,gi=o,hi=s;}return r}("string"==typeof t?JSON.parse(t):t,this,e)}read(t){return Ai(this),this.getEditorState().read(t,{editor:this})}update(t,e){!function(t,e,n){t._updating?t._updates.push([e,n]):Ii(t,e,n);}(this,t,e);}focus(t,e={}){const n=this._rootElement;null!==n&&(n.setAttribute("autocapitalize","off"),Ki(this,()=>{const r=Qr(),i=Zo();null!==r?r.dirty||es(r.clone()):0!==i.getChildrenSize()&&("rootStart"===e.defaultSelection?i.selectStart():i.selectEnd()),Os("focus"),Ms(()=>{n.removeAttribute("autocapitalize"),t&&t();});}),null===this._pendingEditorState&&n.removeAttribute("autocapitalize"));}blur(){const t=this._rootElement;null!==t&&t.blur();const e=Js(this._window);null!==e&&e.removeAllRanges();}isEditable(){return this._editable}setEditable(t){this._editable!==t&&(this._editable=t,Di("editable",this,true,t));}toJSON(){return {editorState:this._editorState.toJSON()}}}Co.version="0.44.0+prod.esm";let So=null;function vo(t){So=t;}let ko=1;function To(){ko=1;}function No(e,n){const r=bo(e,n);return void 0===r&&t(30,n),r}function bo(t,e){return t._nodes.get(e)}const wo="function"==typeof queueMicrotask?queueMicrotask:t=>{Promise.resolve().then(t);};function Eo(t){return ji(Go(t))}function Oo(t){const e=document.activeElement;if(!Ys(e))return  false;const n=e.nodeName;return ji(Go(t))&&("INPUT"===n||"TEXTAREA"===n||"true"===e.contentEditable&&null==Po(e))}function Mo(t,e,n){const r=t.getRootElement();try{return null!==r&&r.contains(e)&&r.contains(n)&&null!==e&&!Oo(e)&&Do(e)===t}catch(t){return  false}}function Ao(t){return t instanceof Co}function Do(t){let e=t;for(;null!=e;){const t=Po(e);if(Ao(t))return t;e=bs(e);}return null}function Po(t){return t?t.__lexicalEditor:null}function Fo(t){return I$6.test(t)?"rtl":K$4.test(t)?"ltr":null}function Lo(t){return Er(t)||t.isToken()}function Io(t){return Lo(t)||t.isSegmented()}function Ko(t){return qs(t)&&3===t.nodeType}function zo(t){return qs(t)&&9===t.nodeType}function Ro(t){let e=t;for(;null!=e;){if(Ko(e))return e;e=e.firstChild;}return null}function Bo(t,e,n){const r=z$7[e];if(null!==n&&(t&r)===(n&r))return t;let i=t^r;return "subscript"===e?i&=~z$7.superscript:"superscript"===e?i&=~z$7.subscript:"lowercase"===e?(i&=~z$7.uppercase,i&=~z$7.capitalize):"uppercase"===e?(i&=~z$7.lowercase,i&=~z$7.capitalize):"capitalize"===e&&(i&=~z$7.lowercase,i&=~z$7.uppercase),i}function Wo(t){return Tr(t)||sr(t)||ji(t)}function $o(t,e){const n=function(){const t=So;return So=null,t}();if(null!=(e=e||n&&n.__key))return void(t.__key=e);xi(),Ci();const r=vi(),i=Si(),o=""+ko++;i._nodeMap.set(o,t),Wi(t)?r._dirtyElements.set(o,true):r._dirtyLeaves.add(o),r._cloneNotNeeded.add(o),r._dirtyType=1,t.__key=o;}function Jo(t){const e=t.getParent();if(null!==e){const n=t.getWritable(),r=e.getWritable(),i=t.getPreviousSibling(),o=t.getNextSibling(),s=null!==o?o.__key:null,l=null!==i?i.__key:null,c=null!==i?i.getWritable():null,a=null!==o?o.getWritable():null;null===i&&(r.__first=s),null===o&&(r.__last=l),null!==c&&(c.__next=s),null!==a&&(a.__prev=l),n.__prev=null,n.__next=null,n.__parent=null,r.__size--;}}function jo(e){Ci(),zn(e)&&t(323,e.__key,e.__type);const n=e.getLatest(),r=n.__parent,i=Si(),o=vi(),s=i._nodeMap,l=o._dirtyElements;null!==r&&function(t,e,n){let r=t;for(;null!==r;){if(n.has(r))return;const t=e.get(r);if(void 0===t)break;n.set(r,false),r=t.__parent;}}(r,s,l);const c=n.__key;o._dirtyType=1,Wi(e)?l.set(c,true):o._dirtyLeaves.add(c);}function Uo(t){xi();const e=vi(),n=e._compositionKey;if(t!==n){if(e._compositionKey=t,null!==n){const t=Yo(n);null!==t&&t.getWritable();}if(null!==t){const e=Yo(t);null!==e&&e.getWritable();}}}function Vo(){if(mi())return null;return vi()._compositionKey}function Yo(t,e){const n=(e||Si())._nodeMap.get(t);return void 0===n?null:n}function qo(t,e){const n=Ho(t,vi());return void 0!==n?Yo(n,e):null}function Ho(t,e){return t[`__lexicalKey_${e._key}`]}function Go(t,e){let n=t;for(;null!=n;){const t=qo(n,e);if(null!==t)return t;n=bs(n);}return null}function Xo(t){const e=t._decorators,n=Object.assign({},e);return t._pendingDecorators=n,n}function Qo(t){return t.read(()=>Zo().getTextContent())}function Zo(){return ts(Si())}function ts(t){return t._nodeMap.get("root")}function es(t){xi();const e=Si();null!==t&&(t.dirty=true,t.setCachedNodes(null)),e._selection=t;}function ns(t){const e=vi(),n=function(t,e){let n=t;for(;null!=n;){const t=Ho(n,e);if(void 0!==t)return t;n=bs(n);}return null}(t,e);if(null===n){return t===e.getRootElement()?Yo("root"):null}return Yo(n)}function rs(t){return /[\uD800-\uDBFF][\uDC00-\uDFFF]/g.test(t)}function is(t){const e=[];for(let n=t;null!==n;n=n._parentEditor)e.push(n);return e}function os(){return Math.random().toString(36).replace(/[^a-z]+/g,"").substring(0,5)}function ss(t){return Ko(t)?t.nodeValue:null}function ls(t,e,n){const r=Js(Ps(e));if(null===r)return;const i=r.anchorNode;let{anchorOffset:o,focusOffset:s}=r;if(null!==i){let e=ss(i);const r=Go(i);if(null!==e&&Tr(r)){if((e===A$3||e===P$3)&&n){const t=n.length;e=n,o=t,s=t;}null!==e&&cs(r,e,o,s,t);}}}function cs(t,e,n,r,i){let o=t;if(o.isAttached()&&(i||!o.isDirty())){const s=o.isComposing();let c=e;if((s||i)&&(e.endsWith(A$3)&&(c=e.slice(0,-A$3.length)),i)){const t=P$3;let e;for(;-1!==(e=c.indexOf(t));)c=c.slice(0,e)+c.slice(e+t.length),null!==n&&n>e&&(n=Math.max(e,n-t.length)),null!==r&&r>e&&(r=Math.max(e,r-t.length));}const u=o.getTextContent();if(i||c!==u){if(""===c){if(Uo(null),a$1||l||d$1)o.remove();else {const t=vi();setTimeout(()=>{t.update(()=>{o.isAttached()&&o.remove();});},20);}return}const e=o.getParent(),i=Zr(),u=o.getTextContentSize(),f=Vo(),h=o.getKey();if(o.isToken()||null!==f&&h===f&&!s||Fr(i)&&(null!==e&&!e.canInsertTextBefore()&&0===i.anchor.offset||i.anchor.key===t.__key&&0===i.anchor.offset&&!o.canInsertTextBefore()&&!s||i.focus.key===t.__key&&i.focus.offset===u&&!o.canInsertTextAfter()&&!s))return void o.markDirty();const g=Qr();if(!Fr(g)||null===n||null===r)return void as(o,c,g);if(g.setTextNodeRange(o,n,o,r),o.isSegmented()){const t=kr(o.getTextContent());o.replace(t),o=t;}as(o,c,g);}}}function as(t,e,n){if(t.setTextContent(e),Fr(n)){const e=t.getKey();for(const r of ["anchor","focus"]){const i=n[r];"text"===i.type&&i.key===e&&(i.offset=Al(t,i.offset,"clamp"));}}}function us(t,e,n){const r=e[n]||false;return "any"===r||r===t[n]}function fs(t,e){return us(t,e,"altKey")&&us(t,e,"ctrlKey")&&us(t,e,"shiftKey")&&us(t,e,"metaKey")}function ds(t,e,n){if(!fs(t,n))return  false;if(t.key.toLowerCase()===e.toLowerCase())return  true;if(e.length>1)return  false;
7324if(1===t.key.length&&t.key.charCodeAt(0)<=127)return  false;if(t.code.startsWith("Digit")&&/^\d$/.test(e))return t.code===`Digit${e}`;const r="Key"+e.toUpperCase();return t.code===r}const hs={ctrlKey:!i,metaKey:i},gs={altKey:i,ctrlKey:!i};function _s(t){return "Backspace"===t.key}function ps(t){return ds(t,"a",hs)}function ys(t){const e=Zo();if(Fr(t)){const e=t.anchor,n=t.focus,r=e.getNode().getTopLevelElementOrThrow().getParentOrThrow();return e.set(r.getKey(),0,"element"),n.set(r.getKey(),r.getChildrenSize(),"element"),St$3(t),t}{const t=e.select(0,e.getChildrenSize());return es(St$3(t)),t}}function ms(t,e){ void 0===t.__lexicalClassNameCache&&(t.__lexicalClassNameCache={});const n=t.__lexicalClassNameCache,r=n[e];if(void 0!==r)return r;const i=t[e];if("string"==typeof i){const t=yc(i);return n[e]=t,t}return i}function xs(e,n,r,i,o){if(0===r.size)return;const s=i.__type,l=i.__key,c=n.get(s);void 0===c&&t(33,s);const a=c.klass;let u=e.get(a);void 0===u&&(u=new Map,e.set(a,u));const f=u.get(l),d="destroyed"===f&&"created"===o;(void 0===f||d)&&u.set(l,d?"updated":o);}function Cs(t){const e=t.getType(),n=Si();if(n._readOnly){const t=rl(n).get(e);return t?Array.from(t.values()):[]}const r=n._nodeMap,i=[];for(const[,n]of r)n instanceof t&&n.__type===e&&n.isAttached()&&i.push(n);return i}function Ss(t,e,n){const r=t.getParent();let i=n,o=t;return null!==r&&(e&&0===n?(i=o.getIndexWithinParent(),o=r):e||n!==o.getChildrenSize()||(i=o.getIndexWithinParent()+1,o=r)),o.getChildAtIndex(e?i-1:i)}function vs(t,e){const n=t.offset;if("element"===t.type){return Ss(t.getNode(),e,n)}{const r=t.getNode();if(e&&0===n||!e&&n===r.getTextContentSize()){const t=e?r.getPreviousSibling():r.getNextSibling();return null===t?Ss(r.getParentOrThrow(),e,r.getIndexWithinParent()+(e?0:1)):t}}return null}function ks(t){const e=Ps(t).event,n=e&&e.inputType;return "insertFromPaste"===n||"insertFromPasteAsQuotation"===n}function Ts(t,e,n){return Pi(t,e,n,t)}function Ns(e,n){const r=e._keyToDOMMap.get(n);return void 0===r&&t(75,n),r}function bs(t){const e=t.assignedSlot||t.parentElement;return Hs(e)?e.host:e}function ws(t){return zo(t)?t:Ys(t)?t.ownerDocument:null}function Es(t){return vi()._updateTags.has(t)}function Os(t){xi();vi()._updateTags.add(t);}function Ms(t){xi();vi()._deferred.push(t);}function As(t,e){let n=t.getParent();for(;null!==n;){if(n.is(e))return  true;n=n.getParent();}return  false}function Ds(t){const e=ws(t);return e?e.defaultView:null}function Ps(e){const n=e._window;return null===n&&t(78),n}function Fs(t){return Wi(t)&&t.isInline()||ji(t)&&t.isInline()}function Ls(t){let e=t.getParentOrThrow();for(;null!==e;){if(Is(e))return e;e=e.getParentOrThrow();}return e}function Is(t){return Vi(t)||Wi(t)&&t.isShadowRoot()}function Ks(t,e=false){const n=t.constructor.clone(t);return $o(n,null),n.afterCloneFrom(t),e||n.resetOnCopyNodeFrom(t),n}function zs(e){const n=vi(),r=e.getType(),i=bo(n,r);void 0===i&&t(200,e.constructor.name,r);const{replace:o,replaceWithKlass:s}=i;if(null!==o){const n=o(e),i=n.constructor;return null!==s?n instanceof s||t(201,s.name,s.getType(),i.name,i.getType(),e.constructor.name,r):n instanceof e.constructor&&i!==e.constructor||t(202,i.name,i.getType(),e.constructor.name,r),n.__key===e.__key&&t(203,e.constructor.name,r,i.name,i.getType()),n}return e}function Rs(e,n){!Vi(e.getParent())||Wi(n)||ji(n)||t(99);}function Bs(e){const n=Yo(e);return null===n&&t(63,e),n}function Ws(t){return (ji(t)||Wi(t)&&!t.canBeEmpty())&&!t.isInline()}function $s(t,e,n){n.style.removeProperty("caret-color"),e._blockCursorElement=null;const r=t.parentElement;null!==r&&r.removeChild(t);}function Js(t){return n?(t||window).getSelection():null}function js(t){const e=Ds(t);return e?e.getSelection():null}function Us(e,n){let r=e.getChildAtIndex(n);null==r&&(r=e),Is(e)&&t(102);const i=e=>{const n=e.getParentOrThrow(),o=Is(n),s=e!==r||o?Ks(e):e;if(o)return Wi(e)&&Wi(s)||t(133),e.insertAfter(s),[e,s,s];{const[t,r,o]=i(n),l=e.getNextSiblings();return o.append(s,...l),[t,r,s]}},[o,s]=i(r);return [o,s]}function Vs(t){return Ys(t)&&"A"===t.tagName}function Ys(t){return qs(t)&&1===t.nodeType}function qs(t){return "object"==typeof t&&null!==t&&"nodeType"in t&&"number"==typeof t.nodeType}function Hs(t){return qs(t)&&11===t.nodeType}function Gs(t){const e=new RegExp(/^(a|abbr|acronym|b|cite|code|del|em|i|ins|kbd|label|mark|output|q|ruby|s|samp|span|strong|sub|sup|time|u|tt|var|#text)$/,"i");return null!==t.nodeName.match(e)}function Xs(t){const e=new RegExp(/^(address|article|aside|blockquote|canvas|dd|div|dl|dt|fieldset|figcaption|figure|footer|form|h1|h2|h3|h4|h5|h6|header|hr|li|main|nav|noscript|ol|p|pre|section|table|td|tfoot|ul|video)$/,"i");return null!==t.nodeName.match(e)}function Qs(t){if(ji(t)&&!t.isInline())return  true;if(!Wi(t)||Is(t))return  false;
7324const e=t.getFirstChild(),n=null===e||sr(e)||Tr(e)||e.isInline();return !t.isInline()&&false!==t.canBeEmpty()&&n}function Zs(){return vi()}function tl(t=Zs()){return t._config.dom||po}const el=new WeakMap,nl=new Map;function rl(e){if(!e._readOnly&&e.isEmpty())return nl;e._readOnly||t(192);let n=el.get(e);return n||(n=function(t){const e=new Map;for(const[n,r]of t._nodeMap){const t=r.__type;let i=e.get(t);i||(i=new Map,e.set(t,i)),i.set(n,r);}return e}(e),el.set(e,n)),n}function il(t){const e=t.constructor.clone(t);return e.afterCloneFrom(t),e}function ol(t){return (e=il(t))[Kn$1]=true,e;var e;}function sl(t,e){const n=parseInt(t.style.paddingInlineStart,10)||0,r=Math.round(n/40);e.setIndent(r);}function ll(t){t.__lexicalUnmanaged=true;}function cl(t){return  true===t.__lexicalUnmanaged}function al(t,e){return function(t,e){return Object.prototype.hasOwnProperty.call(t,e)}(t,e)&&t[e]!==Rn$1[e]}function ul(e){const n=U$6 in e.prototype?e.prototype[U$6]():void 0,r=function(e){if(!(e===Rn$1||e.prototype instanceof Rn$1)){let n="<unknown>",r="<unknown>";try{n=e.getType();}catch(t){}try{Co.version&&(r=JSON.parse(Co.version));}catch(t){}t(290,e.name,n,r);}return e===Ji||e===Bi||e===Rn$1}(e),i=!r&&al(e,"getType")?e.getType():void 0;let o,s=i;if(n)if(i)o=n[i];else for(const[t,e]of Object.entries(n))s=t,o=e;if(!r&&s&&(al(e,"getType")||(e.getType=()=>s),al(e,"clone")||(e.clone=t=>(vo(t),new e)),al(e,"importJSON")||(e.importJSON=o&&o.$importJSON||(t=>(new e).updateFromJSON(t))),!al(e,"importDOM")&&o)){const{importDOM:t}=o;t&&(e.importDOM=()=>t);}return {ownNodeConfig:o,ownNodeType:s}}function fl(t){const e=Zs();xi();return new(e.resolveRegisteredNodeAfterReplacements(e.getRegisteredNode(t)).klass)}const dl=(t,e)=>{let n=t;for(;null!=n&&!Vi(n);){if(e(n))return n;n=n.getParent();}return null};function hl(e,n){const r=[];let i=e.__first;for(;null!==i;){const e=null===n?Yo(i):n.get(i);null==e&&t(174),r.push(i),i=e.__next;}return r}const gl={next:"previous",previous:"next"};class _l{origin;constructor(t){this.origin=t;}
vendor: 14,286 bytes, lines 7324-7396
7324[Symbol.iterator](){return $l({hasNext:Tl,initial:this.getAdjacentCaret(),map:t=>t,step:t=>t.getAdjacentCaret()})}getAdjacentCaret(){return Ol(this.getNodeAtCaret(),this.direction)}getSiblingCaret(){return Ol(this.origin,this.direction)}remove(){const t=this.getNodeAtCaret();return t&&t.remove(),this}replaceOrInsert(t,e){const n=this.getNodeAtCaret();return t.is(this.origin)||t.is(n)||(null===n?this.insert(t):n.replace(t,e)),this}splice(e,n,r="next"){const i=r===this.direction?n:Array.from(n).reverse();let o=this;const s=this.getParentAtCaret(),l=new Map;for(let t=o.getAdjacentCaret();null!==t&&l.size<e;t=t.getAdjacentCaret()){const e=t.origin.getWritable();l.set(e.getKey(),e);}for(const e of i){if(l.size>0){const n=o.getNodeAtCaret();if(n)if(l.delete(n.getKey()),l.delete(e.getKey()),n.is(e)||o.origin.is(e));else {const t=e.getParent();t&&t.is(s)&&e.remove(),n.replace(e);}else null===n&&t(263,Array.from(l).join(" "));}else o.insert(e);o=Ol(e,this.direction);}for(const t of l.values())t.remove();return this}}class pl extends _l{type="child";getLatest(){const t=this.origin.getLatest();return t===this.origin?this:Pl(t,this.direction)}getParentCaret(t="root"){return Ol(xl(this.getParentAtCaret(),t),this.direction)}getFlipped(){const t=ml(this.direction);return Ol(this.getNodeAtCaret(),t)||Pl(this.origin,t)}getParentAtCaret(){return this.origin}getChildCaret(){return this}isSameNodeCaret(t){return t instanceof pl&&this.direction===t.direction&&this.origin.is(t.origin)}isSamePointCaret(t){return this.isSameNodeCaret(t)}}const yl={root:Vi,shadowRoot:Is};function ml(t){return gl[t]}function xl(t,e="root"){return yl[e](t)?null:t}class Cl extends _l{type="sibling";getLatest(){const t=this.origin.getLatest();return t===this.origin?this:Ol(t,this.direction)}getSiblingCaret(){return this}getParentAtCaret(){return this.origin.getParent()}getChildCaret(){return Wi(this.origin)?Pl(this.origin,this.direction):null}getParentCaret(t="root"){return Ol(xl(this.getParentAtCaret(),t),this.direction)}getFlipped(){const t=ml(this.direction);return Ol(this.getNodeAtCaret(),t)||Pl(this.origin.getParentOrThrow(),t)}isSamePointCaret(t){return t instanceof Cl&&this.direction===t.direction&&this.origin.is(t.origin)}isSameNodeCaret(t){return (t instanceof Cl||t instanceof Sl)&&this.direction===t.direction&&this.origin.is(t.origin)}}class Sl extends _l{type="text";offset;constructor(t,e){super(t),this.offset=e;}getLatest(){const t=this.origin.getLatest();return t===this.origin?this:Ml(t,this.direction,this.offset)}getParentAtCaret(){return this.origin.getParent()}getChildCaret(){return null}getParentCaret(t="root"){return Ol(xl(this.getParentAtCaret(),t),this.direction)}getFlipped(){return Ml(this.origin,ml(this.direction),this.offset)}isSamePointCaret(t){return t instanceof Sl&&this.direction===t.direction&&this.origin.is(t.origin)&&this.offset===t.offset}isSameNodeCaret(t){return (t instanceof Cl||t instanceof Sl)&&this.direction===t.direction&&this.origin.is(t.origin)}getSiblingCaret(){return Ol(this.origin,this.direction)}}function vl(t){return t instanceof Sl}function kl(t){return t instanceof _l}function Tl(t){return t instanceof Cl}function Nl(t){return t instanceof pl}const bl={next:class extends Sl{direction="next";getNodeAtCaret(){return this.origin.getNextSibling()}insert(t){return this.origin.insertAfter(t),this}},previous:class extends Sl{direction="previous";getNodeAtCaret(){return this.origin.getPreviousSibling()}insert(t){return this.origin.insertBefore(t),this}}},wl={next:class extends Cl{direction="next";getNodeAtCaret(){return this.origin.getNextSibling()}insert(t){return this.origin.insertAfter(t),this}},previous:class extends Cl{direction="previous";getNodeAtCaret(){return this.origin.getPreviousSibling()}insert(t){return this.origin.insertBefore(t),this}}},El={next:class extends pl{direction="next";getNodeAtCaret(){return this.origin.getFirstChild()}insert(t){return this.origin.splice(0,0,[t]),this}},previous:class extends pl{direction="previous";getNodeAtCaret(){return this.origin.getLastChild()}insert(t){return this.origin.splice(this.origin.getChildrenSize(),0,[t]),this}}};function Ol(t,e){return t?new wl[e](t):null}function Ml(t,e,n){return t?new bl[e](t,Al(t,n)):null}function Al(t,n,r="error"){const i=t.getTextContentSize();let o="next"===n?i:"previous"===n?0:n;return (o<0||o>i)&&("clamp"!==r&&e(284,String(n),String(i),t.getKey()),o=o<0?0:i),o}function Dl(t,e){return new Kl(t,e)}function Pl(t,e){return Wi(t)?new El[e](t):null}function Fl(t){return t&&t.getChildCaret()||t}function Ll(t){return t&&Fl(t.getAdjacentCaret())}class Il{type="node-caret-range";direction;anchor;focus;constructor(t,e,n){this.anchor=t,this.focus=e,this.direction=n;}getLatest(){const t=this.anchor.getLatest(),e=this.focus.getLatest();return t===this.anchor&&e===this.focus?this:new Il(t,e,this.direction)}isCollapsed(){return this.anchor.isSamePointCaret(this.focus)}getTextSlices(){const t=t=>{const e=this[t].getLatest();return vl(e)?function(t,e){const{direction:n,origin:r}=t,i=Al(r,"focus"===e?ml(n):n);return Dl(t,i-t.offset)}(e,t):null},e=t("anchor"),n=t("focus");if(e&&n){const{caret:t}=e,{caret:r}=n;if(t.isSameNodeCaret(r))return [Dl(t,r.offset-t.offset),null]}return [e,n]}iterNodeCarets(t="root"){const e=vl(this.anchor)?this.anchor.getSiblingCaret():this.anchor.getLatest(),n=this.focus.getLatest(),r=vl(n),i=e=>e.isSameNodeCaret(n)?null:Ll(e)||e.getParentCaret(t);return $l({hasNext:t=>null!==t&&!(r&&n.isSameNodeCaret(t)),initial:e.isSameNodeCaret(n)?null:i(e),map:t=>t,step:i})}[Symbol.iterator](){return this.iterNodeCarets("root")}}class Kl{type="slice";caret;distance;constructor(t,e){this.caret=t,this.distance=e;}getSliceIndices(){const{distance:t,caret:{offset:e}}=this,n=e+t;return n<e?[n,e]:[e,n]}getTextContent(){const[t,e]=this.getSliceIndices();return this.caret.origin.getTextContent().slice(t,e)}getTextContentSize(){return Math.abs(this.distance)}removeTextSlice(){const{caret:{origin:t,direction:e}}=this,[n,r]=this.getSliceIndices(),i=t.getTextContent();return Ml(t.setTextContent(i.slice(0,n)+i.slice(r)),e,n)}}function zl(t){return t instanceof Kl}function Rl(t){return Wl(t,Ol(Zo(),t.direction))}function Bl(t){return Wl(t,t)}function Wl(e,n){return e.direction!==n.direction&&t(265),new Il(e,n,e.direction)}function $l(t){const{initial:e,hasNext:n,step:r,map:i}=t;let o=e;return {[Symbol.iterator](){return this},next(){if(!n(o))return {done:true,value:void 0};const t={done:false,value:i(o)};return o=r(o),t}}}function Jl(e,n){const r=Yl(e.origin,n.origin);switch(null===r&&t(275,e.origin.getKey(),n.origin.getKey()),r.type){case "same":{const t="text"===e.type,r="text"===n.type;return t&&r?function(t,e){return Math.sign(t-e)}(e.offset,n.offset):e.type===n.type?0:t?-1:r?1:"child"===e.type?-1:1}case "ancestor":return "child"===e.type?-1:1;case "descendant":return "child"===n.type?1:-1;case "branch":return jl(r)}}function jl(t){const{a:e,b:n}=t,r=e.__key,i=n.__key;let o=e,s=n;for(;o&&s;o=o.getNextSibling(),s=s.getNextSibling()){if(o.__key===i)return  -1;if(s.__key===r)return 1}return null===o?1:-1}function Ul(t,e){return e.is(t)}function Vl(t){return Wi(t)?[t.getLatest(),null]:[t.getParent(),t.getLatest()]}function Yl(e,n){if(e.is(n))return {commonAncestor:e,type:"same"};const r=new Map;for(let[t,n]=Vl(e);t;n=t,t=t.getParent())r.set(t,n);for(let[i,o]=Vl(n);i;o=i,i=i.getParent()){const s=r.get(i);if(void 0!==s)return null===s?(Ul(e,i)||t(276),{commonAncestor:i,type:"ancestor"}):null===o?(Ul(n,i)||t(277),{commonAncestor:i,type:"descendant"}):((Wi(s)||Ul(e,s))&&(Wi(o)||Ul(n,o))&&i.is(s.getParent())&&i.is(o.getParent())||t(278),{a:s,b:o,commonAncestor:i,type:"branch"})}return null}function ql(e,n){const{type:r,key:i,offset:o}=e,s=Bs(e.key);return "text"===r?(Tr(s)||t(266,s.getType(),i),Ml(s,n,o)):(Wi(s)||t(267,s.getType(),i),lc(s,e.offset,n))}function Hl(e,n){const{origin:r,direction:i}=n,o="next"===i;vl(n)?e.set(r.getKey(),n.offset,"text"):Tl(n)?Tr(r)?e.set(r.getKey(),Al(r,i),"text"):e.set(r.getParentOrThrow().getKey(),r.getIndexWithinParent()+(o?1:0),"element"):(Nl(n)&&Wi(r)||t(268),e.set(r.getKey(),o?0:r.getChildrenSize(),"element"));}function Gl(t){const e=Qr(),n=Fr(e)?e:qr();return Xl(n,t),es(n),n}function Xl(t,e){Hl(t.anchor,e.anchor),Hl(t.focus,e.focus);}function Ql(t){const{anchor:e,focus:n}=t,r=ql(e,"next"),i=ql(n,"next"),o=Jl(r,i)<=0?"next":"previous";return Wl(oc(r,o),oc(i,o))}function Zl(t){const{direction:e,origin:n}=t,r=Ol(n,ml(e)).getNodeAtCaret();return r?Ol(r,e):Pl(n.getParentOrThrow(),e)}function tc(t,e="root"){const n=[t];for(let r=Nl(t)?t.getParentCaret(e):t.getSiblingCaret();null!==r;r=r.getParentCaret(e))n.push(Zl(r));return n}function ec(t){return !!t&&t.origin.isAttached()}function nc(e,n="removeEmptySlices"){if(e.isCollapsed())return e;const r="root",i="next";let o=n;const s=sc(e,i),l=tc(s.anchor,r),c=tc(s.focus.getFlipped(),r),a=new Set,u=[];for(const t of s.iterNodeCarets(r))if(Nl(t))a.add(t.origin.getKey());else if(Tl(t)){const{origin:e}=t;Wi(e)&&!a.has(e.getKey())||u.push(e);}for(const t of u)t.remove();for(const t of s.getTextSlices()){if(!t)continue;const{origin:e}=t.caret,n=e.getTextContentSize(),r=Zl(Ol(e,i)),s=e.getMode();if(Math.abs(t.distance)===n&&"removeEmptySlices"===o||"token"===s&&0!==t.distance)r.remove();else if(0!==t.distance){o="removeEmptySlices";let e=t.removeTextSlice();const n=t.caret.origin;if("segmented"===s){const t=e.origin,n=kr(t.getTextContent()).setStyle(t.getStyle()).setFormat(t.getFormat());r.replaceOrInsert(n),e=Ml(n,i,e.offset);}n.is(l[0].origin)&&(l[0]=e),n.is(c[0].origin)&&(c[0]=e.getFlipped());}}let f,d;for(const t of l)if(ec(t)){f=rc(t);break}for(const t of c)if(ec(t)){d=rc(t);break}const h=function(t,e,n){if(!t||!e)return null;const r=t.getParentAtCaret(),i=e.getParentAtCaret();if(!r||!i)return null;const o=r.getParents().reverse();o.push(r);const s=i.getParents().reverse();s.push(i);const l=Math.min(o.length,s.length);let c;for(c=0;c<l&&o[c]===s[c];c++);const a=(t,e)=>{let n;for(let r=c;r<t.length;r++){const i=t[r];if(Is(i))return;!n&&e(i)&&(n=i);}return n},u=a(o,Qs),f=u&&a(s,t=>n.has(t.getKey())&&Qs(t));return u&&f?[u,f]:null}(f,d,a);if(h){const[t,e]=h;Pl(t,"previous").splice(0,e.getChildren());let n=e.getParent();for(e.remove(true);n&&n.isEmpty();){const t=n;n=n.getParent(),t.remove(true);}}const g=[f,d,...l,...c].find(ec);if(g){return Bl(oc(rc(g),e.direction))}t(269,JSON.stringify(l.map(t=>t.origin.__key)));}function rc(t){const e=function(t){let e=t;for(;Nl(e);){const t=Ll(e);if(!Nl(t))break;e=t;}return e}(t.getLatest()),{direction:n}=e;if(Tr(e.origin))return vl(e)?e:Ml(e.origin,n,n);const r=e.getAdjacentCaret();return Tl(r)&&Tr(r.origin)?Ml(r.origin,n,ml(n)):e}function ic(t){return vl(t)&&t.offset!==Al(t.origin,t.direction)}function oc(t,e){return t.direction===e?t:t.getFlipped()}function sc(t,e){return t.direction===e?t:Wl(oc(t.focus,e),oc(t.anchor,e))}function lc(t,e,n){let r=Pl(t,"next");for(let t=0;t<e;t++){const t=r.getAdjacentCaret();if(null===t)break;r=t;}return oc(r,n)}function cc(t,e="root"){let n=0,r=t,i=Ll(r);for(;null===i;){if(n--,i=r.getParentCaret(e),!i)return null;r=i,i=Ll(r);}return i&&[i,n]}function ac(e){const{origin:n,offset:r,direction:i}=e;if(r===Al(n,i))return e.getSiblingCaret();if(r===Al(n,ml(i)))return Zl(e.getSiblingCaret());const[o]=n.splitText(r);return Tr(o)||t(281),oc(Ol(o,"next"),i)}function uc(t,e){return  true}function fc(t,{$copyElementNode:e=Ks,$splitTextPointCaretNext:n=ac,rootMode:r="shadowRoot",$shouldSplit:i=uc,removeEmptyDestination:o=false}={}){if(vl(t))return n(t);const s=t.getParentCaret(r);if(s){const{origin:n}=s;if(Nl(t)){const t=Zl(s);if(o&&n.isEmpty())return n.remove(),t;if(!n.canBeEmpty()||!i(n,"first"))return t}const r=function(t){const e=[];for(let n=t.getAdjacentCaret();n;n=n.getAdjacentCaret())e.push(n.origin);return e}(t);(r.length>0||!o&&n.canBeEmpty()&&i(n,"last"))&&s.insert(e(n).splice(0,0,r));}return s}function dc(t){return t}function hc(...t){return t}function gc(t,e){return [t,e]}function _c(t){return t}function pc(t,e){if(!e||t===e)return t;for(const n in e)if(t[n]!==e[n])return {...t,...e};return t}function yc(...t){const e=[];for(const n of t)if(n&&"string"==typeof n)for(const[t]of n.matchAll(/\S+/g))e.push(t);return e}function mc(t,...e){const n=yc(...e);n.length>0&&t.classList.add(...n);}function xc(t,...e){const n=yc(...e);n.length>0&&t.classList.remove(...n);}function Cc(...t){return ()=>{for(let e=t.length-1;e>=0;e--)t[e]();t.length=0;}}
7325
7326var Lexical_prod = /*#__PURE__*/Object.freeze({
7327	__proto__: null,
7328	$addUpdateTag: Os,
7329	$applyNodeReplacement: zs,
7330	$caretFromPoint: ql,
7331	$caretRangeFromSelection: Ql,
7332	$cloneWithProperties: il,
7333	$cloneWithPropertiesEphemeral: ol,
7334	$comparePointCaretNext: Jl,
7335	$copyNode: Ks,
7336	$create: fl,
7337	$createChildrenArray: hl,
7338	$createLineBreakNode: or,
7339	$createNodeSelection: Hr,
7340	$createParagraphNode: eo,
7341	$createPoint: Mr,
7342	$createRangeSelection: qr,
7343	$createRangeSelectionFromDom: Gr,
7344	$createTabNode: wr,
7345	$createTextNode: kr,
7346	$extendCaretToRange: Rl,
7347	$findMatchingParent: dl,
7348	$getAdjacentChildCaret: Ll,
7349	$getAdjacentNode: vs,
7350	$getAdjacentSiblingOrParentSiblingCaret: cc,
7351	$getCaretInDirection: oc,
7352	$getCaretRange: Wl,
7353	$getCaretRangeInDirection: sc,
7354	$getCharacterOffsets: zr,
7355	$getChildCaret: Pl,
7356	$getChildCaretAtIndex: lc,
7357	$getChildCaretOrSelf: Fl,
7358	$getCollapsedCaretRange: Bl,
7359	$getCommonAncestor: Yl,
7360	$getCommonAncestorResultBranchOrder: jl,
7361	$getEditor: Zs,
7362	$getEditorDOMRenderConfig: tl,
7363	$getNearestNodeFromDOMNode: Go,
7364	$getNearestRootOrShadowRoot: Ls,
7365	$getNodeByKey: Yo,
7366	$getNodeByKeyOrThrow: Bs,
7367	$getNodeFromDOMNode: qo,
7368	$getPreviousSelection: Zr,
7369	$getRoot: Zo,
7370	$getSelection: Qr,
7371	$getSiblingCaret: Ol,
7372	$getState: st$2,
7373	$getStateChange: lt$3,
7374	$getTextContent: ci,
7375	$getTextNodeOffset: Al,
7376	$getTextPointCaret: Ml,
7377	$getTextPointCaretSlice: Dl,
7378	$getWritableNodeState: ft$2,
7379	$hasAncestor: As,
7380	$hasUpdateTag: Es,
7381	$insertNodes: li,
7382	$isBlockElementNode: Vr,
7383	$isChildCaret: Nl,
7384	$isDecoratorNode: ji,
7385	$isEditorState: Gi,
7386	$isElementNode: Wi,
7387	$isExtendableTextPointCaret: ic,
7388	$isInlineElementOrDecoratorNode: Fs,
7389	$isLeafNode: Wo,
7390	$isLexicalNode: Bn,
7391	$isLineBreakNode: sr,
7392	$isNodeCaret: kl,
7393	$isNodeSelection: Ir,
7394	$isParagraphNode: no,
7395	$isRangeSelection: Fr,
7396	$isRootNode: Vi,
7397	$isRootOrShadowRoot: Is,
7398	$isSiblingCaret: Tl,
7399	$isTabNode: Er,
7400	$isTextNode: Tr,
7401	$isTextPointCaret: vl,
7402	$isTextPointCaretSlice: zl,
7403	$isTokenOrSegmented: Io,
7404	$isTokenOrTab: Lo,
7405	$nodesOfType: Cs,
7406	$normalizeCaret: rc,
7407	$normalizeSelection__EXPERIMENTAL: St$3,
7408	$onUpdate: Ms,
7409	$parseSerializedNode: Ei,
7410	$removeTextFromCaretRange: nc,
7411	$rewindSiblingCaret: Zl,
7412	$selectAll: ys,
7413	$setCompositionKey: Uo,
7414	$setPointFromCaret: Hl,
7415	$setSelection: es,
7416	$setSelectionFromCaretRange: Gl,
7417	$setState: ct$2,
7418	$splitAtPointCaretNext: fc,
7419	$splitNode: Us,
7420	$updateRangeSelectionFromCaretRange: Xl,
7421	ArtificialNode__DO_NOT_USE: Qi,
7422	BEFORE_INPUT_COMMAND: le$3,
7423	BLUR_COMMAND: Xe$2,
7424	CAN_REDO_COMMAND: qe$2,
7425	CAN_UNDO_COMMAND: He$2,
7426	CLEAR_EDITOR_COMMAND: Ve$2,
7427	CLEAR_HISTORY_COMMAND: Ye$1,
7428	CLICK_COMMAND: se$5,
7429	COLLABORATION_TAG: Un,
7430	COMMAND_PRIORITY_BEFORE_CRITICAL: ho,
7431	COMMAND_PRIORITY_BEFORE_EDITOR: co,
7432	COMMAND_PRIORITY_BEFORE_HIGH: fo,
7433	COMMAND_PRIORITY_BEFORE_LOW: ao,
7434	COMMAND_PRIORITY_BEFORE_NORMAL: uo,
7435	COMMAND_PRIORITY_CRITICAL: lo,
7436	COMMAND_PRIORITY_EDITOR: ro,
7437	COMMAND_PRIORITY_HIGH: so,
7438	COMMAND_PRIORITY_LOW: io,
7439	COMMAND_PRIORITY_NORMAL: oo,
7440	COMPOSITION_END_COMMAND: ue$4,
7441	COMPOSITION_END_TAG: Xn,
7442	COMPOSITION_START_COMMAND: ae$4,
7443	COMPOSITION_START_TAG: Gn,
7444	CONTROLLED_TEXT_INSERTION_COMMAND: ge$3,
7445	COPY_COMMAND: Je$2,
7446	CUT_COMMAND: je$2,
7447	DEFAULT_EDITOR_DOM_CONFIG: po,
7448	DELETE_CHARACTER_COMMAND: fe$4,
7449	DELETE_LINE_COMMAND: me$3,
7450	DELETE_WORD_COMMAND: ye$2,
7451	DRAGEND_COMMAND: $e$2,
7452	DRAGOVER_COMMAND: We$2,
7453	DRAGSTART_COMMAND: Be$2,
7454	DROP_COMMAND: ze$2,
7455	DecoratorNode: Ji,
7456	ElementNode: Bi,
7457	FOCUS_COMMAND: Ge$2,
7458	FORMAT_ELEMENT_COMMAND: Re$1,
7459	FORMAT_TEXT_COMMAND: xe,
7460	HISTORIC_TAG: Wn$1,
7461	HISTORY_MERGE_TAG: Jn,
7462	HISTORY_PUSH_TAG: $n$1,
7463	INDENT_CONTENT_COMMAND: Ie$3,
7464	INPUT_COMMAND: ce$4,
7465	INSERT_LINE_BREAK_COMMAND: de$4,
7466	INSERT_PARAGRAPH_COMMAND: he$3,
7467	INSERT_TAB_COMMAND: Le$2,
7468	INTERNAL_$isBlock: Qs,
7469	IS_ALL_FORMATTING: T$2,
7470	IS_BOLD: p,
7471	IS_CODE: C$4,
7472	IS_HIGHLIGHT: k$3,
7473	IS_ITALIC: y$1,
7474	IS_STRIKETHROUGH: m$1,
7475	IS_SUBSCRIPT: S$1,
7476	IS_SUPERSCRIPT: v$1,
7477	IS_UNDERLINE: x$1,
7478	KEY_ARROW_DOWN_COMMAND: Ee$3,
7479	KEY_ARROW_LEFT_COMMAND: Ne$1,
7480	KEY_ARROW_RIGHT_COMMAND: ke$2,
7481	KEY_ARROW_UP_COMMAND: we$1,
7482	KEY_BACKSPACE_COMMAND: Ae$3,
7483	KEY_DELETE_COMMAND: Pe$2,
7484	KEY_DOWN_COMMAND: ve$2,
7485	KEY_ENTER_COMMAND: Oe$2,
7486	KEY_ESCAPE_COMMAND: De$2,
7487	KEY_MODIFIER_COMMAND: Qe$1,
7488	KEY_SPACE_COMMAND: Me$2,
7489	KEY_TAB_COMMAND: Fe$2,
7490	LineBreakNode: rr,
7491	MOVE_TO_END: Te$2,
7492	MOVE_TO_START: be$1,
7493	NODE_STATE_KEY: j$7,
7494	OUTDENT_CONTENT_COMMAND: Ke$2,
7495	PASTE_COMMAND: _e$2,
7496	PASTE_TAG: jn,
7497	ParagraphNode: Zi,
7498	REDO_COMMAND: Se$2,
7499	REMOVE_TEXT_COMMAND: pe$3,
7500	RootNode: Ui,
7501	SELECTION_CHANGE_COMMAND: ie$4,
7502	SELECTION_INSERT_CLIPBOARD_NODES_COMMAND: oe$6,
7503	SELECT_ALL_COMMAND: Ue$2,
7504	SKIP_COLLAB_TAG: Vn,
7505	SKIP_DOM_SELECTION_TAG: qn,
7506	SKIP_SCROLL_INTO_VIEW_TAG: Yn,
7507	SKIP_SELECTION_FOCUS_TAG: Hn,
7508	TEXT_TYPE_TO_FORMAT: z$7,
7509	TabNode: br,
7510	TextNode: gr,
7511	UNDO_COMMAND: Ce$2,
7512	addClassNamesToElement: mc,
7513	buildImportMap: In,
7514	configExtension: hc,
7515	createCommand: re$5,
7516	createEditor: yo,
7517	createSharedNodeState: at$3,
7518	createState: ot$3,
7519	declarePeerDependency: gc,
7520	defineExtension: dc,
7521	flipDirection: ml,
7522	getDOMOwnerDocument: ws,
7523	getDOMSelection: Js,
7524	getDOMSelectionFromTarget: js,
7525	getDOMTextNode: Ro,
7526	getEditorPropertyFromDOMNode: Po,
7527	getNearestEditorFromDOMNode: Do,
7528	getRegisteredNode: bo,
7529	getRegisteredNodeOrThrow: No,
7530	getStaticNodeConfig: ul,
7531	getStyleObjectFromCSS: Zn,
7532	getTextDirection: Fo,
7533	getTransformSetFromKlass: _o,
7534	isBlockDomNode: Xs,
7535	isCurrentlyReadOnlyMode: mi,
7536	isDOMDocumentNode: zo,
7537	isDOMNode: qs,
7538	isDOMTextNode: Ko,
7539	isDOMUnmanaged: cl,
7540	isDocumentFragment: Hs,
7541	isExactShortcutMatch: ds,
7542	isHTMLAnchorElement: Vs,
7543	isHTMLElement: Ys,
7544	isInlineDomNode: Gs,
7545	isLexicalEditor: Ao,
7546	isModifierMatch: fs,
7547	isSelectionCapturedInDecoratorInput: Oo,
7548	isSelectionWithinEditor: Mo,
7549	makeStepwiseIterator: $l,
7550	mergeRegister: Cc,
7551	normalizeClassNames: yc,
7552	removeClassNamesFromElement: xc,
7553	removeFromParent: Jo,
7554	resetRandomKey: To,
7555	safeCast: _c,
7556	setDOMStyleFromCSS: nr,
7557	setDOMStyleObject: er,
7558	setDOMUnmanaged: ll,
7559	setNodeIndentFromDOM: sl,
7560	shallowMergeConfig: pc,
7561	toggleTextFormatType: Bo
7562});
7563
7564/**
7565 * Copyright (c) Meta Platforms, Inc. and affiliates.
7566 *
7567 * This source code is licensed under the MIT license found in the
7568 * LICENSE file in the root directory of this source tree.
7569 *
7570 */
7571
7572function E$3(e,...t){const n=new URL("https://lexical.dev/docs/error"),o=new URLSearchParams;o.append("code",e);for(const e of t)o.append("v",e);throw n.search=o.toString(),Error(`Minified Lexical error #${e}; visit ${n.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}function F$6(e){let t="";for(const n in e)n&&(t+=`${n}: ${e[n]};`);return t}function b$2(e){const n=Zs().getElementByKey(e.getKey());if(null===n)return null;const o=n.ownerDocument.defaultView;return null===o?null:o.getComputedStyle(n)}function z$6(e){return b$2(Vi(e)?e:e.getParentOrThrow())}function O$3(e){const t=z$6(e);return null!==t&&"rtl"===t.direction}function R$3(e,t,n="self"){const o=e.getStartEndPoints();if(t.isSelected(e)&&!Io(t)&&null!==o){const[l,r]=o,s=e.isBackward(),i=l.getNode(),u=r.getNode(),g=t.is(i),a=t.is(u);if(g||a){const[o,l]=zr(e),r=i.is(u),g=t.is(s?u:i),a=t.is(s?i:u);let d,p=0;if(r)p=o>l?l:o,d=o>l?o:l;else if(g){p=s?l:o,d=void 0;}else if(a){p=0,d=s?o:l;}const h=t.__text.slice(p,d);h!==t.__text&&("clone"===n&&(t=ol(t)),t.__text=h);}}return t}function A$2(e){if("text"===e.type)return e.offset===e.getNode().getTextContentSize();const t=e.getNode();return Wi(t)||E$3(177),e.offset===t.getChildrenSize()}
7572function M$4(t,n){(Fr(t)?t.isCollapsed():Tr(t)||Wi(t))||E$3(280);const o=Zn(Fr(t)?t.style:Tr(t)?t.getStyle():t.getTextStyle()),r=F$6(Object.entries(n).reduce((e,[n,l])=>("function"==typeof l?e[n]=l(o[n],t):null===l?delete e[n]:e[n]=l,e),{...o}));Fr(t)||Tr(t)?t.setStyle(r):t.setTextStyle(r);}function $$3(e,t){if(Fr(e)&&e.isCollapsed()){M$4(e,t);const n=e.anchor.getNode();Wi(n)&&n.isEmpty()&&M$4(n,t);}D$3(e=>{M$4(e,t);});const n=e.getNodes();if(n.length>0){const e=new Set;for(const o of n){if(!Wi(o)||!o.canBeEmpty()||0!==o.getChildrenSize())continue;const n=o.getKey();e.has(n)||(e.add(n),M$4(o,t));}}}function D$3(t){const n=Qr();if(!n)return;const i=new Map,c=e=>i.get(e.getKey())||[0,e.getTextContentSize()];if(Fr(n))for(const e of Ql(n).getTextSlices())e&&i.set(e.caret.origin.getKey(),e.getSliceIndices());const f=n.getNodes();for(const n of f){if(!Tr(n)||!n.canHaveFormat())continue;const[o,l]=c(n);if(l!==o)if(Io(n)||0===o&&l===n.getTextContentSize())t(n);else {t(n.splitText(o,l)[0===o?0:1]);}}Fr(n)&&"text"===n.anchor.type&&"text"===n.focus.type&&n.anchor.key===n.focus.key&&j$6(n);}function j$6(e){if(e.isBackward()){const{anchor:t,focus:n}=e,{key:o,offset:l,type:r}=t;t.set(n.key,n.offset,n.type),n.set(o,l,r);}}function U$5(e,t){const n=e.getFormatType(),o=e.getIndent();n!==t.getFormatType()&&t.setFormat(n),o!==t.getIndent()&&t.setIndent(o);}function H$6(e,t,n=U$5){if(null===e)return;const l=e.getStartEndPoints(),r=new Map;let s=null;if(l){const[e,t]=l;s=qr(),s.anchor.set(e.key,e.offset,e.type),s.focus.set(t.key,t.offset,t.type);const n=dl(e.getNode(),Qs),o=dl(t.getNode(),Qs);Wi(n)&&r.set(n.getKey(),n),Wi(o)&&r.set(o.getKey(),o);}for(const t of e.getNodes())if(Wi(t)&&Qs(t))r.set(t.getKey(),t);else if(null===l){const e=dl(t,Qs);Wi(e)&&r.set(e.getKey(),e);}for(const[e,o]of r){const l=t();n(o,l),o.replace(l,true),s&&(e===s.anchor.key&&s.anchor.set(l.getKey(),s.anchor.offset,s.anchor.type),e===s.focus.key&&s.focus.set(l.getKey(),s.focus.offset,s.focus.type));}s&&e.is(Qr())&&es(s);}function G$9(e){const t=J$6(e);return null!==t&&"vertical-rl"===t.writingMode}function J$6(e){const t=e.anchor.getNode();return Wi(t)?b$2(t):z$6(t)}function Q$8(e,t){let n=G$9(e)?!t:t;Z$4(e)&&(n=!n);const o=ql(e.focus,n?"previous":"next");if(ic(o))return  false;for(const e of Rl(o)){if(Nl(e))return !e.origin.isInline();if(!Wi(e.origin)){if(ji(e.origin))return  true;break}}return  false}function Y$4(e,t,n,o){e.modify(t?"extend":"move",n,o);}function Z$4(e){const t=J$6(e);return null!==t&&"rtl"===t.direction}function ee$3(e,t,n){const o=Z$4(e);let l;l=G$9(e)||o?!n:n,Y$4(e,t,l,"character");}function te$4(e,t,n){const o=e.getStyle(),l=Zn(o);return null!==l&&l[t]||n}function ne$4(t,n,o=""){let r=null;const s=t.getNodes(),i=t.anchor,c=t.focus,f=t.isBackward(),u=f?c.getNode():i.getNode(),g=f?i.getNode():c.getNode(),a=f?c.offset:i.offset,p=f?i.offset:c.offset;if(Fr(t)&&t.isCollapsed()&&""!==t.style){const e=t.style,o=Zn(e);if(null!==o&&n in o)return o[n]}for(let t=0;t<s.length;t++){const l=s[t];if((0!==t||!l.is(u)||!Tr(l)||a!==l.getTextContentSize())&&((0===t||!l.is(g)||0!==p)&&Tr(l))){const e=te$4(l,n,o);if(null===r)r=e;else if(r!==e){r="";break}}}return null===r?o:r}const oe$5=Zn;
7573
7574function deepMerge(target, source) {
7575  const result = { ...target, ...source };
7576  for (const [ key, value ] of Object.entries(source)) {
7577    if (arePlainHashes(target[key], value)) {
7578      result[key] = deepMerge(target[key], value);
7579    }
7580  }
7581
7582  return result
7583}
7584
7585function arePlainHashes(...values) {
7586  return values.every(value => value && value.constructor == Object)
7587}
7588
7589class Configuration {
7590  #tree = {}
7591
7592  constructor(...configs) {
7593    this.merge(...configs);
7594  }
7595
7596  merge(...configs) {
7597    return this.#tree = configs.reduce(deepMerge, this.#tree)
7598  }
7599
7600  get(path) {
7601    const keys = path.split(".");
7602    return keys.reduce((node, key) => node[key], this.#tree)
7603  }
7604}
7605
7606function range(from, to) {
7607  return [ ...Array(1 + to - from).keys() ].map(i => i + from)
7608}
7609
7610const global$1 = new Configuration({
7611  attachmentTagName: "action-text-attachment",
7612  attachmentContentTypeNamespace: "actiontext",
7613  authenticatedUploads: false,
7614  extensions: []
7615});
7616
7617const presets = new Configuration({
7618  default: {
7619    attachments: true,
7620    markdown: true,
7621    multiLine: true,
7622    permittedAttachmentTypes: null,
7623    richText: true,
7624    toolbar: {
7625      upload: "both"
7626    },
7627    headings: [ "h2", "h3", "h4" ],
7628    highlight: {
7629      buttons: {
7630        color: range(1, 9).map(n => `var(--highlight-${n})`),
7631        "background-color": range(1, 9).map(n => `var(--highlight-bg-${n})`),
7632      },
7633      permit: {
7634        color: [],
7635        "background-color": []
7636      }
7637    }
7638  }
7639});
7640
7641var Lexxy = {
7642  global: global$1,
7643  presets,
7644  configure({ global: newGlobal, ...newPresets }) {
7645    if (newGlobal) {
7646      global$1
vendor: 10,186 bytes, lines 7646-7838
7646.merge(newGlobal);
7647    }
7648    presets.merge(newPresets);
7649  }
7650};
7651
7652// An attachment's `url` ends up as an <img src> (action_text_attachment_node
7653// reads it into `this.src`, which is assigned to img.src). DOMPurify already
7654// permits a data: URI on img[src] — img is in its DATA_URI_TAGS — but it has no
7655// way to know that a custom element's `url` feeds the same sink, so it applies
7656// the plain URI check and drops it.
7657//
7658// Until 3.3.2 that never came up: attributes admitted by a *functional* ADD_ATTR
7659// skipped URI validation entirely (GHSA-cjmm-f4jc-qw8r), which is how data:
7660// URLs worked here — and, less happily, how `url="javascript:…"` survived too.
7661// The fix restored validation for both. The bypass was reported to us by
7662// @petitpois via HackerOne.
7663//
7664// So `url` is marked URI-safe, which hands the decision to this hook. The hook
7665// only ever removes an attribute — it never force-keeps one — so scoping stays
7666// with the ADD_ATTR predicate, and a `url` on a tag that never declared it is
7667// dropped as it always was.
7668//
7669// The data: exception is scoped to the attachment element, not to the attribute
7670// name. ADD_URI_SAFE_ATTR is attribute-name-wide: it takes `url` out of
7671// DOMPurify's URI checking on every tag, not just ours. Extensions may declare
7672// arbitrary attributes on arbitrary tags — home/docs/extensions.md's own worked
7673// example is an <iframe> — so an extension declaring `url` would otherwise
7674// inherit an exception granted because *an attachment's* url becomes an img src.
7675// Nothing about a third party's element supports that, and `data:text/html` in a
7676// navigational sink is script execution. Everything else gets the standard
7677// policy, which is what it would have had if we had never touched `url`.
7678//
7679// That argument is about an attribute feeding a URL sink, not about
7680// ADD_URI_SAFE_ATTR as such. The inert text attributes beside `url` in that list
7681// — `caption`, `filename` — keep the attribute-name-wide exemption, and need it:
7682// ordinary prose like "Q4: results" is not a URI any regex here would accept.
7683const URI_BEARING_ATTACHMENT_ATTRIBUTES = [ "url" ];
7684
7685// DOMPurify's own IS_ALLOWED_URI scheme list, reproduced rather than narrowed, so
7686// `url` on a non-attachment tag is treated exactly as DOMPurify would have treated
7687// it. Kept as a source string so allowedUriRegexp() can widen it with an editor's
7688// declared schemes without re-deriving the rest of the pattern.
7689const BASE_URI_SCHEMES = "(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix";
7690
7691// A scheme name (not a full pattern), so a caller can't inject regexp syntax.
7692const SCHEME_NAME = /^[a-z][a-z0-9+.-]*$/;
7693
7694// The executable schemes, by DOMPurify's own IS_SCRIPT_OR_DATA definition
7695// (/^(?:\w+script|data):/i): javascript, vbscript, …script, and data. Widening the
7696// allowlist to admit one would let it survive on href/object[data], which the
7697// override otherwise defeats — DOMPurify does not re-block a scheme its
7698// ALLOWED_URI_REGEXP accepts. A caller declaring one is dropped, so it stays
7699// refused. This is a closed set (the schemes a browser executes), not a growing
7700// denylist.
7701const EXECUTABLE_SCHEME = /^(?:\w+script|data)$/i;
7702
7703// Builds DOMPurify's default IS_ALLOWED_URI, optionally with extra schemes folded
7704// into the scheme alternation. Widening the recognised-safe scheme set is how a
7705// custom-scheme identifier (a mention's `gid://…`) passes validation without
7706// exempting any attribute from it. Passing no schemes reproduces DOMPurify's
7707// default exactly.
7708function allowedUriRegexp(extraSchemes = []) {
7709  const extra = extraSchemes
7710    .map(scheme => String(scheme).toLowerCase())
7711    .filter(scheme => SCHEME_NAME.test(scheme) && !EXECUTABLE_SCHEME.test(scheme))
7712    .map(scheme => scheme.replace(/[.+-]/g, "\\$&"));
7713
7714  const schemes = [ BASE_URI_SCHEMES, ...extra ].join("|");
7715
7716  return new RegExp(`^(?:(?:${schemes}):|[^a-z]|[a-z+.-]+(?:[^a-z+.:-]|$))`, "i")
7717}
7718
7719const ALLOWED_URI = allowedUriRegexp();
7720
7721// eslint-disable-next-line no-control-regex -- mirrors DOMPurify's own ATTR_WHITESPACE
7722const ATTR_WHITESPACE = /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g;
7723
7724// Tested against the value as given, never the whitespace-stripped copy, so a
7725// scheme smuggled at a nonzero offset is refused. DOMPurify draws the same line:
7726// its data: allowance is a prefix test on the un-stripped value, which is why
7727// this is a second step rather than one more scheme in ALLOWED_URI.
7728//
7729// One deliberate difference from DOMPurify's img[src] handling remains, stated
7730// because the earlier claim of matching it "exactly" was not true: DOMPurify
7731// tests for a literal lowercase `data:` and this is case-insensitive, so `DATA:`
7732// passes here too. That matches how browsers resolve schemes, which is what
7733// actually decides whether the URL loads.
7734const ATTACHMENT_DATA_URI = /^data:/i;
7735
7736function isAttachmentTag(tag) {
7737  return tag === Lexxy.global.get("attachmentTagName")
7738}
7739
7740function attachmentUriFilterHook(currentNode, hookEvent) {
7741  if (!URI_BEARING_ATTACHMENT_ATTRIBUTES.includes(hookEvent.attrName)) return
7742
7743  // DOMPurify keeps an empty value — its chain ends `else if (value) { return
7744  // false } else ;` — while every alternation here needs at least one character.
7745  if (!hookEvent.attrValue) return
7746
7747  const value = String(hookEvent.attrValue);
7748
7749  if (ALLOWED_URI.test(value.replace(ATTR_WHITESPACE, ""))) return
7750  if (isAttachmentTag(currentNode?.nodeName?.toLowerCase()) && ATTACHMENT_DATA_URI.test(value)) return
7751
7752  hookEvent.keepAttr = false;
7753}
7754
7755// Lexxy's own DOMPurify instance, deliberately not the shared default export.
7756//
7757// dompurify's default export is a singleton, and both its config and its hooks
7758// are global to every consumer in the bundle. That makes configuring it from an
7759// editor's connectedCallback actively dangerous for the host app: DOMPurify
7760// treats a persistent config as final, so once setConfig() has run, every
7761// later `sanitize(html, config)` anywhere in the app silently ignores its own
7762// config argument. An app sanitizing untrusted HTML with, say,
7763// `{ ALLOW_DATA_ATTR: false }` would keep passing that option and stop getting
7764// it the moment a Lexxy editor connected — with no error and no visible change
7765// at the call site.
7766//
7767// Calling the default export with a window returns a fresh, independent
7768// instance. This one carries the hooks and config below; nothing we do here can
7769// reach the app's instance, and nothing it does can reach ours.
7770//
7771// Under Trusted Types, every DOMPurify instance tries to create a policy named
7772// `dompurify` on its first sanitize, and TT rejects a duplicate name — so the
7773// second instance on the page gets none. That matters, and not because it throws:
7774// DOMPurify hands its input to DOMParser.parseFromString, which is itself a TT
7775// sink, but `_initDocument` swallows that throw and the innerHTML throw from its
7776// createDocument fallback, and `sanitize` then returns "" for the body it never
7777// got. An unsigned instance silently drops all content, with nothing in the host's
7778// error tracker to say why — and which sanitizer goes silent depends on which one
7779// ran first.
7780//
7781// So we create our own, under our own name, and hand it to DOMPurify rather than
7782// letting it try. Lazily, because resolving it at import would fire a CSP
7783// violation report on every page load of an app that imports Lexxy and never
7784// renders an editor, and at most once, because TT throws on a duplicate name.
7785// Guarded too, because creating a policy the CSP hasn't allowlisted throws: if
7786// that happens we're back to no policy, which is exactly where this stood before.
7787// An app enforcing `require-trusted-types-for 'script'` should add `lexxy` to its
7788// `trusted-types` directive.
7789//
7790// What this does NOT do is make Lexxy work under enforced Trusted Types. It
7791// stops *our* sanitizer from taking the host's policy name and breaking the
7792// host's; it does nothing about Lexxy's own unwrapped sinks, and there are
7793// several. `parseHtml` in helpers/html_helper.js hands a plain string to
7794// DOMParser.parseFromString on the initial-value path, so the editor throws
7795// before it finishes connecting — verified in Chromium under
7796// `require-trusted-types-for 'script'`, with `lexxy` allowlisted and without.
7797// `createElement` in the same file is a second sink in it, writing its `content`
7798// argument through innerHTML for the two callers that pass one — the wrapped-table
7799// figure and the table tools' count. `highlightElement` in
7800// helpers/code_highlighting_helper.js writes Prism's output the same way, and both
7801// it and highlightCode are exported from src/index.js — so that one throws for a
7802// host app calling Lexxy's highlighting API directly, outside any editor. The
7803// `insertAdjacentHTML` in nodes/custom_action_text_attachment_node.js and the
7804// `innerHTML` writes across elements/ — the toolbar, the dropdowns, the node
7805// delete button — are in the same position. Making the editor usable under TT is a
7806// separate piece of work; this is a prerequisite for it, not the whole of it.
7807let trustedTypesPolicyResolved = false;
7808let resolvedTrustedTypesPolicy = null;
7809
7810function trustedTypesPolicy() {
7811  if (!trustedTypesPolicyResolved) {
7812    resolvedTrustedTypesPolicy = createTrustedTypesPolicy();
7813    trustedTypesPolicyResolved = true;
7814  }
7815
7816  return resolvedTrustedTypesPolicy
7817}
7818
7819function createTrustedTypesPolicy() {
7820  // Feature-detected below, so browsers without Trusted Types simply get no
7821  // policy — the same path as a CSP that doesn't allowlist ours.
7822  // eslint-disable-next-line compat/compat
7823  const trustedTypes = window.trustedTypes;
7824
7825  if (typeof trustedTypes?.createPolicy !== "function") return null
7826
7827  try {
7828    return trustedTypes.createPolicy("lexxy", { createHTML: (html) => html, createScriptURL: (url) => url })
7829  } catch {
7830    // Warned rather than swallowed, matching what DOMPurify does when its own
7831    // policy is refused. The fallback is a silent loss of Trusted Types coverage
7832    // otherwise, and the CSP violation report alone doesn't name us.
7833    console.warn("TrustedTypes policy lexxy could not be created.");
7834    return null
7835  }
7836}
7837
7838const DOMPurify = 
vendor: 1,234 bytes, lines 7838-7866
7838purify(window);
7839
7840// alt is inert on every element it can appear on, so it sits in the blanket
7841// list. srcset is deliberately absent — it carries URLs, so it belongs to a
7842// consumer that declares it.
7843const ALLOWED_HTML_ATTRIBUTES = [ "alt", "class", "contenteditable", "href", "src", "style", "title" ];
7844
7845// width/height are scoped to img rather than allowlisted globally, because
7846// ALLOWED_ATTR is not per-tag: putting them there would also permit
7847// `<table width="100000">` and `<td height="500">` in attachment content, which
7848// is layout the editor previously stripped. An image needs them to hold its
7849// place while it loads; nothing else here does.
7850const DEFAULT_TAG_ATTRIBUTES = { img: [ "width", "height" ] };
7851
7852const ALLOWED_STYLE_PROPERTIES = [ "color", "background-color" ];
7853
7854function styleFilterHook(_currentNode, hookEvent) {
7855  if (hookEvent.attrName === "style" && hookEvent.attrValue) {
7856    const styles = { ...oe$5(hookEvent.attrValue) };
7857    const sanitizedStyles = { };
7858
7859    for (const property in styles) {
7860      if (ALLOWED_STYLE_PROPERTIES.includes(property)) {
7861        sanitizedStyles[property] = styles[property];
7862      }
7863    }
7864
7865    if (Object.keys(sanitizedStyles).length) {
7866      hookEvent.attrValue = F$6
vendor: 9,476 bytes, lines 7866-8099
7866(sanitizedStyles);
7867    } else {
7868      hookEvent.keepAttr = false;
7869    }
7870  }
7871}
7872
7873DOMPurify.addHook("uponSanitizeAttribute", styleFilterHook);
7874DOMPurify.addHook("uponSanitizeAttribute", attachmentUriFilterHook);
7875
7876const FORBIDDEN_STIMULUS_ATTRIBUTES = [ "data-controller", "data-action" ];
7877
7878// Stimulus behavior attributes must never survive sanitization, whatever an
7879// extension's allowedElements declares. On dompurify 3.4.13 FORBID_ATTR already
7880// carries that on its own: _isValidAttribute opens with it, ahead of the
7881// functional ADD_ATTR Lexxy builds from the public allowedElements API. So this
7882// hook is defence in depth rather than the barrier, and it is kept because it
7883// holds without reference to the config — the prohibition is a class-level one,
7884// and a FORBID_ATTR entry lives or dies with whatever rebuilds the config.
7885function stimulusAttributeFilterHook(_currentNode, hookEvent) {
7886  if (FORBIDDEN_STIMULUS_ATTRIBUTES.includes(hookEvent.attrName)) {
7887    hookEvent.keepAttr = false;
7888  }
7889}
7890
7891DOMPurify.addHook("uponSanitizeAttribute", stimulusAttributeFilterHook);
7892
7893DOMPurify.addHook("uponSanitizeElement", (node, data) => {
7894  if (data.tagName === "strong" || data.tagName === "em") {
7895    node.removeAttribute("class");
7896  }
7897});
7898
7899// Called with no allowedElements for a sanitizer that has no allowlist to apply,
7900// which is not the same thing as an empty one — see EditorSanitizer's fallback.
7901function buildConfig(allowedElements = null) {
7902  const config = {
7903    ADD_URI_SAFE_ATTR: [ "caption", "filename", ...URI_BEARING_ATTACHMENT_ATTRIBUTES ],
7904    SAFE_FOR_XML: false, // So that it does not strip attributes that contains serialized HTML (like content)
7905    // Stimulus behavior attributes must never survive sanitization: they let stored content
7906    // wire up arbitrary controllers/actions in the viewer's session. FORBID_ATTR wins over
7907    // ALLOWED_ATTR/ADD_ATTR/ALLOW_DATA_ATTR in DOMPurify, so this holds even though other
7908    // data-* attributes (data-language, data-trix-*, etc.) are otherwise allowed through.
7909    FORBID_ATTR: [ "data-controller", "data-action" ]
7910  };
7911
7912  // Left out rather than emptied when there is no allowlist, so DOMPurify's own
7913  // default tag and attribute policy stands. `ALLOWED_TAGS: []` would not be a
7914  // default, it would be a refusal: it strips every tag. An editor that declares
7915  // an empty allowlist still gets that refusal, because it asked for it.
7916  //
7917  // uriSafeSchemes widens the scheme validation rather than exempting an attribute
7918  // from it: ALLOWED_URI_REGEXP is set only when an editor declares custom schemes,
7919  // so a value like a mention's `gid://…` passes while javascript:/data: stay
7920  // refused on every attribute — including href and object[data]. Nothing is taken
7921  // out of URI checking, so there is no attribute to guard against exempting.
7922  if (allowedElements) {
7923    const { uriSafeSchemes, ...tagPolicy } = allowlistFor(allowedElements);
7924    if (uriSafeSchemes.length) config.ALLOWED_URI_REGEXP = allowedUriRegexp(uriSafeSchemes);
7925    Object.assign(config, tagPolicy);
7926  }
7927
7928  // Always assigned, including when we have no policy — `null` is what
7929  // trustedTypesPolicy() returns then, and `TRUSTED_TYPES_POLICY: null` is
7930  // DOMPurify's documented per-call opt-out: sign nothing, create nothing.
7931  //
7932  // Leaving the key out is a different thing entirely, and the wrong one. With no
7933  // key DOMPurify falls through to _getDefaultTrustedTypesPolicy() and asks the
7934  // browser for `dompurify` — the very name this exists to stop competing for — so
7935  // an omitted key would disarm the sanitizer of a host shipping
7936  // `trusted-types dompurify` on the one path where we couldn't get our own.
7937  // Present-and-`undefined` lands in that same fallthrough, so it is not a
7938  // substitute for `null` either.
7939  config.TRUSTED_TYPES_POLICY = trustedTypesPolicy();
7940
7941  return config
7942}
7943
7944function allowlistFor(allowedElements) {
7945  // Null prototype, so a declared tag can never read through to an
7946  // Object.prototype key: `tagAttributes["constructor"]` would answer with a
7947  // function, and ADD_ATTR would call .includes on it.
7948  const tagAttributes = Object.create(null);
7949  const uriSafeSchemes = [];
7950
7951  // Lowercased, because DOMPurify lowercases ALLOWED_TAGS and calls ADD_ATTR
7952  // with the lowercased tag and attribute names. Keeping the caller's casing
7953  // makes allowedElements silently partial: `[ "IMG" ]` allows the element but
7954  // drops the width/height below, and `[ { tag: "img", attributes: [ "GID" ] } ]`
7955  // drops the attribute it declares.
7956  for (const element of allowedElements) {
7957    const tag = String(element.tag ?? element).toLowerCase();
7958    const attributes = (element.attributes ?? []).map(attribute => attribute.toLowerCase());
7959
7960    tagAttributes[tag] ||= [];
7961    tagAttributes[tag].push(...attributes);
7962
7963    // A custom scheme a caller declares is folded into the editor's URI-scheme
7964    // allowlist (ALLOWED_URI_REGEXP in buildConfig), so a value like a mention's
7965    // `gid="gid://…"` — which DOMPurify otherwise drops as an unknown scheme, even
7966    // once the `gid` name is allowed — passes validation. It widens the recognised
7967    // schemes, it does not exempt an attribute: javascript:/data: stay refused
7968    // everywhere, so there is no navigational attribute to guard. Declared per
7969    // element for locality, but a scheme is editor-wide once allowed.
7970    uriSafeSchemes.push(...(element.uriSafeSchemes ?? []));
7971  }
7972
7973  // Only for tags the caller already permits — this widens what an allowed
7974  // element may carry, never which elements are allowed.
7975  for (const [ tag, attributes ] of Object.entries(DEFAULT_TAG_ATTRIBUTES)) {
7976    if (tagAttributes[tag]) tagAttributes[tag].push(...attributes);
7977  }
7978
7979  return {
7980    ALLOWED_TAGS: Object.keys(tagAttributes),
7981    ALLOWED_ATTR: ALLOWED_HTML_ATTRIBUTES,
7982    ADD_ATTR: (attribute, tag) => tagAttributes[tag]?.includes(attribute),
7983    uriSafeSchemes
7984  }
7985}
7986
7987function getNonce() {
7988  const element = document.head.querySelector("meta[name=csp-nonce]");
7989  return element?.content
7990}
7991
7992// Register an event listener with a return function to deregister the listener. Both the element and
7993// the listener are WeakRefs so neither is pinned in memory by the deregister function.
7994function registerEventListener(element, type, listener, options) {
7995  element.addEventListener(type, listener, options);
7996  const elementRef = new WeakRef(element);
7997  const listenerRef = new WeakRef(listener);
7998
7999  return function deregisterListener() {
8000    const listener = listenerRef.deref();
8001    if (listener) elementRef.deref()?.removeEventListener(type, listener, options);
8002  }
8003}
8004
8005class ListenerBin {
8006  #listeners = []
8007
8008  track(...listeners) {
8009    this.#listeners.push(...listeners);
8010  }
8011
8012  dispose() {
8013    while (this.#listeners.length) {
8014      const teardown = this.#listeners.pop();
8015      teardown();
8016    }
8017  }
8018}
8019
8020function handlingDefault(handler) {
8021  return event => {
8022    const handled = handler(event);
8023    if (handled) event.preventDefault();
8024    return handled
8025  }
8026}
8027
8028function createElement(name, properties, content = "") {
8029  const element = document.createElement(name);
8030  for (const [ key, value ] of Object.entries(properties || {})) {
8031    if (key === "dataset") {
8032      Object.entries(value).forEach(([ key, value ]) => (element.dataset[key] = value));
8033    } else if (key in element) {
8034      element[key] = value;
8035    } else if (value !== null && value !== undefined) {
8036      element.setAttribute(key, value);
8037    }
8038  }
8039  if (content) {
8040    element.innerHTML = content;
8041  }
8042  return element
8043}
8044
8045function parseHtml(html) {
8046  const parser = new DOMParser();
8047  return parser.parseFromString(html, "text/html")
8048}
8049
8050function createAttachmentFigure(contentType, isPreviewable, fileName) {
8051  const extension = fileName ? fileName.split(".").pop().toLowerCase() : "unknown";
8052  return createElement("figure", {
8053    className: `attachment attachment--${isPreviewable ? "preview" : "file"} attachment--${extension}`,
8054    "data-content-type": contentType
8055  })
8056}
8057
8058function isPreviewableImage(contentType) {
8059  return contentType.startsWith("image/") && !contentType.includes("svg")
8060}
8061
8062function dispatch(element, eventName, detail = null, cancelable = false) {
8063  return element.dispatchEvent(new CustomEvent(eventName, { bubbles: true, detail, cancelable }))
8064}
8065
8066function addBlockSpacing(doc) {
8067  const selector = "body > :not(h1, h2, h3, h4, h5, h6) + *, blockquote > :not(h1, h2, h3, h4, h5, h6) + *";
8068  for (const block of doc.querySelectorAll(selector)) {
8069    const spacer = doc.createElement("p");
8070    spacer.appendChild(doc.createElement("br"));
8071    block.before(spacer);
8072  }
8073}
8074
8075function generateDomId(prefix) {
8076  const randomPart = Math.random().toString(36).slice(2, 10);
8077  return `${prefix}-${randomPart}`
8078}
8079
8080function extractPlainTextFromHtml(innerHtml = "") {
8081  return parseHtml(innerHtml).body.textContent.trim()
8082}
8083
8084function isActiveAndVisible(element) {
8085  return element && !element.disabled && checkVisibility(element)
8086}
8087
8088// no `checkVisibility` in Safari < 17.4
8089// https://developer.mozilla.org/en-US/docs/Web/API/Element/checkVisibility#browser_compatibility
8090function checkVisibility(element, options) {
8091  if (element.checkVisibility) {
8092    return element.checkVisibility(options)
8093  } else {
8094    // Will not work for body or a fixed position element child of the body
8095    // which is OK since that doesn't apply in the toolbar where this is used
8096    return Boolean(element.offsetParent)
8097  }
8098}
8099
vendor: 1,874 bytes, lines 8100-8178
8100function handleRollingTabIndex(elements, event) {
8101  const previousActiveElement = document.activeElement;
8102
8103  if (elements.includes(previousActiveElement)) {
8104    const finder = new NextElementFinder(elements, event.key);
8105
8106    if (finder.selectNext(previousActiveElement)) {
8107      event.preventDefault();
8108    }
8109  }
8110}
8111
8112class NextElementFinder {
8113  constructor(elements, key) {
8114    this.elements = elements;
8115    this.key = key;
8116  }
8117
8118  selectNext(fromElement) {
8119    const nextElement = this.#findNextElement(fromElement);
8120
8121    if (nextElement) {
8122      const inactiveElements = this.elements.filter(element => element !== nextElement);
8123      this.#unsetTabIndex(inactiveElements);
8124      this.#focusWithActiveTabIndex(nextElement);
8125      return true
8126    }
8127
8128    return false
8129  }
8130
8131  #findNextElement(fromElement) {
8132    switch (this.key) {
8133      case "ArrowRight":
8134      case "ArrowDown":
8135        return this.#findNextSibling(fromElement)
8136
8137      case "ArrowLeft":
8138      case "ArrowUp":
8139        return this.#findPreviousSibling(fromElement)
8140
8141      case "Home":
8142        return this.#findFirst()
8143
8144      case "End":
8145        return this.#findLast()
8146    }
8147  }
8148
8149  #findFirst(elements = this.elements) {
8150    return elements.find(isActiveAndVisible)
8151  }
8152
8153  #findLast(elements = this.elements) {
8154    return elements.findLast(isActiveAndVisible)
8155  }
8156
8157  #findNextSibling(element) {
8158    const afterElements = this.elements.slice(this.#indexOf(element) + 1);
8159    return this.#findFirst(afterElements)
8160  }
8161
8162  #findPreviousSibling(element) {
8163    const beforeElements = this.elements.slice(0, this.#indexOf(element));
8164    return this.#findLast(beforeElements)
8165  }
8166
8167  #indexOf(element) {
8168    return this.elements.indexOf(element)
8169  }
8170
8171  #focusWithActiveTabIndex(element) {
8172    if (isActiveAndVisible(element)) {
8173      element.tabIndex = 0;
8174      element.focus();
8175    }
8176  }
8177
8178  #unsetTabIndex(elements) {
8179    elements.forEach(element => element.tabIndex = -1);
8180  }
8181}
8182
8183var ToolbarIcons = {
8184  "bold":
8185  `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
8186    <path fill-rule="evenodd" clip-rule="evenodd" d="M9.05273 1.88232C10.6866 1.88237 12.0033 2.20353 12.9529 2.89673L13.1272 3.0293C13.974 3.70864 14.4008 4.63245 14.4009 5.76562C14.4008 6.49354 14.2316 7.15281 13.8845 7.73145C13.6683 8.09188 13.3997 8.40162 13.0818 8.66016C13.5902 8.92606 14.0196 9.28599 14.3635 9.74121C14.8586 10.3834 15.0945 11.1743 15.0945 12.0879C15.0944 13.3698 14.5922 14.3931 13.5879 15.1106L13.5857 15.1128C12.5967 15.805 11.196 16.125 9.43799 16.125H3.10547V1.88232L9.05273 1.88232ZM6.36108 13.4084H9.28418C10.224 13.4084 10.8634 13.2491 11.2581 12.9851C11.6259 12.7389 11.8198 12.3768 11.8198 11.8367C11.8197 11.2968 11.6259 10.9351 11.2581 10.689C10.8634 10.425 10.2241 10.2649 9.28418 10.2649H6.36108V13.4084ZM6.36108 7.56812H8.78247C9.5163 7.56809 10.0547 7.45371 10.429 7.25757L10.5791 7.16895C10.9438 6.92178 11.1255 6.57934 11.1255 6.09302C11.1254 5.59017 10.9414 5.25227 10.5835 5.02002L10.5784 5.01636L10.5732 5.01343C10.1994 4.75387 9.61878 4.59818 8.78247 4.59814H6.36108V7.56812Z"/>
8187  </svg>`,
8188
8189  "italic":
8190  `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
8191    <path d="M14.1379 3.91187L14.1086 4.06421H11.4668L9.49805 13.9431H12.0981L11.7473 15.7852L11.7188 15.9375H4.16675L4.51758 14.0955L4.54614 13.9431H7.18799L9.17505 4.06421H6.55664L6.90747 2.22217L6.93677 2.06982H14.4888L14.1379 3.91187Z"/>
8192  </svg>`,
8193
8194  "strikethrough":
8195  `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
8196    <path d="M14.3723 11.8015C14.3771 11.8858 14.3811 11.9756 14.3811 12.0681C14.3811 12.811 14.1777 13.4959 13.7725 14.1174L13.7717 14.1189C13.3624 14.7329 12.7463 15.2162 11.9377 15.5742L11.9348 15.5757C11.1214 15.9223 10.1306 16.092 8.96997 16.092C7.9356 16.092 6.93308 15.9348 5.96338 15.6204L5.96045 15.6189C5.00593 15.292 4.24112 14.8699 3.67676 14.3459L3.57568 14.2522L3.63501 14.1277L4.45605 12.397L4.64282 12.5654C5.13492 13.0083 5.76733 13.3759 6.54492 13.6648C7.33475 13.9406 8.14322 14.0786 8.96997 14.0786C10.0731 14.0786 10.8638 13.8932 11.3708 13.5513C11.8757 13.1982 12.1172 12.7464 12.1172 12.1838C12.1172 12.0662 12.1049 11.9556 12.0828 11.8513L12.0344 11.625H14.3621L14.3723 11.8015Z"/>
8197    <path d="M9.2981 1.91602C10.111 1.91604 10.9109 2.02122 11.6975 2.23096C12.4855 2.44111 13.1683 2.74431 13.7417 3.14429L13.8655 3.23071L13.8083 3.36987L13.1726 4.91235L13.0869 5.1189L12.8987 4.99878C12.3487 4.64881 11.761 4.38633 11.1365 4.21143L11.1328 4.20996C10.585 4.04564 10.0484 3.95419 9.52295 3.93384L9.2981 3.92944C8.22329 3.92944 7.44693 4.12611 6.94043 4.49121C6.44619 4.85665 6.20874 5.31616 6.20874 5.88135L6.21533 6.03296C6.24495 6.37662 6.37751 6.65526 6.61011 6.87964L6.72144 6.97632C6.98746 7.19529 7.30625 7.37584 7.68018 7.51538L8.05151 7.63184C8.45325 7.75061 8.94669 7.87679 9.53247 8.01123L9.53467 8.01196C10.1213 8.15305 10.6426 8.29569 11.0991 8.4375H15C15.5178 8.4375 15.9375 8.85723 15.9375 9.375C15.9375 9.89277 15.5178 10.3125 15 10.3125H3C2.48223 10.3125 2.0625 9.89277 2.0625 9.375C2.0625 8.85723 2.48223 8.4375 3 8.4375H4.93726C4.83783 8.34526 4.74036 8.24896 4.64795 8.146L4.64502 8.14233C4.1721 7.58596 3.94482 6.85113 3.94482 5.95825C3.94483 5.20441 4.14059 4.51965 4.53369 3.90967L4.53516 3.90747C4.94397 3.29427 5.55262 2.81114 6.34863 2.45288C7.15081 2.0919 8.13683 1.91602 9.2981 1.91602Z"/>
8198  </svg>`,
8199
8200  "underline":
8201  `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
8202    <path d="M14 14C14.5523 14 15 14.4477 15 15C15 15.5523 14.5523 16 14 16H4C3.44772 16 3 15.5523 3 15C3 14.4477 3.44772 14 4 14H14Z"/>
8203    <path d="M12.625 1.59375C13.25 1.59375 13.625 1.97656 13.625 2.64062V9.02344C13.625 11.4844 11.8516 13.1875 8.99219 13.1875C6.14062 13.1875 4.35938 11.4844 4.35938 9.02344V2.64062C4.35938 1.97656 4.74219 1.59375 5.36719 1.59375C6 1.59375 6.375 1.97656 6.375 2.64062V8.84375C6.375 10.3828 7.32031 11.4297 8.99219 11.4297C10.6641 11.4297 11.6172 10.3828 11.6172 8.84375V2.64062C11.6172 1.97656 11.9922 1.59375 12.625 1.59375Z"/>
8204  </svg>`,
8205
8206  "heading":
8207  `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
8208    <path d="M11.5 2C12.0523 2 12.5 2.44772 12.5 3V3.5C12.5 4.05228 12.0523 4.5 11.5 4.5H8V15C8 15.5523 7.55228 16 7 16H6.5C5.94772 16 5.5 15.5523 5.5 15V4.5H2C1.44772 4.5 1 4.05228 1 3.5V3C1 2.44772 1.44772 2 2 2H11.5ZM16 7C16.5523 7 17 7.44772 17 8V8.5C17 9.05228 16.5523 9.5 16 9.5H15V15C15 15.5523 14.5523 16 14 16H13.5C12.9477 16 12.5 15.5523 12.5 15V9.5H11.5C10.9477 9.5 10.5 9.05228 10.5 8.5V8C10.5 7.44772 10.9477 7 11.5 7H16Z"/>
8209  </svg>`,
8210
8211  "h1":
8212  `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
8213    <path d="M8.12207 4.30078C8.84668 4.30078 9.25684 4.74512 9.25684 5.51758V12.5518C9.25677 13.3241 8.84662 13.7686 8.12207 13.7686C7.39752 13.7686 6.9942 13.3309 6.99414 12.5518V9.87207H3.56934V12.5518C3.56927 13.3241 3.15912 13.7686 2.43457 13.7686C1.71002 13.7686 1.3067 13.3309 1.30664 12.5518V5.51758C1.30664 4.73828 1.70996 4.30078 2.43457 4.30078C3.15918 4.30078 3.56934 4.74512 3.56934 5.51758V8.07422H6.99414V5.51758C6.99414 4.73828 7.39746 4.30078 8.12207 4.30078ZM13.8418 4.125H14.8271C15.543 4.125 16.0449 4.56934 16.0449 5.23828V12.7207C16.0449 13.4111 15.6348 13.8486 14.9854 13.8486C14.336 13.8486 13.9395 13.418 13.9395 12.7207V6.11133H13.8887L12.9541 6.74219C12.7354 6.88574 12.5303 6.95312 12.3047 6.95312C11.7646 6.95312 11.3955 6.58398 11.3955 6.06445C11.3955 5.69531 11.5801 5.42578 11.9766 5.15625L13.4023 4.32031C13.5459 4.23633 13.6826 4.17578 13.8418 4.125Z"/>
8214  </svg>`,
8215
8216  "h2":
8217  `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
8218    <path d="M8.12207 4.30078C8.84668 4.30078 9.25684 4.74512 9.25684 5.51758V12.5518C9.25677 13.3241 8.84662 13.7686 8.12207 13.7686C7.39752 13.7686 6.9942 13.3309 6.99414 12.5518V9.87207H3.56934V12.5518C3.56927 13.3241 3.15912 13.7686 2.43457 13.7686C1.71002 13.7686 1.3067 13.3309 1.30664 12.5518V5.51758C1.30664 4.73828 1.70996 4.30078 2.43457 4.30078C3.15918 4.30078 3.56934 4.74512 3.56934 5.51758V8.07422H6.99414V5.51758C6.99414 4.73828 7.39746 4.30078 8.12207 4.30078ZM13.6445 4.19824C15.5244 4.19824 16.8984 5.34668 16.8984 6.91211C16.8984 7.8759 16.4335 8.7237 15.292 9.84473L13.3438 11.8135V11.9092H16.1875C16.8232 11.9092 17.2197 12.251 17.2197 12.8115C17.2196 13.3651 16.83 13.7002 16.187
82185 13.7002H11.5117C10.8487 13.7002 10.4112 13.3241 10.4111 12.75C10.4111 12.3399 10.6368 11.9843 11.3203 11.3145L13.6855 8.88086C14.4169 8.13583 14.7245 7.64349 14.7246 7.12402C14.7246 6.4541 14.2393 6.00293 13.5215 6.00293C12.9404 6.00293 12.5166 6.29688 12.2158 6.90527C11.9151 7.37002 11.6552 7.54785 11.2588 7.54785C10.7188 7.54785 10.3429 7.17861 10.3428 6.65918C10.3428 5.3877 11.7783 4.19824 13.6445 4.19824Z"/>
8219  </svg>`,
8220
8221  "h3":
8222  `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
8223    <path d="M13.5967 4.19824C15.5928 4.19824 16.9873 5.23047 16.9873 6.7002C16.9872 7.705 16.2421 8.60059 15.2988 8.7168V8.86719C16.4199 8.94923 17.2607 9.89942 17.2607 11.0889C17.2606 12.7362 15.7362 13.9053 13.583 13.9053C11.6827 13.9053 10.1925 12.873 10.1924 11.7041C10.1924 11.1846 10.5547 10.8154 11.0537 10.8154C11.3818 10.8154 11.6553 10.9727 11.9629 11.3555C12.3799 11.9159 12.92 12.2031 13.583 12.2031C14.4853 12.2031 15.0731 11.7313 15.0732 11C15.0732 10.2754 14.4785 9.7832 13.5898 9.7832H13.0361C12.5645 9.7832 12.2159 9.4208 12.2158 8.92188C12.2158 8.44336 12.5576 8.07422 13.0361 8.07422H13.5693C14.3075 8.07422 14.8544 7.60928 14.8545 6.97363C14.8545 6.33789 14.3213 5.90039 13.5557 5.90039C12.9678 5.90039 12.5029 6.16016 12.0859 6.71387C11.8399 7.03508 11.5527 7.17871 11.1973 7.17871C10.671 7.17871 10.295 6.82314 10.2949 6.31738C10.2949 5.18945 11.751 4.19824 13.5967 4.19824ZM8.0332 4.30078C8.75781 4.30078 9.16797 4.74512 9.16797 5.51758V12.5518C9.1679 13.3241 8.75776 13.7686 8.0332 13.7686C7.30865 13.7686 6.90534 13.3309 6.90527 12.5518V9.87207H3.48047V12.5518C3.4804 13.3241 3.07026 13.7686 2.3457 13.7686C1.62115 13.7686 1.21784 13.3309 1.21777 12.5518V5.51758C1.21777 4.73828 1.62109 4.30078 2.3457 4.30078C3.07031 4.30078 3.48047 4.74512 3.48047 5.51758V8.07422H6.90527V5.51758C6.90527 4.73828 7.30859 4.30078 8.0332 4.30078Z"/>
8224  </svg>`,
8225
8226  "h4":
8227  `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
8228    <path d="M14.6357 4.22559C15.7432 4.22559 16.4336 4.80664 16.4336 5.73633V10.3164H16.7275C17.2881 10.3164 17.6436 10.6787 17.6436 11.2256C17.6435 11.7655 17.3017 12.1006 16.7275 12.1006H16.4336V12.6611C16.4335 13.3515 16.0234 13.7891 15.374 13.7891C14.7247 13.7891 14.3282 13.3583 14.3281 12.6611V12.1006H11.04C10.2335 12.1006 9.76863 11.6766 9.76855 10.918C9.76855 10.5762 9.85064 10.3026 10.1104 9.74219C10.7666 8.42289 11.5733 7.0146 12.5713 5.54492C13.2549 4.56738 13.7812 4.22559 14.6357 4.22559ZM7.88965 4.30078C8.61426 4.30078 9.02441 4.74512 9.02441 5.51758V12.5518C9.02435 13.3241 8.6142 13.7686 7.88965 13.7686C7.1651 13.7686 6.76178 13.3309 6.76172 12.5518V9.87207H3.33691V12.5518C3.33685 13.3241 2.9267 13.7686 2.20215 13.7686C1.4776 13.7686 1.07428 13.3309 1.07422 12.5518V5.51758C1.07422 4.73828 1.47754 4.30078 2.20215 4.30078C2.92676 4.30078 3.33691 4.74512 3.33691 5.51758V8.07422H6.76172V5.51758C6.76172 4.73828 7.16504 4.30078 7.88965 4.30078ZM14.2188 6.07812C13.6035 7.02841 12.2158 9.48929 11.7988 10.2686V10.3164H14.3281V6.07812H14.2188Z"/>
8229  </svg>`,
8230
8231  "h5":
8232  `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
8233    <path d="M8.12207 4.30078C8.84668 4.30078 9.25684 4.74512 9.25684 5.51758V12.5518C9.25677 13.3241 8.84662 13.7686 8.12207 13.7686C7.39752 13.7686 6.9942 13.3309 6.99414 12.5518V9.87207H3.56934V12.5518C3.56927 13.3241 3.15912 13.7686 2.43457 13.7686C1.71002 13.7686 1.3067 13.3309 1.30664 12.5518V5.51758C1.30664 4.73828 1.70996 4.30078 2.43457 4.30078C3.15918 4.30078 3.56934 4.74512 3.56934 5.51758V8.07422H6.99414V5.51758C6.99414 4.73828 7.39746 4.30078 8.12207 4.30078ZM16.1191 4.30078C16.6934 4.30078 17.0762 4.63672 17.0762 5.16602C17.0762 5.69531 16.6934 6.03125 16.1191 6.03125H13.3457L12.9219 8.25586H13.0176C13.248 8.03711 13.6855 7.84375 14.2871 7.84375C15.9277 7.84375 17.1445 9.07422 17.1445 10.7832C17.1445 12.5605 15.8184 13.9053 13.7695 13.9053C11.9512 13.9053 10.6934 12.9277 10.5566 11.7178C10.5566 11.2021 10.9121 10.8193 11.4277 10.8193C11.8379 10.8193 12.1328 11.0244 12.3516 11.4893C12.625 12.0361 13.1133 12.2549 13.7285 12.2549C14.5488 12.2549 15.1367 11.6533 15.1367 10.7695C15.1367 9.92188 14.5625 9.31348 13.7559 9.31348C13.1953 9.31348 12.7578 9.56055 12.4629 10.0254C12.2168 10.3887 11.9355 10.5527 11.5527 10.5527C10.9648 10.5527 10.5684 10.1699 10.5684 9.55469C10.5684 9.42773 10.582 9.30762 10.6094 9.17383L11.2383 5.55273C11.3516 4.88379 11.7207 4.30078 12.6797 4.30078H16.1191Z"/>
8234  </svg>`,
8235
8236  "h6":
8237  `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
8238    <path d="M8.12207 4.30078C8.84668 4.30078 9.25684 4.74512 9.25684 5.51758V12.5518C9.25677 13.3241 8.84662 13.7686 8.12207 13.7686C7.39752 13.7686 6.9942 13.3309 6.99414 12.5518V9.87207H3.56934V12.5518C3.56927 13.3241 3.15912 13.7686 2.43457 13.7686C1.71002 13.7686 1.3067 13.3309 1.30664 12.5518V5.51758C1.30664 4.73828 1.70996 4.30078 2.43457 4.30078C3.15918 4.30078 3.56934 4.74512 3.56934 5.51758V8.07422H6.99414V5.51758C6.99414 4.73828 7.39746 4.30078 8.12207 4.30078ZM13.6719 13.9258C15.5518 13.9258 17.1445 12.37306 17.1445 10.35451V10.05763C17.1445 8.10744 16.6016 6.59574 15.5928 5.58694C14.8613 4.85544 13.8975 4.42384 12.7285 4.25294C12.4199 4.21194 12.1592 4.19824 11.8643 4.19824C11.2627 4.19824 10.8389 4.59474 10.8389 5.14164C10.8389 5.65724 11.2354 6.02054 11.7783 6.04784C12.1758 6.06834 12.4844 6.10944 12.7656 6.19144C13.5176 6.42384 14.0742 6.95314 14.3965 7.75974L14.4922 8.00584H14.3828C14.0605 7.56834 13.4863 7.25974 12.6523 7.25974C11.1406 7.25974 10.0674 8.42384 10.0674 10.
823802345V10.27736C10.0674 12.2549 11.4668 13.9258 13.6719 13.9258ZM13.5215 12.24123C12.6797 12.24123 12.0918 11.48244 12.0918 10.4131V10.1592C12.0918 9.26174 12.6523 8.71291 13.5352 8.71291C14.3965 8.71291 14.9844 9.27638 14.9844 10.1592V10.4131C14.9844 11.48244 14.3828 12.24123 13.5215 12.24123Z"/>
8239  </svg>`,
8240
8241  "paragraph":
8242  `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
8243    <path d="M9 12C9.55228 12 10 12.4477 10 13C10 13.5523 9.55228 14 9 14H3C2.44772 14 2 13.5523 2 13C2 12.4477 2.44772 12 3 12H9ZM15 8C15.5523 8 16 8.44772 16 9C16 9.55228 15.5523 10 15 10H3C2.44772 10 2 9.55228 2 9C2 8.44772 2.44772 8 3 8H15ZM15 4C15.5523 4 16 4.44772 16 5C16 5.55228 15.5523 6 15 6H3C2.44772 6 2 5.55228 2 5C2 4.44772 2.44772 4 3 4H15Z"/>
8244  </svg>`,
8245
8246  "clearFormatting":
8247  `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
8248    <path d="M10.0607 2.07533C10.8417 1.29432 12.1078 1.2943 12.8888 2.07533L16.424 5.61049C17.205 6.39154 17.205 7.65854 16.424 8.43959L9.44937 15.4142C9.07435 15.7891 8.5656 16.0001 8.03531 16.0001H5.0148C4.55074 16.0001 4.10309 15.8385 3.74722 15.547L3.60074 15.4142L1.57534 13.3888C0.79431 12.6078 0.794336 11.3417 1.57534 10.5607L10.0607 2.07533ZM2.98941 11.9747L5.0148 14.0001H8.03531L9.71792 12.3165L6.18179 8.78139L2.98941 11.9747Z"/>
8249  </svg>`,
8250
8251  "highlight":
8252  `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
8253    <path d="M16.4564 14.4272C17.1356 15.5592 16.3204 17.0002 15.0003 17.0004C13.68 17.0004 12.864 15.5593 13.5433 14.4272L15.0003 12.0004L16.4564 14.4272ZM5.1214 1.70746C5.51192 1.31693 6.14494 1.31693 6.53546 1.70746L9.7171 4.8891L13.2532 8.42426C14.2295 9.40056 14.2295 10.9841 13.2532 11.9604L9.7171 15.4955C8.74078 16.4718 7.15822 16.4718 6.18195 15.4955L2.64679 11.9604C1.67048 10.9841 1.67048 9.40057 2.64679 8.42426L6.18195 4.8891C6.30299 4.76805 6.43323 4.66177 6.57062 4.57074L5.1214 3.12152C4.73091 2.73104 4.73099 2.09799 5.1214 1.70746ZM8.30304 6.30316C8.10776 6.10815 7.79119 6.10799 7.59601 6.30316L4.06085 9.83929L3.9964 9.91742C3.88661 10.0838 3.88645 10.3019 3.9964 10.4682L4.02277 10.5004H11.8763C12.0312 10.3043 12.02 10.0205 11.8392 9.83929L8.30304 6.30316Z"/>
8254  </svg>`,
8255
8256  "link":
8257  `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
8258    <path d="M12.8885 7.23091L13.9479 6.17155C14.5337 5.58576 14.5337 4.63602 13.9479 4.05023C13.3621 3.46444 12.4124 3.46444 11.8266 4.05023L8.29235 7.58446C7.9263 7.95051 7.90312 8.52994 8.2233 8.92271L8.36141 9.07463C8.68158 9.4674 8.65841 10.0468 8.29235 10.4129C7.90183 10.8034 7.26866 10.8034 6.87814 10.4129C5.70657 9.24131 5.70657 7.34182 6.87814 6.17025L10.4124 2.63602C11.7792 1.26918 13.9953 1.26918 15.3621 2.63602C16.729 4.00285 16.729 6.21893 15.3621 7.58576L14.3028 8.64512C13.9122 9.03564 13.2791 9.03564 12.8885 8.64512C12.498 8.2546 12.498 7.62143 12.8885 7.23091Z"/>
8259    <path d="M5.11038 10.7664L4.04843 11.8284C3.46264 12.4142 3.46264 13.3639 4.04842 13.9497C4.63421 14.5355 5.58396 14.5355 6.16975 13.9497L9.70657 10.4129C10.0726 10.0468 10.0958 9.46741 9.77563 9.07464L9.63752 8.92272C9.31734 8.52995 9.34052 7.95052 9.70657 7.58446C10.0971 7.19394 10.7303 7.19394 11.1208 7.58446C12.2924 8.75604 12.2924 10.6555 11.1208 11.8271L7.58396 15.3639C6.21712 16.7308 4.00105 16.7308 2.63421 15.3639C1.26738 13.9971 1.26738 11.781 2.63421 10.4142L3.69617 9.35223C4.08669 8.96171 4.71986 8.96171 5.11038 9.35223C5.5009 9.74275 5.5009 10.3759 5.11038 10.7664Z"/>
8260  </svg>`,
8261
8262  "quote":
8263  `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
8264    <path d="M4.96387 4.23438C6.8769 4.23438 8.42767 5.78522 8.42773 7.69824C8.42773 8.32925 8.25769 8.92015 7.96289 9.42969L7.96387 9.43066L5.11816 14.3584C4.77659 14.95 4.02038 15.153 3.42871 14.8115C2.83701 14.4699 2.63397 13.7128 2.97559 13.1211L4.16113 11.0674C2.63532 10.7052 1.5 9.33485 1.5 7.69824C1.50006 5.78524 3.05086 4.2344 4.96387 4.23438ZM13.0361 4.23438C14.9491 4.23449 16.4999 5.7853 16.5 7.69824C16.5 8.32921 16.3299 8.92017 16.0352 9.42969L16.0361 9.43066L13.1904 14.3584C12.8488 14.9501 12.0917 15.1531 11.5 14.8115C10.9085 14.4698 10.7063 13.7127 11.0479 13.1211L12.2324 11.0674C10.7069 10.7049 9.57227 9.33461 9.57227 7.69824C9.57233 5.78522 11.1231 4.23438 13.0361 4.23438Z"/>
8265  </svg>`,
8266
8267  "code":
8268  `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
8269    <path d="M6.29289 3.79295C6.68342 3.40243 7.31643 3.40243 7.70696 3.79295C8.09748 4.18348 8.09748 4.81649 7.70696 5.20702L3.91399 8.99999L7.70696 12.793C8.09748 13.1835 8.09748 13.8165 7.70696 14.207C7.31643 14.597
82695 6.68342 14.5975 6.29289 14.207L1.79289 9.70702C1.40237 9.31649 1.40237 8.68348 1.79289 8.29295L6.29289 3.79295Z"/>
8270    <path d="M11.707 3.79295C11.3164 3.40243 10.6834 3.40243 10.2929 3.79295C9.90237 4.18348 9.90237 4.81649 10.2929 5.20702L14.0859 8.99999L10.2929 12.793C9.90237 13.1835 9.90237 13.8165 10.2929 14.207C10.6834 14.5975 11.3164 14.5975 11.707 14.207L16.207 9.70702C16.5975 9.31649 16.5975 8.68348 16.207 8.29295L11.707 3.79295Z"/>
8271  </svg>`,
8272
8273  "ul":
8274  `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
8275    <path d="M3 12.5C3.82843 12.5 4.5 13.1716 4.5 14C4.5 14.8284 3.82843 15.5 3 15.5C2.17157 15.5 1.5 14.8284 1.5 14C1.5 13.1716 2.17157 12.5 3 12.5ZM15.5 13C16.0523 13 16.5 13.4477 16.5 14C16.5 14.5523 16.0523 15 15.5 15H7C6.44772 15 6 14.5523 6 14C6 13.4477 6.44772 13 7 13H15.5ZM3 7.5C3.82843 7.5 4.5 8.17157 4.5 9C4.5 9.82843 3.82843 10.5 3 10.5C2.17157 10.5 1.5 9.82843 1.5 9C1.5 8.17157 2.17157 7.5 3 7.5ZM15.5 8C16.0523 8 16.5 8.44772 16.5 9C16.5 9.55228 16.0523 10 15.5 10H7C6.44772 10 6 9.55228 6 9C6 8.44772 6.44772 8 7 8H15.5ZM3 2.5C3.82843 2.5 4.5 3.17157 4.5 4C4.5 4.82843 3.82843 5.5 3 5.5C2.17157 5.5 1.5 4.82843 1.5 4C1.5 3.17157 2.17157 2.5 3 2.5ZM15.5 3C16.0523 3 16.5 3.44772 16.5 4C16.5 4.55228 16.0523 5 15.5 5H7C6.44772 5 6 4.55228 6 4C6 3.44772 6.44772 3 7 3H15.5Z"/>
8276  </svg>`,
8277
8278  "ol":
8279  `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
8280    <path d="M15.5 13C16.0523 13 16.5 13.4477 16.5 14C16.5 14.5523 16.0523 15 15.5 15H7C6.44772 15 6 14.5523 6 14C6 13.4477 6.44772 13 7 13H15.5ZM15.5 8C16.0523 8 16.5 8.44772 16.5 9C16.5 9.55228 16.0523 10 15.5 10H7C6.44772 10 6 9.55228 6 9C6 8.44772 6.44772 8 7 8H15.5ZM15.5 3C16.0523 3 16.5 3.44772 16.5 4C16.5 4.55228 16.0523 5 15.5 5H7C6.44772 5 6 4.55228 6 4C6 3.44772 6.44772 3 7 3H15.5Z"/>
8281    <path d="M2.98657 16.0967C2.68042 16.0967 2.41187 16.0465 2.18091 15.9463C1.95174 15.846 1.77002 15.7046 1.63574 15.522C1.50146 15.3376 1.42448 15.1227 1.40479 14.8774L1.4021 14.8452H2.34204L2.34741 14.8748C2.35815 14.9589 2.39038 15.035 2.44409 15.103C2.49959 15.1711 2.5721 15.2248 2.66162 15.2642C2.75293 15.3035 2.86035 15.3232 2.98389 15.3232C3.10563 15.3232 3.21037 15.3027 3.2981 15.2615C3.38761 15.2185 3.45654 15.1603 3.50488 15.0869C3.55322 15.0135 3.57739 14.9294 3.57739 14.8345V14.8291C3.57739 14.6715 3.51921 14.5516 3.40283 14.4692C3.28646 14.3869 3.12085 14.3457 2.90601 14.3457H2.48706V13.677H2.90063C3.02775 13.677 3.13607 13.6582 3.22559 13.6206C3.31689 13.583 3.38672 13.5302 3.43506 13.4622C3.48519 13.3941 3.51025 13.3153 3.51025 13.2258V13.2205C3.51025 13.1256 3.48877 13.0441 3.4458 12.9761C3.40462 12.9062 3.34375 12.8534 3.26318 12.8176C3.18441 12.78 3.08952 12.7612 2.97852 12.7612C2.86572 12.7612 2.76636 12.7809 2.68042 12.8203C2.59627 12.8579 2.52913 12.9125 2.479 12.9841C2.43066 13.054 2.40112 13.1363 2.39038 13.2312L2.3877 13.2581H1.49341L1.49609 13.2205C1.514 12.977 1.58561 12.7666 1.71094 12.5894C1.83805 12.4103 2.00903 12.2725 2.22388 12.1758C2.44051 12.0773 2.69206 12.0281 2.97852 12.0281C3.27393 12.0281 3.52995 12.0728 3.74658 12.1624C3.96322 12.2501 4.13062 12.3727 4.24878 12.5303C4.36694 12.6878 4.42603 12.8722 4.42603 13.0835V13.0889C4.42603 13.2518 4.38932 13.3941 4.31592 13.5159C4.2443 13.6358 4.14762 13.7343 4.02588 13.8113C3.90592 13.8883 3.77254 13.942 3.62573 13.9724V13.9912C3.91756 14.0199 4.14941 14.1121 4.32129 14.2678C4.49316 14.4236 4.5791 14.6295 4.5791 14.8855V14.8909C4.5791 15.1344 4.51375 15.3474 4.38306 15.53C4.25236 15.7109 4.06795 15.8505 3.82983 15.949C3.59172 16.0474 3.31063 16.0967 2.98657 16.0967Z"/>
8282    <path d="M1.54443 11V10.342L2.76099 9.20874C2.95076 9.03507 3.09757 8.89274 3.20142 8.78174C3.30705 8.66895 3.37956 8.57316 3.41895 8.49438C3.46012 8.41382 3.48071 8.33415 3.48071 8.25537V8.24463C3.48071 8.14795 3.46012 8.0638 3.41895 7.99219C3.37777 7.92057 3.31779 7.86507 3.23901 7.82568C3.16024 7.7863 3.06714 7.7666 2.95972 7.7666C2.84692 7.7666 2.74756 7.78988 2.66162 7.83643C2.57747 7.88298 2.51123 7.94743 2.46289 8.02979C2.41455 8.11035 2.39038 8.20345 2.39038 8.30908V8.33057L1.48804 8.32788V8.31177C1.48804 8.05396 1.5507 7.82837 1.67603 7.63501C1.80314 7.44165 1.97949 7.29126 2.20508 7.18384C2.43245 7.07463 2.69653 7.02002 2.99731 7.02002C3.28556 7.02002 3.53711 7.06836 3.75195 7.16504C3.96859 7.25993 4.13688 7.39331 4.25684 7.56519C4.37858 7.73706 4.43945 7.93758 4.43945 8.16675V8.18018C4.43945 8.3252 4.40902 8.46932 4.34814 8.61255C4.28727 8.75578 4.18701 8.90885 4.04736 9.07178C3.90771 9.23291 3.71883 9.41642 3.48071 9.62231L2.58374 10.4092L2.85498 9.98486V10.4092L2.58374 10.2319H4.49048V11H1.54443Z"/>
8283    <path d="M2.84155 6V3.01367H2.79053L1.85596 3.64478V2.79614L2.84155 2.12476H3.82715V6H2.84155Z"/>
8284  </svg>`,
8285
8286  "image":
8287  `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
8288    <path d="M14 2C15.6569 2 17 3.34315 17 5V13C17 14.6569 15.6569 
828816 14 16H4C2.34315 16 1 14.6569 1 13V5C1 3.34315 2.34315 2 4 2H14ZM3.06348 13.3496C3.2053 13.7294 3.57078 14 4 14H13.5859L11 11.4141L9.70703 12.707C9.31651 13.0976 8.68349 13.0976 8.29297 12.707C7.90244 12.3165 7.90244 11.6835 8.29297 11.293L8.58594 11L7 9.41406L3.06348 13.3496ZM4 4C3.44772 4 3 4.44772 3 5V10.5859L6.29297 7.29297L6.36914 7.22461C6.76191 6.90427 7.34092 6.92686 7.70703 7.29297L10 9.58594L10.293 9.29297L10.3691 9.22461C10.7619 8.90427 11.3409 8.92686 11.707 9.29297L15 12.5859V5C15 4.44772 14.5523 4 14 4H4ZM12.5 5C13.3284 5 14 5.67157 14 6.5C14 7.32843 13.3284 8 12.5 8C11.6716 8 11 7.32843 11 6.5C11 5.67157 11.6716 5 12.5 5Z"/>
8289  </svg>`,
8290
8291  "attachment":
8292  `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
8293    <path d="M13 13.5V6C13 4.067 11.433 2.5 9.5 2.5C7.567 2.5 6 4.067 6 6V13.5C6 14.6046 6.89543 15.5 8 15.5H8.23047C9.20759 15.5 10 14.7076 10 13.7305V7C10 6.72386 9.77614 6.5 9.5 6.5C9.22386 6.5 9 6.72386 9 7V12.5C9 13.0523 8.55228 13.5 8 13.5C7.44772 13.5 7 13.0523 7 12.5V7C7 5.61929 8.11929 4.5 9.5 4.5C10.8807 4.5 12 5.61929 12 7V13.7305C12 15.8122 10.3122 17.5 8.23047 17.5H8C5.79086 17.5 4 15.7091 4 13.5V6C4 2.96243 6.46243 0.5 9.5 0.5C12.5376 0.5 15 2.96243 15 6V13.5C15 14.0523 14.5523 14.5 14 14.5C13.4477 14.5 13 14.0523 13 13.5Z"/>
8294  </svg>`,
8295
8296  "table":
8297  `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
8298    <path d="M15 1C16.1046 1 17 1.89543 17 3V15C17 16.1046 16.1046 17 15 17H3C1.89543 17 1 16.1046 1 15V3C1 1.89543 1.89543 1 3 1H15ZM3 15H8V10H3V15ZM10 10V15H15V10H10ZM10 8H15V3H10V8ZM3 8H8V3H3V8Z"/>
8299  </svg>`,
8300
8301  "hr":
8302  `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
8303    <path d="M12.75 12C13.1642 12 13.5 12.3358 13.5 12.75V14.25C13.5 14.6642 13.1642 15 12.75 15H5.25C4.83579 15 4.5 14.6642 4.5 14.25V12.75C4.5 12.3358 4.83579 12 5.25 12H12.75ZM15.4863 8C16.0461 8 16.5 8.44771 16.5 9C16.5 9.55229 16.0461 10 15.4863 10H2.51367C1.95392 10 1.5 9.55229 1.5 9C1.5 8.44771 1.95392 8 2.51367 8H15.4863ZM12.75 3C13.1642 3 13.5 3.33579 13.5 3.75V5.25C13.5 5.66421 13.1642 6 12.75 6H5.25C4.83579 6 4.5 5.66421 4.5 5.25V3.75C4.5 3.33579 4.83579 3 5.25 3H12.75Z"/>
8304  </svg>`,
8305
8306  "undo":
8307  `<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
8308    <path d="M8.36612 5.36612C8.85427 4.87796 9.64554 4.87796 10.1337 5.36612C10.6218 5.85428 10.6218 6.64557 10.1337 7.13369L7.26748 9.9999H15.2499C18.1494 9.99996 20.4999 12.3504 20.4999 15.2499V19.2499C20.4999 19.9402 19.9402 20.4999 19.2499 20.4999C18.5596 20.4999 18 19.9402 17.9999 19.2499V15.2499C17.9999 13.7312 16.7686 12.5 15.2499 12.4999H7.26748L10.1337 15.3661C10.6218 15.8543 10.6218 16.6456 10.1337 17.1337C9.64557 17.6218 8.85428 17.6218 8.36612 17.1337L3.36612 12.1337C2.87796 11.6455 2.87796 10.8543 3.36612 10.3661L8.36612 5.36612Z"/>
8309  </svg>`,
8310
8311  "redo":
8312  `<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
8313    <path d="M15.6338 5.1163C15.1456 4.62814 14.3543 4.62814 13.8662 5.1163C13.3781 5.60446 13.3781 6.39575 13.8662 6.88388L16.7324 9.75009H8.74997C5.85052 9.75014 3.49997 12.1006 3.49997 15.0001V19.0001C3.50002 19.6904 4.05969 20.25 4.74997 20.2501C5.4403 20.2501 5.99992 19.6904 5.99997 19.0001V15.0001C5.99997 13.4813 7.23123 12.2501 8.74997 12.2501H16.7324L13.8662 15.1163C13.3781 15.6045 13.3781 16.3958 13.8662 16.8839C14.3543 17.372 15.1456 17.3719 15.6338 16.8839L20.6338 11.8839C21.1219 11.3957 21.1219 10.6045 20.6338 10.1163L15.6338 5.1163Z" />
8314  </svg>`,
8315
8316  "overflow":
8317  `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
8318    <path d="M3 6.75C4.24264 6.75 5.25 7.75736 5.25 9C5.25 10.2426 4.24264 11.25 3 11.25C1.75736 11.25 0.75 10.2426 0.75 9C0.75 7.75736 1.75736 6.75 3 6.75ZM9 6.75C10.2426 6.75 11.25 7.75736 11.25 9C11.25 10.2426 10.2426 11.25 9 11.25C7.75736 11.25 6.75 10.2426 6.75 9C6.75 7.75736 7.75736 6.75 9 6.75ZM15 6.75C16.2426 6.75 17.25 7.75736 17.25 9C17.25 10.2426 16.2426 11.25 15 11.25C13.7574 11.25 12.75 10.2426 12.75 9C12.75 7.75736 13.7574 6.75 15 6.75Z"/>
8319  </svg>`
8320};
8321
8322class LexicalToolbarElement extends HTMLElement {
8323  static observedAttributes = [ "connected" ]
8324  #listeners = new ListenerBin()
8325  #refreshToolbarAF = null
8326
8327  constructor() {
8328    super();
8329    this.internals = this.attachInternals();
8330    this.internals.role = "toolbar";
8331
8332    this.#createEditorPromise();
8333  }
8334
8335  connectedCallback() {
8336    this.requestOverflowRefresh();
8337    this.setAttribute("role", "toolbar");
8338    this.#installResizeObserver();
8339  }
8340
8341  disconnectedCallback() {
8342    this.dispose();
8343  }
8344
8345  dispose() {
8346    this.#listeners.dispose();
8347
8348    cancelAnimationFrame(this.#refreshToolbarAF);
8349
8350    this.editorElement = null;
8351    this.editor = null;
8352    this.selection = null;
8353    this.#refreshToolbarAF = null;
8354
8355    this.#createEditorPromise();
8356  }
8357
8358  attributeChangedCallback(name, oldValue, newValue) {
8359    if (name === "connected" && this.isConnected && oldValue != null && oldValue !== newValue) {
8360      requestAnimationFrame(() => this.#reconnect());
8361    }
8362  }
8363
8364  configure(config) {
8365    if (typeof config === "object" && config !== null) {
8366      for (const [ button, value ] of Object.entries(config)) {
8367        this.setAttribute(`data-${button}`, value);
8368      }
8369    }
8370  }
8371
8372  setEditor(editorElement) {
8373    this.editorElement = editorElement;
8374    this.editor = editorElement.editor;
8375    this.selection = editorElement.selection;
8376    this.#bindButtons();
8377    this.#bindHotkeys();
8378    this.#resetTabIndexValues();
8379    this.#monitorSelectionChanges();
8380    this.#monitorHistoryChanges();
8381    this.requestOverflowRefresh();
8382    this.#bindFocusListeners();
8383
8384    this.resolveEditorPromise(editorElement);
8385
8386    this.toggleAttribute("connected", true);
8387  }
8388
8389  async getEditorElement() {
8390    return this.editorElement || await this.editorPromise
8391  }
8392
8393  requestOverflowRefresh() {
8394    if (this.#refreshToolbarAF != null) return
8395
8396    this.#refreshToolbarAF = requestAnimationFrame(() => {
8397      this.#refreshOverflow();
8398      this.#refreshToolbarAF = null;
8399    });
8400  }
8401
8402  closeDropdowns({ except } = {}) {
8403    this.#dropdowns.forEach((dropdown) => {
8404      if (dropdown !== except) {
8405        dropdown.close({ focusEditor: false });
8406      }
8407    });
8408  }
8409
8410  #reconnect() {
8411    this.disconnectedCallback();
8412    this.connectedCallback();
8413  }
8414
8415  async #createEditorPromise() {
8416    this.editorPromise = new Promise((resolve) => {
8417      this.resolveEditorPromise = resolve;
8418    });
8419
8420    this.editorElement = await this.editorPromise;
8421  }
8422
8423  #installResizeObserver() {
8424    const resizeObserver = new ResizeObserver(() => this.requestOverflowRefresh());
8425    resizeObserver.observe(this);
8426    this.#listeners.track(() => resizeObserver.disconnect());
8427  }
8428
8429  #bindButtons() {
8430    this.#listeners.track(registerEventListener(this, "click", this.#handleButtonClicked));
8431  }
8432
8433  #handleButtonClicked = (event) => {
8434    this.#handleTargetClicked(event, "[data-command]", this.#dispatchButtonCommand.bind(this));
8435  }
8436
8437  #handleTargetClicked(event, selector, callback) {
8438    const button = event.target.closest(selector);
8439    if (button) {
8440      callback(event, button);
8441    }
8442  }
8443
8444  #dispatchButtonCommand(event, { dataset: { command, payload } }) {
8445    const isKeyboard = event instanceof PointerEvent && event.pointerId === -1;
8446
8447    this.editor.update(() => {
8448      this.editor.dispatchCommand(command, payload);
8449    }, { tag: isKeyboard ? qn : undefined });
8450
8451    if (!isKeyboard) this.editor.focus();
8452  }
8453
8454  #bindHotkeys() {
8455    this.#listeners.track(registerEventListener(this.editorElement, "keydown", this.#handleHotkey));
8456  }
8457
8458  #handleHotkey = (event) => {
8459    const buttons = this.querySelectorAll("[data-hotkey]");
8460    buttons.forEach((button) => {
8461      const hotkeys = button.dataset.hotkey.toLowerCase().split(/\s+/);
8462      if (hotkeys.includes(this.#keyCombinationFor(event))) {
8463        event.preventDefault();
8464        event.stopPropagation();
8465        button.click();
8466      }
8467    });
8468  }
8469
8470  #keyCombinationFor(event) {
8471    const pressedKey = event.key.toLowerCase();
8472    const modifiers = [
8473      event.ctrlKey ? "ctrl" : null,
8474      event.metaKey ? "cmd" : null,
8475      event.altKey ? "alt" : null,
8476      event.shiftKey ? "shift" : null,
vendor: 8,058 bytes, lines 8477-8722
8477    ].filter(Boolean);
8478
8479    return [ ...modifiers, pressedKey ].join("+")
8480  }
8481
8482  #bindFocusListeners() {
8483    this.#listeners.track(
8484      registerEventListener(this.editorElement, "lexxy:focus", this.#handleEditorFocus),
8485      registerEventListener(this.editorElement, "lexxy:blur", this.#handleEditorBlur),
8486      registerEventListener(this, "keydown", this.#handleKeydown)
8487    );
8488  }
8489
8490  #handleEditorFocus = () => {
8491    const firstVisible = this.#buttons.find(isActiveAndVisible);
8492    if (firstVisible) firstVisible.tabIndex = 0;
8493  }
8494
8495  #handleEditorBlur = () => {
8496    this.#resetTabIndexValues();
8497  }
8498
8499  #handleKeydown = (event) => {
8500    handleRollingTabIndex(this.#buttons, event);
8501  }
8502
8503  #resetTabIndexValues() {
8504    this.#buttons.forEach((button) => {
8505      button.tabIndex = -1;
8506    });
8507  }
8508
8509  #monitorSelectionChanges() {
8510    this.#listeners.track(this.editor.registerUpdateListener(({ editorState }) => {
8511      editorState.read(() => {
8512        this.#updateButtonStates();
8513        this.closeDropdowns();
8514      });
8515    }));
8516  }
8517
8518  #monitorHistoryChanges() {
8519    this.#listeners.track(
8520      this.editor.registerCommand(He$2, (enabled) => { this.#setButtonDisabled("undo", !enabled); }, io),
8521      this.editor.registerCommand(qe$2, (enabled) => { this.#setButtonDisabled("redo", !enabled); }, io),
8522    );
8523  }
8524
8525  #updateButtonStates() {
8526    const selection = Qr();
8527    if (!Fr(selection)) return
8528
8529    const anchorNode = selection.anchor.getNode();
8530    if (!anchorNode.getParent()) { return }
8531
8532    const { isBold, isItalic, isStrikethrough, isUnderline, isHighlight, isInLink, isInQuote, isInHeading,
8533      headingTag, isInCode, isInList, listType, isInTable } = this.selection.getFormat();
8534
8535    this.#setButtonPressed("bold", isBold);
8536    this.#setButtonPressed("italic", isItalic);
8537    this.#setButtonPressed("strikethrough", isStrikethrough);
8538    this.#setButtonPressed("underline", isUnderline);
8539
8540    this.#setButtonPressed("format", isInHeading);
8541    this.#setButtonPressed("paragraph", !isInHeading);
8542
8543    this.querySelector("lexxy-heading-dropdown")
8544      ?.updateActiveHeading(headingTag);
8545
8546    this.#setButtonPressed("lists", isInList);
8547    this.#setButtonPressed("unordered-list", isInList && listType === "bullet");
8548    this.#setButtonPressed("ordered-list", isInList && listType === "number");
8549
8550    this.#setButtonPressed("highlight", isHighlight);
8551    this.#setButtonPressed("link", isInLink);
8552    this.#setButtonPressed("quote", isInQuote);
8553    this.#setButtonPressed("code", isInCode);
8554
8555    this.#setButtonPressed("table", isInTable);
8556  }
8557
8558  #setButtonPressed(name, isPressed) {
8559    const button = this.querySelector(`[name="${name}"]`);
8560    if (button) {
8561      const next = isPressed.toString();
8562      if (button.getAttribute("aria-pressed") !== next) {
8563        button.setAttribute("aria-pressed", next);
8564      }
8565    }
8566  }
8567
8568  #setButtonDisabled(name, isDisabled) {
8569    const button = this.querySelector(`[name="${name}"]`);
8570    if (button) {
8571      if (button.disabled !== isDisabled) {
8572        button.disabled = isDisabled;
8573      }
8574      const next = isDisabled.toString();
8575      if (button.getAttribute("aria-disabled") !== next) {
8576        button.setAttribute("aria-disabled", next);
8577      }
8578    }
8579  }
8580
8581  #refreshOverflow() {
8582    this.#hideOverflowMenuButton();
8583    this.#resetToolbarOverflow();
8584    this.#reindexToolbarItems();
8585    this.#compactMenu();
8586
8587    const isOverflowing = this.#overflowMenuDropdown.children.length > 0;
8588
8589    this.toggleAttribute("overflowing", isOverflowing);
8590    this.#setOverflowMenuNonce();
8591    this.#showOverflowMenuButton(isOverflowing);
8592  }
8593
8594  #resetToolbarOverflow() {
8595    const items = Array.from(this.#overflowMenuDropdown.children);
8596    items.sort((a, b) => this.#itemPosition(b) - this.#itemPosition(a));
8597
8598    for (const item of items) {
8599      const nextItem = this.querySelector(`[data-position="${this.#itemPosition(item) + 1}"]`) ?? this.#overflowMenuButton;
8600      item.removeAttribute("role");
8601      this.insertBefore(item, nextItem);
8602    }
8603  }
8604
8605  #showOverflowMenuButton(show = true) {
8606    this.#overflowMenuDropdown.toggleAttribute("disabled", !show);
8607    this.#overflowMenuButton.style.display = show ? "block" : "none";
8608  }
8609
8610  #hideOverflowMenuButton() {
8611    this.#showOverflowMenuButton(false);
8612  }
8613
8614  #itemPosition(item) {
8615    return parseInt(item.dataset.position ?? "999")
8616  }
8617
8618  #reindexToolbarItems() {
8619    this.#toolbarItems.forEach((item, index) => {
8620      item.dataset.position = index;
8621    });
8622  }
8623
8624  #compactMenu() {
8625    const overflowWidth = this.#getOverflowWidth();
8626
8627    if (overflowWidth > 0) {
8628      this.#showOverflowMenuButton();
8629      const gap = this.#getToolbarGap();
8630      const spaceForOverflow = gap + this.#overflowMenuButton.offsetWidth;
8631      this.#reclaimWidth(overflowWidth + spaceForOverflow, { gap });
8632    }
8633  }
8634
8635  #getOverflowWidth() {
8636    return this.scrollWidth - this.clientWidth
8637  }
8638
8639  #reclaimWidth(overflowWidth, { gap }) {
8640    const buttons = this.#overflowableButtons;
8641    const overflowButtons = [];
8642    let recoveredWidth = 0;
8643
8644    while (recoveredWidth < overflowWidth && buttons.length) {
8645      const button = buttons.pop();
8646
8647      overflowButtons.push(button);
8648      button.role = "menuitem";
8649      recoveredWidth += button.offsetWidth + gap;
8650    }
8651
8652    this.#overflowMenuDropdown.append(...overflowButtons.reverse());
8653  }
8654
8655  #setOverflowMenuNonce() {
8656    this.#overflowMenuButton.setAttribute("nonce", getNonce());
8657  }
8658
8659  #getToolbarGap() {
8660    return parseFloat(window.getComputedStyle(this).columnGap) || 0
8661  }
8662
8663  get #dropdowns() {
8664    return this.querySelectorAll(":scope .lexxy-editor__toolbar-dropdown")
8665  }
8666
8667  get #overflowMenuButton() {
8668    return this.querySelector(".lexxy-editor__toolbar-overflow")
8669  }
8670
8671  get #overflowMenuDropdown() {
8672    return this.#overflowMenuButton?.querySelector(":scope > [data-dropdown-panel]")
8673  }
8674
8675  get #overflowableButtons() {
8676    return Array.from(this.querySelectorAll(":scope > button:not([data-prevent-overflow])"))
8677  }
8678
8679  get #buttons() {
8680    return Array.from(this.querySelectorAll(":scope button"))
8681  }
8682
8683  get #toolbarItems() {
8684    return Array.from(this.querySelectorAll(":scope > *:not(.lexxy-editor__toolbar-overflow)"))
8685  }
8686
8687  static get defaultTemplate() {
8688    const linkInputId = generateDomId("lexxy-link-url");
8689
8690    return `
8691      <button class="lexxy-editor__toolbar-button" type="button" name="image" data-command="uploadImage" data-prevent-overflow="true" title="Add images and video">
8692        ${ToolbarIcons.image}
8693      </button>
8694
8695      <button class="lexxy-editor__toolbar-button lexxy-editor__toolbar-group-end" type="button" name="file" data-command="uploadFile" title="Upload files">
8696        ${ToolbarIcons.attachment}
8697      </button>
8698
8699      <button class="lexxy-editor__toolbar-button" type="button" name="bold" data-command="bold" title="Bold">
8700        ${ToolbarIcons.bold}
8701      </button>
8702
8703      <button class="lexxy-editor__toolbar-button" type="button" name="italic" data-command="italic" title="Italic">
8704      ${ToolbarIcons.italic}
8705      </button>
8706
8707      <button class="lexxy-editor__toolbar-button" type="button" name="strikethrough" data-command="strikethrough" title="Strikethrough">
8708        ${ToolbarIcons.strikethrough}
8709      </button>
8710
8711      <button class="lexxy-editor__toolbar-button lexxy-editor__toolbar-group-end" type="button" name="underline" data-command="underline" title="Underline">
8712        ${ToolbarIcons.underline}
8713      </button>
8714
8715      <lexxy-toolbar-dropdown class="lexxy-editor__toolbar-dropdown">
8716        <button data-dropdown-trigger class="lexxy-editor__toolbar-button lexxy-editor__toolbar-button--chevron" type="button" name="format" title="Text formatting" aria-haspopup="menu" aria-expanded="false">
8717          ${ToolbarIcons.heading}
8718        </button>
8719        <div data-dropdown-panel role="menu" class="lexxy-editor__toolbar-dropdown-list" hidden>
8720          <button type="button" name="paragraph" data-command="setFormatParagraph" title="Paragraph" role="menuitem">
8721            ${ToolbarIcons.paragraph} <span>Normal</span>
8722          </button>
8723          <lexxy-heading-dropdown>
8724            <div class="lexxy-heading-options"></div>
8725          </lexxy-heading-dropdown>
8726          <div class="lexxy-editor__toolbar-separator" role="separator"></div>
8727          <button type="button" name="clear-formatting" data-command="clearFormatting" title="Clear formatting" role="menuitem">
8728            ${ToolbarIcons.clearFormatting} <span>Clear formatting</span>
8729          </button>
8730        </div>
8731      </lexxy-toolbar-dropdown>
8732
8733      <lexxy-highlight-dropdown class="lexxy-editor__toolbar-dropdown lexxy-editor__toolbar-dropdown--highlight">
8734        <button data-dropdown-trigger class="lexxy-editor__toolbar-button lexxy-editor__toolbar-button--chevron" type="button" name="highlight" title="Color highlight" aria-haspopup="menu" aria-expanded="false">
8735          ${ToolbarIcons.highlight}
8736        </button>
8737        <div data-dropdown-panel role="menu" hidden>
8738          <div class="lexxy-highlight-colors"></div>
8739          <button data-command="removeHighlight" type="button" class="lexxy-editor__toolbar-button lexxy-editor__toolbar-dropdown-reset" role="menuitem">Remove all coloring</button>
8740        </div>
8741      </lexxy-highlight-dropdown>
8742
8743      <lexxy-link-dropdown class="lexxy-editor__toolbar-dropdown lexxy-editor__toolbar-dropdown--link">
8744        <button data-dropdown-trigger class="lexxy-editor__toolbar-button lexxy-editor__toolbar-group-end" type="button" name="link" title="Link" data-hotkey="cmd+k ctrl+k" aria-haspopup="dialog" aria-expanded="false">
8745          ${ToolbarIcons.link}
8746        </button>
8747        <div data-dropdown-panel role="dialog" aria-label="Link" hidden>
8748          <input type="url" placeholder="Enter a URL…" class="input" id="${linkInputId}">
8749          <div class="lexxy-editor__toolbar-dropdown-actions">
8750            <button type="button" class="lexxy-editor__toolbar-button" value="link">Link</button>
8751            <button type="button" class="lexxy-editor__toolbar-button" value="unlink">Unlink</button>
8752          </div>
8753        </div>
8754      </lexxy-link-dropdown>
8755
8756      <button class="lexxy-editor__toolbar-button" type="button" name="quote" data-command="insertQuoteBlock" title="Quote">
8757        ${ToolbarIcons.quote}
8758      </button>
8759
8760      <button class="lexxy-editor__toolbar-button" type="button" name="code" data-command="insertCodeBlock" title="Code">
8761        ${ToolbarIcons.code}
8762      </button>
8763
8764      <button class="lexxy-editor__toolbar-button" type="button" name="unordered-list" data-command="insertUnorderedList" title="Bullet list">
8765        ${ToolbarIcons.ul}
8766      </button>
8767      <button class="lexxy-editor__toolbar-button lexxy-editor__toolbar-group-end" type="button" name="ordered-list" data-command="insertOrderedList" title="Numbered list">
8768        ${ToolbarIcons.ol}
8769      </button>
8770
8771      <button class="lexxy-editor__toolbar-button" type="button" name="table" data-command="insertTable" title="Insert a table">
8772        ${ToolbarIcons.table}
8773      </button>
8774
8775      <button class="lexxy-editor__toolbar-button" type="button" name="divider" data-command="insertHorizontalDivider" title="Insert a divider">
8776        ${ToolbarIcons.hr}
8777      </button>
8778
8779      <button class="lexxy-editor__toolbar-button lexxy-editor__toolbar-button--push-right" type="button" name="undo" data-command="undo" title="Undo" disabled aria-disabled="true">
8780        ${ToolbarIcons.undo}
8781      </button>
8782
8783      <button class="lexxy-editor__toolbar-button" type="button" name="redo" data-command="redo" title="Redo" disabled aria-disabled="true">
8784        ${ToolbarIcons.redo}
8785      </button>
8786
8787      <lexxy-toolbar-dropdown class="lexxy-editor__toolbar-dropdown lexxy-editor__toolbar-button--push-right lexxy-editor__toolbar-overflow">
8788        <button data-dropdown-trigger class="lexxy-editor__toolbar-button" type="button" aria-haspopup="menu" aria-expanded="false" aria-label="Show more toolbar buttons">
8789          ${ToolbarIcons.overflow}
8790        </button>
8791        <div data-dropdown-panel role="menu" class="lexxy-editor__toolbar-overflow-menu" aria-label="More toolbar buttons" hidden></div>
8792      </lexxy-toolbar-dropdown>
8793    `
8794  }
8795}
8796
8797function debounce(fn, wait) {
8798  let timeout;
8799
8800  return (...args) => {
8801    clearTimeout(timeout);
8802    timeout = setTimeout(() => fn(...args), wait);
8803  }
8804}
8805
8806function debounceAsync(fn, wait) {
8807  let timeout;
8808
8809  return (...args) => {
8810    clearTimeout(timeout);
8811
8812    return new Promise((resolve, reject) => {
8813      timeout = setTimeout(async () => {
8814        try {
8815          const result = await fn(...args);
8816          resolve(result);
8817        } catch (err) {
8818          reject(err);
8819        }
8820      }, wait);
8821    })
8822  }
8823}
8824
8825function delay(ms) {
8826  return new Promise((resolve) => setTimeout(resolve, ms))
8827}
8828
8829function nextFrame() {
8830  return new Promise(requestAnimationFrame)
8831}
8832
8833class ToolbarDropdown extends HTMLElement {
8834  #listeners = new ListenerBin()
8835
8836  connectedCallback() {
8837    this.#onToolbarEditor(() => {
8838      this.#registerListeners();
8839      this.editorReady();
8840    });
8841  }
8842
8843  disconnectedCallback() {
8844    this.#listeners.dispose();
8845  }
8846
8847  editorReady() {}
8848  onOpen() {}
8849  onClose() {}
8850
8851  get trigger() {
8852    return this.querySelector(":scope > [data-dropdown-trigger]")
8853  }
8854
8855  get panel() {
8856    return this.querySelector(":scope > [data-dropdown-panel]")
8857  }
8858
8859  get toolbar() {
8860    return this.closest("lexxy-toolbar")
8861  }
8862
8863  get editorElement() {
8864    return this.toolbar?.editorElement
8865  }
8866
8867  get editor() {
8868    return this.toolbar?.editor
8869  }
8870
8871  get isOpen() {
8872    return this.panel.hidden === false
8873  }
8874
8875  get isClosed() {
8876    return !this.isOpen
8877  }
8878
8879  track(...listeners) {
8880    this.#listeners.track(...listeners);
8881  }
8882
8883  open() {
8884    if (this.isOpen) return
8885    this.trigger.setAttribute("aria-expanded", "true");
8886    this.panel.hidden = false;
vendor: 3,722 bytes, lines 8887-9042
8887    this.onOpen();
8888    this.#focusFirstInteractive();
8889  }
8890
8891  close({ focusEditor = true } = {}) {
8892    if (focusEditor) this.editor?.focus();
8893
8894    if (this.isClosed) return
8895    this.trigger.setAttribute("aria-expanded", "false");
8896    this.panel.hidden = true;
8897    this.onClose();
8898  }
8899
8900  #registerListeners() {
8901    this.#listeners.track(
8902      registerEventListener(this, "keydown", this.#handleKeyDown),
8903      registerEventListener(this.trigger, "click", this.#handleTriggerClick)
8904    );
8905  }
8906
8907  #handleTriggerClick = () => {
8908    if (this.isOpen) {
8909      this.close({ focusEditor: false });
8910    } else {
8911      this.toolbar?.closeDropdowns({ except: this });
8912      this.open();
8913    }
8914  }
8915
8916  async #onToolbarEditor(callback) {
8917    if (!this.toolbar) return
8918
8919    await this.toolbar.getEditorElement();
8920    if (this.isConnected && this.toolbar) callback();
8921  }
8922
8923  #handleKeyDown = (event) => {
8924    if (event.key === "Escape") {
8925      event.stopPropagation();
8926      this.close();
8927    }
8928  }
8929
8930  async #focusFirstInteractive() {
8931    this.#interactiveElements[0]?.focus();
8932    await this.#resetTabIndexValues();
8933  }
8934
8935  async #resetTabIndexValues() {
8936    await nextFrame();
8937    this.#buttons.forEach((element, index) => {
8938      element.setAttribute("tabindex", index === 0 ? 0 : "-1");
8939    });
8940  }
8941
8942  get #interactiveElements() {
8943    return Array.from(this.panel.querySelectorAll("button, input"))
8944  }
8945
8946  get #buttons() {
8947    return Array.from(this.panel.querySelectorAll("button"))
8948  }
8949}
8950
8951const HEADING_BUTTON_SELECTOR = "button.lexxy-heading-button";
8952
8953const HEADING_PRESETS = [
8954  { label: "Large Heading", name: "heading-large", command: "setFormatHeadingLarge" },
8955  { label: "Medium Heading", name: "heading-medium", command: "setFormatHeadingMedium" },
8956  { label: "Small Heading", name: "heading-small", command: "setFormatHeadingSmall" }
8957];
8958
8959class HeadingDropdown extends HTMLElement {
8960  static labelFor(tag, index) {
8961    if (index < HEADING_PRESETS.length) {
8962      return HEADING_PRESETS[index].label
8963    } else {
8964      const level = tag.match(/^h(\d+)$/)?.[1];
8965      if (level) {
8966        return `Heading ${level}`
8967      } else {
8968        return tag.toUpperCase()
8969      }
8970    }
8971  }
8972
8973  static nameFor(tag, index) {
8974    if (index < HEADING_PRESETS.length) {
8975      return HEADING_PRESETS[index].name
8976    } else {
8977      const level = tag.match(/^h(\d+)$/)?.[1];
8978      if (level) {
8979        return `heading-${level}`
8980      } else {
8981        return `heading-${tag}`
8982      }
8983    }
8984  }
8985
8986  static commandFor(index) {
8987    if (index < HEADING_PRESETS.length) {
8988      return HEADING_PRESETS[index].command
8989    } else {
8990      return "applyHeadingFormat"
8991    }
8992  }
8993
8994  #listeners = new ListenerBin()
8995
8996  connectedCallback() {
8997    this.style.display = "contents";
8998
8999    this.#onToolbarEditor(() => {
9000      this.#buttonContainer.style.display = "contents";
9001      this.#setUpButtons();
9002      this.#registerButtonHandlers();
9003      this.#syncActiveHeading();
9004    });
9005  }
9006
9007  disconnectedCallback() {
9008    this.#listeners.dispose();
9009  }
9010
9011  updateActiveHeading(tag) {
9012    this.#headingButtons.forEach(button => {
9013      const next = (button.dataset.heading === tag).toString();
9014      if (button.getAttribute("aria-pressed") !== next) {
9015        button.setAttribute("aria-pressed", next);
9016      }
9017    });
9018  }
9019
9020  get #toolbar() {
9021    return this.closest("lexxy-toolbar")
9022  }
9023
9024  get #editorElement() {
9025    return this.#toolbar?.editorElement
9026  }
9027
9028  get #editor() {
9029    return this.#toolbar?.editor
9030  }
9031
9032  async #onToolbarEditor(callback) {
9033    const toolbar = this.#toolbar;
9034    if (!toolbar) return
9035
9036    await toolbar.getEditorElement();
9037    if (this.isConnected && this.#toolbar) callback();
9038  }
9039
9040  #setUpButtons() {
9041    this.#buttonContainer.innerHTML = "";
9042
9043    this.#configuredHeadings.forEach((tag, index) => {
9044      this.#buttonContainer.appendChild(this.#createButton(tag, index));
9045    });
9046  }
9047
9048  #createButton(tag, index) {
9049    const label = HeadingDropdown.labelFor(tag, index);
9050    const name = HeadingDropdown.nameFor(tag, index);
9051    const icon = ToolbarIcons[tag] || "";
9052
9053    const button = document.createElement("button");
9054    button.type = "button";
9055    button.dataset.heading = tag;
9056    button.dataset.command = HeadingDropdown.commandFor(index);
9057    button.classList.add("lexxy-heading-button");
9058    button.name = name;
9059    button.title = label;
9060    button.setAttribute("role", "menuitem");
9061    button.innerHTML = `${icon} <span>${label}</span>`;
9062    return button
9063  }
9064
9065  #registerButtonHandlers() {
9066    this.#headingButtons.forEach(button => {
9067      this.#listeners.track(registerEventListener(button, "click", (event) => {
9068        if (!this.#editor) return
9069
9070        event.preventDefault();
9071        this.#editor.dispatchCommand(button.dataset.command, button.dataset.heading);
9072        this.#editor.focus();
9073      }));
9074    });
9075  }
9076
9077  #syncActiveHeading() {
9078    const { headingTag } = this.#editor.read(() => this.#editorElement.selection.getFormat());
9079    this.updateActiveHeading(headingTag ?? null);
9080  }
9081
9082  get #configuredHeadings() {
9083    return this.#editorElement.config.get("headings")
9084  }
9085
9086  get #buttonContainer() {
9087    return this.querySelector(".lexxy-heading-options")
9088  }
9089
9090  get #headingButtons() {
9091    return Array.from(this.querySelectorAll(HEADING_BUTTON_SELECTOR))
9092  }
9093}
9094
9095const APPLY_HIGHLIGHT_SELECTOR = "button.lexxy-highlight-button";
9096const REMOVE_HIGHLIGHT_SELECTOR = "[data-command='removeHighlight']";
9097
9098// Use Symbol instead of null since $getSelectionStyleValueForProperty
9099// responds differently for backward selections if null is the default
9100// see https://github.com/facebook/lexical/issues/8013
9101const NO_STYLE = Symbol("no_style");
9102
9103class HighlightDropdown extends ToolbarDropdown {
9104  editorReady() {
9105    this.#setUpButtons();
9106    this.#registerButtonHandlers();
9107  }
9108
9109  onOpen() {
9110    this.editor.getEditorState().read(() => {
9111      this.#updateColorButtonStates(Qr());
9112    });
9113  }
9114
9115  #registerButtonHandlers() {
9116    this.#colorButtons.forEach(button => {
9117      this.track(registerEventListener(button, "click", this.#handleColorButtonClick));
9118    });
9119  }
9120
9121  #setUpButtons() {
9122    this.#buttonContainer.innerHTML = "";
9123
9124    const colorGroups = this.editorElement.config.get("highlight.buttons");
9125
9126    this.#populateButtonGroup("color", colorGroups.color);
9127    this.#populateButtonGroup("background-color", colorGroups["background-color"]);
9128
9129    const maxNumberOfColors = Math.max(colorGroups.color.length, colorGroups["background-color"].length);
9130    this.panel.style.setProperty("--max-colors", maxNumberOfColors);
9131  }
9132
9133  #populateButtonGroup(attribute, values) {
9134    values.forEach((value, index) => {
9135      this.#buttonContainer.appendChild(this.#createButton(attribute, value, index));
9136    });
9137  }
9138
9139  #createButton(attribute, value, index) {
9140    return createElement("button", {
9141      type: "button",
9142      dataset: { value, style: attribute },
9143      style: `${attribute}: ${value}`,
9144      class: "lexxy-editor__toolbar-button lexxy-highlight-button",
9145      name: `${attribute}-${index}`,
9146      role: "menuitem"
9147    })
9148  }
9149
9150  #handleColorButtonClick = (event) => {
9151    event.preventDefault();
9152
9153    const button = event.target.closest(APPLY_HIGHLIGHT_SELECTOR);
9154    if (!button) return
9155
9156    const { style, value } = button.dataset;
9157
9158    this.editor.dispatchCommand("toggleHighlight", { [style]: value });
9159    this.close();
9160  }
9161
9162  #updateColorButtonStates(selection) {
9163    if (!Fr(selection)) { return }
9164
9165    // Use non-"" default, so "" indicates mixed highlighting
9166    const textColor = ne$4(selection, "color", NO_STYLE);
9167    const backgroundColor = ne$4(selection, "background-color", NO_STYLE);
9168
9169    this.#colorButtons.forEach(button => {
9170      const matchesSelection = button.dataset.value === textColor || button.dataset.value === backgroundColor;
9171      const next = matchesSelection.toString();
9172      if (button.getAttribute("aria-pressed") !== next) {
9173        button.setAttribute("aria-pressed", next);
9174      }
9175    });
9176
9177    const hasHighlight = textColor !== NO_STYLE || backgroundColor !== NO_STYLE;
9178    this.panel.querySelector(REMOVE_HIGHLIGHT_SELECTOR).disabled = !hasHighlight;
9179  }
9180
9181  get #buttonContainer() {
9182    return this.panel.querySelector(".lexxy-highlight-colors")
9183  }
9184
9185  get #colorButtons() {
9186    return Array.from(this.panel.querySelectorAll(APPLY_HIGHLIGHT_SELECTOR))
9187  }
9188}
9189
9190/**
9191 * Copyright (c) Meta Platforms, Inc. and affiliates.
9192 *
9193 * This source code is licensed under the MIT license found in the
9194 * LICENSE file in the root directory of this source tree.
9195 *
9196 */
9197
9198function F$5(t,...e){const n=new URL("https://lexical.dev/docs/error"),o=new URLSearchParams;o.append("code",t);for(const t of e)o.append("v",t);throw n.search=o.toString(),Error(`Minified Lexical error #${t}; visit ${n.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}const I$5="undefined"!=typeof window&&void 0!==window.document&&void 0!==window.document.createElement,O$2=I$5&&"documentMode"in document?document.documentMode:null,D$2=I$5&&/Mac|iPod|iPhone|iPad/.test(navigator.platform);!(!I$5||!("InputEvent"in window)||O$2)&&"getTargetRanges"in new window.InputEvent("input");const lt$2=D$2;function pt$2(t,e){return Array.from(vt$2(t))}function vt$2(t,e){return wt$2("next",t)}function yt$5(t,e){const n=cc(Ol(t,e));return n&&n[0]}function wt$2(t,e,n){const o=Zo(),i=e||o,l=Wi(i)?Pl(i,t):Ol(i,t),s=Et$3(i),c=yt$5(i,t);let g=s;
9198return $l({hasNext:t=>null!==t,initial:l,map:t=>({depth:g,node:t.origin}),step:t=>{if(t.isSameNodeCaret(c))return null;Nl(t)&&g++;const e=cc(t);return !e||e[0].isSameNodeCaret(c)?null:(g+=e[1],e[0])}})}function Et$3(t){let e=-1;for(let n=t;null!==n;n=n.getParent())e++;return e}function At$2(t,e){let n=t;for(;null!=n;){if(n instanceof e)return n;n=n.getParent();}return null}function Nt$2(t){const e=dl(t,t=>Wi(t)&&!t.isInline());return Wi(e)||F$5(4,t.__key),e}function Pt$3(t){const e=Qr()||Zr();let r;if(Fr(e))r=ql(e.focus,"next");else {if(null!=e){const t=e.getNodes(),n=t[t.length-1];n&&(r=Ol(n,"next"));}r=r||Pl(Zo(),"previous").getFlipped().insert(eo());}const i=Rt$3(t,r),l=Ll(i),s=Nl(l)?rc(l):i;return Gl(Bl(s)),t.getLatest()}function Rt$3(t,e,n){let o=oc(e,"next");vl(o)&&(0===o.offset?o=Ol(o.origin,"previous").getFlipped():o.offset===o.origin.getTextContentSize()&&(o=Ol(o.origin,"next"))),o.origin.is(t)&&(Tl(o)||F$5(342,t.getKey(),t.getType()),o=Zl(o)),(t.is(o.getNodeAtCaret())||t.is(o.getFlipped().getNodeAtCaret()))&&t.remove(true);for(let t=o;t;t=fc(t,n))o=t;return vl(o)&&F$5(283),o.insert(t.isInline()?eo().append(t):t),oc(Ol(t.getLatest(),"next"),e.direction)}function Tt$4(t,e){const n=e();return t.replace(n),n.append(t),n}function Bt$3(t,e){return null!==t&&Object.getPrototypeOf(t).constructor.name===e.name}function _t$2(t){const e=Qr();if(!Fr(e))return  false;const i=new Set,l=e.getNodes();for(let e=0;e<l.length;e++){const n=l[e],o=n.getKey();if(i.has(o))continue;const s=dl(n,t=>Wi(t)&&!t.isInline());if(null===s)continue;const u=s.getKey();s.canIndent()&&!i.has(u)&&(i.add(u),t(s));}return i.size>0}function $t$2(t,e){Pl(t,"next").insert(e);}function Ot$3(t,e){return Dt$4(t,e,null)}function Dt$4(t,e,n){let o=false;for(const i of zt$4(t))e(i)?null!==n&&n(i):(o=true,Wi(i)&&Dt$4(i,e,n||(t=>i.insertAfter(t))),i.remove());return o}function Ht$3(t,e){const n=[],o=Array.from(t).reverse();for(let t=o.pop();void 0!==t;t=o.pop())if(e(t))n.push(t);else if(Wi(t))for(const e of zt$4(t))o.push(e);return n}function jt$2(t){return Ut$3(Pl(t,"next"))}function zt$4(t){return Ut$3(Pl(t,"previous"))}function Ut$3(t){return $l({hasNext:Tl,initial:t.getAdjacentCaret(),map:t=>t.origin.getLatest(),step:t=>t.getAdjacentCaret()})}
9199
9200/**
9201 * Copyright (c) Meta Platforms, Inc. and affiliates.
9202 *
9203 * This source code is licensed under the MIT license found in the
9204 * LICENSE file in the root directory of this source tree.
9205 *
9206 */
9207
9208const Q$7=Symbol.for("preact-signals");function X$5(){if(ot$2>1)return void ot$2--;let t,e=false;for(!function(){let t=it$1;for(it$1=void 0;void 0!==t;)t.S.v===t.v&&(t.S.i=t.i),t=t.o;}();void 0!==et$1;){let n=et$1;for(et$1=void 0,st$1++;void 0!==n;){const i=n.u;if(n.u=void 0,n.f&=-3,!(8&n.f)&&lt$1(n))try{n.c();}catch(n){e||(t=n,e=true);}n=i;}}if(st$1=0,ot$2--,e)throw t}function Y$3(t){if(ot$2>0)return t();ct$1=++rt$3,ot$2++;try{return t()}finally{X$5();}}let tt$3,et$1;function nt$3(t){const e=tt$3;tt$3=void 0;try{return t()}finally{tt$3=e;}}let it$1,ot$2=0,st$1=0,rt$3=0,ct$1=0,at$2=0;function dt$2(t){if(void 0===tt$3)return;let e=t.n;return void 0===e||e.t!==tt$3?(e={i:0,S:t,p:tt$3.s,n:void 0,t:tt$3,e:void 0,x:void 0,r:e},void 0!==tt$3.s&&(tt$3.s.n=e),tt$3.s=e,t.n=e,32&tt$3.f&&t.S(e),e):-1===e.i?(e.i=0,void 0!==e.n&&(e.n.p=e.p,void 0!==e.p&&(e.p.n=e.n),e.p=tt$3.s,e.n=void 0,tt$3.s.n=e,tt$3.s=e),e):void 0}function ut$2(t,e){this.v=t,this.i=0,this.n=void 0,this.t=void 0,this.l=0,this.W=null==e?void 0:e.watched,this.Z=null==e?void 0:e.unwatched,this.name=null==e?void 0:e.name;}function ft$1(t,e){return new ut$2(t,e)}function lt$1(t){for(let e=t.s;void 0!==e;e=e.n)if(e.S.i!==e.i||!e.S.h()||e.S.i!==e.i)return  true;return  false}function ht$2(t){for(let e=t.s;void 0!==e;e=e.n){const n=e.S.n;if(void 0!==n&&(e.r=n),e.S.n=e,e.i=-1,void 0===e.n){t.s=e;break}}}function gt$2(t){let e,n=t.s;for(;void 0!==n;){const t=n.p;-1===n.i?(n.S.U(n),void 0!==t&&(t.n=n.n),void 0!==n.n&&(n.n.p=t)):e=n,n.S.n=n.r,void 0!==n.r&&(n.r=void 0),n=t;}t.s=e;}function pt$1(t,e){ut$2.call(this,void 0),this.x=t,this.s=void 0,this.g=at$2-1,this.f=4,this.W=null==e?void 0:e.watched,this.Z=null==e?void 0:e.unwatched,this.name=null==e?void 0:e.name;}function vt$1(t){const e=t.m;if(t.m=void 0,"function"==typeof e){ot$2++;const n=tt$3;tt$3=void 0;try{e();}catch(e){throw t.f&=-2,t.f|=8,xt$2(t),e}finally{tt$3=n,X$5();}}}function xt$2(t){for(let e=t.s;void 0!==e;
9208e=e.n)e.S.U(e);t.x=void 0,t.s=void 0,vt$1(t);}function yt$4(t){if(tt$3!==this)throw new Error("Out-of-order effect");gt$2(this),tt$3=t,this.f&=-2,8&this.f&&xt$2(this),X$5();}function Et$2(t,e){this.x=t,this.m=void 0,this.s=void 0,this.u=void 0,this.f=32,this.name=null==e?void 0:e.name;}function St$2(t,e){const n=new Et$2(t,e);try{n.c();}catch(t){throw n.d(),t}const i=n.d.bind(n);return i[Symbol.dispose]=i,i}function bt$2(t,e={}){const n={};for(const i in t){const o=e[i],s=ft$1(void 0===o?t[i]:o);n[i]=s;}return n}ut$2.prototype.brand=Q$7,ut$2.prototype.h=function(){return  true},ut$2.prototype.S=function(t){const e=this.t;e!==t&&void 0===t.e&&(t.x=e,this.t=t,void 0!==e?e.e=t:nt$3(()=>{var t;null==(t=this.W)||t.call(this);}));},ut$2.prototype.U=function(t){if(void 0!==this.t){const e=t.e,n=t.x;void 0!==e&&(e.x=n,t.e=void 0),void 0!==n&&(n.e=e,t.x=void 0),t===this.t&&(this.t=n,void 0===n&&nt$3(()=>{var t;null==(t=this.Z)||t.call(this);}));}},ut$2.prototype.subscribe=function(t){return St$2(()=>{const e=this.value,n=tt$3;tt$3=void 0;try{t(e);}finally{tt$3=n;}},{name:"sub"})},ut$2.prototype.valueOf=function(){return this.value},ut$2.prototype.toString=function(){return this.value+""},ut$2.prototype.toJSON=function(){return this.value},ut$2.prototype.peek=function(){const t=tt$3;tt$3=void 0;try{return this.value}finally{tt$3=t;}},Object.defineProperty(ut$2.prototype,"value",{get(){const t=dt$2(this);return void 0!==t&&(t.i=this.i),this.v},set(t){if(t!==this.v){if(st$1>100)throw new Error("Cycle detected");!function(t){0!==ot$2&&0===st$1&&t.l!==ct$1&&(t.l=ct$1,it$1={S:t,v:t.v,i:t.i,o:it$1});}(this),this.v=t,this.i++,at$2++,ot$2++;try{for(let t=this.t;void 0!==t;t=t.x)t.t.N();}finally{X$5();}}}}),pt$1.prototype=new ut$2,pt$1.prototype.h=function(){if(this.f&=-3,1&this.f)return  false;if(32==(36&this.f))return  true;if(this.f&=-5,this.g===at$2)return  true;if(this.g=at$2,this.f|=1,this.i>0&&!lt$1(this))return this.f&=-2,true;const t=tt$3;try{ht$2(this),tt$3=this;const t=this.x();(16&this.f||this.v!==t||0===this.i)&&(this.v=t,this.f&=-17,this.i++);}catch(t){this.v=t,this.f|=16,this.i++;}return tt$3=t,gt$2(this),this.f&=-2,true},pt$1.prototype.S=function(t){if(void 0===this.t){this.f|=36;for(let t=this.s;void 0!==t;t=t.n)t.S.S(t);}ut$2.prototype.S.call(this,t);},pt$1.prototype.U=function(t){if(void 0!==this.t&&(ut$2.prototype.U.call(this,t),void 0===this.t)){this.f&=-33;for(let t=this.s;void 0!==t;t=t.n)t.S.U(t);}},pt$1.prototype.N=function(){if(!(2&this.f)){this.f|=6;for(let t=this.t;void 0!==t;t=t.x)t.t.N();}}
9208,Object.defineProperty(pt$1.prototype,"value",{get(){if(1&this.f)throw new Error("Cycle detected");const t=dt$2(this);if(this.h(),void 0!==t&&(t.i=this.i),16&this.f)throw this.v;return this.v}}),Et$2.prototype.c=function(){const t=this.S();try{if(8&this.f)return;if(void 0===this.x)return;const t=this.x();"function"==typeof t&&(this.m=t);}finally{t();}},Et$2.prototype.S=function(){if(1&this.f)throw new Error("Cycle detected");this.f|=1,this.f&=-9,vt$1(this),ht$2(this),ot$2++;const t=tt$3;return tt$3=this,yt$4.bind(this,t)},Et$2.prototype.N=function(){2&this.f||(this.f|=2,this.u=et$1,et$1=this);},Et$2.prototype.d=function(){this.f|=8,1&this.f||xt$2(this);},Et$2.prototype.dispose=function(){this.d();};function Ct$1(t){const e=new Set,n=new Set;for(const i of Dt$3(t)){const t="function"==typeof i?i:i.replace;ul(t),e.add(t.getType()),n.add(t);}return {nodes:n,types:e}}function Dt$3(t){return ("function"==typeof t.nodes?t.nodes():t.nodes)||[]}ot$3("format",{parse:t=>"number"==typeof t?t:0});function zt$3(t,...e){const n=new URL("https://lexical.dev/docs/error"),i=new URLSearchParams;i.append("code",t);for(const t of e)i.append("v",t);throw n.search=i.toString(),Error(`Minified Lexical error #${t}; visit ${n.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}function Lt$3(t,e){if(t&&e&&!Array.isArray(e)&&"object"==typeof t&&"object"==typeof e){const n=t,i=e;for(const t in i)n[t]=Lt$3(n[t],i[t]);return t}return e}const Ut$2=0,Tt$3=1,Bt$2=2,Wt$3=3,Gt$2=4,Vt$2=5,Zt$2=6,Jt$3=7;function Ht$2(t){return t.id===Ut$2}function qt$3(t){return t.id===Bt$2}function Qt$2(t){return function(t){return t.id===Tt$3}(t)||zt$3(305,String(t.id),String(Tt$3)),Object.assign(t,{id:Bt$2})}const Xt$3=new Set;let Yt$2 = class Yt{builder;configs;_dependency;_peerNameSet;extension;state;_signal;constructor(t,e){this.builder=t,this.extension=e,this.configs=new Set,this.state={id:Ut$2};}mergeConfigs(){let t=this.extension.config||{};const e=this.extension.mergeConfig?this.extension.mergeConfig.bind(this.extension):pc;for(const n of this.configs)t=e(t,n);return t}init(t){const e=this.state;qt$3(e)||zt$3(306,String(e.id));const n={getDependency:this.getInitDependency.bind(this),getDirectDependentNames:this.getDirectDependentNames.bind(this),getPeer:this.getInitPeer.bind(this),getPeerNameSet:this.getPeerNameSet.bind(this)},i={...n,getDependency:this.getDependency.bind(this),getInitResult:this.getInitResult.bind(this),getPeer:this.getPeer.bind(this)},o=function(t,e,n){return Object.assign(t,{config:e,id:Wt$3,registerState:n})}(e,this.mergeConfigs(),n);let s;this.state=o,this.extension.init&&(s=this.extension.init(t,o.config,n)),this.state=function(t,e,n){return Object.assign(t,{id:Gt$2,initResult:e,registerState:n})}(o,s,i);}build(t){const e=this.state;let n;e.id!==Gt$2&&zt$3(307,String(e.id),String(Vt$2)),this.extension.build&&(n=this.extension.build(t,e.config,e.registerState));const i={...e.registerState,getOutput:()=>n,getSignal:this.getSignal.bind(this)};this.state=function(t,e,n){return Object.assign(t,{id:Vt$2,output:e,registerState:n})}(e,n,i);}register(t,e){this._signal=e;const n=this.state;n.id!==Vt$2&&zt$3(308,String(n.id),String(Vt$2));const i=this.extension.register&&this.extension.register(t,n.config,n.registerState);return this.state=function(t){return Object.assign(t,{id:Zt$2})}(n),()=>{const t=this.state;t.id!==Jt$3&&zt$3(309,String(n.id),String(Jt$3)),this.state=function(t){return Object.assign(t,{id:Vt$2})}(t),i&&i();}}afterRegistration(t){const e=this.state;let n;return e.id!==Zt$2&&zt$3(310,String(e.id),String(Zt$2)),this.extension.afterRegistration&&(n=this.extension.afterRegistration(t,e.config,e.registerState)),this.state=function(t){return Object.assign(t,{id:Jt$3})}(e),n}getSignal(){return void 0===this._signal&&zt$3(311),this._signal}getInitResult(){ void 0===this.extension.init&&zt$3(312,this.extension.name);const t=this.state;return function(t){return t.id>=Gt$2}(t)||zt$3(313,String(t.id),String(Gt$2)),t.initResult}getInitPeer(t){const e=this.builder.extensionNameMap.get(t);return e?e.getExtensionInitDependency():void 0}getExtensionInitDependency(){const t=this.state;return function(t){return t.id>=Wt$3}(t)||zt$3(314,String(t.id),String(Wt$3)),{config:t.config}}getPeer(t){const e=this.builder.extensionNameMap.get(t);return e?e.getExtensionDependency():void 0}getInitDependency(t){const e=this.builder.getExtensionRep(t);return void 0===e&&zt$3(315,this.extension.name,t.name),e.getExtensionInitDependency()}getDependency(t){const e=this.builder.getExtensionRep(t);return void 0===e&&zt$3(315,this.extension.name,t.name),e.getExtensionDependency()}getState(){const t=this.state;return function(t){return t.id>=Jt$3}(t)||zt$3(316,String(t.id),String(Jt$3)),t}getDirectDependentNames(){return this.builder.incomingEdges.get(this.extension.name)||Xt$3}getPeerNameSet(){let t=this._peerNameSet;
9208return t||(t=new Set((this.extension.peerDependencies||[]).map(([t])=>t)),this._peerNameSet=t),t}getExtensionDependency(){if(!this._dependency){const t=this.state;((function(t){return t.id>=Vt$2}))(t)||zt$3(317,this.extension.name),this._dependency={config:t.config,init:t.initResult,output:t.output};}return this._dependency}};const te$3={tag:Jn};function ee$2(){const t=Zo();t.isEmpty()&&t.append(eo());}const ne$3=dc({config:_c({setOptions:te$3,updateOptions:te$3}),init:({$initialEditorState:t=ee$2})=>({$initialEditorState:t,initialized:false}),afterRegistration(t,{updateOptions:e,setOptions:n},i){const o=i.getInitResult();if(!o.initialized){o.initialized=true;const{$initialEditorState:i}=o;if(Gi(i))t.setEditorState(i,n);else if("function"==typeof i)t.update(()=>{i(t);},e);else if(i&&("string"==typeof i||"object"==typeof i)){const e=t.parseEditorState(i);t.setEditorState(e,n);}}return ()=>{}},name:"@lexical/extension/InitialState",nodes:[Ui,gr,rr,br,Zi]}),ie$3=Symbol.for("@lexical/extension/LexicalBuilder");function oe$4(...t){return de$3.fromExtensions(t).buildEditor()}function se$4(){}function re$4(t){throw t}function ce$3(t){return Array.isArray(t)?t:[t]}const ae$3="0.44.0+prod.esm";let de$3 = class de{roots;extensionNameMap;outgoingConfigEdges;incomingEdges;conflicts;_sortedExtensionReps;PACKAGE_VERSION;constructor(t){this.outgoingConfigEdges=new Map,this.incomingEdges=new Map,this.extensionNameMap=new Map,this.conflicts=new Map,this.PACKAGE_VERSION=ae$3,this.roots=t;for(const e of t)this.addExtension(e);}static fromExtensions(t){const e=[ce$3(ne$3)];for(const n of t)e.push(ce$3(n));return new de(e)}static maybeFromEditor(t){const e=t[ie$3];return e&&(e.PACKAGE_VERSION!==ae$3&&zt$3(292,e.PACKAGE_VERSION,ae$3),e instanceof de||zt$3(293)),e}static fromEditor(t){const e=de.maybeFromEditor(t);return void 0===e&&zt$3(294),e}constructEditor(){const{$initialEditorState:t,onError:e,...n}=this.buildCreateEditorArgs(),i=Object.assign(yo({...n,...e?{onError:t=>{e(t,i);}}:{}}),{[ie$3]:this});for(const t of this.sortedExtensionReps())t.build(i);return i}buildEditor(){let t=se$4;function e(){try{t();}finally{t=se$4;}}const n=Object.assign(this.constructEditor(),{dispose:e,[Symbol.dispose]:e});
9208return t=Cc(this.registerEditor(n),()=>n.setRootElement(null)),n}hasExtensionByName(t){return this.extensionNameMap.has(t)}getExtensionRep(t){const e=this.extensionNameMap.get(t.name);if(e)return e.extension!==t&&zt$3(295,t.name),e}addEdge(t,e,n){const i=this.outgoingConfigEdges.get(t);i?i.set(e,n):this.outgoingConfigEdges.set(t,new Map([[e,n]]));const o=this.incomingEdges.get(e);o?o.add(t):this.incomingEdges.set(e,new Set([t]));}addExtension(t){ void 0!==this._sortedExtensionReps&&zt$3(296);const e=ce$3(t),[n]=e;"string"!=typeof n.name&&zt$3(297,typeof n.name);let i=this.extensionNameMap.get(n.name);if(void 0!==i&&i.extension!==n&&zt$3(298,n.name),!i){i=new Yt$2(this,n),this.extensionNameMap.set(n.name,i);const t=this.conflicts.get(n.name);"string"==typeof t&&zt$3(299,n.name,t);for(const t of n.conflictsWith||[])this.extensionNameMap.has(t)&&zt$3(299,n.name,t),this.conflicts.set(t,n.name);for(const t of n.dependencies||[]){const e=ce$3(t);this.addEdge(n.name,e[0].name,e.slice(1)),this.addExtension(e);}for(const[t,e]of n.peerDependencies||[])this.addEdge(n.name,t,e?[e]:[]);}}sortedExtensionReps(){if(this._sortedExtensionReps)return this._sortedExtensionReps;const t=[],e=(n,i)=>{let o=n.state;if(qt$3(o))return;const s=n.extension.name;var r;Ht$2(o)||zt$3(300,s,i||"[unknown]"),Ht$2(r=o)||zt$3(304,String(r.id),String(Ut$2)),o=Object.assign(r,{id:Tt$3}),n.state=o;const c=this.outgoingConfigEdges.get(s);if(c)for(const t of c.keys()){const n=this.extensionNameMap.get(t);n&&e(n,s);}o=Qt$2(o),n.state=o,t.push(n);};for(const t of this.extensionNameMap.values())Ht$2(t.state)&&e(t);for(const e of t)for(const[t,n]of this.outgoingConfigEdges.get(e.extension.name)||[])if(n.length>0){const e=this.extensionNameMap.get(t);if(e)for(const t of n)e.configs.add(t);}for(const[t,...e]of this.roots)if(e.length>0){const n=this.extensionNameMap.get(t.name);void 0===n&&zt$3(301,t.name);for(const t of e)n.configs.add(t);}return this._sortedExtensionReps=t,this._sortedExtensionReps}registerEditor(t){const e=this.sortedExtensionReps(),n=new AbortController,i=[()=>n.abort()],o=n.signal;for(const n of e){const e=n.register(t,o);e&&i.push(e);}for(const n of e){const e=n.afterRegistration(t);e&&i.push(e);}return Cc(...i)}buildCreateEditorArgs(){const t={},e=new Set,n=new Map,i=new Map,o={},s={},r=this.sortedExtensionReps();for(const c of r){const{extension:r}=c;if(void 0!==r.onError&&(t.onError=r.onError),void 0!==r.disableEvents&&(t.disableEvents=r.disableEvents),void 0!==r.parentEditor&&(t.parentEditor=r.parentEditor),void 0!==r.editable&&(t.editable=r.editable),void 0!==r.namespace&&(t.namespace=r.namespace),void 0!==r.$initialEditorState&&(t.$initialEditorState=r.$initialEditorState),r.nodes)for(const t of Dt$3(r)){if("function"!=typeof t){const e=n.get(t.replace);e&&zt$3(302,r.name,t.replace.name,e.extension.name),n.set(t.replace,c);}e.add(t);}if(r.html){if(r.html.export)for(const[t,e]of r.html.export.entries())i.set(t,e);r.html.import&&Object.assign(o,r.html.import);}r.theme&&Lt$3(s,r.theme);}Object.keys(s).length>0&&(t.theme=s),e.size&&(t.nodes=[...e]);const c=Object.keys(o).length>0,a=i.size>0;(c||a)&&(t.html={},c&&(t.html.import=o),a&&(t.html.export=i));for(const e of r)e.init(t);return t.onError||(t.onError=re$4),t}};function ue$3(t,e){const n=de$3.fromEditor(t).getExtensionRep(e);return void 0===n&&zt$3(303,e.name),n.getExtensionDependency()}function fe$3(t,e){const n=de$3.maybeFromEditor(t);if(!n)return;const i=n.extensionNameMap.get(e);return i?i.getExtensionDependency():void 0}
9209
9210/**
9211 * Copyright (c) Meta Platforms, Inc. and affiliates.
9212 *
9213 * This source code is licensed under the MIT license found in the
9214 * LICENSE file in the root directory of this source tree.
9215 *
9216 */
9217
9218const M$3=new Set(["http:","https:","mailto:","sms:","tel:"]);let F$4 = class F extends Bi{__url;__target;__rel;__title;static getType(){return "link"}static clone(t){return new F(t.__url,{rel:t.__rel,target:t.__target,title:t.__title},t.__key)}constructor(t="",e={},n){super(n);const{target:r=null,rel:i=null,title:s=null}=e;this.__url=t,this.__target=r,this.__rel=i,this.__title=s;}afterCloneFrom(t){super.afterCloneFrom(t),this.__url=t.__url,this.__rel=t.__rel,this.__target=t.__target,this.__title=t.__title;}createDOM(e){const n=document.createElement("a");return this.updateLinkDOM(null,n,e),mc(n,e.theme.link),n}updateLinkDOM(t,n,r){if(Vs(n)){t&&t.__url===this.__url||(n.href=this.sanitizeUrl(this.__url));for(const e of ["target","rel","title"]){const r=`__${e}`,i=this[r];t&&t[r]===i||(i?n[e]=i:n.removeAttribute(e));}}}updateDOM(t,e,n){return this.updateLinkDOM(t,e,n),false}static importDOM(){return {a:t=>({conversion:K$3,priority:1})}}static importJSON(t){return $$2().updateFromJSON(t)}updateFromJSON(t){return super.updateFromJSON(t).setURL(t.url).setRel(t.rel||null).setTarget(t.target||null).setTitle(t.title||null)}sanitizeUrl(t){t=X$4(t);try{const e=new URL(X$4(t));if(!M$3.has(e.protocol))return "about:blank"}catch(e){return t}return t}exportJSON(){return {...super.exportJSON(),rel:this.getRel(),target:this.getTarget(),title:this.getTitle(),url:this.getURL()}}getURL(){return this.getLatest().__url}setURL(t){const e=this.getWritable();return e.__url=t,e}getTarget(){return this.getLatest().__target}setTarget(t){const e=this.getWritable();return e.__target=t,e}getRel(){return this.getLatest().__rel}setRel(t){const e=this.getWritable();return e.__rel=t,e}getTitle(){return this.getLatest().__title}setTitle(t){const e=this.getWritable();return e.__title=t,e}insertNewAfter(t,e=true){const n=Ks(this);return this.insertAfter(n,e),n}canInsertTextBefore(){return  false}canInsertTextAfter(){return  false}canBeEmpty(){return  false}isInline(){return  true}extractWithChild(t,e,n){if(!Fr(e))return  false;
9218const r=e.anchor.getNode(),i=e.focus.getNode();return this.isParentOf(r)&&this.isParentOf(i)&&e.getTextContent().length>0}isEmailURI(){return this.__url.startsWith("mailto:")}isWebSiteURI(){return this.__url.startsWith("https://")||this.__url.startsWith("http://")}shouldMergeAdjacentLink(t){return this.getType()===t.getType()&&this.__url===t.__url&&this.__target===t.__target&&this.__rel===t.__rel&&this.__title===t.__title}};function K$3(t){let n=null;if(Vs(t)){const e=t.textContent;(null!==e&&""!==e||t.children.length>0)&&(n=$$2(t.getAttribute("href")||"",{rel:t.getAttribute("rel"),target:t.getAttribute("target"),title:t.getAttribute("title")}));}return {node:n}}function $$2(t="",e){return zs(new F$4(t,e))}function z$5(t){return t instanceof F$4}let j$5 = class j extends F$4{__isUnlinked;constructor(t="",e={},n){super(t,e,n),this.__isUnlinked=void 0!==e.isUnlinked&&null!==e.isUnlinked&&e.isUnlinked;}afterCloneFrom(t){super.afterCloneFrom(t),this.__isUnlinked=t.__isUnlinked;}static getType(){return "autolink"}static clone(t){return new j(t.__url,{isUnlinked:t.__isUnlinked,rel:t.__rel,target:t.__target,title:t.__title},t.__key)}shouldMergeAdjacentLink(t){return  false}getIsUnlinked(){return this.__isUnlinked}setIsUnlinked(t){const e=this.getWritable();return e.__isUnlinked=t,e}createDOM(t){return this.__isUnlinked?document.createElement("span"):super.createDOM(t)}updateDOM(t,e,n){return super.updateDOM(t,e,n)||t.__isUnlinked!==this.__isUnlinked}static importJSON(t){return H$5().updateFromJSON(t)}updateFromJSON(t){return super.updateFromJSON(t).setIsUnlinked(t.isUnlinked||false)}static importDOM(){return null}exportJSON(){return {...super.exportJSON(),isUnlinked:this.__isUnlinked}}insertNewAfter(t,e=true){const n=H$5(this.__url,{isUnlinked:this.__isUnlinked,rel:this.__rel,target:this.__target,title:this.__title});return this.insertAfter(n,e),n}};function H$5(t="",e){return zs(new j$5(t,e))}function G$8(t){return t instanceof j$5}function q$6(t,e){if("element"===t.type){const n=t.getNode();Wi(n)||function(t,...e){const n=new URL("https://lexical.dev/docs/error"),r=new URLSearchParams;r.append("code",t);for(const t of e)r.append("v",t);throw n.search=r.toString(),Error(`Minified Lexical error #${t}; visit ${n.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}(252);return n.getChildren()[t.offset+e]||null}return null}function Q$6(t,e={}){let r;if(t&&"object"==typeof t){const{url:n,...i}=t;r=n,e={...i,...e};}else r=t;const{target:i,title:s}=e,l=void 0===e.rel?"noreferrer":e.rel,a=Qr();if(null===a||!Fr(a)&&!Ir(a))return;if(Ir(a)){const t=a.getNodes();if(0===t.length)return;return void t.forEach(t=>{if(null===r){const e=dl(t,t=>!G$8(t)&&z$5(t));e&&(e.insertBefore(t),0===e.getChildren().length&&e.remove());}else {const e=dl(t,t=>!G$8(t)&&z$5(t));if(e)e.setURL(r),void 0!==i&&e.setTarget(i),void 0!==l&&e.setRel(l);else {const e=$$2(r,{rel:l,target:i});t.insertBefore(e),e.append(t);}}})}if(a.isCollapsed()&&null===r)for(const t of a.getNodes()){const e=dl(t,t=>!G$8(t)&&z$5(t));
9218return void(null!==e&&(e.getChildren().forEach(t=>{e.insertBefore(t);}),e.remove()))}const c=a.extract();if(null===r){const t=new Set;return void c.forEach(e=>{const r=dl(e,t=>!G$8(t)&&z$5(t));if(null!==r){const e=r.getKey();if(t.has(e))return;!function(t,e){const n=new Set(e.filter(e=>t.isParentOf(e)).map(t=>t.getKey())),r=t.getChildren(),i=r=>n.has(r.getKey())||Wi(r)&&e.some(e=>t.isParentOf(e)&&r.isParentOf(e)),s=r.filter(i);if(s.length===r.length)return r.forEach(e=>t.insertBefore(e)),void t.remove();const l=r.findIndex(i),u=r.findLastIndex(i),a=0===l,c=u===r.length-1;if(a)s.forEach(e=>t.insertBefore(e));else if(c)for(let e=s.length-1;e>=0;e--)t.insertAfter(s[e]);else {for(let e=s.length-1;e>=0;e--)t.insertAfter(s[e]);const e=r.slice(u+1);if(e.length>0){const n=Ks(t);s[s.length-1].insertAfter(n),e.forEach(t=>n.append(t));}}}(r,c),t.add(e);}})}const _=new Set,m=t=>{_.has(t.getKey())||(_.add(t.getKey()),t.setURL(r),void 0!==i&&t.setTarget(i),void 0!==l&&t.setRel(l),void 0!==s&&t.setTitle(s));};if(1===c.length){const t=c[0],e=dl(t,z$5);if(null!==e)return m(e)}!function(t){const e=Qr();if(!Fr(e))return t();const n=St$3(e),r=n.isBackward(),i=q$6(n.anchor,r?-1:0),s=q$6(n.focus,r?0:-1);t();if(i||s){const t=Qr();if(Fr(t)){const e=t.clone();if(i){const t=i.getParent();t&&e.anchor.set(t.getKey(),i.getIndexWithinParent()+(r?1:0),"element");}if(s){const t=s.getParent();t&&e.focus.set(t.getKey(),s.getIndexWithinParent()+(r?0:1),"element");}es(St$3(e));}}}(()=>{let t=null;for(const e of c){if(!e.isAttached())continue;const o=dl(e,z$5);if(o){m(o);continue}if(Wi(e)){if(!e.isInline())continue;if(z$5(e)){if(!(G$8(e)||null!==t&&t.getParentOrThrow().isParentOf(e))){m(e),t=e;continue}for(const t of e.getChildren())e.insertBefore(t);e.remove();continue}}const u=e.getPreviousSibling();z$5(u)&&u.is(t)?u.append(e):(t=$$2(r,{rel:l,target:i,title:s}),e.insertAfter(t),t.append(e));}});}const V$6=/^\+?[0-9\s()-]{5,}$/;function X$4(t){return t.match(/^[a-z][a-z0-9+.-]*:/i)||t.match(/^[/#.]/)?t:t.includes("@")?`mailto:${t}`:V$6.test(t)?`tel:${t}`:`https://${t}`}
9219
9220class LinkDropdown extends ToolbarDropdown {
9221  editorReady() {
9222    this.input = this.panel.querySelector("input");
9223
9224    this.track(
9225      registerEventListener(this.input, "keydown", this.#handleEnter),
9226      registerEventListener(this.linkButton, "click", this.#handleLink),
9227      registerEventListener(this.unlinkButton, "click", this.#handleUnlink)
9228    );
9229  }
9230
9231  onOpen() {
9232    this.input.value = this.#selectedLinkUrl;
9233    this.input.required = true;
9234  }
9235
9236  onClose() {
9237    this.input.required = false;
9238  }
9239
9240  get linkButton() {
9241    return this.panel.querySelector("[value='link']")
9242  }
9243
9244  get unlinkButton() {
9245    return this.panel.querySelector("[value='unlink']")
9246  }
9247
9248  #handleEnter = (event) => {
9249    if (event.key === "Enter") {
9250      event.preventDefault();
9251      event.stopPropagation();
9252      this.#handleLink(event);
9253    }
9254  }
9255
9256  #handleLink = () => {
9257    if (!this.input.checkValidity()) {
9258      this.input.reportValidity();
9259      return
9260    }
9261
9262    this.editor.dispatchCommand("link", this.input.value);
9263    this.close();
9264  }
9265
9266  #handleUnlink = () => {
9267    this.editor.dispatchCommand("unlink");
9268    this.close();
9269  }
9270
9271  get #selectedLinkUrl() {
9272    return this.editor.getEditorState().read(() => {
9273      const linkNode = this.editorElement.selection.nearestNodeOfType(F$4);
9274      return linkNode?.getURL() ?? ""
9275    })
9276  }
9277}
9278
9279/**
9280 * Copyright (c) Meta Platforms, Inc. and affiliates.
9281 *
9282 * This source code is licensed under the MIT license found in the
9283 * LICENSE file in the root directory of this source tree.
9284 *
9285 */
9286
9287function q$5(e,...t){const n=new URL("https://lexical.dev/docs/error"),r=new URLSearchParams;r.append("code",e);for(const e of t)r.append("v",e);throw n.search=r.toString(),Error(`Minified Lexical error #${e}; visit ${n.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}function G$7(e){let t=1,n=e.getParent();for(;null!=n;){if(pe$2(n)){const e=n.getParent();if(Se$1(e)){t++,n=e.getParent();continue}q$5(40);}return t}return t}function Q$5(e){let t=e.getParent();Se$1(t)||q$5(40);let n=t;for(;null!==n;)n=n.getParent(),Se$1(n)&&(t=n);return t}function Y$2(e){let t=[];const n=e.getChildren().filter(pe$2);for(let e=0;e<n.length;e++){const r=n[e],i=r.getFirstChild();Se$1(i)?t=t.concat(Y$2(i)):t.push(r);}return t}function Z$3(e){return pe$2(e)&&Se$1(e.getFirstChild())}function ee$1(e){return fe$2().append(e)}function te$2(e,t){return pe$2(e)&&(0===t.length||1===t.length&&e.is(t[0])&&0===e.getChildrenSize())}function ne$2(e){const t=Qr();if(null!==t){let n=t.getNodes();if(Fr(t)){const r=t.getStartEndPoints();null===r&&q$5(143);const[i]=r,s=i.getNode(),o=s.getParent();if(Is(s)){const e=s.getFirstChild();if(e)n=e.selectStart().getNodes();else {const e=eo();s.append(e),n=e.select().getNodes();}}else if(te$2(s,n)){const t=Te$1(e);if(Is(o)){s.replace(t);const e=fe$2();Wi(s)&&(e.setFormat(s.getFormatType()),e.setIndent(s.getIndent())),t.append(e);}else if(pe$2(s)){const e=s.getParentOrThrow();re$3(t,e.getChildren()),e.replace(t);}return}}const r=new Set;for(let t=0;t<n.length;t++){const i=n[t];if(Wi(i)&&i.isEmpty()&&!pe$2(i)&&!r.has(i.getKey())){ie$2(i,e);continue}let s=Wo(i)?i.getParent():pe$2(i)&&i.isEmpty()?i:null;for(;null!=s;){const t=s.getKey();if(Se$1(s)){if(!r.has(t)){const n=Te$1(e);re$3(n,s.getChildren()),s.replace(n),r.add(t);}break}{const n=s.getParent();if(Is(n)&&!r.has(t)){r.add(t),ie$2(s,e);break}s=n;}}}}}function re$3(e,t){e.splice(e.getChildrenSize(),0,t);}function ie$2(e,t){if(Se$1(e))return e;const n=e.getPreviousSibling(),r=e.getNextSibling(),i=fe$2();let s;if(re$3(i,e.getChildren()),Se$1(n)&&t===n.getListType())n.append(i),Se$1(r)&&t===r.getListType()&&(re$3(n,r.getChildren()),r.remove()),s=n;else if(Se$1(r)&&t===r.getListType())r.getFirstChildOrThrow().insertBefore(i),s=r;else {const n=Te$1(t);n.append(i),e.replace(n),s=n;}i.setFormat(e.getFormatType()),i.setIndent(e.getIndent());const o=Qr();return Fr(o)&&(s.getKey()===o.anchor.key&&o.anchor.set(i.getKey(),o.anch
9287or.offset,"element"),s.getKey()===o.focus.key&&o.focus.set(i.getKey(),o.focus.offset,"element")),e.remove(),s}function se$3(e,t){const n=e.getLastChild(),r=t.getFirstChild();n&&r&&Z$3(n)&&Z$3(r)&&(se$3(n.getFirstChild(),r.getFirstChild()),r.remove());const i=t.getChildren();i.length>0&&e.append(...i),t.remove();}function oe$3(){const e=Qr();if(Fr(e)){const t=new Set,r=e.getNodes(),i=e.anchor.getNode();if(te$2(i,r))t.add(Q$5(i));else for(let e=0;e<r.length;e++){const i=r[e];if(Wo(i)){const e=At$2(i,ge$2);null!=e&&t.add(Q$5(e));}}for(const n of t){let t=n;const r=Y$2(n);for(const n of r){const r=eo().setTextStyle(e.style).setTextFormat(e.format);re$3(r,n.getChildren()),t.insertAfter(r),t=r,n.__key===e.anchor.key&&Hl(e.anchor,rc(Pl(r,"next"))),n.__key===e.focus.key&&Hl(e.focus,rc(Pl(r,"next"))),n.remove();}n.remove();}}}function le$2(e){const t="check"!==e.getListType();let n=e.getStart();for(const r of e.getChildren())pe$2(r)&&(r.getValue()!==n&&r.setValue(n),t&&null!=r.getLatest().__checked&&r.setChecked(void 0),Se$1(r.getFirstChild())||n++);}function ce$2(e){const t=new Set;if(Z$3(e)||t.has(e.getKey()))return;const n=e.getParent(),r=e.getNextSibling(),i=e.getPreviousSibling();if(Z$3(r)&&Z$3(i)){const n=i.getFirstChild();if(Se$1(n)){n.append(e);const i=r.getFirstChild();if(Se$1(i)){re$3(n,i.getChildren()),r.remove(),t.add(r.getKey());}}}else if(Z$3(r)){const t=r.getFirstChild();if(Se$1(t)){const n=t.getFirstChild();null!==n&&n.insertBefore(e);}}else if(Z$3(i)){const t=i.getFirstChild();Se$1(t)&&t.append(e);}else if(Se$1(n)){const t=Ks(e),s=Ks(n);t.append(s),s.append(e),i?i.insertAfter(t):r?r.insertBefore(t):n.append(t);}}function ae$2(e){if(Z$3(e))return;const t=e.getParent(),n=t?t.getParent():void 0;if(Se$1(n?n.getParent():void 0)&&pe$2(n)&&Se$1(t)){const r=t?t.getFirstChild():void 0,i=t?t.getLastChild():void 0;if(e.is(r))n.insertBefore(e),t.isEmpty()&&n.remove();else if(e.is(i))n.insertAfter(e),t.isEmpty()&&n.remove();else {const r=Ks(e),i=Ks(t);
9287r.append(i),e.getPreviousSiblings().forEach(e=>i.append(e));const s=Ks(e),o=Ks(t);s.append(o),re$3(o,e.getNextSiblings()),n.insertBefore(r),n.insertAfter(s),n.replace(e);}}}function ue$2(e=false){const t=Qr();if(!Fr(t)||!t.isCollapsed())return  false;const n=t.anchor.getNode();let r=null;if(pe$2(n)&&0===n.getChildrenSize())r=n;else if(Tr(n)){const e=n.getParent();pe$2(e)&&e.getChildren().every(e=>Tr(e)&&""===e.getTextContent().trim())&&(r=e);}if(null===r)return  false;const i=Q$5(r),s=r.getParent();Se$1(s)||q$5(40);const o=s.getParent();let l;if(Is(o))l=eo(),i.insertAfter(l);else {if(!pe$2(o))return  false;l=Ks(o),o.insertAfter(l);}l.setTextStyle(t.style).setTextFormat(t.format).select();const c=r.getNextSiblings();if(c.length>0){const t=e?function(e,t){return e.getStart()+t.getIndexWithinParent()}(s,r):1,n=Ks(s).setStart(t);if(pe$2(l)){const e=Ks(l);e.append(n),l.insertAfter(e);}else l.insertAfter(n);n.append(...c);}return function(e){let t=e;for(;null==t.getNextSibling()&&null==t.getPreviousSibling();){const e=t.getParent();if(null==e||!pe$2(e)&&!Se$1(e))break;t=e;}t.remove();}(r),true}let ge$2 = class ge extends Bi{__value;__checked;$config(){return this.config("listitem",{$transform:e=>{const t=e.getParent();if(Se$1(t))"check"!==t.getListType()&&null!=e.getChecked()&&e.setChecked(void 0);else if(t){const n=e.createParentElementNode();Se$1(n)||q$5(340);const i=[e];for(const t of ["previous","next"]){i.reverse();for(const{origin:n}of Ol(e,t)){if(!pe$2(n))break;i.push(n);}}e.insertBefore(n),n.splice(0,0,i),Is(t)||(Rt$3(n,Zl(Ol(n,"next")),{$shouldSplit:()=>false,removeEmptyDestination:true}),t.isEmpty()&&t.isAttached()&&t.remove());}},extends:Bi,importDOM:In({li:()=>({conversion:he$2,priority:0})})})}constructor(e=1,t=void 0,n){super(n),this.__value=void 0===e?1:e,this.__checked=t;}afterCloneFrom(e){super.afterCloneFrom(e),this.__value=e.__value,this.__checked=e.__checked;}createDOM(e){const t=document.createElement("li");return this.updateListItemDOM(null,t,e),t}updateListItemDOM(e,t,n){!function(e,t,n){const r=t.getParent();!Se$1(r)||"check"!==r.getListType()||Se$1(t.getFirstChild())?(e.removeAttribute("role"),e.removeAttribute("tabIndex"),e.removeAttribute("aria-checked")):(e.setAttribute("role","checkbox"),e.setAttribute("tabIndex","-1"),n&&t.__checked===n.__checked||e.setAttribute("aria-checked",t.getChecked()?"true":"false"));}(t,this,e),t.value=this.__value,function(e,t,n){const r=[],o=[],l=t.list,c=l?l.listitem:void 0;let a;l&&l.nested&&(a=l.nested.listitem);void 0!==c&&r.push(...yc(c));if(l){const e=n.getParent(),t=Se$1(e)&&"check"===e.getListType(),i=n.getChecked();t&&!i||o.push(l.listitemUnchecked),t&&i||o.push(l.listitemChecked),t&&r.push(i?l.listitemChecked:l.listitemUnchecked);}if(void 0!==a){const e=yc(a);n.getChildren().some(e=>Se$1(e))?r.push(...e):o.push(...e);}o.length>0&&xc(e,...o);r.length>0&&mc(e,...r);}(t,n.theme,this);const r=e?e.__style:"",o=this.__style;r!==o&&nr(t.style,o,r),function(e,t,n){const r=t.__textStyle,i=n?n.__textStyle:"";if(null!==n&&i===r)return;const s=Zn(r);for(const t in s)e.style.setProperty(`--listitem-marker-${t}`,s[t]);if(""!==i)for(const t in Zn(i))t in s||e.style.removeProperty(`--listitem-marker-${t}`);}(t,this,e);}updateDOM(e,t,n){const r=t;return this.updateListItemDOM(e,r,n),false}updateFromJSON(e){return super.updateFromJSON(e).setValue(e.value).setChecked(e.checked)}exportDOM(e){const t=this.createDOM(e._config),n=this.getFormatType();n&&(t.style.textAlign=n);const r=this.getDirection();return r&&(t.dir=r),Z$3(this)?{after(e){if(Ys(e)){const t=e.previousElementSibling;if(Ys(t)&&"LI"===t.nodeName){for(;e.firstChild;)t.append(e.firstChild);e.remove();}}return e},element:t}:{element:t}}exportJSON(){return {...super.exportJSON(),checked:this.getChecked(),value:this.getValue()}}append(...e){for(let t=0;t<e.length;t++){const n=e[t];if(Wi(n)&&this.canMergeWith(n)){const e=n.getChildren();this.append(...e),n.remove();}else super.append(n);}return this}replace(e,t){if(pe$2(e))return super.replace(e);this.setIndent(0);const n=this.getParentOrThrow();if(!Se$1(n))return e;if(n.__first===this.getKey())n.insertBefore(e);else if(n.__last===this.getKey())n.insertAfter(e);else {const t=Ks(n);let r=this.getNextSibling();for(;r;){const e=r;r=r.getNextSibling(),t.append(e);}n.insertAfter(e),e.insertAfter(t);}
9287return t&&(Wi(e)||q$5(139),this.getChildren().forEach(t=>{e.append(t);})),this.remove(),0===n.getChildrenSize()&&n.remove(),e}insertAfter(e,t=true){const n=this.getParentOrThrow();if(Se$1(n)||q$5(39),pe$2(e))return super.insertAfter(e,t);const r=this.getNextSiblings();if(n.insertAfter(e,t),0!==r.length){const i=Ks(n);r.forEach(e=>i.append(e)),e.insertAfter(i,t);}return e}remove(e){const t=this.getPreviousSibling(),n=this.getNextSibling();super.remove(e),t&&n&&Z$3(t)&&Z$3(n)&&(se$3(t.getFirstChild(),n.getFirstChild()),n.remove());}resetOnCopyNodeFrom(e){super.resetOnCopyNodeFrom(e),e.getChecked()&&this.setChecked(false);}insertNewAfter(e,t=true){const n=Ks(this);return this.insertAfter(n,t),n}collapseAtStart(e){const t=eo();this.getChildren().forEach(e=>t.append(e));const n=this.getParentOrThrow(),r=n.getParentOrThrow(),i=pe$2(r);if(1===n.getChildrenSize())if(i)n.remove(),r.select();else {n.insertBefore(t),n.remove();const r=e.anchor,i=e.focus,s=t.getKey();"element"===r.type&&r.getNode().is(this)&&r.set(s,r.offset,"element"),"element"===i.type&&i.getNode().is(this)&&i.set(s,i.offset,"element");}else n.insertBefore(t),this.remove();return  true}getValue(){return this.getLatest().__value}setValue(e){const t=this.getWritable();return t.__value=e,t}getChecked(){const e=this.getLatest();let t;const n=this.getParent();return Se$1(n)&&(t=n.getListType()),"check"===t?Boolean(e.__checked):void 0}setChecked(e){const t=this.getWritable();return t.__checked=e,t}toggleChecked(){const e=this.getWritable();return e.setChecked(!e.__checked)}getIndent(){const e=this.getParent();if(null===e||!this.isAttached())return this.getLatest().__indent;let t=e.getParentOrThrow(),n=0;for(;pe$2(t);)t=t.getParentOrThrow().getParentOrThrow(),n++;return n}setIndent(e){"number"!=typeof e&&q$5(117),(e=Math.floor(e))>=0||q$5(199);let t=this.getIndent();for(;t!==e;)t<e?(ce$2(this),t++):(ae$2(this),t--);return this}canInsertAfter(e){return pe$2(e)}canReplaceWith(e){return pe$2(e)}canMergeWith(e){return pe$2(e)||no(e)}extractWithChild(e,t){if(!Fr(t))return  false;const n=t.anchor.getNode(),r=t.focus.getNode();return this.isParentOf(n)&&this.isParentOf(r)&&this.getTextContent().length===t.getTextContent().length}isParentRequired(){return  true}createParentElementNode(){return Te$1("bullet")}canMergeWhenEmpty(){return  true}};function he$2(e){if(e.classList.contains("task-list-item"))for(const t of e.children)if("INPUT"===t.tagName)return de$2(t);if(e.classList.contains("joplin-checkbox"))for(const t of e.children)if(t.classList.contains("checkbox-wrapper")&&t.children.length>0&&"INPUT"===t.children[0].tagName)return de$2(t.children[0]);const t=e.getAttribute("aria-checked");return {node:fe$2("true"===t||"false"!==t&&void 0)}}function de$2(e){if(!("checkbox"===e.getAttribute("type")))return {node:null};return {node:fe$2(e.hasAttribute("checked"))}}function fe$2(e){return zs(new ge$2(void 0,e))}function pe$2(e){return e instanceof ge$2}let me$2 = class me extends Bi{__tag;__start;__listType;$config(){return this.config("list",{$transform:e=>{!function(e){const t=e.getNextSibling();Se$1(t)&&e.getListType()===t.getListType()&&se$3(e,t);}(e),le$2(e);},extends:Bi,importDOM:In({ol:()=>({conversion:ye$1,priority:0}),ul:()=>({conversion:ye$1,priority:0})})})}constructor(e="number",t=1,n){super(n);const r=ve$1[e]||e;this.__listType=r,this.__tag="number"===r?"ol":"ul",this.__start=t;}afterCloneFrom(e){super.afterCloneFrom(e),this.__listType=e.__listType,this.__tag=e.__tag,this.__start=e.__start;}getTag(){return this.getLatest().__tag}setListType(e){const t=this.getWritable();return t.__listType=e,t.__tag="number"===e?"ol":"ul",t}getListType(){return this.getLatest().__listType}getStart(){return this.getLatest().__start}setStart(e){const t=this.getWritable();return t.__start=e,t}createDOM(e,t){const n=this.__tag,r=document.createElement(n);return 1!==this.__start&&r.setAttribute("start",String(this.__start)),r.__lexicalListType=this.__listType,_e$1(r,e.theme,this),r}updateDOM(e,t,n){return e.__tag!==this.__tag||e.__listType!==this.__listType||(_e$1(t,n.theme,this),e.__start!==this.__start&&t.setAttribute("start",String(this.__start)),false)}updateFromJSON(e){return super.updateFromJSON(e).setListType(e.listType).setStart(e.start)}exportDOM(e){const t=this.createDOM(e._config,e);return Ys(t)&&(1!==this.__start&&t.setAttribute("start",String(this.__start)),"check"===this.__listType&&t.setAttribute("__lexicalListType","check")),{element:t}}exportJSON(){return {...super.exportJSON(),listType:this.getListType(),start:this.getStart(),tag:this.getTag()}}canBeEmpty(){return  false}canIndent(){return  false}splice(e,t,n){const r=n.find(pe$2)??this.getChildren().find(pe$2),i=r?()=>Ks(r):fe$2;let s=n;for(let e=0;e<n.length;e++){const t=n[e];pe$2(t)||(s===n&&(s=[...n]),s[e]=i().append(!Wi(t)||Se$1(t)||t.isInline()?t:kr(t.getTextContent())));}return super.splice(e,t,s)}extractWithChild(e){return pe$2(e)}};
9287function _e$1(e,t,n){const r=[],o=[],l=t.list;if(void 0!==l){const e=l[`${n.__tag}Depth`]||[],t=G$7(n)-1,i=t%e.length,s=e[i],c=l[n.__tag];let a;const u=l.nested,g=l.checklist;if(void 0!==u&&u.list&&(a=u.list),void 0!==c&&r.push(c),void 0!==g&&"check"===n.__listType&&r.push(g),void 0!==s){r.push(...yc(s));for(let t=0;t<e.length;t++)t!==i&&o.push(n.__tag+t);}if(void 0!==a){const e=yc(a);t>1?r.push(...e):o.push(...e);}}o.length>0&&xc(e,...o),r.length>0&&mc(e,...r);}function Ce$1(e){const t=[];for(let n=0;n<e.length;n++){const r=e[n];if(pe$2(r)){t.push(r);const e=r.getChildren();e.length>1&&e.forEach(e=>{Se$1(e)&&t.push(ee$1(e));});}else t.push(ee$1(r));}return t}function ye$1(e){const t=e.nodeName.toLowerCase();let n=null;if("ol"===t){n=Te$1("number",e.start);}else "ul"===t&&(n=function(e){if("check"===e.getAttribute("__lexicallisttype")||e.classList.contains("contains-task-list")||"1"===e.getAttribute("data-is-checklist"))return  true;for(const t of e.childNodes)if(Ys(t)&&t.hasAttribute("aria-checked"))return  true;return  false}(e)?Te$1("check"):Te$1("bullet"));return {after:Ce$1,node:n}}const ve$1={ol:"number",ul:"bullet"};function Te$1(e="number",t=1){return zs(new me$2(e,t))}function Se$1(e){return e instanceof me$2}const Fe$1=re$5("UPDATE_LIST_START_COMMAND"),Ee$2=re$5("INSERT_UNORDERED_LIST_COMMAND"),Oe$1=re$5("INSERT_ORDERED_LIST_COMMAND"),Ae$2=re$5("REMOVE_LIST_COMMAND");function Ie$2(e,t){return Cc(e.registerCommand(Oe$1,()=>(ne$2("number"),true),io),e.registerCommand(Fe$1,e=>{const{listNodeKey:t,newStart:n}=e,r=Yo(t);return !!Se$1(r)&&("number"===r.getListType()&&(r.setStart(n),le$2(r)),true)},io),e.registerCommand(Ee$2,()=>(ne$2("bullet"),true),io),e.registerCommand(Ae$2,()=>(oe$3(),true),io),e.registerCommand(he$3,()=>ue$2(false),io),e.registerNodeTransform(ge$2,e=>{const t=e.getFirstChild();if(t){if(Tr(t)){const n=t.getStyle(),r=t.getFormat();e.getTextStyle()!==n&&e.setTextStyle(n),e.getTextFormat()!==r&&e.setTextFormat(r);}}else {const t=Qr();Fr(t)&&(t.style!==e.getTextStyle()||t.format!==e.getTextFormat())&&t.isCollapsed()&&e.is(t.anchor.getNode())&&e.setTextStyle(t.style).setTextFormat(t.format);}}),e.registerNodeTransform(gr,e=>{const t=e.getParent();if(pe$2(t)&&e.is(t.getFirstChild())){const n=e.getStyle(),r=e.getFormat();n===t.getTextStyle()&&r===t.getTextFormat()||t.setTextStyle(n).setTextFormat(r);}}))}
9288
9289/**
9290 * Copyright (c) Meta Platforms, Inc. and affiliates.
9291 *
9292 * This source code is licensed under the MIT license found in the
9293 * LICENSE file in the root directory of this source tree.
9294 *
9295 */
9296
9297function D$1(t,...n){const e=new URL("https://lexical.dev/docs/error"),o=new URLSearchParams;o.append("code",t);for(const t of n)o.append("v",t);throw e.search=o.toString(),Error(`Minified Lexical error #${t}; visit ${e.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}let C$3;function A$1(t,n){const{key:e}=n;return t&&e in t?t[e]:n.defaultValue}function E$2(t){return C$3&&C$3.editor===t?C$3:void 0}function N$2(t,n){if("cfg"in n){const{cfg:e,updater:o}=n;return [e,o(A$1(t,e))]}return n}function P$2(t,n){let e=n;for(const o of t){const[t,r]=N$2(e,o),c=t.key;if(e===n&&A$1(e,t)===r)continue;const s=e||T$1(n);s[c]=r,e=s;}return e}function T$1(t){return Object.create(t||null)}function j$4(t,n){return [t,n]}const L$4="@lexical/html/DOM",F$3=Symbol.for("@lexical/html/DOMExportContext"),I$4=()=>true;function R$2(t){return n=>n instanceof t}function W$4(t,{nodes:n}){if("*"===n)return I$4;let e={};const o=[];for(const r of n)if("getType"in r){const n=r.getType();if(e){const o=t[n];void 0===o&&D$1(339,r.name,n),e=Object.assign(e,o.types);}o.push(R$2(r));}else e=void 0,o.push(r);return e||(1===o.length?o[0]:t=>{for(const n of o)if(n(t))return  true;return  false})}function q$4(t){return (n,e,o)=>t(n,o)}function B$4(t){return (n,e,o,r)=>t(n,e,r)}function U$4(t){return (n,e,o,r,c)=>t(n,e,o,c)}function V$5(t){return (n,e,o,r,c,s)=>t(n,e,o,r,s)}function H$4(t,n){return (e,o)=>{const r=()=>t(e,o),c=n(e);return c?c(e,r,o):r()}}function Y$1(t,n){return (e,o,r)=>{const c=()=>t(e,o,r),s=n(e);return s?s(e,o,c,r):c()}}function _$2(t,n){return (e,o,r,c)=>{const s=()=>t(e,o,r,c),u=n(e);return u?u(e,o,r,s,c):s()}}function z$4(t,n){return (e,o,r,c,s)=>{const u=()=>t(e,o,r,c,s),i=n(e);return i?i(e,o,r,c,u,s):u()}}function G$6(t,n){return (e,o,r,c)=>{t(e,o,r,c);const s=n(e);s&&s(e,o,r,c);}}function J$5(t,n,e,o,r){let c=e[n];for(const e of t[n])if("function"==typeof e[0]){const[t,n]=e;c=o(c,e=>t(e)&&n||void 0);}else {const t=e[1],n={};for(const e in t){const r=t[e];r&&(n[e]=r.reduce((t,n)=>o(t,()=>n),c));}c=o(c,t=>{const e=n[t.getType()];return e&&r(e)});}e[n]=c;}function K$2(t,n,e,o){if(!o)return;const r=t[n];if("function"==typeof e)r.push([e,o]);else {const t=r[r.length-1];let n;t&&"types"===t[0]?n=t[1]:(n={},r.push(["types",n]));for(const t in e){const e=n[t]||[];n[t]=e,e.push(o);}}
9297}function Q$4(t){return "*"===t.nodes}function X$3(t,n){const e=function(t){const n={},{nodes:e}=Ct$1(t);for(const t of e)n[t.getType()]={klass:t,types:{}};for(const t of Object.values(n))if(t){const e=t.klass.getType();for(let{klass:o}=t;Bn(o.prototype);o=Object.getPrototypeOf(o)){const{ownNodeType:t}=ul(o),r=t&&n[t];r&&(r.types[e]=true);}}return n}(t),o={$createDOM:[],$decorateDOM:[],$exportDOM:[],$extractWithChild:[],$getDOMSlot:[],$shouldExclude:[],$shouldInclude:[],$updateDOM:[]};for(const t of function(t){const n=[],e=[],o=[];for(const c of t)if(Q$4(c))n.push(c);else if(Array.isArray(c.nodes))for(const t of c.nodes)Bn(t.prototype)?o.push(1===c.nodes.length?c:{...c,nodes:[t]}):e.push(1===c.nodes.length?c:{...c,nodes:[t]});const c=new Map,s=t=>{let n=c.get(t);if(void 0===n){n=0;for(let e=t;Bn(e.prototype);e=Object.getPrototypeOf(e))n++;c.set(t,n);}return n};return o.sort((t,n)=>s(t.nodes[0])-s(n.nodes[0])),[...o,...e,...n]}(n)){const n=W$4(e,t);for(const e in o){K$2(o,e,n,t[e]);}}return o}function Z$2(t){return t}const tt$2=dc({build:(t,n,e)=>({defaults:P$2(n.contextDefaults,void 0)}),config:{contextDefaults:[],overrides:[]},html:{export:new Map([[Ui,()=>{const t=document.createElement("div");return t.role="textbox",{element:t}}]])},init(t,n){t.dom=function(t,{overrides:n}){const e=X$3(t,n),r={...po,...t.dom};return J$5(e,"$createDOM",r,H$4,q$4),J$5(e,"$exportDOM",r,H$4,q$4),J$5(e,"$extractWithChild",r,z$4,V$5),J$5(e,"$getDOMSlot",r,Y$1,B$4),J$5(e,"$shouldExclude",r,Y$1,B$4),J$5(e,"$shouldInclude",r,Y$1,B$4),J$5(e,"$updateDOM",r,_$2,U$4),J$5(e,"$decorateDOM",r,G$6,Z$2),r}(t,n);},mergeConfig(t,n){const e=pc(t,n);for(const o of ["overrides","contextDefaults"])n[o]&&(e[o]=[...t[o],...n[o]]);return e},name:L$4});function nt$2(t,n,o){return function(t,n,o,r){return Object.assign(ot$3(Symbol(n),{isEqual:r,parse:o}),{[t]:true})}(F$3,t,n,o)}nt$2("root",Boolean);const ot$1=nt$2("isExport",Boolean);function rt$2(t){const n=de$3.maybeFromEditor(t);return n&&n.hasExtensionByName(L$4)?ue$3(t,tt$2).output.defaults:void 0}const ut$1=function(t,e=()=>{}){return (o,r=Zs())=>c=>{const s=E$2(r),u=s&&s[t],i=P$2(o,u||e(r));return i&&i!==u?function(t,e,o,r=Zs()){const c=C$3,s=E$2(r);try{return C$3={...s,editor:r,[t]:e},o()}finally{C$3=c;}}(t,i,c,r):c()}}(F$3,rt$2);function lt(t){return t.constructor.name===CSSStyleRule.name}const ft=new Set(["STYLE","SCRIPT"]);function dt$1(t,n){zo(n)&&function(t){if(null===t.querySelector("style"))return;const n=new Map;function e(t){let e=n.get(t);if(void 0===e){e=new Set;for(let n=0;n<t.style.length;n++)e.add(t.style[n]);n.set(t,e);}return e}try{for(const n of Array.from(t.styleSheets)){let o;try{o=n.cssRules;}catch(t){continue}for(const n of Array.from(o)){if(!lt(n))continue;let o;try{o=t.querySelectorAll(n.selectorText);}catch(t){continue}for(const t of Array.from(o)){if(!Ys(t))continue;const o=e(t);for(let e=0;e<n.style.length;e++){const r=n.style[e];o.has(r)||t.style.setProperty(r,n.style.getPropertyValue(r),n.style.getPropertyPriority(r));}}}}}catch(t){}}(n);const e=zo(n)?n.body.childNodes:n.childNodes,o=[],r=[];for(const n of e)if(!ft.has(n.nodeName)){const e=gt$1(n,t,r,false);if(null!==e)for(const t of e)o.push(t);}return function(t){for(const n of t)n.getParent()&&n.getNextSibling()instanceof Qi&&n.insertAfter(or());for(const n of t){const t=n.getParent();t&&t.splice(n.getIndexWithinParent(),1,n.getChildren());}}(r),o}function at$1(t,e=null,o=Zs()){return ut$1([j$4(ot$1,true)],o)(()=>{const n=Zo(),r=tl(o),c=t.append.bind(t);for(const t of n.getChildren())yt$3(o,t,c,e,r);return t})}function ht$1(t,n=null){return ("undefined"==typeof document||"undefined"==typeof window&&void 0===global.window)&&D$1(338),at$1(document.createElement("div"),n,t).innerHTML}function yt$3(n,e,o,r=null,c=tl(n)){let s=c.$shouldInclude(e,r,n);const u=c.$shouldExclude(e,r,n);let i=e;null!==r&&Tr(e)&&(i=R$3(r,e,"clone"));const l=c.$exportDOM(i,n),{element:d,after:g,append:m,$getChildNodes:x}=l;if(!d)return  false;const v=document.createDocumentFragment(),$=x?x():Wi(i)?i.getChildren():[],b=v.append.bind(v);for(const t of $){const o=yt$3(n,t,b,r,c);!s&&o&&c.$extractWithChild(e,t,r,"html",n)&&(s=true);}if(s&&!u){if((Ys(d)||Hs(d))&&(m?m(v):d.append(v)),o(d),g){const t=g.call(i,d);t&&(Hs(d)?d.replaceChildren(t):d.replaceWith(t));}}else o(v);return s}function gt$1(t,n,e,o,r=new Map,c){const s=[];if(ft.has(t.nodeName))return s;let u=null;const i=function(t,n){const{nodeName:e}=t,o=n._htmlConversions.get(e.toLowerCase());let r=null;if(void 0!==o)for(const n of o){const e=n(t);null!==e&&(null===r||(r.priority||0)<=(e.priority||0))&&(r=e);}return null!==r?r.conversion:null}(t,n),l=i?i(t):null;let f=null;if(null!==l){f=l.after;const n=l.node;if(u=Array.isArray(n)?n[n.length-1]:n,null!==u){for(const[,t]of r)if(u=t(u,c),!u)break;u&&s.push(...Array.isArray(n)?n:[u]);}null!=l.forChild&&r.set(t.nodeName,l.forChild);}const d=t.childNodes;let a=[];const h=(null==u||!Is(u))&&(null!=u&&Vr(u)||o);for(let t=0;t<d.length;t++)a.push(...gt$1(d[t],n,e,h,new Map(r),u));if(null!=f&&(a=f(a)),Xs(t)&&(a=mt$2(t,a,h?()=>{const t=new Qi;return e.push(t),t}:eo)),null==u)if(a.length>0)for(const t of a)s.push(t);else Xs(t)&&function(t){if(null==t.nextSibling||null==t.previousSibling)return  false;return Gs(t.nextSibling)&&Gs(t.previousSibling)}(t)&&s.push(or());else Wi(u)&&u.append(...a);return s}function mt$2(t,n,e){const o=t.style.textAlign,r=[];let c=[];for(let t=0;t<n.length;t++){const s=n[t];if(Vr(s))o&&!s.getFormat()&&s.setFormat(o),r.push(s);else if(c.push(s),t===n.length-1||t<n.length-1&&Vr(n[t+1])){const t=e();t.setFormat(o),t.append(...c),r.push(t),c=[];}}return r}
9298
9299/**
9300 * Copyright (c) Meta Platforms, Inc. and affiliates.
9301 *
9302 * This source code is licensed under the MIT license found in the
9303 * LICENSE file in the root directory of this source tree.
9304 *
9305 */
9306
9307function _$1(t,...e){const n=new URL("https://lexical.dev/docs/error"),r=new URLSearchParams;r.append("code",t);for(const t of e)r.append("v",t);throw n.search=r.toString(),Error(`Minified Lexical error #${t}; visit ${n.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}function J$4(t,e=Qr()){return null==e&&_$1(166),Fr(e)&&e.isCollapsed()||0===e.getNodes().length?"":ht$1(t,e)}function L$3(t,e=Qr()){return null==e&&_$1(166),Fr(e)&&e.isCollapsed()||0===e.getNodes().length?null:JSON.stringify(X$2(t,e))}function j$3(t,e){const n=t.getData("text/plain")||t.getData("text/uri-l
9307ist");null!=n&&e.insertRawText(n);}function I$3(t,e,n){const o=t.getData("application/x-lexical-editor");if(o)try{const t=JSON.parse(o);if(t.namespace===n._config.namespace&&Array.isArray(t.nodes)){return z$3(n,Y(t.nodes),e)}}catch(t){console.error(t);}const i=t.getData("text/html"),l=t.getData("text/plain");if(i&&l!==i)try{const t=(new DOMParser).parseFromString(function(t){if(window.trustedTypes&&window.trustedTypes.createPolicy){return window.trustedTypes.createPolicy("lexical",{createHTML:t=>t}).createHTML(t)}return t}(i),"text/html");return z$3(n,dt$1(n,t),e)}catch(t){console.error(t);}const u=l||t.getData("text/uri-list");if(null!=u)if(Fr(e)){const t=u.split(/(\r?\n|\t)/);""===t[t.length-1]&&t.pop();for(let e=0;e<t.length;e++){const n=Qr();if(Fr(n)){const r=t[e];"\n"===r||"\r\n"===r?n.insertParagraph():"\t"===r?n.insertNodes([wr()]):n.insertText(r);}}}else e.insertRawText(u);}const k$2="application/x-lexical-drag";function B$3(t,e){const n={editorKey:e.getKey()};t.setData(k$2,JSON.stringify(n));}function H$3(t){const e=function(t,e){if(void 0!==document.caretRangeFromPoint){const n=document.caretRangeFromPoint(t,e);return null===n?null:{node:n.startContainer,offset:n.startOffset}}if("undefined"!==document.caretPositionFromPoint){const n=document.caretPositionFromPoint(t,e);return null===n?null:{node:n.offsetNode,offset:n.offset}}return null}(t.clientX,t.clientY);if(null===e)return null;const n=Go(e.node);if(null===n)return null;if(Tr(n))return Ml(n,"next",e.offset);if(Wi(n))return lc(n,e.offset,"next");const r=n.getParent();return null===r?null:lc(r,n.getIndexWithinParent()+1,"next")}function U$3(t,e,n){const r=t.dataTransfer;if(null===r)return  false;const o=function(t){const e=t.getData(k$2);if(!e)return null;let n;try{n=JSON.parse(e);}catch(t){return null}return null!==(r=n)&&"object"==typeof r&&"editorKey"in r&&"string"==typeof r.editorKey?n:null;var r;}(r);if(null===o)return  false;const i=H$3(t);if(null===i)return  false;const l=fc(i);if(null===l)return  false;const a=o.editorKey===e.getKey(),u=Qr();if(a){if(!Fr(u)||u.isCollapsed())return  false;if(function(t,e){const{anchor:n,focus:r}=sc(Ql(e),"next");return Jl(n,t)<0&&Jl(t,r)<0}(i,u))return t.preventDefault(),true;u.removeText();}if(!l.origin.isAttached())return t.preventDefault(),true;if(n(r,Gl(Bl(l)),e),!a){const t=e.getRootElement(),n=t?t.ownerDocument:null,r=n?function(t,e){const n=e.querySelectorAll('[data-lexical-editor="true"]');for(const e of Array.from(n)){const n=e.__lexicalEditor;if(n&&n.getKey()===t)return e}return null}(o.editorKey,n):null;null!==r&&r.dispatchEvent(new InputEvent("beforeinput",{bubbles:true,cancelable:true,inputType:"deleteByDrag"}));}return t.preventDefault(),true}function W$3(t,e){return U$3(t,e,I$3)}function q$3(t,e){return U$3(t,e,(t,e)=>j$3(t,e))}function z$3(t,e,n){t.dispatchCommand(oe$6,{nodes:e,selection:n})||(n.insertNodes(e),function(t){if(Fr(t)&&t.isCollapsed()){const e=t.anchor;let n=null;const r=ql(e,"previous");if(r)if(vl(r))n=r.origin;else {const t=Wl(r,Pl(Zo(),"next").getFlipped());for(const e of t){if(Tr(e.origin)){n=e.origin;break}if(Wi(e.origin)&&!e.origin.isInline())break}}if(n&&Tr(n)){const e=n.getFormat(),r=n.getStyle();t.format===e&&t.style===r||(t.format=e,t.style=r,t.dirty=true);}}}(n));}function G$5(t,e,n,r=[]){let o=null===e||n.isSelected(e);const l=Wi(n)&&n.excludeFromCopy("html");let c=n;null!==e&&Tr(c)&&(c=R$3(e,c,"clone"));const s=Wi(c)?c.getChildren():[],a=function(t){const e=t.exportJSON(),n=t.constructor;if(e.type!==n.getType()&&_$1(58,n.name),Wi(t)){const t=e.children;Array.isArray(t)||_$1(59,n.name);}return e}(c);Tr(c)&&0===c.getTextContentSize()&&(o=false);for(let r=0;r<s.length;r++){const i=s[r],l=G$5(t,e,i,a.children);!o&&Wi(n)&&l&&n.extractWithChild(i,e,"clone")&&(o=true);}if(o&&!l)r.push(a);else if(Array.isArray(a.children))for(let t=0;t<a.children.length;t++){const e=a.children[t];r.push(e);}return o}function X$2(t,e){const n=[],r=Zo().getChildren();for(let o=0;o<r.length;o++){G$5(t,e,r[o],n);}return {namespace:t._config.namespace,nodes:n}}function Y(t){const e=[];for(let n=0;n<t.length;n++){const r=t[n],i=Ei(r);e.push(i);}return e}let Q$3=null;async function V$4(t,e,n){if(null!==Q$3)return  false;if(null!==e)return new Promise((r,o)=>{t.update(()=>{r(Z$1(t,e,n));});});const r=t.getRootElement(),o=t._window||window,i=o.document,c=Js(o);if(null===r||null===c)return  false;
9307const s=i.createElement("span");s.style.position="fixed",s.style.top="-1000px",s.append(i.createTextNode("#")),r.append(s);const a=new Range;return a.setStart(s,0),a.setEnd(s,1),c.removeAllRanges(),c.addRange(a),new Promise((e,r)=>{const c=t.registerCommand(Je$2,r=>(Bt$3(r,ClipboardEvent)&&(c(),null!==Q$3&&(o.clearTimeout(Q$3),Q$3=null),e(Z$1(t,r,n))),true),lo);Q$3=o.setTimeout(()=>{c(),Q$3=null,e(false);},50),i.execCommand("copy"),s.remove();})}function Z$1(t,e,n){if(void 0===n){const e=Js(t._window),r=Qr();if(!r||r.isCollapsed())return  false;if(!e)return  false;const o=e.anchorNode,i=e.focusNode;if(null!==o&&null!==i&&!Mo(t,o,i))return  false;n=et(r);}e.preventDefault();const r=e.clipboardData;return null!==r&&(nt$1(r,n),true)}const tt$1=[["text/html",J$4],["application/x-lexical-editor",L$3]];function et(n=Qr()){return function(t,e){const n={"text/plain":""};for(const[r,o]of Object.entries(t)){const t=ot(o,e);null!==t&&(n[r]=t);}return n}(function(){const n=Zs(),r=de$3.maybeFromEditor(n);if(r&&r.hasExtensionByName(it.name))return ue$3(n,it).output;return rt$1}(),n)}function nt$1(t,e){for(const[n]of tt$1) void 0===e[n]&&t.setData(n,"");for(const n in e){const r=e[n];void 0!==r&&t.setData(n,r);}}const rt$1={"application/x-lexical-editor":[(t,e)=>t?L$3(Zs(),t):e()],"text/html":[(t,e)=>t?J$4(Zs(),t):e()],"text/plain":[(t,e)=>t?t.getTextContent():e()]};function ot(t,e){const n=r=>t[r]?t[r](e,n.bind(null,r-1)):null;return n(t.length-1)}const it=dc({build:(t,e,n)=>e.$exportMimeType,config:_c({$exportMimeType:rt$1}),mergeConfig(t,e){const n=pc(t,e);if(e.$exportMimeType){const r={...t.$exportMimeType};for(const[t,n]of Object.entries(e.$exportMimeType))r[t]=[...r[t],...n];n.$exportMimeType=r;}return n},name:"@lexical/clipboard/GetClipboardData"});
9308
9309/**
9310 * Copyright (c) Meta Platforms, Inc. and affiliates.
9311 *
9312 * This source code is licensed under the MIT license found in the
9313 * LICENSE file in the root directory of this source tree.
9314 *
9315 */
9316
9317function s(e){const t=window.location.origin,n=n=>{if(n.origin!==t)return;const o=e.getRootElement();if(document.activeElement!==o)return;const s=n.data;if("string"==typeof s){let t;try{t=JSON.parse(s);}catch(e){return}if(t&&"nuanria_messaging"===t.protocol&&"request"===t.type){const o=t.payload;if(o&&"makeChanges"===o.functionId){const t=o.args;if(t){const[o,s,d,c,g]=t;e.update(()=>{const e=Qr();if(Fr(e)){const t=e.anchor;let i=t.getNode(),a=0,l=0;if(Tr(i)&&o>=0&&s>=0&&(a=o,l=o+s,e.setTextNodeRange(i,a,i,l)),a===l&&""===d||(e.insertRawText(d),i=t.getNode()),Tr(i)){a=c,l=c+g;const t=i.getTextContentSize();a=a>t?t:a,l=l>t?t:l,e.setTextNodeRange(i,a,i,l);}n.stopImmediatePropagation();}});}}}}};return window.addEventListener("message",n,true),()=>{window.removeEventListener("message",n,true);}}const d=dc({build:(e,n,o)=>bt$2(n),config:_c({disabled:"undefined"==typeof window}),name:"@lexical/dragon",register:(t,n,o)=>St$2(()=>o.getOutput().disabled.value?void 0:s(t))});
9318
9319/**
9320 * Copyright (c) Meta Platforms, Inc. and affiliates.
9321 *
9322 * This source code is licensed under the MIT license found in the
9323 * LICENSE file in the root directory of this source tree.
9324 *
9325 */
9326
9327const W$2="undefined"!=typeof window&&void 0!==window.document&&void 0!==window.document.createElement,B$2=W$2&&"documentMode"in document?document.documentMode:null,I$2=W$2&&/Mac|iPod|iPhone|iPad/.test(navigator.platform),R$1=!(!W$2||!("InputEvent"in window)||B$2)&&"getTargetRanges"in new window.InputEvent("input"),V$3=W$2&&/iPad|iPhone|iPod/.test(navigator.userAgent)&&!window.MSStream,j$2=W$2&&/Android/.test(navigator.userAgent),q$2=W$2&&/Version\/[\d.]+.*Safari/.test(navigator.userAgent)&&!j$2,z$2=W$2&&/^(?=.*Chrome).*/i.test(navigator.userAgent),F$2=W$2&&/AppleWebKit\/[\d.]+/.test(navigator.userAgent)&&I$2&&!z$2;function G$4(e,t){t.update(()=>{if(null!==e){const n=Bt$3(e,KeyboardEvent)?null:e.clipboardData,o=Qr();if(null!==o&&!o.isCollapsed()&&null!=n){e.preventDefault();const i=J$4(t);null!==i&&n.setData("text/html",i),n.setData("text/plain",o.getTextContent());}}});}function H$2(r){return Cc(r.registerCommand(fe$4,e=>{const t=Qr();return !!Fr(t)&&(t.deleteCharacter(e),true)},ro),r.registerCommand(ye$2,e=>{const t=Qr();return !!Fr(t)&&(t.deleteWord(e),true)},ro),r.registerCommand(me$3,e=>{const t=Qr();return !!Fr(t)&&(t.deleteLine(e),true)},ro),r.registerCommand(ge$3,t=>{const n=Qr();if(!Fr(n))return  false;if("string"==typeof t)n.insertText(t);else {const r=t.dataTransfer;if(null!=r)j$3(r,n);else {const e=t.data;e&&n.insertText(e);}}return  true},ro),r.registerCommand(pe$3,()=>{const e=Qr();return !!Fr(e)&&(e.removeText(),true)},ro),r.registerCommand(de$4,e=>{const t=Qr();return !!Fr(t)&&(t.insertLineBreak(e),true)},ro),r.registerCommand(he$3,()=>{const e=Qr();return !!Fr(e)&&(e.insertLineBreak(),true)},ro),r.registerCommand(Ne$1,e=>{const t=Qr();if(!Fr(t))return  false;
9327const n=e,r=n.shiftKey;return !!Q$8(t,true)&&(n.preventDefault(),ee$3(t,r,true),true)},ro),r.registerCommand(ke$2,e=>{const t=Qr();if(!Fr(t))return  false;const n=e,r=n.shiftKey;return !!Q$8(t,false)&&(n.preventDefault(),ee$3(t,r,false),true)},ro),r.registerCommand(Ae$3,e=>{const t=Qr();return !!Fr(t)&&((!V$3||"ko-KR"!==navigator.language)&&(e.preventDefault(),r.dispatchCommand(fe$4,true)))},ro),r.registerCommand(Pe$2,e=>{const t=Qr();return !!Fr(t)&&(e.preventDefault(),r.dispatchCommand(fe$4,false))},ro),r.registerCommand(Oe$2,e=>{const t=Qr();if(!Fr(t))return  false;if(null!==e){if((V$3||q$2||F$2)&&R$1)return  false;e.preventDefault();}return r.dispatchCommand(de$4,false)},ro),r.registerCommand(Ue$2,()=>(ys(),true),ro),r.registerCommand(Je$2,e=>{const t=Qr();return !!Fr(t)&&(G$4(e,r),true)},ro),r.registerCommand(je$2,e=>{const t=Qr();return !!Fr(t)&&(function(e,t){G$4(e,t),t.update(()=>{const e=Qr();Fr(e)&&e.removeText();});}(e,r),true)},ro),r.registerCommand(_e$2,t=>{const n=Qr();return !!Fr(n)&&(function(t,n){t.preventDefault(),n.update(()=>{const n=Qr(),r=Bt$3(t,ClipboardEvent)?t.clipboardData:null;null!=r&&Fr(n)&&j$3(r,n);},{tag:jn});}(t,r),true)},ro),r.registerCommand(ze$2,e=>q$3(e,r),ro),r.registerCommand(Be$2,e=>{const t=Qr();return !!Fr(t)&&(t.isCollapsed()||null===e.dataTransfer||B$3(e.dataTransfer,r),true)},ro))}
9328
9329/**
9330 * Copyright (c) Meta Platforms, Inc. and affiliates.
9331 *
9332 * This source code is licensed under the MIT license found in the
9333 * LICENSE file in the root directory of this source tree.
9334 *
9335 */
9336
9337function yt$2(t,e){if(void 0!==document.caretRangeFromPoint){const n=document.caretRangeFromPoint(t,e);return null===n?null:{node:n.startContainer,offset:n.startOffset}}if("undefined"!==document.caretPositionFromPoint){const n=document.caretPositionFromPoint(t,e);return null===n?null:{node:n.offsetNode,offset:n.offset}}return null}const xt$1="undefined"!=typeof window&&void 0!==window.document&&void 0!==window.document.createElement,Dt$2=xt$1&&"documentMode"in document?document.documentMode:null,_t$1=xt$1&&/Mac|iPod|iPhone|iPad/.test(navigator.platform),Nt$1=!(!xt$1||!("InputEvent"in window)||Dt$2)&&"getTargetRanges"in new window.InputEvent("input"),wt$1=xt$1&&/iPad|iPhone|iPod/.test(navigator.userAgent)&&!window.MSStream,Tt$2=xt$1&&/Android/.test(navigator.userAgent),Et$1=xt$1&&/Version\/[\d.]+.*Safari/.test(navigator.userAgent)&&!Tt$2,Ft$2=xt$1&&/^(?=.*Chrome).*/i.test(navigator.userAgent),Ot$2=xt$1&&/AppleWebKit\/[\d.]+/.test(navigator.userAgent)&&_t$1&&!Ft$2,Pt$2=re$5("DRAG_DROP_PASTE_FILE");let At$1 = class At extends Bi{static getType(){return "quote"}static clone(t){return new At(t.__key)}createDOM(t){const e=document.createElement("blockquote");return mc(e,t.theme.quote),e}updateDOM(t,e){return  false}static importDOM(){return {blockquote:t=>({conversion:kt$2,priority:0})}}exportDOM(t){const{element:e}=super.exportDOM(t);if(Ys(e)){this.isEmpty()&&e.append(document.createElement("br"));const t=this.getFormatType();t&&(e.style.textAlign=t);const n=this.getDirection();n&&(e.dir=n);}return {element:e}}static importJSON(t){return St$1().updateFromJSON(t)}insertNewAfter(t,e){const n=eo(),r=this.getDirection();return n.setDirection(r),this.insertAfter(n,e),n}collapseAtStart(){const t=eo();
9337return this.getChildren().forEach(e=>t.append(e)),this.replace(t),true}canMergeWhenEmpty(){return  true}};function St$1(){return zs(new At$1)}function Mt$2(t){return t instanceof At$1}let It$1 = class It extends Bi{__tag;static getType(){return "heading"}static clone(t){return new It(t.__tag,t.__key)}afterCloneFrom(t){super.afterCloneFrom(t),this.__tag=t.__tag;}constructor(t="h1",e){super(e),this.__tag=t;}getTag(){return this.getLatest().__tag}setTag(t){const e=this.getWritable();return e.__tag=t,e}createDOM(t){const e=this.__tag,n=document.createElement(e),r=t.theme.heading;if(void 0!==r){const t=r[e];mc(n,t);}return n}updateDOM(t,e,n){return t.__tag!==this.__tag}static importDOM(){return {h1:t=>({conversion:Kt$2,priority:0}),h2:t=>({conversion:Kt$2,priority:0}),h3:t=>({conversion:Kt$2,priority:0}),h4:t=>({conversion:Kt$2,priority:0}),h5:t=>({conversion:Kt$2,priority:0}),h6:t=>({conversion:Kt$2,priority:0}),p:t=>{const e=t.firstChild;return null!==e&&bt$1(e)?{conversion:()=>({node:null}),priority:3}:null},span:t=>bt$1(t)?{conversion:t=>({node:Jt$2("h1")}),priority:3}:null}}exportDOM(t){const{element:e}=super.exportDOM(t);if(Ys(e)){this.isEmpty()&&e.append(document.createElement("br"));const t=this.getFormatType();t&&(e.style.textAlign=t);const n=this.getDirection();n&&(e.dir=n);}return {element:e}}static importJSON(t){return Jt$2(t.tag).updateFromJSON(t)}updateFromJSON(t){return super.updateFromJSON(t).setTag(t.tag)}exportJSON(){return {...super.exportJSON(),tag:this.getTag()}}insertNewAfter(t,e=true){const n=t?t.anchor.offset:0,r=this.getLastDescendant(),o=!r||t&&t.anchor.key===r.getKey()&&n===r.getTextContentSize()||!t?eo():Jt$2(this.getTag()),i=this.getDirection();if(o.setDirection(i),this.insertAfter(o,e),0===n&&!this.isEmpty()&&t){const t=eo();t.select(),this.replace(t,true);}return o}collapseAtStart(){const t=this.isEmpty()?eo():Jt$2(this.getTag());
9337return this.getChildren().forEach(e=>t.append(e)),this.replace(t),true}extractWithChild(){return  true}};function bt$1(t){return "span"===t.nodeName.toLowerCase()&&"26pt"===t.style.fontSize}function Kt$2(t){const e=t.nodeName.toLowerCase();let n=null;return "h1"!==e&&"h2"!==e&&"h3"!==e&&"h4"!==e&&"h5"!==e&&"h6"!==e||(n=Jt$2(e),null!==t.style&&(sl(t,n),n.setFormat(t.style.textAlign))),{node:n}}function kt$2(t){const e=St$1();return null!==t.style&&(e.setFormat(t.style.textAlign),sl(t,e)),{node:e}}function Jt$2(t="h1"){return zs(new It$1(t))}function Lt$2(t){return t instanceof It$1}function Wt$2(t){let e=null;if(Bt$3(t,DragEvent)?e=t.dataTransfer:Bt$3(t,ClipboardEvent)&&(e=t.clipboardData),null===e)return [false,[],false];const n=e.types,r=n.includes("Files"),o=n.includes("text/html")||n.includes("text/plain");return [r,Array.from(e.files),o]}function Rt$2(t){const e=Go(t);return ji(e)}function qt$2(t){for(const e of ["lowercase","uppercase","capitalize"])t.hasFormat(e)&&t.toggleFormat(e);}function zt$2(s){return Cc(s.registerCommand(se$5,t=>{const e=Qr();return !!Ir(e)&&(e.clear(),true)},ro),s.registerCommand(fe$4,t=>{const e=Qr();return Fr(e)?(e.deleteCharacter(t),true):!!Ir(e)&&(e.deleteNodes(),true)},ro),s.registerCommand(ye$2,t=>{const e=Qr();return !!Fr(e)&&(e.deleteWord(t),true)},ro),s.registerCommand(me$3,t=>{const e=Qr();return !!Fr(e)&&(e.deleteLine(t),true)},ro),s.registerCommand(ge$3,e=>{const n=Qr();if("string"==typeof e)null!==n&&n.insertText(e);else {if(null===n)return  false;const r=e.dataTransfer;if(null!=r)I$3(r,n,s);else if(Fr(n)){const t=e.data;return t&&n.insertText(t),true}}return  true},ro),s.registerCommand(pe$3,()=>{const t=Qr();return !!Fr(t)&&(t.removeText(),true)},ro),s.registerCommand(xe,t=>{const e=Qr();return !!Fr(e)&&(e.formatText(t),true)},ro),s.registerCommand(Re$1,t=>{const e=Qr();if(!Fr(e)&&!Ir(e))return  false;const n=e.getNodes();for(const e of n){const n=dl(e,t=>Wi(t)&&!t.isInline());null!==n&&n.setFormat(t);}return  true},ro),s.registerCommand(de$4,t=>{const e=Qr();return !!Fr(e)&&(e.insertLineBreak(t),true)},ro),s.registerCommand(he$3,()=>{const t=Qr();return !!Fr(t)&&(t.insertParagraph(),true)},ro),s.registerCommand(Le$2,()=>{const t=wr(),e=Qr();return Fr(e)&&(t.setFormat(e.format),t.setStyle(e.style)),li([t]),true},ro),s.registerCommand(Ie$3,()=>_t$2(t=>{const e=t.getIndent();t.setIndent(e+1);}),ro),s.registerCommand(Ke$2,()=>_t$2(t=>{const e=t.getIndent();e>0&&t.setIndent(Math.max(0,e-1));}),ro),s.registerCommand(we$1,t=>{const e=Qr();if(Ir(e)){const n=e.getNodes();if(n.length>0)return t.preventDefault(),n[0].selectPrevious(),true}else if(Fr(e)){const n=vs(e.focus,true);if(!t.shiftKey&&ji(n)&&!n.isIsolated()&&!n.isInline())return n.selectPrevious(),t.preventDefault(),true}return  false},ro),s.registerCommand(Ee$3,t=>{const e=Qr();if(Ir(e)){const n=e.getNodes();if(n.length>0)return t.preventDefault(),n[0].selectNext(0,0),true}else if(Fr(e)){if(function(t){const e=t.focus;return "root"===e.key&&e.offset===Zo().getChildrenSize()}(e))return t.preventDefault(),true;const n=vs(e.focus,false);if(!t.shiftKey&&ji(n)&&!n.isIsolated()&&!n.isInline())return n.selectNext(),t.preventDefault(),true}return  false},ro),s.registerCommand(Ne$1,t=>{const e=Qr();if(Ir(e)){const n=e.getNodes();if(n.length>0)return t.preventDefault(),O$3(n[0])?n[0].selectNext(0,0):n[0].selectPrevious(),true}if(!Fr(e))return  false;if(Q$8(e,true)){const n=t.shiftKey;return t.preventDefault(),ee$3(e,n,true),true}return  false},ro),s.registerCommand(ke$2,t=>{const e=Qr();if(Ir(e)){const n=e.getNodes();if(n.length>0)return t.preventDefault(),O$3(n[0])?n[0].selectPrevious():n[0].selectNext(0,0),true}if(!Fr(e))return  false;const n=t.shiftKey;return !!Q$8(e,false)&&(t.preventDefault(),ee$3(e,n,false),true)},ro),s.registerCommand(Ae$3,t=>{if(Rt$2(t.target))return  false;const e=Qr();if(Fr(e)){if(function(t){if(!t.isCollapsed())return  false;const{anchor:e}=t;if(0!==e.offset)return  false;const n=e.getNode();if(Vi(n))return  false;const r=Nt$2(n);return r.getIndent()>0&&(r.is(n)||n.is(r.getFirstDescendant()))}(e))return t.preventDefault(),s.dispatchCommand(Ke$2,void 0);if(wt$1&&"ko-KR"===navigator.language)return  false}else if(!Ir(e))return  false;return t.preventDefault(),s.dispatchCommand(fe$4,true)},ro),s.registerCommand(Pe$2,t=>{if(Rt$2(t.target))return  false;
9337const e=Qr();return !(!Fr(e)&&!Ir(e))&&(t.preventDefault(),s.dispatchCommand(fe$4,false))},ro),s.registerCommand(Oe$2,t=>{const e=Qr();if(!Fr(e))return  false;if(qt$2(e),null!==t){if((wt$1||Et$1||Ot$2)&&Nt$1)return  false;if(t.preventDefault(),t.shiftKey)return s.dispatchCommand(de$4,false)}return s.dispatchCommand(he$3,void 0)},ro),s.registerCommand(De$2,()=>{const t=Qr();return !!Fr(t)&&(s.blur(),true)},ro),s.registerCommand(ze$2,t=>{const[,n]=Wt$2(t);if(n.length>0){const e=yt$2(t.clientX,t.clientY);if(null!==e){const{offset:t,node:r}=e,o=Go(r);if(null!==o){const e=qr();if(Tr(o))e.anchor.set(o.getKey(),t,"text"),e.focus.set(o.getKey(),t,"text");else {const t=o.getParentOrThrow().getKey(),n=o.getIndexWithinParent()+1;e.anchor.set(t,n,"element"),e.focus.set(t,n,"element");}const n=St$3(e);es(n);}s.dispatchCommand(Pt$2,n);}return t.preventDefault(),true}return W$3(t,s)},ro),s.registerCommand(Be$2,t=>{const[e]=Wt$2(t),i=Qr();return !(e&&!Fr(i))&&(Fr(i)&&!i.isCollapsed()&&null!==t.dataTransfer&&(nt$1(t.dataTransfer,et(i)),B$3(t.dataTransfer,s)),true)},ro),s.registerCommand(We$2,t=>{const[e]=Wt$2(t),n=Qr();if(e&&!Fr(n))return  false;const r=yt$2(t.clientX,t.clientY);if(null!==r){const e=Go(r.node);ji(e)&&t.preventDefault();}return  true},ro),s.registerCommand(Ue$2,()=>(ys(),true),ro),s.registerCommand(Je$2,t=>(V$4(s,Bt$3(t,ClipboardEvent)?t:null),true),ro),s.registerCommand(je$2,t=>(async function(t,e){await V$4(e,Bt$3(t,ClipboardEvent)?t:null),e.update(()=>{const t=Qr();Fr(t)?t.removeText():Ir(t)&&t.getNodes().forEach(t=>t.remove());});}(t,s),true),ro),s.registerCommand(_e$2,e=>{const[,n,r]=Wt$2(e);if(n.length>0&&!r)return s.dispatchCommand(Pt$2,n),true;if(qs(e.target)&&Oo(e.target))return  false;return null!==Qr()&&(function(e,n){e.preventDefault(),n.update(()=>{const r=Qr(),o=Bt$3(e,InputEvent)||Bt$3(e,KeyboardEvent)?null:e.clipboardData;null!=o&&null!==r&&I$3(o,r,n);},{tag:jn});}(e,s),true)},ro),s.registerCommand(Me$2,t=>{const e=Qr();return Fr(e)&&qt$2(e),false},ro),s.registerCommand(Fe$2,t=>{const e=Qr();return Fr(e)&&qt$2(e),false},ro))}const Xt$2=dc({conflictsWith:["@lexical/plain-text"],dependencies:[d],name:"@lexical/rich-text",nodes:()=>[It$1,At$1],register:zt$2});
9338
9339// An editor's sanitizer: the allowlist it was registered with, applied to a
9340// string.
9341//
9342// The allowlist is per editor, and passed to each sanitize() call. Neither of
9343// those is incidental. This used to be a module-level config installed with
9344// DOMPurify.setConfig() on the shared singleton, which had two distinct
9345// consequences:
9346//
9347// 1. A persistent config is final — DOMPurify ignores the per-call config once
9348//    one is set — so it silently disarmed the sanitizing of any host app that
9349//    also imports dompurify. See config/dom_purify for why we now own our
9350//    instance; keeping the config per-call means there is no global sanitizer
9351//    state left even on that instance.
9352//
9353// 2. One config for the whole module meant the last editor to connect decided
9354//    how every other editor on the page sanitized. That is not cosmetic: an
9355//    editor's `value` is sanitized on read, so a rich editor sharing a page with
9356//    a plain one would silently drop its own headings, lists and links from the
9357//    value it submits.
9358//
9359// Sanitizers are keyed by the Lexical editor, which is the identity both call
9360// sites have: the element registers with it and keeps the result as
9361// `this.sanitizer`, while nodes only receive it as createDOM()'s second argument
9362// and resolve their sanitizer with for().
9363class EditorSanitizer {
9364  static #instances = new WeakMap()
9365
9366  // Only reached for an editor that never registered, which is a supported case:
9367  // CustomActionTextAttachmentNode is exported from src/index.js, so it can be
9368  // registered in a Lexical editor Lexxy did not build.
9369  //
9370  // Fixed, and never reassigned. Pointing it at whichever sanitizer registered
9371  // most recently would make an unregistered consumer's allowlist depend on
9372  // which Lexxy editor happened to initialise last — the last-editor-wins bug
9373  // this class exists to remove, reintroduced on the one path that has no editor
9374  // to key on, and unobservable from the consumer's own code.
9375  //
9376  // It declares no allowlist, so DOMPurify's own default policy applies. An
9377  // empty allowlist would be deterministic too and strips every tag, which
9378  // silently drops markup a standalone consumer used to keep. It holds no
9379  // editor either, so nothing here pins a disconnected editor's DOM.
9380  //
9381  // A consumer wanting its own allowlist registers for it: register() needs only
9382  // the Lexical editor and is reachable as EditorSanitizer from src/index.js.
9383  //
9384  // Built on first use rather than as a static field initializer, which would run
9385  // buildConfig at import: src/index.js exports this class, so that would create
9386  // the Trusted Types policy — and, unallowlisted, report a CSP violation — on
9387  // every page load of an app that never renders an editor.
9388  static #fallback
9389
9390  static #fallbackSanitizer() {
9391    return this.#fallback ||= new EditorSanitizer()
9392  }
9393
9394  static register(editor, allowedElements = []) {
9395    const sanitizer = new EditorSanitizer(this.#allowedElementsFor(editor, allowedElements));
9396    this.#instances.set(editor, sanitizer);
9397
9398    return sanitizer
9399  }
9400
9401  static for(editor) {
9402    return this.#instances.get(editor) ?? this.#fallbackSanitizer()
9403  }
9404
9405  // An editor can import every tag it can convert from HTML, plus whatever its
9406  // extensions declare. Lexical registers the conversions while building the
9407  // editor, so they are already in place when $initialEditorState registers us.
9408  static #allowedElementsFor(editor, allowedElements) {
9409    return this.#importableTags(editor).concat(allowedElements)
9410  }
9411
9412  static #importableTags(editor) {
9413    const tags = Array.from(editor._htmlConversions.keys());
9414    return tags.filter(tag => !tag.startsWith("#"))
9415  }
9416
9417  #config
9418
9419  constructor(allowedElements = null) {
9420    this.#config = buildConfig(allowedElements);
9421  }
9422
9423  // safeForXml opts into DOMPurify's mXSS-safe mode, for a caller re-inflating
9424  // stored content. It is off by default, and the reason is not that the default
9425  // hop is trustworthy — the value an editor reads back carries the attacker's
9426  // stored `content` verbatim. The reason is that strictness there is destructive:
9427  // SAFE_FOR_XML drops any attribute whose value could close a comment, a
9428  // serialized `content` full of Rails view annotations is exactly that, and
9429  // CustomActionTextAttachmentNode.importDOM returns null for an attachment with no
9430  // `content` — so the attachment vanishes on the next edit. Verified: strict on the
9431  // value hop leaves `<action-text-attachment sgid content-type>` and re-editing that
9432  // renders nothing.
9433  //
9434  // The strict config is this instance's own, spread rather than rebuilt, so the
9435  // per-editor allowlist and everything else buildConfig put there — the Trusted
9436  // Types policy, ADD_URI_SAFE_ATTR — survive the flip.
9437  sanitize(html, { safeForXml = false } = {}) {
9438    if (safeForXml) {
9439      return DOMPurify.sanitize(html, { ...this.#config, SAFE_FOR_XML: true })
9440    }
9441
9442    return DOMPurify.sanitize(html, this.#config)
9443  }
9444}
9445
9446function bytesToHumanSize(bytes) {
9447  if (bytes === 0) return "0 B"
9448  const sizes = [ "B", "KB", "MB", "GB", "TB", "PB" ];
9449  const i = Math.floor(Math.log(bytes) / Math.log(1024));
9450  const value = bytes / Math.pow(1024, i);
9451  return `${ value.toFixed(2) } ${ sizes[i] }`
9452}
9453
9454function extractFileName(string) {
9455  return string.split("/").pop()
9456}
9457
9458// The content attribute is raw HTML (matching Trix/ActionText). Older Lexxy
9459// versions JSON-encoded it, so try JSON.parse first for backward compatibility.
9460function parseAttachmentContent(content) {
9461  try {
9462    return JSON.parse(content)
9463  } catch {
9464    return content
9465  }
9466}
9467
9468function mimeTypeToExtension(mimeType) {
9469  if (!mimeType) return null
9470
9471  const extension = mimeType.split("/")[1];
9472  return extension
9473}
vendor: 2,951 bytes, lines 9473-9553
9473
9474
9475class CustomActionTextAttachmentNode extends Ji {
9476  static getType() {
9477    return "custom_action_text_attachment"
9478  }
9479
9480  static clone(node) {
9481    return new CustomActionTextAttachmentNode({ ...node }, node.__key)
9482  }
9483
9484  static importJSON(serializedNode) {
9485    return new CustomActionTextAttachmentNode({ ...serializedNode })
9486  }
9487
9488  static importDOM() {
9489    return {
9490      [this.TAG_NAME]: (element) => {
9491        if (!element.getAttribute("content")) {
9492          return null
9493        }
9494
9495        return {
9496          conversion: (attachment) => {
9497            // Preserve initial space if present since Lexical removes it
9498            const nodes = [];
9499            const previousSibling = attachment.previousSibling;
9500            if (previousSibling && previousSibling.nodeType === Node.TEXT_NODE && /\s$/.test(previousSibling.textContent)) {
9501              nodes.push(kr(" "));
9502            }
9503
9504            const innerHtml = parseAttachmentContent(attachment.getAttribute("content"));
9505
9506            nodes.push(new CustomActionTextAttachmentNode({
9507              sgid: attachment.getAttribute("sgid"),
9508              innerHtml,
9509              plainText: attachment.textContent.trim() || extractPlainTextFromHtml(innerHtml),
9510              contentType: attachment.getAttribute("content-type")
9511            }));
9512
9513            const nextSibling = attachment.nextSibling;
9514            if (nextSibling && nextSibling.nodeType === Node.TEXT_NODE && /^\s/.test(nextSibling.textContent)) {
9515              nodes.push(kr(" "));
9516            }
9517
9518            return { node: nodes }
9519          },
9520          priority: 2
9521        }
9522      }
9523    }
9524  }
9525
9526  static get TAG_NAME() {
9527    return Lexxy.global.get("attachmentTagName")
9528  }
9529
9530  constructor({ tagName, sgid, contentType, innerHtml, plainText } = {}, key) {
9531    super(key);
9532
9533    const contentTypeNamespace = Lexxy.global.get("attachmentContentTypeNamespace");
9534
9535    this.tagName = tagName || CustomActionTextAttachmentNode.TAG_NAME;
9536    this.sgid = sgid;
9537    this.contentType = contentType || `application/vnd.${contentTypeNamespace}.unknown`;
9538    this.innerHtml = innerHtml;
9539    this.plainText = plainText ?? extractPlainTextFromHtml(innerHtml);
9540  }
9541
9542  createDOM(_config, editor) {
9543    const figure = createElement(this.tagName, { "content-type": this.contentType, "data-lexxy-decorator": true, draggable: true });
9544    figure.dataset.lexicalNodeKey = this.__key;
9545
9546    // Resolved from the editor so this content is sanitized with its own
9547    // allowlist rather than whichever editor connected most recently.
9548    //
9549    // this.innerHtml is untrusted stored content being re-inflated into the editor,
9550    // so it goes through DOMPurify's mXSS-safe mode. Strictness is free here because
9551    // of where the `content` attribute that has to survive is sanitized, which is not
9552    // this hop: it is produced by exportDOM and by the server-side pass in
9553    // lib/lexxy/rich_text_area_tag.rb, and it is only ever sanitized on the lax hop
9554    // where an editor reads its own value back.
9555    //
9556    // The decoded inner markup can carry a `content` attribute of its own — nested
9557    // attachment markup does, and the attribute is allowlisted on the attachment tag
9558    // in extensions/attachments_extension.js — and mXSS-safe mode drops it. That loss
9559    // is cosmetic: it is a nested attachment's rendering inside this one, not the
9560    // attribute anything re-imports from.
9561    figure.insertAdjacentHTML("beforeend", EditorSanitizer.for(editor).sanitize(this.innerHtml, { safeForXml: true }));
9562
9563    const deleteButton = createElement("lexxy-node-delete-button");
9564    figure.appendChild(deleteButton);
9565
9566    return figure
9567  }
9568
9569  updateDOM() {
9570    return false
9571  }
9572
9573  getTextContent() {
9574    return "\ufeff"
9575  }
9576
9577  getReadableTextContent() {
9578    return this.plainText || `[${this.contentType}]`
9579  }
9580
9581  isInline() {
9582    return true
9583  }
9584
9585  exportDOM() {
9586    const attachment = createElement(this.tagName, {
9587      sgid: this.sgid,
9588      content: this.innerHtml,
9589      "content-type": this.contentType
9590    });
9591
9592    return { element: attachment }
9593  }
9594
9595  exportJSON() {
9596    return {
9597      type: "custom_action_text_attachment",
9598      version: 1,
9599      tagName: this.tagName,
9600      sgid: this.sgid,
9601      contentType: this.contentType,
9602      innerHtml: this.innerHtml,
9603      plainText: this.plainText
9604    }
9605  }
9606
9607  decorate() {
9608    return null
9609  }
9610}
9611
9612function $isCustomActionTextAttachmentNode(node) {
9613  return node instanceof CustomActionTextAttachmentNode
9614}
9615
9616function dasherize(value) {
9617  return value.replace(/([A-Z])/g, (_, char) => `-${char.toLowerCase()}`)
9618}
9619
9620function isAutolinkableURL(string) {
9621  return /^(?:[a-z0-9]+:\/\/|www\.)[^\s]+$/i.test(string)
9622}
9623
9624function normalizeFilteredText(string) {
9625  return string
9626    .toLowerCase()
9627    .normalize("NFD").replace(/[\u0300-\u036f]/g, "") // Remove diacritics
9628}
9629
9630function filterMatchPosition(text, potentialMatch) {
9631  const normalizedText = normalizeFilteredText(text);
9632  const normalizedMatch = normalizeFilteredText(potentialMatch);
9633
9634  if (!normalizedMatch) return 0
9635
9636  const match = normalizedText.match(new RegExp(`(?<![\\p{L}\\p{N}])${escapeForRegExp(normalizedMatch)}`, "u"));
9637  return match ? match.index : -1
9638}
9639
9640function upcaseFirst(string) {
9641  return string.charAt(0).toUpperCase() + string.slice(1)
9642}
9643
9644function escapeForRegExp(string) {
9645  return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")
9646}
9647
9648// Parses a value that may arrive as a boolean or as a string (e.g. from DOM
9649// getAttribute) into a proper boolean. Ensures "false" doesn't evaluate as truthy.
9650function parseBoolean(value) {
9651  if (typeof value === "string") return value === "true"
9652  return Boolean(value)
9653}
9654
9655/**
9656 * Copyright (c) Meta Platforms, Inc. and affiliates.
9657 *
9658 * This source code is licensed under the MIT license found in the
9659 * LICENSE file in the root directory of this source tree.
9660 *
9661 */
9662
9663function C$2(t,e,n,r,o){if(null===t||0===n.size&&0===r.size&&!o)return 0;const i=e._selection,a=t._selection;if(o)return 1;if(!(Fr(i)&&Fr(a)&&a.isCollapsed()&&i.isCollapsed()))return 0;const s=function(t,e,n){const r=t._nodeMap,o=[];for(const t of e){const e=r.get(t);void 0!==e&&o.push(e);}for(const[t,e]of n){if(!e)continue;const n=r.get(t);void 0===n||Vi(n)||o.push(n);}return o}(e,n,r);if(0===s.length)return 0;if(s.length>1){const n=e._nodeMap,r=n.get(i.anchor.key),o=n.get(a.anchor.key);return r&&o&&!t._nodeMap.has(r.__key)&&Tr(r)&&1===r.__text.length&&1===i.anchor.offset?2:0}const d=s[0],l=t._nodeMap.get(d.__key);if(!Tr(l)||!Tr(d)||l.__mode!==d.__mode)return 0;const u=l.__text,c=d.__text;if(u===c)return 0;const f=i.anchor,p=a.anchor;if(f.key!==p.key||"text"!==f.type)return 0;const h=f.offset,m=p.offset,g=c.length-u.length;return 1===g&&m===h-1?2:-1===g&&m===h+1?3:-1===g&&m===h?4:0}function b$1(t,e,n){let r=n(),o=0,i=r,a=0,s=null;return (d,l,u,c,f,p)=>{const h=n();if(p.has(Gn)&&(i=r,a=o,s=d),p.has(Wn$1))return o=0,r=h,2;p.has(Xn)&&s&&(r=i,o=a,d=s);const x=C$2(d,l,c,f,t.isComposing()),b=(()=>{const n=null===u||u.editor===t,i=p.has($n$1);if(!i&&n&&p.has(Jn))return 0;if(1===x)return 2;if(null===d)return 1;const a=l._selection;if(!(c.size>0||f.size>0))return null!==a?0:2;const s="number"==typeof e?e:e.peek();if(false===i&&0!==x&&x===o&&h<r+s&&n)return 0;if(1===c.size){if(function(t,e,n){const r=e._nodeMap.get(t),o=n._nodeMap.get(t),i=e._selection,a=n._selection;return !(Fr(i)&&Fr(a)&&"element"===i.anchor.type&&"element"===i.focus.type&&"text"===a.anchor.type&&"text"===a.focus.type||!Tr(r)||!Tr(o)||r.__parent!==o.__parent)&&JSON.stringify(e.read(()=>r.exportJSON()))===JSON.stringify(n.read(()=>o.exportJSON()))}(Array.from(c)[0],d,l))return 0}return 1})();return r=h,o=x,b}}function w$2(t){t.undoStack=[],t.redoStack=[],t.current=null;}
9663function E$1(t,e,n,r=Date.now){const i=b$1(t,n,r);return Cc(t.registerCommand(Ce$2,()=>(function(t,e){const n=e.redoStack,r=e.undoStack;if(0!==r.length){const o=e.current,i=r.pop();null!==o&&(n.push(o),t.dispatchCommand(qe$2,true)),0===r.length&&t.dispatchCommand(He$2,false),e.current=i||null,i&&i.editor.setEditorState(i.editorState,{tag:Wn$1});}}(t,e),true),ro),t.registerCommand(Se$2,()=>(function(t,e){const n=e.redoStack,r=e.undoStack;if(0!==n.length){const o=e.current;null!==o&&(r.push(o),t.dispatchCommand(He$2,true));const i=n.pop();0===n.length&&t.dispatchCommand(qe$2,false),e.current=i||null,i&&i.editor.setEditorState(i.editorState,{tag:Wn$1});}}(t,e),true),ro),t.registerCommand(Ve$2,()=>(w$2(e),false),ro),t.registerCommand(Ye$1,()=>(w$2(e),t.dispatchCommand(qe$2,false),t.dispatchCommand(He$2,false),true),ro),t.registerUpdateListener(({editorState:n,prevEditorState:r,dirtyLeaves:o,dirtyElements:a,tags:s})=>{const d=e.current,l=e.redoStack,u=e.undoStack,c=null===d?null:d.editorState;if(null!==d&&n===c)return;const f=i(r,n,d,o,a,s);if(1===f)0!==l.length&&(e.redoStack=[],t.dispatchCommand(qe$2,false)),null!==d&&(u.push({...d}),t.dispatchCommand(He$2,true));else if(2===f)return;e.current={editor:t,editorState:n};}))}function M$2(){return {current:null,redoStack:[],undoStack:[]}}const O$1=dc({build:(t,{delay:n,createInitialHistoryState:r,disabled:o,now:i})=>bt$2({delay:n,disabled:o,historyState:r(t),now:i}),config:_c({createInitialHistoryState:M$2,delay:300,disabled:"undefined"==typeof window,now:Date.now}),name:"@lexical/history/History",register:(e,n,r)=>{const o=r.getOutput();return St$2(()=>o.disabled.value?void 0:E$1(e,o.historyState.value,o.delay,()=>o.now.peek()()))}});dc({build:(t,{disabled:n,parentEditor:r})=>bt$2({disabled:n,parentEditor:r||t._parentEditor}),config:_c({disabled:false,parentEditor:null}),dependencies:[hc(O$1,{disabled:true})],name:"@lexical/history/SharedHistory",register:(e,o,i)=>St$2(()=>{const{disabled:t,parentEditor:e}=i.getOutput();if(!t.value){const{output:t}=i.getDependency(O$1),o=function(t){return t?fe$3(t,O$1.name):null}(e.value);if(!o)return;const a=o.output;Y$3(()=>{t.delay.value=a.delay.value,t.historyState.value=a.historyState.value,t.now.value=a.now.value,t.disabled.value=a.disabled.value;});}})});
9664
9665class LexxyExtension {
9666  #editorElement
9667
9668  constructor(editorElement) {
9669    this.#editorElement = editorElement;
9670  }
9671
9672  get editorElement() {
9673    return this.#editorElement
9674  }
9675
9676  get editorConfig() {
9677    return this.#editorElement.config
9678  }
9679
9680  // optional: defaults to true
9681  get enabled() {
9682    return true
9683  }
9684
9685  get lexicalExtension() {
9686    return null
9687  }
9688
9689  get allowedElements() {
9690    return []
9691  }
9692
9693  defineExtension(...args) {
9694    return dc(...args)
9695  }
9696
9697  initializeToolbar(_lexxyToolbar) {
9698  }
9699
9700  setEditorValidity(flags, message) {
9701    this.editorElement.setElementValidity(this, flags, message);
9702  }
9703
9704  dispose() {
9705  }
9706}
9707
9708function $containsRangeSelection(node, selection = Qr()) {
9709  if (Fr(selection)) {
9710    const { commonAncestor } = Yl(selection.focus.getNode(), selection.anchor.getNode());
9711    return dl(commonAncestor, parent => parent.is(node))
9712  } else {
9713    return false
9714  }
9715}
9716
9717function $createNodeSelectionWith(...nodes) {
9718  const selection = Hr();
9719  nodes.forEach(node => selection.add(node.getKey()));
9720  return selection
9721}
9722
9723function $isShadowRoot(node) {
9724  return Wi(node) && Is(node) && !Vi(node)
9725}
9726
9727function $isSafeForRoot(node) {
9728  return (Wi(node) || ji(node)) && !node.isParentRequired()
9729}
9730
9731function $makeSafeForRoot(node) {
9732  if ($isSafeForRoot(node)) {
9733    return node
9734  } else if (node.getParent()) {
9735    return Tt$4(node, () => node.createParentElementNode())
9736  } else {
9737    // Detached nodes (e.g. clipboard nodes being inserted) can't be `replace`d in place,
9738    // so append them into a fresh required parent instead.
9739    return node.createParentElementNode().append(node)
9740  }
9741}
9742
9743function getListType(node) {
9744  const list = At$2(node, me$2);
9745  return list?.getListType() ?? null
9746}
9747
9748function isEditorFocused(editor) {
9749  const rootElement = editor.getRootElement();
9750  return rootElement !== null && rootElement.contains(document.activeElement)
9751}
9752
9753function $isAtNodeEdge(point, atStart = null) {
9754  if (atStart === null) {
9755    return $isAtNodeEdge(point, true) || $isAtNodeEdge(point, false)
9756  } else {
9757    return atStart ? $isAtNodeStart(point) : A$2(point)
9758  }
9759}
9760
9761function $isAtNodeStart(point) {
9762  return point.offset === 0
9763}
9764
9765function extendTextNodeConversion(conversionName, ...callbacks) {
9766  return extendConversion(gr, conversionName, (conversionOutput, element) => ({
9767    ...conversionOutput,
9768    forChild: (lexicalNode, parentNode) => {
9769      const originalForChild = conversionOutput?.forChild ?? (x => x);
9770      let childNode = originalForChild(lexicalNode, parentNode);
9771
9772
9773      if (Tr(childNode)) {
9774        childNode = callbacks.reduce(
9775          (childNode, callback) => callback(childNode, element) ?? childNode,
9776          childNode
9777        );
9778        return childNode
9779      }
9780    }
9781  }))
9782}
9783
9784function extendConversion(nodeKlass, conversionName, callback = (output => output)) {
9785  return (element) => {
9786    const converter = nodeKlass.importDOM()?.[conversionName]?.(element);
9787    if (!converter) return null
9788
9789    const conversionOutput = converter.conversion(element);
9790    if (!conversionOutput) return conversionOutput
9791
9792    return callback(conversionOutput, element) ?? conversionOutput
9793  }
9794}
9795
9796function $isCursorOnLastLine(selection) {
9797  const anchorNode = selection.anchor.getNode();
9798  const elementNode = Wi(anchorNode) ? anchorNode : anchorNode.getParentOrThrow();
9799  const children = elementNode.getChildren();
9800  if (children.length === 0) return true
9801
9802  const lastChild = children[children.length - 1];
9803
9804  if (anchorNode === elementNode.getLatest() && selection.anchor.offset === children.length) return true
9805  if (anchorNode === lastChild) return true
9806
vendor: 24,061 bytes, lines 9807-10579
9807  const lastLineBreakIndex = children.findLastIndex(child => sr(child));
9808  if (lastLineBreakIndex === -1) return true
9809
9810  const anchorIndex = children.indexOf(anchorNode);
9811  return anchorIndex > lastLineBreakIndex
9812}
9813
9814function $isBlankNode(node) {
9815  if (node.getTextContent().trim() !== "") return false
9816
9817  const children = node.getChildren?.();
9818  if (!children || children.length === 0) return true
9819
9820  return children.every(child => {
9821    if (sr(child)) return true
9822    return $isBlankNode(child)
9823  })
9824}
9825
9826function $trimTrailingBlankNodes(parent) {
9827  for (const child of zt$4(parent)) {
9828    if ($isBlankNode(child)) {
9829      child.remove();
9830    } else {
9831      break
9832    }
9833  }
9834}
9835
9836// A list item is structurally empty if it contains no meaningful content.
9837// Unlike getTextContent().trim() === "", this walks descendants to ensure
9838// decorator nodes (mentions, attachments whose getTextContent() may return
9839// invisible characters like \ufeff) are treated as non-empty content.
9840function $isListItemStructurallyEmpty(listItem) {
9841  const children = listItem.getChildren();
9842  for (const child of children) {
9843    if (ji(child)) return false
9844    if (sr(child)) continue
9845    if (Tr(child)) {
9846      if (child.getTextContent().trim() !== "") return false
9847    } else if (Wi(child)) {
9848      if (child.getTextContent().trim() !== "") return false
9849    }
9850  }
9851  return true
9852}
9853
9854// Returns the document text up to `offset` inside `targetNode`. Non-inline
9855// element siblings are joined with `\n\n`, matching Lexical's own
9856// ElementNode.getTextContent behavior.
9857function $textBeforeOffset(targetNode, offset) {
9858  const parts = [];
9859  let done = false;
9860
9861  function visit(node) {
9862    if (done) return
9863    if (node === targetNode) {
9864      parts.push(node.getTextContent().slice(0, offset));
9865      done = true;
9866      return
9867    }
9868    if (Wi(node)) {
9869      const children = node.getChildren();
9870      for (let i = 0; i < children.length; i++) {
9871        visit(children[i]);
9872        if (done) return
9873        const child = children[i];
9874        if (Wi(child) && !child.isInline() && i < children.length - 1) {
9875          parts.push("\n\n");
9876        }
9877      }
9878    } else {
9879      parts.push(node.getTextContent());
9880    }
9881  }
9882
9883  visit(Zo());
9884  return parts.join("")
9885}
9886
9887function isAttachmentSpacerTextNode(node, previousNode, index, childCount) {
9888  return Tr(node)
9889    && node.getTextContent() === " "
9890    && index === childCount - 1
9891    && previousNode instanceof CustomActionTextAttachmentNode
9892}
9893
9894function $splitSelectedParagraphsAtInnerLineBreaks(selection) {
9895  const topLevelElements = new Set();
9896  for (const node of selection.getNodes()) {
9897    const topLevel = node.getTopLevelElement();
9898    if (topLevel) topLevelElements.add(topLevel);
9899  }
9900
9901  for (const element of topLevelElements) {
9902    if (!no(element)) continue
9903
9904    const children = element.getChildren();
9905    if (!children.some(sr)) continue
9906
9907    const groups = [ [] ];
9908    for (const child of children) {
9909      if (sr(child)) {
9910        groups.push([]);
9911        child.remove();
9912      } else {
9913        groups[groups.length - 1].push(child);
9914      }
9915    }
9916
9917    for (const group of groups) {
9918      if (group.length === 0) continue
9919      const paragraph = eo();
9920      group.forEach(child => paragraph.append(child));
9921      element.insertBefore(paragraph);
9922    }
9923    if (groups.some(group => group.length > 0)) element.remove();
9924  }
9925}
9926
9927function $expandSelectionToLineBreaksAndSplitAtEdges(selection, fallbackAncestor = (node) => node.getTopLevelElement()) {
9928  j$6(selection);
9929  $shrinkSelectionPastBlockEdges(selection);
9930
9931  const focusCaret = ql(selection.focus, "next");
9932  const anchorCaret = ql(selection.anchor, "previous");
9933
9934  // A collapsed cursor adjacent to a <br> would claim it from both sides via
9935  // inward-edge; force outward-only walks so each side finds its own boundary.
9936  const skipInwardEdge = selection.isCollapsed();
9937  const focusBrCaret = $getCaretAtLineBreakBoundary(focusCaret, skipInwardEdge);
9938  let anchorBrCaret = $getCaretAtLineBreakBoundary(anchorCaret, skipInwardEdge);
9939
9940  if (focusBrCaret?.origin.is(anchorBrCaret?.origin)) {
9941    anchorBrCaret = null;
9942  }
9943
9944  // Splitting focus first keeps the anchor <br>'s position stable.
9945  const focusOuter = focusBrCaret && $splitAroundLineBreak(focusBrCaret);
9946  const anchorOuter = anchorBrCaret && $splitAroundLineBreak(anchorBrCaret);
9947
9948  const innerStart = anchorOuter?.getNextSibling() ?? fallbackAncestor(selection.anchor.getNode());
9949  const innerEnd = focusOuter?.getPreviousSibling() ?? fallbackAncestor(selection.focus.getNode());
9950  if (!innerStart || !innerEnd) return
9951
9952  Gl(Wl(
9953    rc(Pl(innerStart, "next")),
9954    oc(
9955      rc(Pl(innerEnd, "previous")),
9956      "next",
9957    ),
9958  ));
9959}
9960
9961// A selection whose anchor sits at the very end of one block while its focus
9962// lives in a later block (e.g. selecting a pasted paragraph when the browser
9963// anchors at the end of the line above) contributes nothing from the anchor's
9964// block. Pull each endpoint that is flush against a block edge into the block
9965// that actually holds the selected content, so we don't wrap the empty edge
9966// block too.
9967function $shrinkSelectionPastBlockEdges(selection) {
9968  if (selection.isCollapsed()) return
9969
9970  const anchorBlock = selection.anchor.getNode().getTopLevelElement();
9971  const focusBlock = selection.focus.getNode().getTopLevelElement();
9972  if (!anchorBlock || !focusBlock || anchorBlock.is(focusBlock)) return
9973
9974  if ($isAtBlockEnd(selection.anchor, anchorBlock)) {
9975    const nextBlock = $nearestElementSibling(anchorBlock, "next");
9976    if (nextBlock) selection.anchor.set(nextBlock.getKey(), 0, "element");
9977  }
9978
9979  if ($isAtBlockStart(selection.focus, focusBlock)) {
9980    const previousBlock = $nearestElementSibling(focusBlock, "previous");
9981    if (previousBlock) selection.focus.set(previousBlock.getKey(), previousBlock.getChildrenSize(), "element");
9982  }
9983
9984  // Shrinking moves the endpoints toward each other, so they can cross when
9985  // both were flush against block edges; callers assume a forward selection.
9986  j$6(selection);
9987}
9988
9989// Top-level decorator blocks (attachments, horizontal dividers) can't hold a
9990// selection point, so walk past them to the nearest element sibling. Returns
9991// null when no element sibling exists in that direction.
9992function $nearestElementSibling(block, direction) {
9993  let sibling = block;
9994  do {
9995    sibling = direction === "next" ? sibling.getNextSibling() : sibling.getPreviousSibling();
9996  } while (sibling && !Wi(sibling))
9997  return sibling
9998}
9999
10000function $isAtBlockEnd(point, block) {
10001  return $isAtBlockBoundary(ql(point, "next"), block)
10002}
10003
10004function $isAtBlockStart(point, block) {
10005  return $isAtBlockBoundary(ql(point, "previous"), block)
10006}
10007
10008// A text point sitting mid-node still has content ahead of it in the caret's
10009// direction, even though that content is not a sibling node. $getNodeAtCaret
10010// only sees siblings, so check the text edge before walking the block.
10011function $isAtBlockBoundary(caret, block) {
10012  if (vl(caret) && ic(caret)) return false
10013
10014  let cursor = rc(caret);
10015  while (cursor && block.isParentOf(cursor.origin)) {
10016    if (cursor.getNodeAtCaret()) return false
10017    cursor = cursor.getParentCaret();
10018  }
10019  return true
10020}
10021
10022function $getCaretAtLineBreakBoundary(caret, skipInwardEdge = false) {
10023  const paragraph = caret.origin.getTopLevelElement();
10024  if (!paragraph || !no(paragraph)) return null
10025
10026  const lineBreak = (skipInwardEdge ? null : $inwardEdgeLineBreak(caret, paragraph))
10027    ?? $outwardLineBreak(caret, paragraph);
10028
10029  return lineBreak ? Ol(lineBreak, caret.direction) : null
10030}
10031
10032// Prefer a <br> the cursor is sitting flush against, except when a further <br>
10033// also exists outward — that one is the real paragraph break for this side.
10034function $inwardEdgeLineBreak(caret, paragraph) {
10035  let candidateCaret;
10036
10037  if (
10038    (Nl(caret) && caret.origin.is(paragraph)) ||
10039    (vl(caret) && ic(caret.getFlipped()))
10040  ) {
10041    candidateCaret = null;
10042  } else if (Tl(caret) && caret.getParentAtCaret().is(paragraph)) {
10043    candidateCaret = caret;
10044  } else {
10045    const childCaret = $paragraphChildCaretAtInwardEdge(caret, paragraph);
10046    candidateCaret = childCaret ? Zl(childCaret) : null;
10047  }
10048
10049  if (candidateCaret && sr(candidateCaret.origin)) {
10050    return $candidateUnlessShadowed(candidateCaret)
10051  } else {
10052    return null
10053  }
10054}
10055
10056function $candidateUnlessShadowed(candidateCaret) {
10057  const outward = candidateCaret.getNodeAtCaret();
10058  return sr(outward) ? null : candidateCaret.origin
10059}
10060
10061function $outwardLineBreak(caret, paragraph) {
10062  const startCaret = $outwardWalkStartCaret(caret, paragraph);
10063  if (!startCaret) return null
10064
10065  for (const { origin } of startCaret) {
10066    if (!origin.getParent().is(paragraph)) break
10067    if (sr(origin)) return origin
10068  }
10069  return null
10070}
10071
10072function $outwardWalkStartCaret(caret, paragraph) {
10073  if (caret.getParentAtCaret().is(paragraph)) {
10074    return caret
10075  } else {
10076    return $paragraphChildCaretContaining(caret, paragraph)
10077  }
10078}
10079
10080function $paragraphChildCaretContaining(caret, paragraph) {
10081  let cursor = caret.getSiblingCaret();
10082  while (cursor && !cursor.origin.getParent()?.is(paragraph)) {
10083    cursor = cursor.getParentCaret();
10084  }
10085  return cursor?.origin.getParent()?.is(paragraph) ? cursor : null
10086}
10087
10088// Only succeeds when the cursor is flush against the inward edge of every
10089// ancestor between itself and the paragraph child.
10090function $paragraphChildCaretAtInwardEdge(caret, paragraph) {
10091  let cursor = caret.getSiblingCaret();
10092  while (cursor && !cursor.origin.getParent()?.is(paragraph)) {
10093    if (cursor.getNodeAtCaret()) return null
10094    cursor = cursor.getParentCaret();
10095  }
10096  return cursor?.origin.getParent()?.is(paragraph) ? cursor : null
10097}
10098
10099function $splitAroundLineBreak(lineBreakCaret) {
10100  let outer = null;
10101
10102  if (lineBreakCaret.getNodeAtCaret() === null) {
10103    lineBreakCaret.origin.remove();
10104  } else {
10105    const lineBreak = lineBreakCaret.origin;
10106    const splitCaret = oc(Zl(lineBreakCaret), "next");
10107
10108    fc(splitCaret);
10109    outer = lineBreak.getTopLevelElement();
10110    lineBreak.remove();
10111  }
10112
10113  return outer
10114}
10115
10116// Lexical's RangeSelection.insertNodes/insertLineBreak require every selection point to have a
10117// block ancestor with inline children. An element point on a container of block nodes — e.g. a
10118// quote holding paragraphs — has none, so Lexical throws invariant #211 or #212. This detects
10119// such a point so callers can descend it to a leaf before inserting.
10120function $isPointOnBlockContainer(point) {
10121  if (point.type !== "element") return false
10122
10123  const firstChild = point.getNode().getFirstChild();
10124  return (Wi(firstChild) || ji(firstChild)) && !firstChild.isInline()
10125}
10126
10127function $hasPointOnBlockContainer(selection) {
10128  return Fr(selection) &&
10129    [ selection.anchor, selection.focus ].some($isPointOnBlockContainer)
10130}
10131
10132// Descend any block-container element point in the selection to a leaf position, so a subsequent
10133// Lexical insert (insertNodes, insertLineBreak, INSERT_PARAGRAPH) doesn't throw invariant #211/#212.
10134function $normalizeBlockContainerSelection(selection = Qr()) {
10135  if (!$hasPointOnBlockContainer(selection)) return false
10136
10137  St$3(selection);
10138  return true
10139}
10140
10141function $consecutiveSiblingGroups(blocks) {
10142  const ordered = [ ...blocks ].sort((a, b) => a.getIndexWithinParent() - b.getIndexWithinParent());
10143  const groups = [];
10144
10145  for (const block of ordered) {
10146    const lastGroup = groups.at(-1);
10147    const previous = lastGroup?.at(-1);
10148
10149    if (previous && previous.getParent().is(block.getParent()) && previous.getNextSibling()?.is(block)) {
10150      lastGroup.push(block);
10151    } else {
10152      groups.push([ block ]);
10153    }
10154  }
10155
10156  return groups
10157}
10158
10159// Payload: Record<nodeKey, { patch?, replace? }>
10160//   - patch: plain object, shallow-merged into the existing node's properties
10161//   - replace: a LexicalNode instance that replaces the node
10162const REWRITE_HISTORY_COMMAND = re$5("REWRITE_HISTORY_COMMAND");
10163
10164class RewritableHistoryExtension extends LexxyExtension {
10165  #historyState = null
10166
10167  get lexicalExtension() {
10168    return dc({
10169      name: "lexxy/rewritable-history",
10170      dependencies: [ O$1 ],
10171      register: (editor, _config, state) => {
10172        const historyOutput = state.getDependency(O$1).output;
10173        this.#historyState = historyOutput.historyState.value;
10174
10175        return editor.registerCommand(
10176          REWRITE_HISTORY_COMMAND,
10177          (rewrites) => this.#rewriteHistory(rewrites),
10178          ro
10179        )
10180      }
10181    })
10182  }
10183
10184  get historyState() {
10185    return this.#historyState
10186  }
10187
10188  get #allHistoryEntries() {
10189    const entries = Array.from(this.#historyState.undoStack);
10190    if (this.#historyState.current) entries.push(this.#historyState.current);
10191    return entries.concat(this.#historyState.redoStack)
10192  }
10193
10194  #rewriteHistory(rewrites) {
10195    this.#applyRewritesImmediatelyToCurrentState(rewrites);
10196    this.#applyRewritesToHistory(rewrites);
10197
10198    return true
10199  }
10200
10201  #applyRewritesImmediatelyToCurrentState(rewrites) {
10202    Zs().update(() => {
10203      for (const [ nodeKey, { patch, replace } ] of Object.entries(rewrites)) {
10204        const node = Yo(nodeKey);
10205        if (!node) continue
10206
10207        if (patch) Object.assign(node.getWritable(), patch);
10208        if (replace) node.replace(replace);
10209      }
10210    }, { discrete: true, tag: this.#getBackgroundUpdateTags() });
10211  }
10212
10213  #applyRewritesToHistory(rewrites) {
10214    const nodeKeys = Object.keys(rewrites);
10215
10216    for (const entry of this.#allHistoryEntries) {
10217      if (!this.#entryHasSomeKeys(entry, nodeKeys)) continue
10218
10219      const editorState = entry.editorState = safeCloneEditorState(entry.editorState);
10220
10221      for (const [ nodeKey, { patch, replace } ] of Object.entries(rewrites)) {
10222        const node = editorState._nodeMap.get(nodeKey);
10223        if (!node) continue
10224
10225        if (patch) {
10226          this.#patchNodeInEditorState(editorState, node, patch);
10227        } else if (replace) {
10228          this.#replaceNodeInEditorState(editorState, node, replace);
10229        }
10230      }
10231    }
10232  }
10233
10234  #entryHasSomeKeys(entry, nodeKeys) {
10235    return nodeKeys.some(key => entry.editorState._nodeMap.has(key))
10236  }
10237
10238  #getBackgroundUpdateTags() {
10239    const tags = [ Jn, Yn ];
10240    if (!isEditorFocused(this.editorElement.editor)) { tags.push(qn); }
10241    return tags
10242  }
10243
10244  #patchNodeInEditorState(editorState, node, patch) {
10245    editorState._nodeMap.set(node.__key, $cloneNodeWithPatch(node, patch));
10246  }
10247
10248  #replaceNodeInEditorState(editorState, node, replaceWith) {
10249    editorState._nodeMap.set(node.__key, $cloneNodeAdoptingKeys(replaceWith, node));
10250  }
10251}
10252
10253function $cloneNodeWithPatch(node, patch) {
10254  const clone = il(node);
10255  Object.assign(clone, patch);
10256  return clone
10257}
10258
10259function $cloneNodeAdoptingKeys(node, previousNode) {
10260  const clone = il(node);
10261  clone.__key = previousNode.__key;
10262  clone.__parent = previousNode.__parent;
10263  clone.__prev = previousNode.__prev;
10264  clone.__next = previousNode.__next;
10265  return clone
10266}
10267
10268// EditorState#clone() keeps the same map reference.
10269// A new Map is needed to prevent editing Lexical's internal map
10270// Warning: this bypasses DEV's safety map freezing
10271function safeCloneEditorState(editorState) {
10272  const clone = editorState.clone();
10273  clone._nodeMap = new Map(editorState._nodeMap);
10274  return clone
10275}
10276
10277const INITIAL_PREVIEW_POLL_DELAY_MS = 3000;
10278const MAX_PREVIEW_POLL_DELAY_MS = 120000;
10279const MAX_PREVIEW_POLL_ATTEMPTS = 20;
10280
10281
10282class ActionTextAttachmentNode extends Ji {
10283  static getType() {
10284    return "action_text_attachment"
10285  }
10286
10287  static clone(node) {
10288    return new ActionTextAttachmentNode({ ...node }, node.__key)
10289  }
10290
10291  static importJSON(serializedNode) {
10292    return new ActionTextAttachmentNode({ ...serializedNode })
10293  }
10294
10295  static importDOM() {
10296    return {
10297      [this.TAG_NAME]: () => {
10298        return {
10299          conversion: (attachment) => ({
10300            node: new ActionTextAttachmentNode({
10301              sgid: attachment.getAttribute("sgid"),
10302              src: attachment.getAttribute("url"),
10303              previewable: attachment.getAttribute("previewable"),
10304              altText: attachment.getAttribute("alt"),
10305              caption: attachment.getAttribute("caption"),
10306              contentType: attachment.getAttribute("content-type"),
10307              fileName: attachment.getAttribute("filename"),
10308              fileSize: attachment.getAttribute("filesize"),
10309              width: attachment.getAttribute("width"),
10310              height: attachment.getAttribute("height")
10311            })
10312          }), priority: 1
10313        }
10314      },
10315      "img": () => {
10316        return {
10317          conversion: (img) => {
10318            const fileName = extractFileName(img.getAttribute("src") ?? "");
10319            return {
10320              node: new ActionTextAttachmentNode({
10321                src: img.getAttribute("src"),
10322                fileName: fileName,
10323                caption: img.getAttribute("alt") || "",
10324                contentType: "image/*",
10325                width: img.getAttribute("width"),
10326                height: img.getAttribute("height")
10327              })
10328            }
10329          }, priority: 1
10330        }
10331      },
10332      "video": () => {
10333        return {
10334          conversion: (video) => {
10335            const videoSource = video.getAttribute("src") || video.querySelector("source")?.src;
10336            const fileName = videoSource?.split("/")?.pop();
10337            const contentType = video.querySelector("source")?.getAttribute("content-type") || "video/*";
10338
10339            return {
10340              node: new ActionTextAttachmentNode({
10341                src: videoSource,
10342                fileName: fileName,
10343                contentType: contentType
10344              })
10345            }
10346          }, priority: 1
10347        }
10348      }
10349    }
10350  }
10351
10352  static get TAG_NAME() {
10353    return Lexxy.global.get("attachmentTagName")
10354  }
10355
10356  constructor({ tagName, sgid, src, previewSrc, previewable, previewStatusUrl, pendingPreview, altText, caption, contentType, fileName, fileSize, width, height, uploadError } = {}, key) {
10357    super(key);
10358
10359    this.tagName = tagName || ActionTextAttachmentNode.TAG_NAME;
10360    this.sgid = sgid;
10361    this.src = src;
10362    this.previewSrc = previewSrc;
10363    this.previewable = parseBoolean(previewable);
10364    this.previewStatusUrl = previewStatusUrl;
10365    this.pendingPreview = pendingPreview;
10366    this.altText = altText || "";
10367    this.caption = caption || "";
10368    this.contentType = contentType || "";
10369    this.fileName = fileName || "";
10370    this.fileSize = fileSize;
10371    this.width = width;
10372    this.height = height;
10373    this.uploadError = uploadError;
10374
10375    this.editor = Zs();
10376  }
10377
10378  createDOM() {
10379    if (this.uploadError) return this.createDOMForError()
10380    if (this.pendingPreview) return this.#createDOMForPendingPreview()
10381
10382    const figure = this.createAttachmentFigure();
10383
10384    if (this.isPreviewableAttachment) {
10385      figure.appendChild(this.#createDOMForImage());
10386      figure.appendChild(this.#createEditableCaption());
10387    } else if (this.isVideo) {
10388      figure.appendChild(this.#createDOMForFile());
10389      figure.appendChild(this.#createEditableCaption());
10390    } else {
10391      figure.appendChild(this.#createDOMForFile());
10392      figure.appendChild(this.#createDOMForNotImage());
10393    }
10394
10395    return figure
10396  }
10397
10398  updateDOM(prevNode, dom) {
10399    if (this.uploadError !== prevNode.uploadError) return true
10400
10401    const caption = dom.querySelector("figcaption textarea");
10402    if (caption && this.caption) {
10403      caption.value = this.caption;
10404    }
10405
10406    return false
10407  }
10408
10409  getTextContent() {
10410    return `[${this.caption || this.fileName}]\n\n`
10411  }
10412
10413  isInline() {
10414    return this.isAttached() && !this.getParent().is(Ls(this))
10415  }
10416
10417  exportDOM() {
10418    const attachment = createElement(this.tagName, {
10419      sgid: this.sgid,
10420      previewable: this.previewable || null,
10421      url: this.src,
10422      alt: this.altText,
10423      caption: this.caption,
10424      "content-type": this.contentType,
10425      filename: this.fileName,
10426      filesize: this.fileSize,
10427      width: this.width,
10428      height: this.height,
10429      presentation: "gallery"
10430    });
10431
10432    return { element: attachment }
10433  }
10434
10435  exportJSON() {
10436    return {
10437      type: "action_text_attachment",
10438      version: 1,
10439      tagName: this.tagName,
10440      sgid: this.sgid,
10441      src: this.src,
10442      previewable: this.previewable,
10443      previewStatusUrl: this.previewStatusUrl,
10444      pendingPreview: this.pendingPreview,
10445      altText: this.altText,
10446      caption: this.caption,
10447      contentType: this.contentType,
10448      fileName: this.fileName,
10449      fileSize: this.fileSize,
10450      width: this.width,
10451      height: this.height
10452    }
10453  }
10454
10455  decorate() {
10456    return null
10457  }
10458
10459  createDOMForError() {
10460    const figure = this.createAttachmentFigure();
10461    figure.classList.add("attachment--error");
10462    figure.appendChild(createElement("div", { innerText: `Error uploading ${this.fileName || "file"}` }));
10463    return figure
10464  }
10465
10466  createAttachmentFigure(previewable = this.isPreviewableAttachment) {
10467    const figure = createAttachmentFigure(this.contentType, previewable, this.fileName);
10468    figure.draggable = true;
10469    figure.dataset.lexicalNodeKey = this.__key;
10470
10471    const deleteButton = createElement("lexxy-node-delete-button");
10472    figure.appendChild(deleteButton);
10473
10474    return figure
10475  }
10476
10477  get isPreviewableAttachment() {
10478    return this.isPreviewableImage || this.previewable
10479  }
10480
10481  get isPreviewableImage() {
10482    return isPreviewableImage(this.contentType)
10483  }
10484
10485  get isVideo() {
10486    return this.contentType.startsWith("video/")
10487  }
10488
10489  #createDOMForPendingPreview() {
10490    const figure = this.createAttachmentFigure(false);
10491    figure.appendChild(this.#createDOMForFile());
10492    figure.appendChild(this.#createDOMForNotImage());
10493    this.#pollForPreview(figure);
10494    return figure
10495  }
10496
10497  patchAndRewriteHistory(patch) {
10498    this.editor.dispatchCommand(REWRITE_HISTORY_COMMAND, {
10499      [this.getKey()]: { patch }
10500    });
10501  }
10502
10503  replaceAndRewriteHistory(node) {
10504    this.editor.dispatchCommand(REWRITE_HISTORY_COMMAND, {
10505      [this.getKey()]: { replace: node }
10506    });
10507  }
10508
10509  #createDOMForImage(options = {}) {
10510    const initialSrc = this.previewSrc || this.src;
10511    const img = createElement("img", { src: initialSrc, draggable: false, alt: this.altText, ...this.#imageDimensions, ...options });
10512
10513    if (this.previewable && !this.isPreviewableImage) {
10514      img.onerror = () => this.#swapPreviewToFileDOM(img);
10515    }
10516
10517    if (this.previewSrc) {
10518      this.#preloadAndSwapSrc(img);
10519    }
10520
10521    const container = createElement("div", { className: "attachment__container" });
10522    container.appendChild(img);
10523    return container
10524  }
10525
10526  #preloadAndSwapSrc(img) {
10527    const previewSrc = this.previewSrc;
10528    const serverImage = new Image();
10529
10530    serverImage.onload = () => this.#handleImageLoaded(img, previewSrc);
10531    serverImage.onerror = () => this.#handleImageLoadError(previewSrc);
10532    serverImage.src = this.src;
10533  }
10534
10535  #handleImageLoaded(img, previewSrc) {
10536    img.src = this.src;
10537    this.patchAndRewriteHistory({ previewSrc: null });
10538    this.#revokePreviewSrc(previewSrc);
10539  }
10540
10541  #handleImageLoadError(previewSrc) {
10542    this.patchAndRewriteHistory({
10543      previewSrc: null,
10544      uploadError: true
10545    });
10546    this.#revokePreviewSrc(previewSrc);
10547  }
10548
10549  #revokePreviewSrc(previewSrc) {
10550    if (previewSrc?.startsWith("blob:")) URL.revokeObjectURL(previewSrc);
10551  }
10552
10553  #swapPreviewToFileDOM(img) {
10554    const figure = img.closest("figure.attachment");
10555    if (!figure) return
10556
10557    this.#swapFigureContent(figure, "attachment--preview", "attachment--file", () => {
10558      figure.appendChild(this.#createDOMForFile());
10559      figure.appendChild(this.#createDOMForNotImage());
10560    });
10561  }
10562
10563  // While the file-icon is shown, watch for the preview to become ready.
10564  // With a status URL, poll it (2xx = processing, anything else = ready).
10565  // Without one, preload the preview URL once and swap on load.
10566  #pollForPreview(figure) {
10567    if (this.previewStatusUrl) {
10568      this.#waitForPreviewByPollingStatus(figure);
10569    } else {
10570      this.#waitForPreviewByPreloadingImage(figure);
10571    }
10572  }
10573
10574  #waitForPreviewByPollingStatus(figure) {
10575    let attempt = 0;
10576
10577    const tryStatus = async () => {
10578      if (!this.editor.read(() => this.isAttached())) return
10579
10580      try {
10581        // redirect: "manual" prevents fetch from transparently following a
10582        // 3xx response — without it, a status endpoint that redirected to,
10583        // say, the preview URL would resolve to a 200 and look like
10584        // "still processing." The contract is "any non-2xx means done."
10585        const response = await fetch(this.previewStatusUrl, { credentials: "include", redirect: "manual" });
10586
10587        if (!this.editor.read(() => this.isAttached())) return
10588
10589        if (response.ok) {
10590          retry();
10591        } else {
10592          this.#swapToPreviewDOM(figure, this.src);
10593        }
10594      } catch {
10595        retry();
10596      }
10597    };
10598
10599    const retry = () => {
10600      attempt++;
10601      if (attempt < MAX_PREVIEW_POLL_ATTEMPTS && this.editor.read(() => this.isAttached())) {
10602        const delay = Math.min(2000 * Math.pow(1.5, attempt), MAX_PREVIEW_POLL_DELAY_MS);
10603        setTimeout(tryStatus, delay);
10604      }
10605    };
10606
10607    // Give the server time to start processing before the first attempt
10608    setTimeout(tryStatus, INITIAL_PREVIEW_POLL_DELAY_MS);
10609  }
10610
10611  #waitForPreviewByPreloadingImage(figure) {
10612    const img = new Image();
10613    img.onload = () => {
10614      if (!this.editor.read(() => this.isAttached())) return
10615      this.#swapToPreviewDOM(figure, this.src);
10616    };
10617    img.onerror = () => {
10618      // Clear pendingPreview so undo/redo or any JSON round-trip doesn't
10619      // re-enter the pending flow and issue another fetch. The file icon
10620      // stays as the stable fallback.
10621      if (!this.editor.read(() => this.isAttached())) return
10622      this.patchAndRewriteHistory({ pendingPreview: false });
10623    };
10624    img.src = this.src;
10625  }
10626
10627  #swapToPreviewDOM(figure, previewSrc) {
10628    this.#swapFigureContent(figure, "attachment--file", "attachment--preview", () => {
10629      const img = createElement("img", { src: previewSrc, draggable: false, alt: this.altText });
10630      img.onerror = () => this.#swapPreviewToFileDOM(img);
10631      const container = createElement("div", { className: "attachment__container" });
10632      container.appendChild(img);
10633      figure.appendChild(container);
10634      figure.appendChild(this.#createEditableCaption());
10635    });
10636
10637    this.patchAndRewriteHistory({ pendingPreview: false });
10638  }
10639
10640  #swapFigureContent(figure, fromClass, toClass, renderContent) {
10641    figure.className = figure.className.replace(fromClass, toClass);
10642
10643    for (const child of [ ...figure.querySelectorAll(".attachment__container, .attachment__icon, figcaption") ]) {
10644      child.remove();
10645    }
10646
10647    renderContent();
10648  }
10649
10650  get #imageDimensions() {
10651    if (this.width && this.height) {
10652      return { width: this.width, height: this.height }
10653    } else {
10654      return {}
10655    }
10656  }
10657
10658  #createDOMForFile() {
10659    const extension = this.fileName ? this.fileName.split(".").pop().toLowerCase() : "unknown";
10660    return createElement("span", { className: "attachment__icon", textContent: `${extension}` })
10661  }
10662
10663  #createDOMForNotImage() {
10664    const figcaption = createElement("figcaption", { className: "attachment__caption" });
10665
10666    const nameTag = createElement("strong", { className: "attachment__name", textContent: this.caption || this.fileName });
10667
10668    figcaption.appendChild(nameTag);
10669
10670    if (this.fileSize) {
10671      const sizeSpan = createElement("span", { className: "attachment__size", textContent: bytesToHumanSize(this.fileSize) });
10672      figcaption.appendChild(sizeSpan);
10673    }
10674
10675    return figcaption
10676  }
10677
10678  #createEditableCaption() {
10679    const caption = createElement("figcaption", { className: "attachment__caption" });
10680    const input = createElement("textarea", {
10681      value: this.caption,
10682      placeholder: this.fileName,
10683      rows: "1"
10684    });
10685
10686    input.addEventListener("focusin", () => input.placeholder = "Add caption...");
10687    input.addEventListener("blur", (event) => this.#handleCaptionInputBlurred(event));
10688    input.addEventListener("keydown", (event) => this.#handleCaptionInputKeydown(event));
10689    input.addEventListener("copy", (event) => event.stopPropagation());
10690    input.addEventListener("cut", (event) => event.stopPropagation());
10691    input.addEventListener("paste", (event) => event.stopPropagation());
10692
10693    caption.appendChild(input);
10694
10695    return caption
10696  }
10697
10698  #handleCaptionInputBlurred(event) {
10699    this.#updateCaptionValueFromInput(event.target);
10700  }
10701
10702  #updateCaptionValueFromInput(input) {
10703    input.placeholder = this.fileName;
10704    this.editor.update(() => {
10705      this.getWritable().caption = input.value;
10706    });
10707  }
10708
10709  #handleCaptionInputKeydown(event) {
10710    if (event.key === "Enter") {
10711      event.preventDefault();
10712      event.target.blur();
10713
10714      this.editor.update(() => {
10715        // Place the cursor after the current image
10716        this.selectNext(0, 0);
10717      }, {
10718        tag: Jn
10719      });
10720    }
10721
10722    // Stop all keydown events from bubbling to the Lexical root element.
10723    // The caption textarea is outside Lexical's content model and should
10724    // handle its own keyboard events natively (Ctrl+A, Ctrl+C, Ctrl+X, etc.).
10725    event.stopPropagation();
10726  }
10727}
10728
10729function $createActionTextAttachmentNode(...args) {
10730  return new ActionTextAttachmentNode(...args)
10731}
10732
10733function $isActionTextAttachmentNode(node) {
10734  return node instanceof ActionTextAttachmentNode
10735}
10736
10737function filterDisallowedAttachmentNodes(nodes, editorElement) {
10738  return nodes
10739    .filter(node => !isDisallowedAttachment(node, editorElement))
10740    .map(node => {
10741      Ht$3([ node ], descendant => isDisallowedAttachment(descendant, editorElement))
10742        .forEach(descendant =>
10742 descendant.remove());
10743      return node
10744    })
10745}
10746
10747function isDisallowedAttachment(node, editorElement) {
10748  const isAttachmentNode =
10749    node instanceof CustomActionTextAttachmentNode ||
10750    node instanceof ActionTextAttachmentNode;
10751  return isAttachmentNode &&
10752         !editorElement.permitsAttachmentContentType(node.contentType)
10753}
10754
10755// Replaces inline `data:image/...` attachments with upload nodes that flow through the normal
10756// file upload pipeline.
10757//
10758// Without this step, pasted-from-Google-Docs-style content lands in the editor with the entire
10759// base64 image embedded in the attachment's `src`, which then persists into the saved HTML and
10760// bloats the stored document.
10761//
10762// Each conversion dispatches the cancelable `lexxy:file-accept` event so the host's allowlist (and
10763// any other listener) can refuse the synthesized File before it's accepted into the upload
10764// pipeline; on refusal, the node is dropped silently — matching how `Contents#uploadFiles` handles
10765// file-picker rejections.
10766function $convertInlineImageDataURIs(nodes, editorElement) {
10767  const topLevel = nodes
10768    .map(node => isInlineImageDataURIAttachment(node) ? $tryCreateUploadFromDataURI(node, editorElement) : node)
10769    .filter(node => node !== null);
10770
10771  for (const node of topLevel) {
10772    for (const desc of Ht$3([ node ], isInlineImageDataURIAttachment)) {
10773      const upload = $tryCreateUploadFromDataURI(desc, editorElement);
10774      if (upload) {
10775        desc.replace(upload);
10776      } else {
10777        desc.remove();
10778      }
10779    }
10780  }
10781
10782  return topLevel
10783}
10784
10785function isInlineImageDataURIAttachment(node) {
10786  return node instanceof ActionTextAttachmentNode &&
10787    /^data:image\/[^,]*;base64,/i.test(node.src ?? "")
10788}
10789
10790function $tryCreateUploadFromDataURI(node, editorElement) {
10791  const file = dataURIToFile(node.src);
10792  if (file && editorElement.acceptsFile(file)) {
10793    return editorElement.contents.$createUploadNode(file)
10794  }
10795  return null
10796}
10797
10798function dataURIToFile(dataURI) {
10799  try {
10800    const [ header, data ] = dataURI.split(",");
10801
10802    // https://datatracker.ietf.org/doc/html/rfc6838#section-4.2
10803    const mimeType = header.match(/^data:(image\/[A-Za-z0-9][A-Za-z0-9!#$&\-^_.+]*)/)?.[1];
10804    if (mimeType) {
10805      const bytes = Uint8Array.from(atob(data), (c) => c.charCodeAt(0));
10806      const extension = mimeTypeToExtension(mimeType) ?? "png";
10807      return new File([ bytes ], `pasted-image-${Date.now()}.${extension}`, { type: mimeType })
10808    } else {
10809      return null
10810    }
10811  } catch {
10812    return null
10813  }
10814}
10815
10816/**
10817 * Copyright (c) Meta Platforms, Inc. and affiliates.
10818 *
10819 * This source code is licensed under the MIT license found in the
10820 * LICENSE file in the root directory of this source tree.
10821 *
10822 */
10823
10824function C$1(t,...e){const n=new URL("https://lexical.dev/docs/error"),r=new URLSearchParams;r.append("code",t);for(const t of e)r.append("v",t);throw n.search=r.toString(),Error(`Minified Lexical error #${t}; visit ${n.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}function N$1(t,e){let r=t;for(let o=Ol(t,e);o&&(X$1(o.origin)||Er(o.origin));o=o.getAdjacentCaret())r=o.origin;return r}function O(t){return N$1(t,"previous")}function A(t){return N$1(t,"next")}function H$1(n){const r=O(n),i=A(n);let o=r;for(;null!==o;){if(X$1(o)){const e=Fo(o.getTextContent());if(null!==e)return e}if(o===i)break;o=o.getNextSibling();}const s=r.getParent();if(Wi(s)){const t=s.getDirection();if("ltr"===t||"rtl"===t)return t}return null}function L$2(t,e){let i=null,o=null,s=t,l=e,u=t.getTextContent();for(;;){if(0===l){if(s=s.getPreviousSibling(),null===s)break;if(X$1(s)||Er(s)||sr(s)||C$1(167),sr(s)){i={node:s,offset:1};break}l=Math.max(0,s.getTextContentSize()-1),u=s.getTextContent();}else l--;const t=u[l];X$1(s)&&" "!==t&&(o={node:s,offset:l});}if(null!==o)return o;let g=null;if(e<t.getTextContentSize())X$1(t)&&(g=t.getTextContent()[e]);else {const e=t.getNextSibling();X$1(e)&&(g=e.getTextContent()[0]);}if(null!==g&&" "!==g)return i;{const n=function(t,e){let n=t,i=e,o=t.getTextContent(),s=t.getTextContentSize();for(;;){if(!X$1(n)||i===s){if(n=n.getNextSibling(),null===n||sr(n))return null;X$1(n)&&(i=0,o=n.getTextContent(),s=n.getTextContentSize());}if(X$1(n)){if(" "!==o[i])return {node:n,offset:i};i++;}}}(t,e);return null!==n?n:i}}function F$1(t){const e=A(t);return sr(e)&&C$1(168),e}const J$3="javascript";function M$1(t,e){for(const n of t.childNodes){if(Ys(n)&&n.tagName===e)return  true;M$1(n,e);}return  false}
10824const k$1="data-language",w$1="data-highlight-language",P$1="data-theme";let z$1 = class z extends Bi{__language;__theme;__isSyntaxHighlightSupported;static getType(){return "code"}static clone(t){return new z(t.__language,t.__key)}constructor(t,e){super(e),this.__language=t||void 0,this.__isSyntaxHighlightSupported=false,this.__theme=void 0;}afterCloneFrom(t){super.afterCloneFrom(t),this.__language=t.__language,this.__theme=t.__theme,this.__isSyntaxHighlightSupported=t.__isSyntaxHighlightSupported;}createDOM(t){const e=document.createElement("code");mc(e,t.theme.code),e.setAttribute("spellcheck","false");const n=this.getLanguage();n&&(e.setAttribute(k$1,n),this.getIsSyntaxHighlightSupported()&&e.setAttribute(w$1,n));const r=this.getTheme();r&&e.setAttribute(P$1,r);const i=this.getStyle();return i&&nr(e.style,i),e}updateDOM(t,e,n){const r=this.__language,i=t.__language;r?r!==i&&e.setAttribute(k$1,r):i&&e.removeAttribute(k$1);const o=this.__isSyntaxHighlightSupported;t.__isSyntaxHighlightSupported&&i?o&&r?r!==i&&e.setAttribute(w$1,r):e.removeAttribute(w$1):o&&r&&e.setAttribute(w$1,r);const s=this.__theme,l=t.__theme;s?s!==l&&e.setAttribute(P$1,s):l&&e.removeAttribute(P$1);const g=this.__style,a=t.__style;return g!==a&&nr(e.style,g,a),false}exportDOM(t){const e=document.createElement("pre");mc(e,t._config.theme.code),e.setAttribute("spellcheck","false");const n=this.getLanguage();n&&(e.setAttribute(k$1,n),this.getIsSyntaxHighlightSupported()&&e.setAttribute(w$1,n));const r=this.getTheme();r&&e.setAttribute(P$1,r);const i=this.getStyle();return i&&nr(e.style,i),{element:e}}static importDOM(){return {code:t=>null!=t.textContent&&(/\r?\n/.test(t.textContent)||M$1(t,"BR"))?{conversion:j$1,priority:1}:null,div:()=>({conversion:R,priority:1}),pre:()=>({conversion:j$1,priority:0}),table:t=>q$1(t)?{conversion:B$1,priority:3}:null,td:t=>{const e=t,n=e.closest("table");return e.classList.contains("js-file-line")||n&&q$1(n)?{conversion:U$2,priority:3}:null},tr:t=>{const e=t.closest("table");return e&&q$1(e)?{conversion:U$2,priority:3}:null}}}static importJSON(t){return I$1().updateFromJSON(t)}updateFromJSON(t){return super.updateFromJSON(t).setLanguage(t.language).setTheme(t.theme)}exportJSON(){return {...super.exportJSON(),language:this.getLanguage(),theme:this.getTheme()}}insertNewAfter(t,e=true){if(!fe$3(Zs(),"@lexical/code")){const e=G$3(t);if(e)return e}const{anchor:r,focus:i}=t,o=(r.isBefore(i)?r:i).getNode();if(Tr(o)){let t=O(o);const e=[];for(;;)if(Er(t))e.push(wr()),t=t.getNextSibling();else {if(!X$1(t))break;{let n=0;const r=t.getTextContent(),i=t.getTextContentSize();for(;n<i&&" "===r[n];)n++;if(0!==n&&e.push(V$2(" ".repeat(n))),n!==i)break;t=t.getNextSibling();}}const i=o.splitText(r.offset)[0],s=0===r.offset?0:1,l=i.getIndexWithinParent()+s,u=o.getParentOrThrow(),g=[or(),...e];u.splice(l,0,g);const a=e[e.length-1];a?a.select():0===r.offset?i.selectPrevious():i.getNextSibling().selectNext(0,0);}if(W$1(o)){const{offset:e}=t.anchor;o.splice(e,0,[or()]),o.select(e+1,e+1);}return null}canIndent(){return  false}collapseAtStart(){const t=eo();
10824return this.getChildren().forEach(e=>t.append(e)),this.replace(t),true}setLanguage(t){const e=this.getWritable();return e.__language=t||void 0,e}getLanguage(){return this.getLatest().__language}setIsSyntaxHighlightSupported(t){const e=this.getWritable();return e.__isSyntaxHighlightSupported=t,e}getIsSyntaxHighlightSupported(){return this.getLatest().__isSyntaxHighlightSupported}setTheme(t){const e=this.getWritable();return e.__theme=t||void 0,e}getTheme(){return this.getLatest().__theme}};function I$1(t,e){return fl(z$1).setLanguage(t).setTheme(e)}function W$1(t){return t instanceof z$1}function j$1(t){return {node:I$1(t.getAttribute(k$1))}}function R(t){const e=t,n=$$1(e);return n||function(t){let e=t.parentElement;for(;null!==e;){if($$1(e))return  true;e=e.parentElement;}return  false}(e)?{node:n?I$1():null}:{node:null}}function B$1(){return {node:I$1()}}function U$2(){return {node:null}}function $$1(t){return null!==t.style.fontFamily.match("monospace")}function q$1(t){return t.classList.contains("js-file-line-container")}function G$3(t){const{anchor:e}=t;if(t.isCollapsed()&&"element"===e.type){const t=e.getNode();if(W$1(t)){const n=t.getChildrenSize();if(n>=2&&e.offset===n){const e=t.getLastChild();if(sr(e)&&sr(e.getPreviousSibling())){const e=eo();return t.splice(n-2,2,[]).insertAfter(e,false),e.select(),e}}}}return null}let K$1 = class K extends gr{__highlightType;constructor(t="",e,n){super(t,n),this.__highlightType=e;}static getType(){return "code-highlight"}static clone(t){return new K(t.__text,t.__highlightType||void 0,t.__key)}afterCloneFrom(t){super.afterCloneFrom(t),this.__highlightType=t.__highlightType;}getHighlightType(){return this.getLatest().__highlightType}setHighlightType(t){const e=this.getWritable();return e.__highlightType=t||void 0,e}canHaveFormat(){return  false}createDOM(t){const e=super.createDOM(t),n=Q$2(t.theme,this.__highlightType);return mc(e,n),e}updateDOM(t,e,n){const r=super.updateDOM(t,e,n),i=Q$2(n.theme,t.__highlightType),o=Q$2(n.theme,this.__highlightType);return i!==o&&(i&&xc(e,i),o&&mc(e,o)),r}static importJSON(t){return V$2().updateFromJSON(t)}updateFromJSON(t){return super.updateFromJSON(t).setHighlightType(t.highlightType)}exportJSON(){return {...super.exportJSON(),highlightType:this.getHighlightType()}}setFormat(t){return this}isParentRequired(){return  true}createParentElementNode(){return I$1()}};function Q$2(t,e){return e&&t&&t.codeHighlight&&t.codeHighlight[e]}function V$2(t="",e){return zs(new K$1(t,e))}function X$1(t){return t instanceof K$1}
10825
10826/**
10827 * Copyright (c) Meta Platforms, Inc. and affiliates.
10828 *
10829 * This source code is licensed under the MIT license found in the
10830 * LICENSE file in the root directory of this source tree.
10831 *
10832 */
10833
10834function J$2(e,...t){const n=new URL("https://lexical.dev/docs/error"),r=new URLSearchParams;r.append("code",e);for(const e of t)r.append("v",e);throw n.search=r.toString(),Error(`Minified Lexical error #${e}; visit ${n.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}!function(e){e.languages.diff={coord:[/^(?:\*{3}|-{3}|\+{3}).*$/m,/^@@.*@@$/m,/^\d.*$/m]};var t={"deleted-sign":"-","deleted-arrow":"<","inserted-sign":"+","inserted-arrow":">",unchanged:" ",diff:"!"};Object.keys(t).forEach(function(n){var r=t[n],o=[];/^\w+$/.test(n)||o.push(/\w+/.exec(n)[0]),"diff"===n&&o.push("bold"),e.languages.diff[n]={pattern:RegExp("^(?:["+r+"].*(?:\r\n?|\n|(?![\\s\\S])))+","m"),alias:o,inside:{line:{pattern:/(.)(?=[\s\S]).*(?:\r\n?|\n)?/,lookbehind:true},prefix:{pattern:/[\s\S]/,alias:/\w+/.exec(n)[0]}}};}),Object.defineProperty(e.languages.diff,"PREFIXES",{value:t});}(Prism);const U$1=globalThis.Prism||window.Prism,Q$1={c:"C",clike:"C-like",cpp:"C++",css:"CSS",html:"HTML",java:"Java",js:"JavaScript",markdown:"Markdown",objc:"Objective-C",plain:"Plain Text",powershell:"PowerShell",py:"Python",rust:"Rust",sql:"SQL",swift:"Swift",typescript:"TypeScript",xml:"XML"},G$2={cpp:"cpp",java:"java",javascript:"js",md:"markdown",plaintext:"plain",python:"py",text:"plain",ts:"typescript"};function V$1(e){return G$2[e]||e}function te$1(e){const t=function(e){const t=/^diff-([\w-]+)/i.exec(e);return t?t[1]:null}(e),n=t||e;try{return !!n&&U$1.languages.hasOwnProperty(n)}catch(e){return  false}}
10834async function ne$1(e,t,n){}function re$2(e){return "string"==typeof e?e:Array.isArray(e)?e.map(re$2).join(""):re$2(e.content)}function oe$2(e,t){const n=/^diff-([\w-]+)/i.exec(t),r=e.getTextContent();let o=U$1.tokenize(r,U$1.languages[n?"diff":t]);return n&&(o=function(e,t){const n=t,r=U$1.languages[n],o={tokens:e},s=U$1.languages.diff.PREFIXES;for(const e of o.tokens){if("string"==typeof e||!(e.type in s)||!Array.isArray(e.content))continue;const t=e.type;let n=0;const o=()=>(n++,new U$1.Token("prefix",s[t],t.replace(/^(\w+).*/,"$1"))),i=e.content.filter(e=>"string"==typeof e||"prefix"!==e.type),c=e.content.length-i.length,l=U$1.tokenize(re$2(i),r);l.unshift(o());const a=/\r\n|\n/g,f=e=>{const t=[];a.lastIndex=0;let r,s=0;for(;n<c&&(r=a.exec(e));){const n=r.index+r[0].length;t.push(e.slice(s,n)),s=n,t.push(o());}if(0!==t.length)return s<e.length&&t.push(e.slice(s)),t},u=e=>{for(let t=0;t<e.length&&n<c;t++){const n=e[t];if("string"==typeof n){const r=f(n);r&&(e.splice(t,1,...r),t+=r.length-1);}else if("string"==typeof n.content){const e=f(n.content);e&&(n.content=e);}else Array.isArray(n.content)?u(n.content):u([n.content]);}};u(l),n<c&&l.push(o()),e.content=l;}return o.tokens}(o,n[1])),se$2(o)}function se$2(t,n){const r=[];for(const o of t)if("string"==typeof o){const t=o.split(/(\n|\t)/),s=t.length;for(let o=0;o<s;o++){const s=t[o];"\n"===s||"\r\n"===s?r.push(or()):"\t"===s?r.push(wr()):s.length>0&&r.push(V$2(s,n));}}else {const{content:e,alias:t}=o;"string"==typeof e?r.push(...se$2([e],"prefix"===o.type&&"string"==typeof t?t:o.type)):Array.isArray(e)&&r.push(...se$2(e,"unchanged"===o.type?void 0:o.type));}return r}const ie$1={$tokenize(e,t){return oe$2(e,t||this.defaultLanguage)},defaultLanguage:J$3,tokenize(e,t){return U$1.tokenize(e,U$1.languages[t||""]||U$1.languages[this.defaultLanguage])}};function ce$1(e,t,o,s){const i=s.getParent();W$1(i)?ae$1(e,t,o,i):X$1(s)&&s.replace(kr(s.__text));}function le$1(e,t){const n=t.getElementByKey(e.getKey());if(null===n)return;const r=e.getChildren(),o=r.length;if(o===n.__cachedChildrenLength)return;n.__cachedChildrenLength=o;let s="1",i=1;for(let e=0;e<o;e++)sr(r[e])&&(s+="\n"+ ++i);n.setAttribute("data-gutter",s);}function ae$1(e,t,r,o){const{nodesCurrentlyHighlighting:s}=r,i=o.getKey();void 0===o.getLanguage()&&o.setLanguage(t.defaultLanguage);const c=o.getLanguage()||t.defaultLanguage;if(!te$1(c))return o.getIsSyntaxHighlightSupported()&&o.setIsSyntaxHighlightSupported(false),void ne$1();o.getIsSyntaxHighlightSupported()||o.setIsSyntaxHighlightSupported(true),s.has(i)||(s.add(i),r.didTransform||(r.didTransform=true,Ms(()=>{r.didTransform=false,s.clear();})),function(e,t){const r=Yo(e);if(!W$1(r)||!r.isAttached())return;const o=Qr();if(!Fr(o))return void t();const s=o.anchor,i=s.offset,c="element"===s.type&&sr(r.getChildAtIndex(s.offset-1));let l=0;if(!c){const e=s.getNode();l=i+e.getPreviousSiblings().reduce((e,t)=>e+t.getTextContentSize(),0);}if(!t())return;if(c)return void s.getNode().select(i,i);r.getChildren().some(e=>{const t=Tr(e);if(t||sr(e)){const n=e.getTextContentSize();if(t&&n>=l)return e.select(l,l),true;l-=n;}return  false});}(i,()=>{const e=Yo(i);if(!W$1(e)||!e.isAttached())return  false;const r=e.getLanguage()||t.defaultLanguage,s=t.$tokenize(e,r),c=function(e,t){let n=0;for(;n<e.length&&fe$1(e[n],t[n]);)n++;const r=e.length,o=t.length,s=Math.min(r,o)-n;let i=0;for(;i<s;)if(i++,!fe$1(e[r-i],t[o-i])){i--;break}const c=n,l=r-i,a=t.slice(n,o-i);return {from:c,nodesForReplacement:a,to:l}}(e.getChildren(),s),{from:l,to:a,nodesForReplacement:f}=c;return !(l===a&&!f.length)&&(o.splice(l,a-l,f),true)}));}function fe$1(e,t){return X$1(e)&&X$1(t)&&e.__text===t.__text&&e.__highlightType===t.__highlightType||Er(e)&&Er(t)||sr(e)&&sr(t)}function ue$1(e){if(!Fr(e))return  false;const t=e.anchor.getNode(),r=W$1(t)?t:t.getParent(),o=e.focus.getNode(),s=W$1(o)?o:o.getParent();return W$1(r)&&r.is(s)}function ge$1(e){const t=e.getNodes(),o=[];if(1===t.length&&W$1(t[0]))return o;let s=[];for(let e=0;e<t.length;e++){const n=t[e];X$1(n)||Er(n)||sr(n)||J$2(169),sr(n)?s.length>0&&(o.push(s),s=[]):s.push(n);}if(s.length>
108340){const t=e.isBackward()?e.anchor:e.focus,n=Mr(s[0].getKey(),0,"text");t.is(n)||o.push(s);}return o}function pe$1(e){const t=Qr();if(!Fr(t)||!ue$1(t))return  false;const n=ge$1(t),r=n.length;if(0===r&&t.isCollapsed())return e===Ie$3&&t.insertNodes([wr()]),true;if(0===r&&e===Ie$3&&"\n"===t.getTextContent()){const e=wr(),n=or(),r=t.isBackward()?"previous":"next";return t.insertNodes([e,n]),Gl(sc(Wl(Ml(e,"next",0),rc(Ol(n,"next"))),r)),true}for(let s=0;s<r;s++){const r=n[s];if(r.length>0){let n=r[0];if(0===s&&(n=O(n)),e===Ie$3){const e=wr();if(n.insertBefore(e),0===s){const r=t.isBackward()?"focus":"anchor",o=Mr(n.getKey(),0,"text");t[r].is(o)&&t[r].set(e.getKey(),0,"text");}}else Er(n)&&n.remove();}}return  true}function de$1(e,t){const n=Qr();if(!Fr(n))return  false;const{anchor:i,focus:c}=n,l=i.offset,a=c.offset,f=i.getNode(),u=c.getNode(),g=e===we$1;if(!ue$1(n)||!X$1(f)&&!Er(f)||!X$1(u)&&!Er(u))return  false;if(!t.altKey){if(n.isCollapsed()){const e=f.getParentOrThrow();if(g&&0===l&&null===f.getPreviousSibling()){if(null===e.getPreviousSibling())return e.selectPrevious(),t.preventDefault(),true}else if(!g&&l===f.getTextContentSize()&&null===f.getNextSibling()){if(null===e.getNextSibling())return e.selectNext(),t.preventDefault(),true}}return  false}let p,d;if(f.isBefore(u)?(p=O(f),d=A(u)):(p=O(u),d=A(f)),null==p||null==d)return  false;const m=p.getNodesBetween(d);for(let e=0;e<m.length;e++){const t=m[e];if(!X$1(t)&&!Er(t)&&!sr(t))return  false}t.preventDefault(),t.stopPropagation();const h=g?p.getPreviousSibling():d.getNextSibling();if(!sr(h))return  true;const x=g?h.getPreviousSibling():h.getNextSibling();if(null==x)return  true;const j=X$1(x)||Er(x)||sr(x)?g?O(x):A(x):null;let w=null!=j?j:x;return h.remove(),m.forEach(e=>e.remove()),e===we$1?(m.forEach(e=>w.insertBefore(e)),w.insertBefore(h)):(w.insertAfter(h),w=h,m.forEach(e=>{w.insertAfter(e),w=e;})),n.setTextNodeRange(f,l,u,a),true}function me$1(e,t){const n=Qr();if(!Fr(n))return  false;const{anchor:o,focus:s}=n,a=o.getNode(),f=s.getNode(),u=e===be$1;if(!ue$1(n)||!X$1(a)&&!Er(a)||!X$1(f)&&!Er(f))return  false;const g=f;if("rtl"===H$1(g)?!u:u){const e=L$2(g,s.offset);if(null!==e){const{node:t,offset:r}=e;sr(t)?t.selectNext(0,0):n.setTextNodeRange(t,r,t,r);}else g.getParentOrThrow().selectStart();}else {F$1(g).select();}return t.preventDefault(),t.stopPropagation(),true}function he$1(e,t){if(!e.hasNodes([z$1,K$1]))throw new Error("CodeHighlightPlugin: CodeNode or CodeHighlightNode not registered on editor");null==t&&(t=ie$1);const n=[];true!==e._headless&&n.push(e.registerMutationListener(z$1,t=>{e.getEditorState().read(()=>{for(const[n,r]of t)if("destroyed"!==r){const t=Yo(n);null!==t&&le$1(t,e);}});},{skipInitialization:false}));const r={didTransform:false,nodesCurrentlyHighlighting:new Set};return n.push(e.registerNodeTransform(z$1,ae$1.bind(null,e,t,r)),e.registerNodeTransform(gr,ce$1.bind(null,e,t,r)),e.registerNodeTransform(K$1,ce$1.bind(null,e,t,r)),e.registerCommand(Fe$2,t=>{const n=function(e){const t=Qr();if(!Fr(t)||!ue$1(t))return null;const n=e?Ke$2:Ie$3,r=e?Ke$2:Le$2,i=t.anchor,c=t.focus;if(i.is(c))return r;const l=ge$1(t);if(1!==l.length)return n;const a=l[0];let f,u;0===a.length&&J$2(285),t.isBackward()?(f=c,u=i):(f=i,u=c);const g=O(a[0]),p=A(a[0]),d=Mr(g.getKey(),0,"text"),m=Mr(p.getKey(),p.getTextContentSize(),"text");return f.isBefore(d)||m.isBefore(u)?n:d.isBefore(f)||u.isBefore(m)?r:n}(t.shiftKey);return null!==n&&(t.preventDefault(),e.dispatchCommand(n,void 0),true)},io),e.registerCommand(Le$2,()=>!!ue$1(Qr())&&(li([wr()]),true),io),e.registerCommand(Ie$3,e=>pe$1(Ie$3),io),e.registerCommand(Ke$2,e=>pe$1(Ke$2),io),e.registerCommand(we$1,e=>{const t=Qr();if(!Fr(t)||!ue$1(t))return  false;const n=Zo().getFirstDescendant(),{anchor:r}=t,o=r.getNode();return (!n||!o||n.getKey()!==o.getKey())&&de$1(we$1,e)},io),e.registerCommand(Ee$3,e=>{const t=Qr();if(!Fr(t)||!ue$1(t))return  false;const n=Zo().getLastDescendant(),{anchor:r}=t,o=r.getNode();return (!n||!o||n.getKey()!==o.getKey())&&de$1(Ee$3,e)},io),e.registerCommand(be$1,e=>me$1(be$1,e),io),e.registerCommand(Te$2,e=>me$1(Te$2,e),io)),Cc(...n)}
10835
10836/**
10837 * Copyright (c) Meta Platforms, Inc. and affiliates.
10838 *
10839 * This source code is licensed under the MIT license found in the
10840 * LICENSE file in the root directory of this source tree.
10841 *
10842 */
10843
10844const o=Q$1,a=V$1,r=ie$1,L$1=he$1;
10845
10846/**
10847 * Copyright (c) Meta Platforms, Inc. and affiliates.
10848 *
10849 * This source code is licensed under the MIT license found in the
10850 * LICENSE file in the root directory of this source tree.
10851 *
10852 */
10853
10854function G$1(t,e){const n={};for(const o of t){const t=e(o);t&&(n[t]?n[t].push(o):n[t]=[o]);}return n}function H(t){const e=G$1(t,t=>t.type);return {element:e.element||[],multilineElement:e["multiline-element"]||[],textFormat:e["text-format"]||[],textMatch:e["text-match"]||[]}}const J$1=/[!-/:-@[-`{-~\s]/;function Z(t){return t.replace(/\\([!-/:-@[-`{-~])/g,"$1").replace(/&#(\d+);/g,(t,e)=>String.fromCodePoint(Number(e)))}function at(t){return Tr(t)&&!t.hasFormat("code")}function ht(t,...e){const n=new URL("https://lexical.dev/docs/error"),o=new URLSearchParams;o.append("code",t);for(const t of e)o.append("v",t);throw n.search=o.toString(),Error(`Minified Lexical error #${t}; visit ${n.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}const xt=/^(\s*)(\d{1,})\.\s/,mt$1=/^(\s*)[-*+]\s/,Tt$1=/^(#{1,6})\s/,$t$1=/^>\s/,vt=/^([ \t]*`{3,})([\w-]+)?[ \t]?/,yt$1=/^[ \t]*`{3,}$/,Ft$1=ot$3("mdListMarker",{parse:t=>"string"==typeof t&&/^[-*+]$/.test(t)?t:"-",resetOnCopyNode:true}),Lt$1=ot$3("mdCodeFence",{parse:t=>"string"==typeof t&&/^`{3,}$/.test(t)?t:"```",resetOnCopyNode:true}),kt$1=t=>(e,n,o,r)=>{const s=t(o);s.append(...n),e.replace(s),r||s.select(0,0);};const Rt$1=t=>(e,n,o,r)=>{const s=e.getPreviousSibling(),i=e.getNextSibling(),l=fe$2("check"===t?"x"===o[3]:void 0),c=o[0].trim()[0],a="bullet"!==t&&"check"!==t||c!==Ft$1.parse(c)?void 0:c;if(Se$1(i)&&i.getListType()===t){a&&ct$2(i,Ft$1,a);const t=i.getFirstChild();null!==t?t.insertBefore(l):i.append(l),e.remove();}else if(Se$1(s)&&s.getListType()===t)a&&ct$2(s,Ft$1,a),s.append(l),e.remove();else {const n=Te$1(t,"number"===t?Number(o[2]):void 0);a&&ct$2(n,Ft$1,a),n.append(l),e.replace(n);}l.append(...n),r||l.select(0,0);const f=function(t){const e=t.match(/\t/g),n=t.match(/ /g);let o=0;return e&&(o+=e.length),n&&(o+=Math.floor(n.length/4)),o}(o[1]);f&&l.setIndent(f);},Mt$1=(t,e,n)=>{const o=[],r=t.getChildren();let s=0;for(const i of r)if(pe$2(i)){if(1===i.getChildrenSize()){const t=i.getFirstChild();if(Se$1(t)){o.push(Mt$1(t,e,n+1));continue}}const r=" ".repeat(4*n),l=t.getListType(),c=st$2(t,Ft$1),a="number"===l?`${t.getStart()+s}. `:"check"===l?`${c} [${i.getChecked()?"x":" "}] `:c+" ";let f=e(i);"number"!==l&&(f=f.replace(/^(\s{0,3}\d+)(\.\s)/,"$1\\$2")),o.push(r+a+f),s++;}return o.join("\n")},_t={dependencies:[It$1],export:(t,e)=>{if(!Lt$2(t))return null;const n=Number(t.getTag().slice(1));return "#".repeat(n)+" "+e(t)},regExp:Tt$1,replace:kt$1(t=>{const e="h"+t[1].length;return Jt$2(e)}),type:"element"}
10854,Bt$1={dependencies:[At$1],export:(t,e)=>{if(!Mt$2(t))return null;const n=e(t).split("\n"),o=[];for(const t of n)o.push("> "+t);return o.join("\n")},regExp:$t$1,replace:(t,e,n,o)=>{if(o){const n=t.getPreviousSibling();if(Mt$2(n))return n.splice(n.getChildrenSize(),0,[or(),...e]),void t.remove()}const r=St$1();r.append(...e),t.replace(r),o||r.select(0,0);},type:"element"},Ot$1={dependencies:[z$1],export:t=>{if(!W$1(t))return null;const e=t.getTextContent();let n=st$2(t,Lt$1);if(e.indexOf(n)>-1){const t=e.match(/`{3,}/g);if(t){const e=Math.max(...t.map(t=>t.length));n="`".repeat(e+1);}}return n+(t.getLanguage()||"")+(e?"\n"+e:"")+"\n"+n},handleImportAfterStartMatch:({lines:t,rootNode:e,startLineIndex:n,startMatch:o})=>{const r=o[1],s=r.trim().length,i=t[n],l=o.index+r.length,c=i.slice(l),a=new RegExp(`\`{${s},}$`);if(a.test(c)){const t=c.match(a),r=c.slice(0,c.lastIndexOf(t[0])),s=[...o];return s[2]="",Ot$1.replace(e,null,s,t,[r],true),[true,n]}const f=new RegExp(`^[ \\t]*\`{${s},}$`);for(let r=n+1;r<t.length;r++){const s=t[r];if(f.test(s)){const l=s.match(f),c=t.slice(n+1,r),a=i.slice(o[0].length);return a.length>0&&c.unshift(a),Ot$1.replace(e,null,o,l,c,true),[true,r]}}const u=t.slice(n+1),g=i.slice(o[0].length);return g.length>0&&u.unshift(g),Ot$1.replace(e,null,o,null,u,true),[true,t.length-1]},regExpEnd:{optional:true,regExp:yt$1},regExpStart:vt,replace:(t,e,n,o,r,s)=>{let i,c;const a=n[1]?n[1].trim():"```",f=n[2]||void 0;if(!e&&r){if(1===r.length)o?(i=I$1(f),c=r[0]):(i=I$1(f),c=r[0].startsWith(" ")?r[0].slice(1):r[0]);else {for(i=I$1(f),r.length>0&&(0===r[0].trim().length?r.shift():r[0].startsWith(" ")&&(r[0]=r[0].slice(1)));r.length>0&&!r[r.length-1].length;)r.pop();c=r.join("\n");}ct$2(i,Lt$1,a);const e=kr(c);i.append(e),t.append(i);}else e&&kt$1(t=>I$1(t?t[2]:void 0))(t,e,n,s);},type:"multiline-element"},jt$1={dependencies:[me$2,ge$2],export:(t,e)=>Se$1(t)?Mt$1(t,e,0):null,regExp:mt$1,replace:Rt$1("bullet"),type:"element"},Pt$1={dependencies:[me$2,ge$2],export:(t,e)=>Se$1(t)?Mt$1(t,e,0):null,regExp:xt,replace:Rt$1("number"),type:"element"},zt$1={format:["code"],tag:"`",type:"text-format"},Ut$1={format:["highlight"],tag:"==",type:"text-format"},Wt$1={format:["bold","italic"],tag:"***",type:"text-format"},Dt$1={format:["bold","italic"],intraword:false,tag:"___",type:"text-format"},Kt$1={format:["bold"],tag:"**",type:"text-format"},qt$1={format:["bold"],intraword:false,tag:"__",type:"text-format"},Gt$1={format:["strikethrough"],tag:"~~",type:"text-format"},Ht$1={format:["italic"],tag:"*",type:"text-format"},Jt$1={format:["italic"],intraword:false,tag:"_",type:"text-format"},Qt$1={dependencies:[F$4],export:(t,e,n)=>{if(!z$5(t)||G$8(t))return null;const o=e(t);let r=t.getTitle();null!=r&&(r=r.replace(/([\\"])/g,"\\$1"));return r?`[${o}](${t.getURL()} "${r}")`:`[${o}](${t.getURL()})`},importRegExp:/(?:\[(.+?)\])(?:\((?:([^()\s]+)(?:\s"((?:[^"]*\\")*[^"]*)"\s*)?)\))/,regExp:/(?:\[([^[\]]*(?:\[[^[\]]*\][^[\]]*)*)\])(?:\((?:([^()\s]+)(?:\s"((?:[^"]*\\")*[^"]*)"\s*)?)\))$/,replace:(t,e)=>{if(dl(t,z$5))return;const[,n,o,r]=e,s=null!=o?Z(o):void 0,i=null!=r?Z(r):void 0,c=$$2(s,{title:i}),a=n.split("[").length-1,f=n.split("]").length-1;let u=n,g="";if(a<f)return;if(a>f){const t=n.split("[");g="["+t[0],u=t.slice(1).join("[");}const d=kr(u);return d.setFormat(t.getFormat()),c.append(d),t.replace(c),g&&c.insertBefore(kr(g)),d},trigger:")",type:"text-match"},Vt$1=[_t,Bt$1,jt$1,Pt$1],Xt$1=[Ot$1],Yt$1=[zt$1,Wt$1,Dt$1,Kt$1,qt$1,Ut$1,Ht$1,Jt$1,Gt$1],Zt$1=[Qt$1],te=[...Vt$1,...Xt$1,...Yt$1,...Zt$1];function ee(t,e,n,o,r){const s=t.getParent();if(!Is(s)||t.getFirstChild()!==e)return  false;const i=e.getTextContent();if(!r&&" "!==i[n-1])return  false;for(const{regExpStart:s,replace:l,regExpEnd:c}of o){if(c&&!("optional"in c)||c&&"optional"in c&&!c.optional)continue;const o=i.match(s);if(o){const s=r||o[0].endsWith(" ")?n:n-1;if(o[0].length!==s)continue;const i=e.getNextSiblings(),[c,a]=e.splitText(n);if(false!==l(t,a?[a,...i]:i,o,null,null,false))return c.remove(),true}}return  false}function ne(t,e){let n=0;const o=t.getTextContent();for(let t=0;t<e;t++)"`"===o[t]&&n++;return n%2!=0}function oe$1(t,e,n){const o=n.length;for(let r=e;r>=o;r--){const e=r-o;if(re$1(t,e,n,0,o)&&" "!==t[e+o])return e}return  -1}function re$1(t,e,n,o,r){for(let s=0;s<r;s++)if(t[e+s]!==n[o+s])return  false;return  true}function se$1(t,n=te){const o=H(n),r=G$1(o.textFormat,({tag:t})=>t[t.length-1]),l=G$1(o.textMatch,({trigger:t})=>t);for(const e of n){const n=e.type;if("element"===n||"text-match"===n||"multiline-element"===n){const n=e.dependencies;
10854for(const e of n)t.hasNode(e)||ht(173,e.getType());}}const c=(t,n,c)=>!!function(t,e,n,o){const r=t.getParent();if(!Is(r)||t.getFirstChild()!==e)return  false;const s=e.getTextContent();if(" "!==s[n-1])return  false;for(const{regExp:r,replace:i}of o){const o=s.match(r);if(o&&o[0].length===(o[0].endsWith(" ")?n:n-1)){const r=e.getNextSiblings(),[s,l]=e.splitText(n);if(false!==i(t,l?[l,...r]:r,o,false))return s.remove(),true}}return  false}(t,n,c,o.element)||(!!ee(t,n,c,o.multilineElement)||(!!function(t,e,n){let o=t.getTextContent();const r=n[o[e-1]];if(null==r)return  false;e<o.length&&(o=o.slice(0,e));for(const e of r){if(!e.replace||!e.regExp)continue;const n=o.match(e.regExp);if(null===n)continue;const r=n.index||0,s=r+n[0].length;let i;return 0===r?[i]=t.splitText(s):[,i]=t.splitText(r,s),i.selectNext(0,0),e.replace(i,n),true}return  false}(n,c,l)||!!function(t,n,o){const r=t.getTextContent(),l=n-1,c=r[l],a=o[c];if(!a)return  false;for(const n of a){const{tag:o}=n,a=o.length,f=l-a+1;if(a>1&&!re$1(r,f,o,0,a))continue;if(" "===r[f-1])continue;const u=r[l+1];if(false===n.intraword&&u&&!J$1.test(u))continue;const g=t;let d=g,p=oe$1(r,f,o),h=d;for(;p<0&&(h=h.getPreviousSibling())&&!sr(h);)if(Tr(h)){if(h.hasFormat("code"))continue;const t=h.getTextContent();d=h,p=oe$1(t,t.length,o);}if(p<0)continue;if(d===g&&p+a===f)continue;const x=d.getTextContent();if(p>0&&x[p-1]===c)continue;const m=x[p-1];if(false===n.intraword&&m&&!J$1.test(m))continue;if(!n.format.includes("code")&&ne(d,p))continue;const T=g.getTextContent(),$=T.slice(0,f)+T.slice(l+1);g.setTextContent($);const v=d===g?$:x;d.setTextContent(v.slice(0,p)+v.slice(p+a));const y=Qr(),E=qr();es(E);const S=l-a*(d===g?2:1)+1;E.anchor.set(d.__key,p,"text"),E.focus.set(g.__key,S,"text");for(const t of n.format)E.hasFormat(t)||E.formatText(t);E.anchor.set(E.focus.key,E.focus.offset,E.focus.type);for(const t of n.format)E.hasFormat(t)&&E.toggleFormat(t);return Fr(y)&&(E.format=y.format),true}return  false}(n,c,r)));return Cc(t.registerUpdateListener(({tags:n,dirtyLeaves:o,editorState:r,prevEditorState:s})=>{if(n.has(Un)||n.has(Wn$1))return;if(t.isComposing())return;const l=r.read(Qr),a=s.read(Qr);if(!Fr(a)||!Fr(l)||!l.isCollapsed()||l.is(a))return;const f=l.anchor.key,u=l.anchor.offset,g=r._nodeMap.get(f);!Tr(g)||!o.has(f)||1!==u&&u>a.anchor.offset+1||t.update(()=>{if(!at(g))return;const t=g.getParent();null===t||W$1(t)||c(t,g,l.anchor.offset)&&Os($n$1);});}),t.registerCommand(Oe$2,t=>{if(null!==t&&t.shiftKey)return  false;const n=Qr();if(!Fr(n)||!n.isCollapsed())return  false;const r=n.anchor.offset,s=n.anchor.getNode();if(!Tr(s)||!at(s))return  false;const l=s.getParent();if(null===l||W$1(l))return  false;return r===s.getTextContent().length&&(!!ee(l,s,r,o.multilineElement,true)&&(null!==t&&t.preventDefault(),true))},io))}
10855
10856class HorizontalDividerNode extends Ji {
10857  static getType() {
10858    return "horizontal_divider"
10859  }
10860
10861  static clone(node) {
10862    return new HorizontalDividerNode(node.__key)
10863  }
10864
10865  static importJSON(serializedNode) {
10866    return new HorizontalDividerNode()
10867  }
10868
10869  static importDOM() {
10870    return {
10871      "hr": (hr) => {
10872        return {
10873          conversion: () => ({
10874            node: new HorizontalDividerNode()
10875          }),
10876          priority: 1
10877        }
10878      }
10879    }
10880  }
10881
10882  constructor(key) {
10883    super(key);
10884  }
10885
10886  createDOM() {
10887    const figure = createElement("figure", { className: "horizontal-divider" });
10888    const hr = createElement("hr");
10889
10890    figure.appendChild(hr);
10891
10892    const deleteButton = createElement("lexxy-node-delete-button");
10893    figure.appendChild(deleteButton);
10894
10895    return figure
10896  }
10897
10898  updateDOM() {
10899    return true
10900  }
10901
10902  getTextContent() {
10903    return "┄\n\n"
10904  }
10905
10906  isInline() {
10907    return false
10908  }
10909
10910  exportDOM() {
10911    const hr = createElement("hr");
10912    return { element: hr }
10913  }
10914
10915  exportJSON() {
10916    return {
10917      type: "horizontal_divider",
10918      version: 1
10919    }
10920  }
10921
10922  decorate() {
10923    return null
10924  }
10925}
10926
10927const HORIZONTAL_DIVIDER = {
10928  dependencies: [ HorizontalDividerNode ],
10929  export: (node) => {
10930    return node instanceof HorizontalDividerNode ? "---" : null
10931  },
10932  regExpStart: /^-{3,}\s?$/,
10933  replace: (parentNode, children, match, endMatch, linesInBetween, isImport) => {
10934    const hrNode = new HorizontalDividerNode();
10935    parentNode.replace(hrNode);
10936
10937    if (!isImport) {
10938      const paragraph = eo();
10939      hrNode.insertAfter(paragraph);
10940      paragraph.select();
10941    }
10942  },
10943  type: "multiline-element"
10944};
10945
10946const PUNCTUATION_OR_SPACE = /[^\w]/;
10947
10948// Supplements Lexical's built-in registerMarkdownShortcuts to handle the case
10949// where a user types a leading tag before text that already ends with a
10950// trailing tag (e.g. typing ` before `hello`` or ** before **hello**).
10951//
10952// Lexical's markdown shortcut handler only triggers format transformations when
10953// the closing tag is the character just typed. When the opening tag is typed
10954// instead (e.g. typing ` before `hello`` to form ``hello``), the built-in
10955// handler doesn't match because it looks backward from the cursor for an
10956// opening tag, but the cursor is right after it.
10957//
10958// This listener detects that scenario for ALL text format transformers
10959// (backtick, bold, italic, strikethrough, etc.) and applies the appropriate
10960// format.
10961function registerMarkdownLeadingTagHandler(editor, transformers) {
10962  const textFormatTransformers = transformers
10963    .filter(t => t.type === "text-format")
10964    .sort((a, b) => b.tag.length - a.tag.length); // Longer tags first
10965
10966  return editor.registerUpdateListener(({ tags, dirtyLeaves, editorState, prevEditorState }) => {
10967    if (tags.has("historic") || tags.has("collaboration")) return
10968    if (editor.isComposing()) return
10969
10970    const selection = editorState.read(Qr);
10971    const prevSelection = prevEditorState.read(Qr);
10972
10973    if (!Fr(prevSelection) || !Fr(selection) || !selection.isCollapsed()) return
10974
10975    const anchorKey = selection.anchor.key;
10976    const anchorOffset = selection.anchor.offset;
10977
10978    if (!dirtyLeaves.has(anchorKey)) return
10979
10980    const anchorNode = editorState.read(() => Yo(anchorKey));
10981    if (!Tr(anchorNode)) return
10982
10983    // Only trigger when cursor moved forward (typing)
10984    const prevOffset = prevSelection.anchor.key === anchorKey ? prevSelection.anchor.offset : 0;
10985    if (anchorOffset <= prevOffset) return
10986
10987    const textContent = editorState.read(() => anchorNode.getTextContent());
10988
10989    // Try each transformer, longest tags first
10990    for (const transformer of textFormatTransformers) {
10991      const tag = transformer.tag;
10992      const tagLen = tag.length;
10993
10994      // The typed characters must end at the cursor position and form the opening tag
10995      const openTagStart = anchorOffset - tagLen;
10996      if (openTagStart < 0) continue
10997
10998      const candidateOpenTag = textContent.slice(openTagStart, anchorOffset);
10999      if (candidateOpenTag !== tag) continue
11000
11001      // Disambiguate from longer tags: if the character before the opening tag
11002      // is the same as the tag character, this might be part of a longer tag
11003      // (e.g. seeing `*` when the user is actually typing `**`)
11004      const tagChar = tag[0];
11005      if (openTagStart > 0 && textContent[openTagStart - 1] === tagChar) continue
11006
11007      // Check intraword constraint: if intraword is false, the character before
11008      // the opening tag must be a space, punctuation, or the start of the text
11009      if (transformer.intraword === false && openTagStart > 0) {
11010        const beforeChar = textContent[openTagStart - 1];
11011        if (beforeChar && !PUNCTUATION_OR_SPACE.test(beforeChar)) continue
11012      }
11013
11014      // Search forward for a closing tag in the same text node
11015      const searchStart = anchorOffset;
11016      const closeTagIndex = textContent.indexOf(tag, searchStart);
11017      if (closeTagIndex < 0) continue
11018
11019      // Disambiguate closing tag from longer tags: if the character r
vendor: 4,204 bytes, lines 11019-11139
11019ight after
11020      // the closing tag is the same as the tag character, skip
11021      // (e.g. `*hello**` — the first `*` at index 6 is part of `**`)
11022      if (textContent[closeTagIndex + tagLen] === tagChar) continue
11023
11024      // Also check if the character before the closing tag start is the same
11025      // tag character (e.g. the closing tag might be a suffix of a longer sequence)
11026      if (closeTagIndex > 0 && textContent[closeTagIndex - 1] === tagChar) continue
11027
11028      // There must be content between the tags (not just empty or whitespace-adjacent)
11029      const innerStart = anchorOffset;
11030      const innerEnd = closeTagIndex;
11031      if (innerEnd <= innerStart) continue
11032
11033      // No space immediately after opening tag
11034      if (textContent[innerStart] === " ") continue
11035
11036      // No space immediately before closing tag
11037      if (textContent[innerEnd - 1] === " ") continue
11038
11039      // Check intraword constraint for closing tag
11040      if (transformer.intraword === false) {
11041        const afterCloseChar = textContent[closeTagIndex + tagLen];
11042        if (afterCloseChar && !PUNCTUATION_OR_SPACE.test(afterCloseChar)) continue
11043      }
11044
11045      editor.update(() => {
11046        const node = Yo(anchorKey);
11047        if (!node || !Tr(node)) return
11048
11049        const parent = node.getParent();
11050        if (parent === null || W$1(parent)) return
11051
11052        $applyFormatFromLeadingTag(node, openTagStart, transformer);
11053      });
11054
11055      break // Only apply the first (longest) matching transformer
11056    }
11057  })
11058}
11059
11060function $applyFormatFromLeadingTag(anchorNode, openTagStart, transformer) {
11061  const tag = transformer.tag;
11062  const tagLen = tag.length;
11063  const textContent = anchorNode.getTextContent();
11064
11065  const innerStart = openTagStart + tagLen;
11066  const closeTagIndex = textContent.indexOf(tag, innerStart);
11067  if (closeTagIndex < 0) return
11068
11069  const inner = textContent.slice(innerStart, closeTagIndex);
11070  if (inner.length === 0) return
11071
11072  // Remove both tags and apply format
11073  const before = textContent.slice(0, openTagStart);
11074  const after = textContent.slice(closeTagIndex + tagLen);
11075
11076  anchorNode.setTextContent(before + inner + after);
11077
11078  const nextSelection = qr();
11079  es(nextSelection);
11080
11081  // Select the inner text to apply formatting
11082  nextSelection.anchor.set(anchorNode.getKey(), openTagStart, "text");
11083  nextSelection.focus.set(anchorNode.getKey(), openTagStart + inner.length, "text");
11084
11085  for (const format of transformer.format) {
11086    if (!nextSelection.hasFormat(format)) {
11087      nextSelection.formatText(format);
11088    }
11089  }
11090
11091  // Collapse selection to end of formatted text and clear the format
11092  // so subsequent typing is plain text
11093  nextSelection.anchor.set(nextSelection.focus.key, nextSelection.focus.offset, nextSelection.focus.type);
11094
11095  for (const format of transformer.format) {
11096    if (nextSelection.hasFormat(format)) {
11097      nextSelection.toggleFormat(format);
11098    }
11099  }
11100}
11101
11102var theme = {
11103  text: {
11104    bold: "lexxy-content__bold",
11105    italic: "lexxy-content__italic",
11106    strikethrough: "lexxy-content__strikethrough",
11107    underline: "lexxy-content__underline",
11108    highlight: "lexxy-content__highlight"
11109  },
11110  tableCellHeader: "lexxy-content__table-cell--header",
11111  tableCellSelected: "lexxy-content__table-cell--selected",
11112  tableSelection: "lexxy-content__table--selection",
11113  tableScrollableWrapper: "lexxy-content__table-wrapper",
11114  tableCellHighlight: "lexxy-content__table-cell--highlight",
11115  tableCellFocus: "lexxy-content__table-cell--focus",
11116  list: {
11117    nested: {
11118      listitem: "lexxy-nested-listitem",
11119    }
11120  },
11121  codeHighlight: {
11122    addition: "code-token__selector",
11123    atrule: "code-token__attr",
11124    attr: "code-token__attr",
11125    "attr-name": "code-token__attr",
11126    "attr-value": "code-token__selector",
11127    boolean: "code-token__property",
11128    bold: "code-token__variable",
11129    builtin: "code-token__selector",
11130    cdata: "code-token__comment",
11131    char: "code-token__selector",
11132    class: "code-token__function",
11133    "class-name": "code-token__function",
11134    color: "code-token__property",
11135    comment: "code-token__comment",
11136    constant: "code-token__property",
11137    coord: "code-token__comment",
11138    decorator: "code-token__function",
11139    deleted: "code-token__operator",
11140    deletion: "code-token__operator",
11141    directive: "code-token__attr",
11142    "directive-hash": "code-token__property",
11143    doctype: "code-token__comment",
11144    entity: "code-token__operator",
11145    function: "code-token__function",
11146    hexcode: "code-token__property",
11147    important: "code-token__function",
11148    inserted: "code-token__selector",
11149    italic: "code-token__comment",
11150    keyword: "code-token__attr",
11151    line: "code-token__selector",
11152    namespace: "code-token__variable",
11153    number: "code-token__property",
11154    macro: "code-token__function",
11155    operator: "code-token__operator",
11156    parameter: "code-token__variable",
11157    prolog: "code-token__comment",
11158    property: "code-token__property",
11159    punctuation: "code-token__punctuation",
11160    "raw-string": "code-token__operator",
11161    regex: "code-token__variable",
11162    script: "code-token__function",
11163    selector: "code-token__selector",
11164    string: "code-token__selector",
11165    style: "code-token__function",
11166    symbol: "code-token__property",
11167    tag: "code-token__property",
11168    title: "code-token__function",
11169    "type-definition": "code-token__function",
11170    url: "code-token__operator",
11171    variable: "code-token__variable",
11172  }
11173};
11174
11175class UploadRequests {
11176  #requestsByKey = new Map()
11177
11178  track(key, request) {
11179    this.#requestsByKey.set(key, request);
11180  }
11181
11182  forget(key) {
11183    this.#requestsByKey.delete(key);
11184  }
11185
11186  abort(key) {
11187    const request = this.#requestsByKey.get(key);
11188    if (request) {
11189      this.#requestsByKey.delete(key);
11190      request.abort();
11191    }
11192  }
11193
11194  clear() {
11195    this.#requestsByKey.clear();
11196  }
11197}
11198
11199/**
11200 * Copyright (c) Meta Platforms, Inc. and affiliates.
11201 *
11202 * This source code is licensed under the MIT license found in the
11203 * LICENSE file in the root directory of this source tree.
11204 *
11205 */
11206
11207const Ke$1=/^(\d+(?:\.\d+)?)px$/,Ae$1={BOTH:3,COLUMN:2,NO_STATUS:0,ROW:1};let Ee$1 = class Ee extends Bi{__colSpan;__rowSpan;__headerState;__width;__backgroundColor;__verticalAlign;static getType(){return "tablecell"}static clone(e){return new Ee(e.__headerState,e.__colSpan,e.__width,e.__key)}afterCloneFrom(e){super.afterCloneFrom(e),this.__rowSpan=e.__rowSpan,this.__backgroundColor=e.__backgroundColor,this.__verticalAlign=e.__verticalAlign,this.__colSpan=e.__colSpan,this.__headerState=e.__headerState,this.__width=e.__width;}static importDOM(){return {td:e=>({conversion:Me$1,priority:0}),th:e=>({conversion:Me$1,priority:0})}}static importJSON(e){return $e$1().updateFromJSON(e)}updateFromJSON(e){return super.updateFromJSON(e).setHeaderStyles(e.headerState).setColSpan(e.colSpan||1).setRowSpan(e.rowSpan||1).setWidth(e.width||void 0).setBackgroundColor(e.backgroundColor||null).setVerticalAlign(e.verticalAlign||void 0)}constructor(e=Ae$1.NO_STATUS,t=1,n,o){super(o),this.__colSpan=t,this.__rowSpan=1,this.__headerState=e,this.__width=n,this.__backgroundColor=null,this.__verticalAlign=void 0;}createDOM(t){const n=document.createElement(this.getTag());return this.__width&&(n.style.width=`${this.__width}px`),this.__colSpan>1&&(n.colSpan=this.__colSpan),this.__rowSpan>1&&(n.rowSpan=this.__rowSpan),null!==this.__backgroundColor&&(n.style.backgroundColor=this.__backgroundColor),ke$1(this.__verticalAlign)&&(n.style.verticalAlign=this.__verticalAlign),mc(n,t.theme.tableCell,this.hasHeader()&&t.theme.tableCellHeader),n}exportDOM(e){const t=super.exportDOM(e);if(Ys(t.element)){const e=t.element;e.setAttribute("data-temporary-table-cell-lexical-key",this.getKey()),e.style.border="1px solid black",this.__colSpan>1&&(e.colSpan=this.__colSpan),this.__rowSpan>1&&(e.rowSpan=this.__rowSpan),e.style.width=`${this.getWidth()||75}px`,e.style.verticalAlign=this.getVerticalAlign()||"top",e.style.textAlign="start",null===this.__backgroundColor&&this.hasHeader()&&(e.style.backgroundColor="#f2f3f5");}return t}exportJSON(){return {...super.exportJSON(),...ke$1(this.__verticalAlign)&&{verticalAlign:this.__verticalAlign},backgroundColor:this.getBackgroundColor(),colSpan:this.__colSpan,headerState:this.__headerState,rowSpan:this.__rowSpan,width:this.getWidth()}}getColSpan(){return this.getLatest().__colSpan}setColSpan(e){const t=this.getWritable();return t.__colSpan=e,t}getRowSpan(){return this.getLatest().__rowSpan}setRowSpan(e){const t=this.getWritable();return t.__rowSpan=e,t}getTag(){return this.hasHeader()?"th":"td"}setHeaderStyles(e,t=Ae$1.BOTH){const n=this.getWritable();return n.__headerState=e&t|n.__headerState&~t,n}getHeaderStyles(){return this.getLatest().__headerState}setWidth(e){const t=this.getWritable();return t.__width=e,t}getWidth(){return this.getLatest().__width}
11207getBackgroundColor(){return this.getLatest().__backgroundColor}setBackgroundColor(e){const t=this.getWritable();return t.__backgroundColor=e,t}getVerticalAlign(){return this.getLatest().__verticalAlign}setVerticalAlign(e){const t=this.getWritable();return t.__verticalAlign=e||void 0,t}toggleHeaderStyle(e){const t=this.getWritable();return (t.__headerState&e)===e?t.__headerState-=e:t.__headerState+=e,t}hasHeaderState(e){return (this.getHeaderStyles()&e)===e}hasHeader(){return this.getLatest().__headerState!==Ae$1.NO_STATUS}updateDOM(e){return e.__headerState!==this.__headerState||e.__width!==this.__width||e.__colSpan!==this.__colSpan||e.__rowSpan!==this.__rowSpan||e.__backgroundColor!==this.__backgroundColor||e.__verticalAlign!==this.__verticalAlign}isShadowRoot(){return  true}collapseAtStart(){return  true}canBeEmpty(){return  false}canIndent(){return  false}};function ke$1(e){return "middle"===e||"bottom"===e}function Me$1(e){const t=e,n=e.nodeName.toLowerCase();let o;Ke$1.test(t.style.width)&&(o=parseFloat(t.style.width));let r=Ae$1.NO_STATUS;if("th"===n){const e=t.getAttribute("scope");if("col"===e)r=Ae$1.COLUMN;else if("row"===e)r=Ae$1.ROW;else {const e=t.parentElement,n=Ys(e)&&"tr"===e.nodeName.toLowerCase()&&Ys(e.parentElement)&&("thead"===e.parentElement.nodeName.toLowerCase()||0===e.rowIndex),o=0===t.cellIndex;n&&(r|=Ae$1.ROW),o&&(r|=Ae$1.COLUMN),r===Ae$1.NO_STATUS&&(r=Ae$1.ROW);}}const l=$e$1(r,t.colSpan,o);l.__rowSpan=t.rowSpan;const s=t.style.backgroundColor;""!==s&&(l.__backgroundColor=s);const i=t.style.verticalAlign;ke$1(i)&&(l.__verticalAlign=i);const c=t.style,a=(c&&c.textDecoration||"").split(" "),u="700"===c.fontWeight||"bold"===c.fontWeight,h=a.includes("line-through"),C="italic"===c.fontStyle,_=a.includes("underline"),S=c.color;return {after:e=>{const t=[];let n=null;const o=()=>{if(n){const e=n.getFirstChild();sr(e)&&1===n.getChildrenSize()&&e.remove();}};for(const r of e)if(Fs(r)||Tr(r)||sr(r)){if(Tr(r)&&(u&&r.toggleFormat("bold"),h&&r.toggleFormat("strikethrough"),C&&r.toggleFormat("italic"),_&&r.toggleFormat("underline"),S)){const e=r.getStyle();e.includes("color:")||r.setStyle(e+`color: ${S};`);}n?n.append(r):(n=eo().append(r),t.push(n));}else t.push(r),o(),n=null;return o(),0===t.length&&t.push(eo()),t},node:l}}function $e$1(e=Ae$1.NO_STATUS,t=1,n){return zs(new Ee$1(e,t,n))}function We$1(e){return e instanceof Ee$1}const ze$1=re$5("INSERT_TABLE_COMMAND");function Le$1(e,...t){const n=new URL("https://lexical.dev/docs/error"),o=new URLSearchParams;o.append("code",e);for(const e of t)o.append("v",e);throw n.search=o.toString(),Error(`Minified Lexical error #${e}; visit ${n.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}let He$1 = class He extends Bi{__height;static getType(){return "tablerow"}static clone(e){return new He(e.__height,e.__key)}afterCloneFrom(e){super.afterCloneFrom(e),this.__height=e.__height;}static importDOM(){return {tr:e=>({conversion:Be$1,priority:0})}}static importJSON(e){return Pe$1().updateFromJSON(e)}updateFromJSON(e){return super.updateFromJSON(e).setHeight(e.height)}constructor(e,t){super(t),this.__height=e;}exportJSON(){const e=this.getHeight();return {...super.exportJSON(),...void 0===e?void 0:{height:e}}}createDOM(t){const n=document.createElement("tr");return this.__height&&(n.style.height=`${this.__height}px`),mc(n,t.theme.tableRow),n}extractWithChild(e,t,n){return "html"===n}isShadowRoot(){return  true}setHeight(e){const t=this.getWritable();return t.__height=e,t}getHeight(){return this.getLatest().__height}updateDOM(e){return e.__height!==this.__height}canBeEmpty(){return  false}canIndent(){return  false}};function Be$1(e){const n=e;let o;return Ke$1.test(n.style.height)&&(o=parseFloat(n.style.height)),{after:e=>Ht$3(e,We$1),node:Pe$1(o)}}function Pe$1(e){return zs(new He$1(e))}function De$1(e){return e instanceof He$1}const Ie$1="undefined"!=typeof window&&void 0!==window.document&&void 0!==window.document.createElement,Ue$1=Ie$1&&"documentMode"in document?document.documentMode:null,Je$1=Ie$1&&/^(?!.*Seamonkey)(?=.*Firefox).*/i.test(navigator.userAgent);function Xe$1(e,t,n=true){const o=Fn();for(let r=0;r<e;r++){const e=Pe$1();for(let o=0;o<t;o++){let t=Ae$1.NO_STATUS;"object"==typeof n?(0===r&&n.rows&&(t|=Ae$1.ROW),0===o&&n.columns&&(t|=Ae$1.COLUMN)):n&&(0===r&&(t|=Ae$1.ROW),0===o&&(t|=Ae$1.COLUMN));const l=$e$1(t),s=eo();s.append(kr()),l.append(s),e.append(l);}o.append(e);}return o}function Ye(e){const t=dl(e,e=>We$1(e));return We$1(t)?t:null}function qe$1(e){const t=dl(e,e=>De$1(e));if(De$1(t))return t;throw new Error("Expected table cell to be inside of table row.")}function je$1(e){const t=dl(e,e=>Rn(e));if(Rn(t))return t;throw new Error("Expected table cell to be inside of table.")}function Ve$1(e){const t=qe$1(e);return je$1(t).getChildren().findIndex(e=>e.is(t))}function Ge$1(e){return qe$1(e).getChildren().findIndex(t=>t.is(e))}Ie$1&&"InputEvent"in window&&!Ue$1&&new window.InputEvent("input");const tt=(e,t)=>e===Ae$1.BOTH||e===t?t:Ae$1.NO_STATUS;function nt(e=true){const t=Qr();Fr(t)||Ot(t)||Le$1(188);const n=t.anchor.getNode(),o=t.focus.getNode(),[r]=yt(n),[l,,s]=yt(o),[,i,c]=wt(s,l,r),{startRow:a}=c,{startRow:u}=i;return e?rt(a+r.__rowSpan>u+l.__rowSpan?r:l,true):rt(u<a?l:r,false)}function rt(e,t=true){const[,,n]=yt(e),[o,r]=wt(n,e,e),l=o[0].length,{startRow:s}=r;let i=null;if(t){const t=s+e.__rowSpan-1,r=o[t],c=Pe$1();for(let e=0;e<l;e++){const{cell:n,startRow:o}=r[e];if(o+n.__rowSpan-1<=t){const t=r[e].cell.__headerState,n=tt(t,Ae$1.COLUMN);c.append($e$1(n).append(eo()));}else n.setRowSpan(n.__rowSpan+1);}const a=n.getChildAtIndex(t);De$1(a)||Le$1(256),a.insertAfter(c),i=c;}else {const e=s,t=o[e],r=Pe$1();for(let n=0;n<l;n++){const{cell:o,startRow:l}=t[n];if(l===e){const e=t[n].cell.__headerState,o=tt(e,Ae$1.COLUMN);r.append($e$1(o).append(eo()));}else o.setRowSpan(o.__rowSpan+1);}const c=n.getChildAtIndex(e);De$1(c)||Le$1(257),c.insertBefore(r),i=r;}return i}function st(e=true){const t=Qr();Fr(t)||Ot(t)||Le$1(188);const n=t.anchor.getNode(),o=t.focus.getNode(),[r]=yt(n),[l,,s]=yt(o),[,i,c]=wt(s,l,r),{startColumn:a}=c,{startColumn:u}=i;return e?ct(a+r.__colSpan>u+l.__colSpan?r:l,true):ct(u<a?l:r,false)}
11207function ct(e,t=true,n=true){const[,,o]=yt(e),[r,l]=wt(o,e,e),s=r.length,{startColumn:i}=l,c=t?i+e.__colSpan-1:i-1,a=o.getFirstChild();De$1(a)||Le$1(120);let u=null;function h(e=Ae$1.NO_STATUS){const t=$e$1(e).append(eo());return null===u&&(u=t),t}let d=a;e:for(let e=0;e<s;e++){if(0!==e){const e=d.getNextSibling();De$1(e)||Le$1(121),d=e;}const t=r[e],n=t[c<0?0:c].cell.__headerState,o=tt(n,Ae$1.ROW);if(c<0){mt(d,h(o));continue}const{cell:l,startColumn:s,startRow:i}=t[c];if(s+l.__colSpan-1<=c){let n=l,r=i,s=c;for(;r!==e&&n.__rowSpan>1;){if(s-=l.__colSpan,!(s>=0)){d.append(h(o));continue e}{const{cell:e,startRow:o}=t[s];n=e,r=o;}}n.insertAfter(h(o));}else l.setColSpan(l.__colSpan+1);}null!==u&&n&&gt(u);const f=o.getColWidths();if(f){const e=[...f],t=c<0?0:c,n=e[t];e.splice(t,0,n),o.setColWidths(e);}return u}function ut(){const e=Qr();Fr(e)||Ot(e)||Le$1(188);const[t,n]=e.isBackward()?[e.focus.getNode(),e.anchor.getNode()]:[e.anchor.getNode(),e.focus.getNode()],[o,,r]=yt(t),[l]=yt(n),[s,i,c]=wt(r,o,l),{startRow:a}=i,{startRow:u}=c,h=u+l.__rowSpan-1;if(s.length===h-a+1)return void r.remove();const d=s[0].length,f=s[h+1],g=r.getChildAtIndex(h+1);for(let e=h;e>=a;e--){for(let t=d-1;t>=0;t--){const{cell:n,startRow:o,startColumn:r}=s[e][t];if(r===t){if(o<a||o+n.__rowSpan-1>h){const e=Math.max(o,a),t=Math.min(n.__rowSpan+o-1,h),r=e<=t?t-e+1:0;n.setRowSpan(n.__rowSpan-r);}if(o>=a&&o+n.__rowSpan-1>h&&e===h){null===g&&Le$1(122);let o=null;for(let n=0;n<t;n++){const t=f[n],r=t.cell;t.startRow===e+1&&(o=r),r.__colSpan>1&&(n+=r.__colSpan-1);}null===o?mt(g,n):o.insertAfter(n);}}}const t=r.getChildAtIndex(e);De$1(t)||Le$1(206,String(e)),t.remove();}if(void 0!==f){const{cell:e}=f[0];gt(e);}else {const e=s[a-1],{cell:t}=e[0];gt(t);}}function dt(){const e=Qr();Fr(e)||Ot(e)||Le$1(188);const t=e.anchor.getNode(),n=e.focus.getNode(),[o,,r]=yt(t),[l]=yt(n),[s,i,c]=wt(r,o,l),{startColumn:a}=i,{startRow:u,startColumn:h}=c,d=Math.min(a,h),f=Math.max(a+o.__colSpan-1,h+l.__colSpan-1),g=f-d+1;if(s[0].length===f-d+1)return r.selectPrevious(),void r.remove();const m=s.length;for(let e=0;e<m;e++)for(let t=d;t<=f;t++){const{cell:n,startColumn:o}=s[e][t];if(o<d){if(t===d){const e=d-o;n.setColSpan(n.__colSpan-Math.min(g,n.__colSpan-e));}}else if(o+n.__colSpan-1>f){if(t===f){const e=f-o+1;n.setColSpan(n.__colSpan-e);}}else n.remove();}const p=s[u],C=a>h?p[a+o.__colSpan]:p[h+l.__colSpan];if(void 0!==C){const{cell:e}=C;gt(e);}else {const e=h<a?p[h-1]:p[a-1],{cell:t}=e;gt(t);}const _=r.getColWidths();if(_){const e=[..._];e.splice(d,g),r.setColWidths(e);}}function gt(e){const t=e.getFirstDescendant();null==t?e.selectStart():t.getParentOrThrow().selectStart();}function mt(e,t){const n=e.getFirstChild();null!==n?n.insertBefore(t):e.append(t);}function pt(e){if(0===e.length)return null;const t=je$1(e[0]),[n]=bt(t,null,null);let o=1/0,r=-1/0,l=1/0,s=-1/0;const i=new Set;for(const t of n)for(const n of t){if(!n||!n.cell)continue;const t=n.cell.getKey();if(!i.has(t)&&e.some(e=>e.is(n.cell))){i.add(t);const e=n.startRow,c=n.startColumn,a=n.cell.__rowSpan||1,u=n.cell.__colSpan||1;o=Math.min(o,e),r=Math.max(r,e+a-1),l=Math.min(l,c),s=Math.max(s,c+u-1);}}if(o===1/0||l===1/0)return null;const c=r-o+1,a=s-l+1,u=n[o][l];if(!u.cell)return null;const h=u.cell;h.setColSpan(a),h.setRowSpan(c);const d=new Set([h.getKey()]);for(let e=o;e<=r;e++)for(let t=l;t<=s;t++){const o=n[e][t];if(!o.cell)continue;const r=o.cell,l=r.getKey();if(!d.has(l)){d.add(l);Ct(r)||h.append(...r.getChildren()),r.remove();}}return 0===h.getChildrenSize()&&h.append(eo()),h}function Ct(e){if(1!==e.getChildrenSize())return  false;const t=e.getFirstChildOrThrow();return !(!no(t)||!t.isEmpty())}function St(e){const[t,n,o]=yt(e),r=t.__colSpan,l=t.__rowSpan;if(1===r&&1===l)return;const[s,i]=wt(o,t,t),{startColumn:c,startRow:a}=i,u=t.__headerState&Ae$1.COLUMN,h=Array.from({length:r},(e,t)=>{let n=u;for(let e=0;0!==n&&e<s.length;e++)n&=s[e][t+c].cell.__headerState;return n}),d=t.__headerState&Ae$1.ROW,f=Array.from({length:l},(e,t)=>{let n=d;for(let e=0;0!==n&&e<s[0].length;e++)n&=s[t+a][e].cell.__headerState;return n});if(r>1){for(let e=1;e<r;e++)t.insertAfter($e$1(h[e]|f[0]).append(eo()));t.setColSpan(1);}if(l>1){let e;for(let t=1;t<l;t++){const o=a+t,l=s[o];e=(e||n).getNextSibling(),De$1(e)||Le$1(125);let i=null;for(let e=0;e<c;e++){const t=l[e],n=t.cell;t.startRow===o&&(i=n),n.__colSpan>1&&(e+=n.__colSpan-1);}if(null===i)for(let n=r-1;n>=0;n--)mt(e,$e$1(h[n]|f[t]).append(eo()));else for(let e=r-1;e>=0;e--)i.insertAfter($e$1(h[e]|f[t]).append(eo()));}t.setRowSpan(1);}}function wt(e,t,n){const[o,r,l]=bt(e,t,n);return null===r&&Le$1(207),null===l&&Le$1(208),[o,r,l]}function bt(e,t,n){const o=[];let r=null,l=null;function s(e){let t=o[e];return void 0===t&&(o[e]=t=[]),t}const i=e.getChildren();for(let e=0;e<i.length;e++){const o=i[e];De$1(o)||Le$1(209);const c=s(e);for(let a=o.getFirstChild(),u=0;null!=a;a=a.getNextSibling()){for(We$1(a)||Le$1(147);void 0!==c[u];)u++;const o={cell:a,startColumn:u,startRow:e},{__rowSpan:h,__colSpan:d}=a;for(let t=0;t<h&&!(e+t>=i.length);t++){const n=s(e+t);for(let e=0;e<d;e++)n[u+e]=o;}null!==t&&null===r&&t.is(a)&&(r=o),null!==n&&null===l&&n.is(a)&&(l=o);}}return [o,r,l]}function yt(e){let t;if(e instanceof Ee$1)t=e;else if("__type"in e){const o=dl(e,We$1);
vendor: 4,886 bytes, line 11207
11207We$1(o)||Le$1(148),t=o;}else {const o=dl(e.getNode(),We$1);We$1(o)||Le$1(148),t=o;}const o=t.getParent();De$1(o)||Le$1(149);const r=o.getParent();return Rn(r)||Le$1(210),[t,o,r]}function Nt(e,t,n){let o,r=Math.min(t.startColumn,n.startColumn),l=Math.min(t.startRow,n.startRow),s=Math.max(t.startColumn+t.cell.__colSpan-1,n.startColumn+n.cell.__colSpan-1),i=Math.max(t.startRow+t.cell.__rowSpan-1,n.startRow+n.cell.__rowSpan-1);do{o=false;for(let t=0;t<e.length;t++)for(let n=0;n<e[0].length;n++){const c=e[t][n];if(!c)continue;const a=c.startColumn+c.cell.__colSpan-1,u=c.startRow+c.cell.__rowSpan-1,h=c.startColumn<=s&&a>=r,d=c.startRow<=i&&u>=l;if(h&&d){const e=Math.min(r,c.startColumn),t=Math.max(s,a),n=Math.min(l,c.startRow),h=Math.max(i,u);e===r&&t===s&&n===l&&h===i||(r=e,s=t,l=n,i=h,o=true);}}}while(o);return {maxColumn:s,maxRow:i,minColumn:r,minRow:l}}function Tt(e){const[t,,n]=yt(e),o=n.getChildren(),r=o.length,l=o[0].getChildren().length,s=new Array(r);for(let e=0;e<r;e++)s[e]=new Array(l);for(let e=0;e<r;e++){const n=o[e].getChildren();let r=0;for(let o=0;o<n.length;o++){for(;s[e][r];)r++;const l=n[o],i=l.__rowSpan||1,c=l.__colSpan||1;for(let t=0;t<i;t++)for(let n=0;n<c;n++)s[e+t][r+n]=l;if(t===l)return {colSpan:c,columnIndex:r,rowIndex:e,rowSpan:i};r+=c;}}return null}function Ft(e){const[[t,o,r,l],[s,i,c,a]]=["anchor","focus"].map(t=>{const o=e[t].getNode(),r=dl(o,We$1);We$1(r)||Le$1(238,t,o.getKey(),o.getType());const l=r.getParent();De$1(l)||Le$1(239,t);const s=l.getParent();return Rn(s)||Le$1(240,t),[o,r,l,s]});return l.is(a)||Le$1(241),{anchorCell:o,anchorNode:t,anchorRow:r,anchorTable:l,focusCell:i,focusNode:s,focusRow:c,focusTable:a}}class Rt{tableKey;anchor;focus;_cachedNodes;dirty;constructor(e,t,n){this.anchor=t,this.focus=n,t._selection=this,n._selection=this,this._cachedNodes=null,this.dirty=false,this.tableKey=e;}getStartEndPoints(){return [this.anchor,this.focus]}isValid(){if("root"===this.tableKey||"root"===this.anchor.key||"element"!==this.anchor.type||"root"===this.focus.key||"element"!==this.focus.type)return  false;const e=Yo(this.tableKey),t=Yo(this.anchor.key),n=Yo(this.focus.key);return null!==e&&null!==t&&null!==n}isBackward(){return this.focus.isBefore(this.anchor)}getCachedNodes(){return this._cachedNodes}setCachedNodes(e){this._cachedNodes=e;}is(e){return Ot(e)&&this.tableKey===e.tableKey&&this.anchor.is(e.anchor)&&this.focus.is(e.focus)}set(e,t,n){this.dirty=this.dirty||e!==this.tableKey||t!==this.anchor.key||n!==this.focus.key,this.tableKey=e,this.anchor.key=t,this.focus.key=n,this._cachedNodes=null;}clone(){return new Rt(this.tableKey,Mr(this.anchor.key,this.anchor.offset,this.anchor.type),Mr(this.focus.key,this.focus.offset,this.focus.type))}isCollapsed(){return  false}extract(){return this.getNodes()}insertRawText(e){}insertText(){}hasFormat(e){let t=0;this.getNodes().filter(We$1).forEach(e=>{const n=e.getFirstChild();no(n)&&(t|=n.getTextFormat());});const n=z$7[e];return 0!==(t&n)}insertNodes(e){const t=this.focus.getNode();Wi(t)||Le$1(151);St$3(t.select(0,t.getChildrenSize())).insertNodes(e);}getShape(){const{anchorCell:e,focusCell:t}=Ft(this),n=Tt(e);null===n&&Le$1(153);const o=Tt(t);null===o&&Le$1(155);const r=Math.min(n.columnIndex,o.columnIndex),l=Math.max(n.columnIndex+n.colSpan-1,o.columnIndex+o.colSpan-1),s=Math.min(n.rowIndex,o.rowIndex),i=Math.max(n.rowIndex+n.rowSpan-1,o.rowIndex+o.rowSpan-1);return {fromX:Math.min(r,l),fromY:Math.min(s,i),toX:Math.max(r,l),toY:Math.max(s,i)}}getNodes(){if(!this.isValid())return [];const e=this._cachedNodes;if(null!==e)return e;const{anchorTable:t,anchorCell:n,focusCell:o}=Ft(this),r=o.getParents()[1];if(r!==t){if(t.isParentOf(o)){const e=r.getParent();null==e&&Le$1(159),this.set(this.tableKey,o.getKey(),e.getKey());}else {const e=t.getParent();null==e&&Le$1(158),this.set(this.tableKey,e.getKey(),o.getKey());}return this.getNodes()}const[l,s,i]=wt(t,n,o),{minColumn:c,maxColumn:a,minRow:u,maxRow:h}=Nt(l,s,i),d=new Map([[t.getKey(),t]]);let f=null;for(let e=u;e<=h;e++)for(let t=c;t<=a;t++){const{cell:n}=l[e][t],o=n.getParent();De$1(o)||Le$1(160),o!==f&&(d.set(o.getKey(),o),f=o),d.has(n.getKey())||Et(n,e=>{d.set(e.getKey(),e);});}const g=Array.from(d.values());return mi()||(this._cachedNodes=g),g}getTextContent(){const e=this.getNodes().filter(e=>We$1(e));let t="";for(let n=0;n<e.length;n++){const o=e[n],r=o.__parent,l=(e[n+1]||{}).__parent;t+=o.getTextContent()+(l!==r?"\n":"\t");}return t}}function Ot(e){return e instanceof Rt}function Kt(){const e=Mr("root",0,"element"),t=Mr("root",0,"element");return new Rt("root",e,t)}function At(e,t,n){e.getKey(),t.getKey(),n.getKey();const o=Qr(),r=Ot(o)?o.clone():Kt();return r.set(e.getKey(),t.getKey(),n.getKey()),r}function Et(e,t){const n=[[e]];for(let e=n.at(-1);void 0!==e&&n.length>0;e=n.at(-1)){const o=e.pop();void 0===o?n.pop():false!==t(o)&&Wi(o)&&n.push(o.getChildren());}}
11207function kt(e,t=Zs()){const n=Yo(e);Rn(n)||Le$1(231,e);const o=Lt(n,t.getElementByKey(e));return null===o&&Le$1(232,e),{tableElement:o,tableNode:n}}class Mt{observers;nextFocus;shouldCheckSelectionForTable;constructor(){this.observers=new Map,this.nextFocus=null,this.shouldCheckSelectionForTable=null;}setNextFocus(e){this.nextFocus=e;}getAndClearNextFocus(){const{nextFocus:e}=this;return null!==e&&(this.nextFocus=null),e}setShouldCheckSelectionForTable(e){this.shouldCheckSelectionForTable=e;}getAndClearShouldCheckSelectionForTable(){const{shouldCheckSelectionForTable:e}=this;return e?(this.shouldCheckSelectionForTable=null,e):null}}class $t{focusX;focusY;listenersToRemove;table;isHighlightingCells;anchorX;anchorY;tableNodeKey;anchorCell;focusCell;anchorCellNodeKey;focusCellNodeKey;editor;tableSelection;hasHijackedSelectionStyles;isSelecting;pointerType;abortController;listenerOptions;constructor(e,t){this.isHighlightingCells=false,this.anchorX=-1,this.anchorY=-1,this.focusX=-1,this.focusY=-1,this.listenersToRemove=new Set,this.tableNodeKey=t,this.editor=e,this.table={columns:0,domRows:[],rows:0},this.tableSelection=null,this.anchorCellNodeKey=null,this.focusCellNodeKey=null,this.anchorCell=null,this.focusCell=null,this.hasHijackedSelectionStyles=false,this.isSelecting=false,this.pointerType=null,this.abortController=new AbortController,this.listenerOptions={signal:this.abortController.signal},this.trackTable();}getTable(){return this.table}removeListeners(){this.abortController.abort("removeListeners"),Array.from(this.listenersToRemove).forEach(e=>e()),this.listenersToRemove.clear();}$lookup(){return kt(this.tableNodeKey,this.editor)}trackTable(){const e=new MutationObserver(e=>{this.editor.getEditorState().read(()=>{let t=false;for(let n=0;n<e.length;n++){const o=e[n].target.nodeName;if("TABLE"===o||"TBODY"===o||"THEAD"===o||"TR"===o){t=true;break}}if(!t)return;const{tableNode:n,tableElement:o}=this.$lookup();this.table=Gt(n,o);},{editor:this.editor});});this.editor.getEditorState().read(()=>{const{tableNode:t,tableElement:n}=this.$lookup();this.table=Gt(t,n),e.observe(n,{attributes:true,childList:true,subtree:true});},{editor:this.editor});}$clearHighlight(e=true){const t=this.editor;this.isHighlightingCells=false,this.anchorX=-1,this.anchorY=-1,this.focusX=-1,this.focusY=-1,this.tableSelection=null,this.anchorCellNodeKey=null,this.focusCellNodeKey=null,this.anchorCell=null,this.focusCell=null,this.hasHijackedSelectionStyles=false,this.$enableHighlightStyle();const{tableNode:n,tableElement:o}=this.$lookup();Qt(t,Gt(n,o),null),e&&null!==Qr()&&(es(null),t.dispatchCommand(ie$4,void 0));}$enableHighlightStyle(){const e=this.editor,{tableElement:t}=this.$lookup();xc(t,e._config.theme.tableSelection),t.classList.remove("disable-selection"),this.hasHijackedSelectionStyles=false;}$disableHighlightStyle(){const{tableElement:t}=this.$lookup();mc(t,this.editor._config.theme.tableSelection),this.hasHijackedSelectionStyles=true;}$updateTableTableSelection(e){if(null!==e){e.tableKey!==this.tableNodeKey&&Le$1(233,e.tableKey,this.tableNodeKey);const t=this.editor;this.tableSelection=e,this.isHighlightingCells=true,this.$disableHighlightStyle(),this.updateDOMSelection(),Qt(t,this.table,this.tableSelection);}else this.$clearHighlight();}updateDOMSelection(){if(null!==this.anchorCell&&null!==this.focusCell){const e=Js(this.editor._window);e&&e.rangeCount>0&&e.removeAllRanges();}}$setFocusCellForSelection(e,t=false){const n=this.editor,{tableNode:o}=this.$lookup(),r=e.x,l=e.y;if(this.focusCell=e,!this.isHighlightingCells){(t||this.anchorX!==r||this.anchorY!==l||null!=this.tableSelection&&null!=this.anchorCellNodeKey)&&(this.isHighlightingCells=true,this.$disableHighlightStyle());}if(-1!==this.focusX&&-1!==this.focusY&&r===this.focusX&&l===this.focusY)return  false;if(this.focusX=r,this.focusY=l,this.isHighlightingCells){const s=_n(o,e.elem);if(null!=this.tableSelection&&null!=this.anchorCellNodeKey){let e=s;if(null===e&&t&&(e=o.getCellNodeFromCords(r,l,this.table)),null!==e){const t=this.$getAnchorTableCellOrThrow();return this.focusCellNodeKey=e.getKey(),this.tableSelection=At(o,t,e),es(this.tableSelection),n.dispatchCommand(ie$4,void 0),Qt(n,this.table,this.tableSelection),true}}}return  false}$getAnchorTableCell(){return this.anchorCellNodeKey?Yo(this.anchorCellNodeKey):null}$getAnchorTableCellOrThrow(){const e=this.$getAnchorTableCell();return null===e&&Le$1(234),e}$getFocusTableCell(){return this.focusCellNodeKey?Yo(this.focusCellNodeKey):null}$getFocusTableCellOrThrow(){const e=this.$getFocusTableCell();return null===e&&Le$1(235),e}
11207$setAnchorCellForSelection(e){this.isHighlightingCells=false,this.anchorCell=e,this.anchorX=e.x,this.anchorY=e.y,this.focusX=-1,this.focusY=-1,this.focusCell=null,this.focusCellNodeKey=null;const{tableNode:t}=this.$lookup(),n=_n(t,e.elem);if(null!==n){const e=n.getKey();null!=this.tableSelection?(this.tableSelection=this.tableSelection.clone(),this.tableSelection.set(t.getKey(),e,e)):this.tableSelection=At(t,n,n),this.anchorCellNodeKey=e;}}$formatCells(e){const t=Qr();Ot(t)||Le$1(236);const n=qr(),o=n.anchor,r=n.focus,l=t.getNodes().filter(We$1);l.length>0||Le$1(237);const s=l[0].getFirstChild(),i=no(s)?s.getFormatFlags(e,null):null;l.forEach(t=>{o.set(t.getKey(),0,"element"),r.set(t.getKey(),t.getChildrenSize(),"element"),n.formatText(e,i);}),es(t),this.editor.dispatchCommand(ie$4,void 0);}$clearText(){const{editor:e}=this,t=Yo(this.tableNodeKey);if(!Rn(t))throw new Error("Expected TableNode.");const n=Qr();Ot(n)||Le$1(253);const o=n.getNodes().filter(We$1),r=t.getFirstChild(),l=t.getLastChild();if(o.length>0&&null!==r&&null!==l&&De$1(r)&&De$1(l)&&o[0]===r.getFirstChild()&&o[o.length-1]===l.getLastChild()){t.selectPrevious();const n=t.getParent();return t.remove(),void(Vi(n)&&n.isEmpty()&&e.dispatchCommand(he$3,void 0))}o.forEach(e=>{if(Wi(e)){const t=eo(),n=kr();
11207t.append(n),e.append(t),e.getChildren().forEach(e=>{e!==t&&e.remove();});}}),Qt(e,this.table,null),es(null),e.dispatchCommand(ie$4,void 0);}}const Wt="__lexicalTableSelection";function zt(e){return Ys(e)&&"TABLE"===e.nodeName}function Lt(e,t){if(!t)return t;const n=zt(t)?t:t.querySelector("table");return zt(n)||Le$1(341,e.constructor.name,e.getType(),e.getKey(),t.nodeName),n}function Ht(e){return e._window}function Bt(e,t){for(let n=t,o=null;null!==n;n=n.getParent()){if(e.is(n))return o;We$1(n)&&(o=n);}return null}const Pt=[[Ee$3,"down"],[we$1,"up"],[Ne$1,"backward"],[ke$2,"forward"]],Dt=[ye$2,me$3,fe$4],It=[Ae$3,Pe$2];function Ut(e,t){const n=e.getRootElement(),o=e._window;if(!n||!o)return ()=>{};const r=o=>{const r=o.target;if(0!==o.button||!qs(r)||!n.contains(r))return;const l=function(e){const t=jt(e);if(null===t)return null;let n=t.elem;for(;null!=n;){if("TABLE"===n.nodeName&&Wt in n&&n[Wt])return {cellElement:t,tableElement:n,tableObserver:n[Wt]};n=n.parentNode;}return null}(r);e.update(()=>{if(Ot(Qr())){for(const[e]of t.observers.values())e.$clearHighlight(false);es(null),e.dispatchCommand(ie$4,void 0);}if(!l)return;const{tableObserver:n,tableElement:r,cellElement:s}=l;!function(e,t,n,o,r,l){const s=e._window;if(!s)return;const i=t=>{if(r.isSelecting)return;r.isSelecting=true,null!==t&&null===r.anchorCell&&e.update(()=>
11207{r.$setAnchorCellForSelection(t);});const n=()=>{r.isSelecting=false,s.removeEventListener("pointerup",n),s.removeEventListener("pointermove",i);},i=t=>{if(!(e=>!(1&~e.buttons))(t)&&r.isSelecting)return r.isSelecting=false,s.removeEventListener("pointerup",n),void s.removeEventListener("pointermove",i);if(!qs(t.target))return;let c=null;const a=!(Je$1||o.contains(t.target));if(a)c=Vt(o,t.target);else for(const e of document.elementsFromPoint(t.clientX,t.clientY))if(c=Vt(o,e),c)break;if(c){const t=c;null===r.anchorCell&&e.update(()=>{r.$setAnchorCellForSelection(t);}),null!==r.focusCell&&c.elem===r.focusCell.elem||(l.setNextFocus({focusCell:c,override:a,tableKey:r.tableNodeKey}),e.dispatchCommand(ie$4,void 0));}};s.addEventListener("pointerup",n,r.listenerOptions),s.addEventListener("pointermove",i,r.listenerOptions);};r.pointerType=t.pointerType;const c=Bs(r.tableNodeKey),a=Zr();if(Je$1&&t.shiftKey&&ln(a,c)&&(Fr(a)||Ot(a))){const e=a.anchor.getNode(),o=Bt(c,a.anchor.getNode());if(o)r.$setAnchorCellForSelection(Cn(r,o)),r.$setFocusCellForSelection(n),gn(t);else {(c.isBefore(e)?c.selectStart():c.selectEnd()).anchor.set(a.anchor.key,a.anchor.offset,a.anchor.type);}}
11207else "touch"!==t.pointerType&&r.$setAnchorCellForSelection(n);i(n);}(e,o,s,r,n,t);});};return o.addEventListener("pointerdown",r),()=>{o.removeEventListener("pointerdown",r);}}function Jt(e,t,o,l,s){const i=o.getRootElement(),c=Ht(o);null!==i&&null!==c||Le$1(246);const a=new $t(o,e.getKey()),u=Lt(e,t);!function(e,t){null!==qt(e)&&Le$1(205);e[Wt]=t;}(u,a),a.listenersToRemove.add(()=>function(e,t){qt(e)===t&&delete e[Wt];}(u,a));const h=e=>{if(e.detail>=3&&qs(e.target)){null!==jt(e.target)&&e.preventDefault();}};u.addEventListener("mousedown",h,a.listenerOptions),a.listenersToRemove.add(()=>{u.removeEventListener("mousedown",h);});for(const[t,n]of Pt)a.listenersToRemove.add(o.registerCommand(t,t=>fn(o,t,n,e,a,s),so));a.listenersToRemove.add(o.registerCommand(De$2,t=>{const n=Qr();if(Ot(n)){const o=Bt(e,n.focus.getNode());if(null!==o)return gn(t),o.selectEnd(),true}return  false},so));const d=t=>()=>{const o=Qr();if(!ln(o,e))return  false;if(Ot(o))return a.$clearText(),true;if(Fr(o)){if(!We$1(Bt(e,o.anchor.getNode())))return  false;const r=o.anchor.getNode(),l=o.focus.getNode(),s=e.isParentOf(r),i=e.isParentOf(l);if(s&&!i||i&&!s)return a.$clearText(),true;const c=dl(o.anchor.getNode(),e=>Wi(e)),u=c&&dl(c,e=>Wi(e)&&We$1(e.getParent()));if(!Wi(u)||!Wi(c))return  false;if(t===me$3&&null===u.getPreviousSibling())return  true}return  false};for(const e of Dt)a.listenersToRemove.add(o.registerCommand(e,d(e),so));const f=t=>{const n=Qr();if(!Ot(n)&&!Fr(n))return  false;const o=e.isParentOf(n.anchor.getNode());if(o!==e.isParentOf(n.focus.getNode())){const t=o?"anchor":"focus",r=o?"focus":"anchor",{key:l,offset:s,type:i}=n[r];return e[n[t].isBefore(n[r])?"selectPrevious":"selectNext"]()[r].set(l,s,i),false}return !!ln(n,e)&&(!!Ot(n)&&(t&&(t.preventDefault(),t.stopPropagation()),a.$clearText(),true))};for(const e of It)a.listenersToRemove.add(o.registerCommand(e,f,so));return a.listenersToRemove.add(o.registerCommand(je$2,e=>{const t=Qr();if(t){if(!Ot(t)&&!Fr(t))return  false;V$4(o,Bt$3(e,ClipboardEvent)?e:null,et(t));const n=f(e);return Fr(t)?(t.removeText(),true):n}return  false},so)),a.listenersToRemove.add(o.registerCommand(xe,t=>{const o=Qr();if(!ln(o,e))return  false;if(Ot(o))return a.$formatCells(t),true;if(Fr(o)){const e=dl(o.anchor.getNode(),e=>We$1(e));if(!We$1(e))return  false}return  false},so)),a.listenersToRemove.add(o.registerCommand(Re$1,t=>{const n=Qr();if(!Ot(n)||!ln(n,e))return  false;const o=n.anchor.getNode(),r=n.focus.getNode();if(!We$1(o)||!We$1(r))return  false;if(function(e,t){if(Ot(e)){const n=e.anchor.getNode(),o=e.focus.getNode();if(t&&n&&o){const[e]=wt(t,n,o);return n.getKey()===e[0][0].cell.getKey()&&o.getKey()===e[e.length-1].at(-1).cell.getKey()}}return  false}(n,e))return e.setFormat(t),true;const[l,s,i]=wt(e,o,r),c=Math.max(s.startRow+s.cell.__rowSpan-1,i.startRow+i.cell.__rowSpan-1),a=Math.max(s.startColumn+s.cell.__colSpan-1,i.startColumn+i.cell.__colSpan-1),u=Math.min(s.startRow,i.startRow),h=Math.min(s.startColumn,i.startColumn),d=new Set;for(let e=u;e<=c;e++)for(let n=h;n<=a;n++){const o=l[e][n].cell;if(d.has(o))continue;d.add(o),o.setFormat(t);const r=o.getChildren();for(let e=0;e<r.length;e++){const n=r[e];Wi(n)&&!n.isInline()&&n.setFormat(t);}}return  true},so)),a.listenersToRemove.add(o.registerCommand(ge$3,t=>{const r=Qr();if(!ln(r,e))return  false;if(Ot(r))return a.$clearHighlight(),false;if(Fr(r)){const l=dl(r.anchor.getNode(),e=>We$1(e));if(!We$1(l))return  false;if("string"==typeof t){const n=pn(o,r,e);if(n)return mn(n,e,[kr(t)]),true}}return  false},so)),l&&a.listenersToRemove.add(o.registerCommand(Fe$2,t=>{const o=Qr();if(!Fr(o)||!o.isCollapsed()||!ln(o,e))return  false;const r=un(o.anchor.getNode());return !(null===r||!e.is(hn(r)))&&(gn(t),function(e,t){const o="next"===t?"getNextSibling":"getPreviousSibling",r="next"===t?"getFirstChild":"getLastChild",l=e[o]();if(Wi(l))return l.selectEnd();const s=dl(e,De$1);null===s&&Le$1(247);for(let e=s[o]();De$1(e);e=e[o]()){const t=e[r]();if(Wi(t))return t.selectEnd()}const i=dl(s,Rn);null===i&&Le$1(248);"next"===t?i.selectNext():i.selectPrevious();}(r,t.shiftKey?"previous":"next"),true)},so)),a.listenersToRemove.add(o.registerCommand(Ge$2,t=>e.isSelected(),so)),a.listenersToRemove.add(o.registerCommand(he$3,()=>{const t=Qr();if(!Fr(t)||!t.isCollapsed()||!ln(t,e))return  false;
11207const n=pn(o,t,e);return !!n&&(mn(n,e),true)},so)),a}function Xt(e,t){const o=Qr(),r=Zr(),l=e.getAndClearNextFocus();if(null!==l){const{tableKey:t,focusCell:n}=l,r=e.observers.get(t);r||Le$1(335,t);const[s]=r;if(Ot(o)&&o.tableKey===s.tableNodeKey)return (n.x!==s.focusX||n.y!==s.focusY)&&(s.$setFocusCellForSelection(n),true);if(null!==s.anchorCell&&null!==s.anchorCellNodeKey&&n.elem!==s.anchorCell.elem&&null!==s.tableSelection)return s.$setFocusCellForSelection(n,true),true}const s=e.getAndClearShouldCheckSelectionForTable();if(s&&Fr(r)&&Fr(o)&&o.isCollapsed()){const e=Bs(s),t=o.anchor.getNode(),r=e.getFirstChild(),l=un(t);if(null!==l&&De$1(r)){const t=r.getFirstChild();if(We$1(t)&&e.is(dl(l,n=>n.is(e)||n.is(t))))return t.selectStart(),true}}Ot(o)&&function(e,t){const n=Ht(e),o=Zr();if(!t.is(o))return;const r=Bs(t.tableKey),l=Js(n);if(l&&l.anchorNode&&l.focusNode){const n=Go(l.focusNode),o=n&&!r.isParentOf(n),s=Go(l.anchorNode),i=s&&r.isParentOf(s);if(o&&i&&l.rangeCount>0){const n=Gr(l,e);n&&(n.anchor.set(r.getKey(),t.isBackward()?r.getChildrenSize():0,"element"),l.removeAllRanges(),es(n));}}}(t,o),Fr(o)&&function(e,t){const n=Zr(),{anchor:o,focus:r}=e,l=o.getNode(),s=r.getNode(),i=un(l),c=un(s),a=i?hn(i):null,u=c?hn(c):null,h=e.isBackward(),d=i&&c&&a&&u&&a.is(u),f=u&&(!a||a.isParentOf(u)),g=a&&(!u||u.isParentOf(a));if(f){const t=e.clone(),[n]=wt(u,c,c),o=n[0][0].cell,r=n[n.length-1].at(-1).cell;t.focus.set(h?o.getKey():r.getKey(),h?0:r.getChildrenSize(),"element"),es(t);}else if(g){const t=e.clone(),[n]=wt(a,i,i),o=n[0][0].cell,r=n[n.length-1].at(-1).cell;t.anchor.set(h?r.getKey():o.getKey(),h?r.getChildrenSize():0,"element"),es(t);}else if(d){const o=t.observers.get(a.getKey());o||Le$1(335,a.getKey());const[r]=o;if(i.is(c)||(r.$setAnchorCellForSelection(Cn(r,i)),r.$setFocusCellForSelection(Cn(r,c),true)),"touch"===r.pointerType&&r.isSelecting&&e.isCollapsed()&&Fr(n)&&n.isCollapsed()){const e=un(n.anchor.getNode());e&&!e.is(c)&&(r.$setAnchorCellForSelection(Cn(r,e)),r.$setFocusCellForSelection(Cn(r,c),true),r.pointerType=null);}}}(o,e);const i=Array.from(e.observers.entries()).map(([e,[t]])=>({tableNode:Bs(e),tableObserver:t}));for(const{tableNode:e,tableObserver:n}of i)Yt(t,e,n);return  false}function Yt(e,t,n){const o=Qr(),r=Zr();o&&!o.is(r)&&(Ot(o)||Ot(r))&&n.tableSelection&&!n.tableSelection.is(r)&&(Ot(o)&&o.tableKey===n.tableNodeKey?n.$updateTableTableSelection(o):!Ot(o)&&Ot(r)&&r.tableKey===n.tableNodeKey&&n.$updateTableTableSelection(null)),n.hasHijackedSelectionStyles&&!t.isSelected()?function(e,t){t.$enableHighlightStyle(),Zt(t.table,t=>{const n=t.elem;t.highlighted=false,an(e,t),n.getAttribute("style")||n.removeAttribute("style");});}(e,n):!n.hasHijackedSelectionStyles&&t.isSelected()&&function(e,t){t.$disableHighlightStyle(),Zt(t.table,t=>{t.highlighted=true,cn(e,t);});}(e,n);}function qt(e){return e[Wt]||null}function jt(e){let t=e;for(;null!=t;){const e=t.nodeName;if("TD"===e||"TH"===e){const e=t._cell;return void 0===e?null:e}t=t.parentNode;}return null}function Vt(e,t){if(!e.contains(t))return null;let n=null;for(let o=t;null!=o;o=o.parentNode){if(o===e)return n;const t=o.nodeName;"TD"!==t&&"TH"!==t||(n=o._cell||null);}return null}function Gt(e,t){const n=[],o={columns:0,domRows:n,rows:0};let r=Lt(e,t).querySelector("tr"),l=0,s=0;for(n.length=0;null!=r;){const e=r.nodeName;if("TD"===e||"TH"===e){const e={elem:r,hasBackgroundColor:""!==r.style.backgroundColor,highlighted:false,x:l,y:s};r._cell=e;let t=n[s];void 0===t&&(t=n[s]=[]),t[l]=e;}else {const e=r.firstChild;if(null!=e){r=e;continue}}const t=r.nextSibling;if(null!=t){l++,r=t;continue}const o=r.parentNode;if(null!=o){const e=o.nextSibling;if(null==e)break;s++,l=0,r=e;}}return o.columns=l+1,o.rows=s+1,o}function Qt(e,t,n){const o=new Set(n?n.getNodes():[]);Zt(t,(t,n)=>{const r=t.elem;o.has(n)?(t.highlighted=true,cn(e,t)):(t.highlighted=false,an(e,t),r.getAttribute("style")||r.removeAttribute("style"));});}function Zt(e,t){const{domRows:n}=e;for(let e=0;e<n.length;e++){const o=n[e];if(o)for(let n=0;n<o.length;n++){const r=o[n];if(!r)continue;const l=Go(r.elem);null!==l&&t(r,l,{x:n,y:e});}}}const en=(e,t,n,o,r)=>{const l="forward"===r;switch(r){case "backward":case "forward":return n!==(l?e.table.columns-1:0)?sn(t.getCellNodeFromCordsOrThrow(n+(l?1:-1),o,e.table),l):o!==(l?e.table.rows-1:0)?sn(t.getCellNodeFromCordsOrThrow(l?0:e.table.columns-1,o+(l?1:-1),e.table),l):l?t.selectNext():t.selectPrevious(),true;case "up":return 0!==o?sn(t.getCellNodeFromCordsOrThrow(n,o-1,e.table),false):t.selectPrevious(),true;case "down":return o!==e.table.rows-1?sn(t.getCellNodeFromCordsOrThrow(n,o+1,e.table),true):t.selectNext(),true;default:return  false}};function tn(e,t){let n,o;
11207if(t.startColumn===e.minColumn)n="minColumn";else {if(t.startColumn+t.cell.__colSpan-1!==e.maxColumn)return null;n="maxColumn";}if(t.startRow===e.minRow)o="minRow";else {if(t.startRow+t.cell.__rowSpan-1!==e.maxRow)return null;o="maxRow";}return [n,o]}function nn([e,t]){return ["minColumn"===e?"maxColumn":"minColumn","minRow"===t?"maxRow":"minRow"]}function on(e,t,[n,o]){const r=t[o],l=e[r];void 0===l&&Le$1(250,o,String(r));const s=t[n],i=l[s];return void 0===i&&Le$1(250,n,String(s)),i}function rn(e,t,n,o,r){const l=Nt(t,n,o),s=function(e,t){const{minColumn:n,maxColumn:o,minRow:r,maxRow:l}=t;let s=1,i=1,c=1,a=1;const u=e[r],h=e[l];for(let e=n;e<=o;e++)s=Math.max(s,u[e].cell.__rowSpan),a=Math.max(a,h[e].cell.__rowSpan);for(let t=r;t<=l;t++)i=Math.max(i,e[t][n].cell.__colSpan),c=Math.max(c,e[t][o].cell.__colSpan);return {bottomSpan:a,leftSpan:i,rightSpan:c,topSpan:s}}(t,l),{topSpan:i,leftSpan:c,bottomSpan:a,rightSpan:u}=s,h=function(e,t){const n=tn(e,t);return null===n&&Le$1(249,t.cell.getKey()),n}(l,n),[d,f]=nn(h);let g=l[d],m=l[f];"forward"===r?g+="maxColumn"===d?1:c:"backward"===r?g-="minColumn"===d?1:u:"down"===r?m+="maxRow"===f?1:i:"up"===r&&(m-="minRow"===f?1:a);const p=t[m];if(void 0===p)return  false;const C=p[g];if(void 0===C)return  false;const[_,S]=function(e,t,n){const o=Nt(e,t,n),r=tn(o,t);if(r)return [on(e,o,r),on(e,o,nn(r))];const l=tn(o,n);if(l)return [on(e,o,nn(l)),on(e,o,l)];const s=["minColumn","minRow"];return [on(e,o,s),on(e,o,nn(s))]}(t,n,C),w=Cn(e,_.cell),b=Cn(e,S.cell);return e.$setAnchorCellForSelection(w),e.$setFocusCellForSelection(b,true),true}function ln(e,t){if(Fr(e)||Ot(e)){const n=t.isParentOf(e.anchor.getNode()),o=t.isParentOf(e.focus.getNode());return n&&o}return  false}function sn(e,t){t?e.selectStart():e.selectEnd();}function cn(t,n){const o=n.elem,r=t._config.theme;We$1(Go(o))||Le$1(131),mc(o,r.tableCellSelected);}function an(e,t){const n=t.elem;We$1(Go(n))||Le$1(131);const r=e._config.theme;xc(n,r.tableCellSelected);}function un(e){const t=dl(e,We$1);return We$1(t)?t:null}function hn(e){const t=dl(e,Rn);return Rn(t)?t:null}function dn(e,t,o,r,l,s,i){const c=ql(o.focus,l?"previous":"next");if(ic(c))return  false;let a=c;for(const e of Rl(c).iterNodeCarets("shadowRoot")){if(!Tl(e)||!Wi(e.origin))return  false;a=e;}const u=a.getParentAtCaret();if(!We$1(u))return  false;const h=u,d=function(e){for(const t of Rl(e).iterNodeCarets("root")){const{origin:n}=t;if(We$1(n)){if(Nl(t))return Pl(n,e.direction)}else if(!De$1(n))break}return null}(Ol(h,a.direction)),f=dl(h,Rn);if(!f||!f.is(s))return  false;const g=e.getElementByKey(h.getKey()),m=jt(g);if(!g||!m)return  false;const p=xn(e,f);if(i.table=p,d)if("extend"===r){const t=jt(e.getElementByKey(d.origin.getKey()));if(!t)return  false;i.$setAnchorCellForSelection(m),i.$setFocusCellForSelection(t,true);}else {const e=rc(d);Hl(o.anchor,e),Hl(o.focus,e);}else if("extend"===r)i.$setAnchorCellForSelection(m),i.$setFocusCellForSelection(m,true);else {const e=function(e){const t=Ll(e);return Nl(t)?rc(t):e}(Ol(f,c.direction));Hl(o.anchor,e),Hl(o.focus,e);}return gn(t),true}function fn(e,t,o,r,l,s){if(("up"===o||"down"===o)&&function(e){const t=e.getRootElement();if(!t)return  false;return t.hasAttribute("aria-controls")&&"typeahead-menu"===t.getAttribute("aria-controls")}(e))return  false;const i=Qr();if(!ln(i,r)){if(Fr(i)){if("backward"===o){if(i.focus.offset>0)return  false;const e=function(e){for(let t=e,n=e;null!==n;t=n,n=n.getParent())if(Wi(n)){if(n!==t&&n.getFirstChild()!==t)return null;if(!n.isInline())return n}return null}(i.focus.getNode());if(!e)return  false;const n=e.getPreviousSibling();return !!Rn(n)&&(gn(t),t.shiftKey?i.focus.set(n.getParentOrThrow().getKey(),n.getIndexWithinParent(),"element"):n.selectEnd(),true)}if(t.shiftKey&&("up"===o||"down"===o)){const e=i.focus.getNode();if(!i.isCollapsed()&&("up"===o&&!i.isBackward()||"down"===o&&i.isBackward())){let l=dl(e,e=>Rn(e));if(We$1(l)&&(l=dl(l,Rn)),l!==r)return  false;if(!l)return  false;const s="down"===o?l.getNextSibling():l.getPreviousSibling();if(!s)return  false;let c=0;"up"===o&&Wi(s)&&(c=s.getChildrenSize());let a=s;if("up"===o&&Wi(s)){const e=s.getLastChild();a=e||s,c=Tr(a)?a.getTextContentSize():0;}const u=i.clone();return u.focus.set(a.getKey(),c,Tr(a)?"text":"element"),es(u),gn(t),true}if(Is(e)){const e="up"===o?i.getNodes()[i.getNodes().length-1]:i.getNodes()[0];if(e){if(null!==Bt(r,e)){const e=r.getFirstDescendant(),t=r.getLastDescendant();if(!e||!t)return  false;
11207const[n]=yt(e),[o]=yt(t),s=r.getCordsFromCellNode(n,l.table),i=r.getCordsFromCellNode(o,l.table),c=r.getDOMCellFromCordsOrThrow(s.x,s.y,l.table),a=r.getDOMCellFromCordsOrThrow(i.x,i.y,l.table);return l.$setAnchorCellForSelection(c),l.$setFocusCellForSelection(a,true),true}}return  false}{let r=dl(e,e=>Wi(e)&&!e.isInline());if(We$1(r)&&(r=dl(r,Rn)),!r)return  false;const s="down"===o?r.getNextSibling():r.getPreviousSibling();if(Rn(s)&&l.tableNodeKey===s.getKey()){const e=s.getFirstDescendant(),n=s.getLastDescendant();if(!e||!n)return  false;const[r]=yt(e),[l]=yt(n),c=i.clone();return c.focus.set(("up"===o?r:l).getKey(),"up"===o?0:l.getChildrenSize(),"element"),gn(t),es(c),true}}}}return "down"===o&&yn(e)&&s.setShouldCheckSelectionForTable(r.getKey()),false}if(Fr(i)){if("backward"===o||"forward"===o){return dn(e,t,i,t.shiftKey?"extend":"move","backward"===o,r,l)}if(i.isCollapsed()){const{anchor:c,focus:a}=i,u=dl(c.getNode(),We$1),h=dl(a.getNode(),We$1);if(!We$1(u)||!u.is(h))return  false;const d=hn(u);if(d!==r&&null!=d){const n=Lt(d,e.getElementByKey(d.getKey()));if(null!=n)return l.table=Gt(d,n),fn(e,t,o,d,l,s)}const f=e.getElementByKey(u.__key),g=e.getElementByKey(c.key);if(null==g||null==f)return  false;let m;if("element"===c.type)m=g.getBoundingClientRect();else {const t=Js(Ht(e));if(null===t||0===t.rangeCount)return  false;m=t.getRangeAt(0).getBoundingClientRect();}const p="up"===o?u.getFirstChild():u.getLastChild();if(null==p)return  false;const C=e.getElementByKey(p.__key);if(null==C)return  false;const _=C.getBoundingClientRect();if("up"===o?_.top>m.top-m.height:m.bottom+m.height>_.bottom){gn(t);const e=r.getCordsFromCellNode(u,l.table);if(!t.shiftKey)return en(l,r,e.x,e.y,o);{const t=r.getDOMCellFromCordsOrThrow(e.x,e.y,l.table);l.$setAnchorCellForSelection(t),l.$setFocusCellForSelection(t,true);}return  true}}}else if(Ot(i)){const{anchor:s,focus:c}=i,a=dl(s.getNode(),We$1),u=dl(c.getNode(),We$1),[h]=i.getNodes();Rn(h)||Le$1(251);const d=Lt(h,e.getElementByKey(h.getKey()));if(!We$1(a)||!We$1(u)||!Rn(h)||null==d)return  false;l.$updateTableTableSelection(i);const f=Gt(h,d),g=r.getCordsFromCellNode(a,f),m=r.getDOMCellFromCordsOrThrow(g.x,g.y,f);
11207if(l.$setAnchorCellForSelection(m),gn(t),t.shiftKey){const[e,t,n]=wt(r,a,u);return rn(l,e,t,n,o)}return u.selectEnd(),true}return  false}function gn(e){e.preventDefault(),e.stopImmediatePropagation(),e.stopPropagation();}function mn(e,t,n){const o=eo();"first"===e?t.insertBefore(o):t.insertAfter(o),o.append(...n||[]),o.selectEnd();}function pn(e,t,o){const r=o.getParent();if(!r)return;const l=Js(Ht(e));if(!l)return;const s=l.anchorNode,i=e.getElementByKey(r.getKey()),c=Lt(o,e.getElementByKey(o.getKey()));if(!s||!i||!c||!i.contains(s)||c.contains(s))return;const a=dl(t.anchor.getNode(),e=>We$1(e));if(!a)return;const u=dl(a,e=>Rn(e));if(!Rn(u)||!u.is(o))return;const[h,d]=wt(o,a,a),f=h[0][0],g=h[h.length-1][h[0].length-1],{startRow:m,startColumn:p}=d,C=m===f.startRow&&p===f.startColumn,_=m===g.startRow&&p===g.startColumn;return C?"first":_?"last":void 0}function Cn(e,t){const{tableNode:n}=e.$lookup(),o=n.getCordsFromCellNode(t,e.table);return n.getDOMCellFromCordsOrThrow(o.x,o.y,e.table)}function _n(e,t,n){return Bt(e,Go(t,n))}function Sn(e,t,n){const o=e.querySelector("colgroup");if(!o)return;const r=[];for(let e=0;e<t;e++){const t=document.createElement("col"),o=n&&n[e];o&&(t.style.width=`${o}px`),r.push(t);}o.replaceChildren(...r);}function wn(t,n,r){if(!n.theme.tableAlignment)return;const l=[],s=[];for(const e of ["center","right"]){const t=n.theme.tableAlignment[e];t&&(e===r?s:l).push(t);}xc(t,...l),mc(t,...s);}const bn=new WeakSet;function yn(e=Zs()){return bn.has(e)}function Nn(e,t){bn.add(e);}class vn extends Bi{__rowStriping;__frozenColumnCount;__frozenRowCount;__colWidths;static getType(){return "table"}getColWidths(){return this.getLatest().__colWidths}setColWidths(e){const t=this.getWritable();return t.__colWidths=e,t}static clone(e){return new vn(e.__key)}afterCloneFrom(e){super.afterCloneFrom(e),this.__colWidths=e.__colWidths,this.__rowStriping=e.__rowStriping,this.__frozenColumnCount=e.__frozenColumnCount,this.__frozenRowCount=e.__frozenRowCount;}static importDOM(){return {table:e=>({conversion:Tn,priority:1})}}static importJSON(e){return Fn().updateFromJSON(e)}updateFromJSON(e){return super.updateFromJSON(e).setRowStriping(e.rowStriping||false).setFrozenColumns(e.frozenColumnCount||0).setFrozenRows(e.frozenRowCount||0).setColWidths(e.colWidths)}constructor(e){super(e),this.__rowStriping=false,this.__frozenColumnCount=0,this.__frozenRowCount=0,this.__colWidths=void 0;}exportJSON(){return {...super.exportJSON(),colWidths:this.getColWidths(),frozenColumnCount:this.__frozenColumnCount?this.__frozenColumnCount:void 0,frozenRowCount:this.__frozenRowCount?this.__frozenRowCount:void 0,rowStriping:this.__rowStriping?this.__rowStriping:void 0}}extractWithChild(e,t,n){return "html"===n}getDOMSlot(e){const t=zt(e)?e:e.querySelector("table");return zt(t)||Le$1(229),super.getDOMSlot(e).withElement(t).withAfter(t.querySelector("colgroup"))}createDOM(t,n){const o=document.createElement("table");this.__style&&nr(o.style,this.__style);const r=document.createElement("colgroup");if(o.appendChild(r),ll(r),mc(o,t.theme.table),this.updateTableElement(null,o,t),yn(n)){const n=document.createElement("div"),r=t.theme.tableScrollableWrapper;return r?mc(n,r):n.style.overflowX="auto",n.appendChild(o),this.updateTableWrapper(null,n,o,t),n}return o}updateTableWrapper(t,n,r,l){this.__frozenColumnCount!==(t?t.__frozenColumnCount:0)&&function(t,n,r,l){l>0?(mc(t,r.theme.tableFrozenColumn),n.setAttribute("data-lexical-frozen-column","true")):(xc(t,r.theme.tableFrozenColumn),n.removeAttribute("data-lexical-frozen-column"));}(n,r,l,this.__frozenColumnCount),this.__frozenRowCount!==(t?t.__frozenRowCount:0)&&function(t,n,r,l){l>0?(mc(t,r.theme.tableFrozenRow),n.setAttribute("data-lexical-frozen-row","true")):(xc(t,r.theme.tableFrozenRow),n.removeAttribute("data-lexical-frozen-row"));}(n,r,l,this.__frozenRowCount);}updateTableElement(t,n,r){this.__style!==(t?t.__style:"")&&nr(n.style,this.__style,t?t.__style:""),this.__rowStriping!==(!!t&&t.__rowStriping)&&function(t,n,r){r?(mc(t,n.theme.tableRowStriping),t.setAttribute("data-lexical-row-striping","true")):(xc(t,n.theme.tableRowStriping),t.removeAttribute("data-lexical-row-striping"));}(n,r,this.__rowStriping);const l=t?t.getColumnCount():0,s=t?t.__colWidths:void 0;this.getColumnCount()===l&&this.getColWidths()===s||Sn(n,this.getColumnCount(),this.getColWidths()),wn(n,r,this.getFormatType());}updateDOM(e,t,n){const o=Lt(this,t);return t===o===yn()||(Ys(r=t)&&"DIV"===r.nodeName&&this.updateTableWrapper(e,t,o,n),this.updateTableElement(e,o,n),false);var r;}scaleDOMColWidths(e,t){const n=this.getColWidths();if(!n)return;Sn(Lt(this,e),this.getColumnCount(),n.map(e=>e*t));}exportDOM(e){const t=super.exportDOM(e),{element:n}=t;return {after:n=>{if(t.after&&(n=t.after(n)),!zt(n)&&Ys(n)&&(n=n.querySelector("table")),!zt(n))return null;wn(n,e._config,this.getFormatType());const[o]=bt(this,null,null),r=new Map;for(const e of o)for(const t of e){const e=t.cell.getKey();r.has(e)||r.set(e,{colSpan:t.cell.getColSpan(),startColumn:t.startColumn});}const s=new Set;for(const e of n.querySelectorAll(":scope > tr > [data-temporary-table-cell-lexical-key]")){const t=e.getAttribute("data-temporary-table-cell-lexical-key");if(t){const n=r.get(t);if(e.removeAttribute("data-temporary-table-cell-lexical-key"),n){r.delete(t);for(let e=0;e<n.colSpan;e++)s.add(e+n.startColumn);}}}const i=n.querySelector(":scope > colgroup");if(i){const e=Array.from(n.querySelectorAll(":scope > colgroup > col")).filter((e,t)=>
11207s.has(t));i.replaceChildren(...e);}const c=n.querySelectorAll(":scope > tr");if(c.length>0){const e=document.createElement("tbody");for(const t of c)e.appendChild(t);n.append(e);}return n},element:!zt(n)&&Ys(n)?n.querySelector("table"):n}}canBeEmpty(){return  false}isShadowRoot(){return  true}getCordsFromCellNode(e,t){const{rows:n,domRows:o}=t;for(let t=0;t<n;t++){const n=o[t];if(null!=n)for(let o=0;o<n.length;o++){const r=n[o];if(null==r)continue;const{elem:l}=r,s=_n(this,l);if(null!==s&&e.is(s))return {x:o,y:t}}}throw new Error("Cell not found in table.")}getDOMCellFromCords(e,t,n){const{domRows:o}=n,r=o[t];if(null==r)return null;const l=r[e<r.length?e:r.length-1];return null==l?null:l}getDOMCellFromCordsOrThrow(e,t,n){const o=this.getDOMCellFromCords(e,t,n);if(!o)throw new Error("Cell not found at cords.");return o}getCellNodeFromCords(e,t,n){const o=this.getDOMCellFromCords(e,t,n);if(null==o)return null;const r=Go(o.elem);return We$1(r)?r:null}getCellNodeFromCordsOrThrow(e,t,n){const o=this.getCellNodeFromCords(e,t,n);if(!o)throw new Error("Node at cords not TableCellNode.");return o}getRowStriping(){return Boolean(this.getLatest().__rowStriping)}setRowStriping(e){const t=this.getWritable();return t.__rowStriping=e,t}setFrozenColumns(e){const t=this.getWritable();return t.__frozenColumnCount=e,t}getFrozenColumns(){return this.getLatest().__frozenColumnCount}setFrozenRows(e){const t=this.getWritable();return t.__frozenRowCount=e,t}getFrozenRows(){return this.getLatest().__frozenRowCount}canSelectBefore(){return  true}canIndent(){return  false}getColumnCount(){const e=this.getFirstChild();if(!e)return 0;let t=0;
11207return e.getChildren().forEach(e=>{We$1(e)&&(t+=e.getColSpan());}),t}}function xn(e,t){const n=e.getElementByKey(t.getKey());return null===n&&Le$1(230),Gt(t,n)}function Tn(e){const n=Fn();e.hasAttribute("data-lexical-row-striping")&&n.setRowStriping(true),e.hasAttribute("data-lexical-frozen-column")&&n.setFrozenColumns(1),e.hasAttribute("data-lexical-frozen-row")&&n.setFrozenRows(1);const o=e.querySelector(":scope > colgroup");if(o){let e=[];for(const t of o.querySelectorAll(":scope > col")){let n=t.style.width||"";if(!Ke$1.test(n)&&(n=t.getAttribute("width")||"",!/^\d+$/.test(n))){e=void 0;break}e.push(parseFloat(n));}e&&n.setColWidths(e);}return {after:e=>Ht$3(e,De$1),node:n}}function Fn(){return zs(new vn)}function Rn(e){return e instanceof vn}function On(e){De$1(e.getParent())?e.isEmpty()&&e.append(eo()):e.remove();}function Kn(e){Rn(e.getParent())?Ot$3(e,We$1):e.remove();}function An(e){Ot$3(e,De$1);const[t]=bt(e,null,null),n=t.reduce((e,t)=>Math.max(e,t.length),0),o=e.getChildren();for(let e=0;e<t.length;++e){const r=o[e];if(!r)continue;De$1(r)||Le$1(254,r.constructor.name,r.getType());const l=t[e].reduce((e,t)=>t?1+e:e,0);if(l!==n)for(let e=l;e<n;++e){const e=$e$1();e.append(eo()),r.append(e);}}const r=e.getColWidths(),l=e.getColumnCount();if(r&&r.length!==l){let t;if(l<r.length)t=r.slice(0,l);else if(r.length>0){const e=r[r.length-1];t=[...r,...Array(l-r.length).fill(e)];}e.setColWidths(t);}}function En(e){if(e.detail<3||!qs(e.target))return  false;const t=Go(e.target);if(null===t)return  false;const o=dl(t,e=>Wi(e)&&!e.isInline());if(null===o)return  false;return !!We$1(o.getParent())&&(o.select(0),true)}function kn(){const e=Qr();if(!Fr(e))return  false;const t=hn(e.anchor.getNode());if(null===t)return  false;const n=Zo();if(!n.is(t.getParent())||1!==n.getChildrenSize())return  false;const[o]=bt(t,null,null);if(0===o.length||0===o[0].length)return  false;const r=o[0][0];if(!r||!r.cell)return  false;const l=o[o.length-1],s=l[l.length-1];if(!s||!s.cell)return  false;const i=At(t,r.cell,s.cell);return es(i),true}function $n(e,t=true){const n=new Mt,o=(o,r,l)=>{const s=Lt(o,l),i=Jt(o,s,e,t,n);n.observers.set(r,[i,s]);};return Cc(Ut(e,n),e.registerCommand(ie$4,()=>Xt(n,e),so),e.registerMutationListener(vn,t=>{e.getEditorState().read(()=>{for(const[e,r]of t){const t=n.observers.get(e);if("created"===r||"updated"===r){const{tableNode:r,tableElement:l}=kt(e);void 0===t?o(r,e,l):l!==t[1]&&(t[0].removeListeners(),n.observers.delete(e),o(r,e,l));}else "destroyed"===r&&void 0!==t&&(t[0].removeListeners(),n.observers.delete(e));}},{editor:e});},{skipInitialization:false}),()=>{for(const[,[e]]of n.observers)e.removeListeners();})}function Wn(e,t){e.hasNodes([vn])||Le$1(255);const{hasNestedTables:o=ft$1(false)}={};return Cc(e.registerCommand(ze$1,e=>function({rows:e,columns:t,includeHeaders:n},o){const r=Qr()||Zr();if(!r||!Fr(r))return  false;if(!o&&hn(r.anchor.getNode()))return  false;const l=Xe$1(Number(e),Number(t),n);Pt$3(l);const s=l.getFirstDescendant();return Tr(s)&&s.select(),true}(e,o.peek()),ro),e.registerCommand(oe$6,(t,r)=>e===r&&function(e,t){const{nodes:o,selection:r}=e;if(!o.some(e=>Rn(e)||pt$2(e).some(e=>Rn(e.node))))return  false;const l=Ot(r),s=Fr(r);if(!(s&&null!==dl(r.anchor.getNode(),e=>We$1(e))&&null!==dl(r.focus.getNode(),e=>We$1(e))||l))return  false;if(1===o.length&&Rn(o[0]))return function(e,t){const o=t.getStartEndPoints(),r=Ot(t);if(null===o)return  false;const[l,s]=o,[i,c,a]=yt(l),u=dl(s.getNode(),e=>We$1(e));if(!(We$1(i)&&We$1(u)&&De$1(c)&&Rn(a)))return  false;const[h,d,f]=wt(a,i,u),[m]=bt(e,null,null),C=h.length,_=C>0?h[0].length:0;let S=d.startRow,w=d.startColumn,b=m.length,y=b>0?m[0].length:0;if(r){const e=Nt(h,d,f),t=e.maxRow-e.minRow+1,n=e.maxColumn-e.minColumn+1;S=e.minRow,w=e.minColumn,b=Math.min(b,t),y=Math.min(y,n);}let N=false;const v=Math.min(C,S+b)-1,x=Math.min(_,w+y)-1,T=new Set;for(let e=S;e<=v;e++)for(let t=w;t<=x;t++){const n=h[e][t];T.has(n.cell.getKey())||(1===n.cell.__rowSpan&&1===n.cell.__colSpan||(St(n.cell),T.add(n.cell.getKey()),N=true));}let[F]=bt(a.getWritable(),null,null);const R=b-C+S;for(let e=0;e<R;e++){rt(F[C-1][0].cell);}const O=y-_+w;for(let e=0;e<O;e++){ct(F[0][_-1].cell,true,false);}[F]=bt(a.getWritable(),null,null);for(let e=S;e<S+b;e++)for(let t=w;t<w+y;t++){const n=e-S,o=t-w,r=m[n][o];if(r.startRow!==n||r.startColumn!==o)continue;const l=r.cell;if(1!==l.__rowSpan||1!==l.__colSpan){const n=[],o=Math.min(e+l.__rowSpan,S+b)-1,r=Math.min(t+l.__colSpan,w+y)-1;for(let l=e;l<=o;l++)for(let e=t;e<=r;e++){const t=F[l][e];n.push(t.cell);}pt(n),N=true;}const{cell:s}
11207=F[e][t],i=l.getBackgroundColor();null!=i&&s.setBackgroundColor(i);const c=s.getChildren();l.getChildren().forEach(e=>{if(Tr(e)){eo().append(e),s.append(e);}else s.append(e);}),c.forEach(e=>e.remove());}if(r&&N){const[e]=bt(a.getWritable(),null,null);e[d.startRow][d.startColumn].cell.selectEnd();}return  true}(o[0],r);if(s&&t.peek()&&!function(e){if(Ot(e)&&!e.focus.getNode().is(e.anchor.getNode()))return  true;if(Fr(e)&&We$1(e.anchor.getNode())&&!e.anchor.getNode().is(e.focus.getNode()))return  true;return  false}(r))return  false;return  true}(t,o),ro),e.registerCommand(Ue$2,kn,io),e.registerCommand(se$5,En,ro),e.registerNodeTransform(vn,An),e.registerNodeTransform(He$1,Kn),e.registerNodeTransform(Ee$1,On))}
11208
11209// Shared, strictly-contained element used to attach ephemeral nodes when we
11210// need to read computed styles (e.g. canonicalizing style values, resolving
11211// CSS custom properties). The container is created once and attached to
11212// `document.body` once; subsequent child mutations happen *inside* the
11213// contained subtree so they do not invalidate style on the rest of the page.
11214//
11215// Without this, `document.body.appendChild(...)` / `element.remove()` calls
11216// forced the browser to re-evaluate every ancestor-dependent selector (`:has()`,
11217// descendant combinators, universal sibling rules) across the document on each
11218// invocation — a 13,000+ element style recalc per call on a typical Basecamp
11219// page.
11220
11221let resolverRoot = null;
11222
11223function styleResolverRoot() {
11224  if (resolverRoot && resolverRoot.isConnected) return resolverRoot
11225
11226  resolverRoot = document.createElement("div");
11227  resolverRoot.setAttribute("aria-hidden", "true");
11228  resolverRoot.setAttribute("data-lexxy-style-resolver", "");
11229  // `contain: strict` (size, layout, paint, style) isolates everything.
vendor: 82,247 bytes, lines 11230-13999
11230  // The root itself paints nothing (visibility hidden), has zero
11231  // geometric impact (position fixed, intrinsic size via contain), and
11232  // never leaks style invalidation to its ancestors.
11233  resolverRoot.style.cssText = "contain: strict; position: fixed; top: 0; left: 0; visibility: hidden; pointer-events: none; width: 0; height: 0;";
11234  document.body.appendChild(resolverRoot);
11235  return resolverRoot
11236}
11237
11238function isSelectionHighlighted(selection) {
11239  if (!Fr(selection)) return false
11240
11241  if (selection.isCollapsed()) {
11242    return hasHighlightStyles(selection.style)
11243  } else {
11244    return selection.hasFormat("highlight")
11245  }
11246}
11247
11248function getHighlightStyles(selection) {
11249  if (!Fr(selection)) return null
11250
11251  let styles = oe$5(selection.style);
11252  if (!styles.color && !styles["background-color"]) {
11253    const anchorNode = selection.anchor.getNode();
11254    if (Tr(anchorNode)) {
11255      styles = oe$5(anchorNode.getStyle());
11256    }
11257  }
11258
11259  const color = styles.color || null;
11260  const backgroundColor = styles["background-color"] || null;
11261  if (!color && !backgroundColor) return null
11262
11263  return { color, backgroundColor }
11264}
11265
11266function hasHighlightStyles(cssOrStyles) {
11267  const styles = typeof cssOrStyles === "string" ? oe$5(cssOrStyles) : cssOrStyles;
11268  return !!(styles.color || styles["background-color"])
11269}
11270
11271function applyCanonicalizers(styles, canonicalizers = []) {
11272  return canonicalizers.reduce((css, canonicalizer) => {
11273    return canonicalizer.applyCanonicalization(css)
11274  }, styles)
11275}
11276
11277class StyleCanonicalizer {
11278  constructor(property, allowedValues= []) {
11279    this._property = property;
11280    this._allowedValues = allowedValues;
11281    this._canonicalValues = this.#allowedValuesIdentityObject;
11282  }
11283
11284  applyCanonicalization(css) {
11285    const styles = { ...oe$5(css) };
11286
11287    styles[this._property] = this.getCanonicalAllowedValue(styles[this._property]);
11288    if (!styles[this._property]) {
11289      delete styles[this._property];
11290    }
11291
11292    return F$6(styles)
11293  }
11294
11295  getCanonicalAllowedValue(value) {
11296    return this._canonicalValues[value] ||= this.#resolveCannonicalValue(value)
11297  }
11298
11299  // Private
11300
11301  get #allowedValuesIdentityObject() {
11302    return this._allowedValues.reduce((object, value) => ({ ...object, [value]: value }), {})
11303  }
11304
11305  #resolveCannonicalValue(value) {
11306    let index = this.#computedAllowedValues.indexOf(value);
11307    if (index === -1) {
11308      index = this.#computedAllowedValues.indexOf(computeStyleValues(this._property, [ value ])[0]);
11309    }
11310    return index === -1 ? null : this._allowedValues[index]
11311  }
11312
11313  get #computedAllowedValues() {
11314    return this._computedAllowedValues ||= computeStyleValues(this._property, this._allowedValues)
11315  }
11316}
11317
11318// Separates DOM writes from layout reads to avoid forced reflows, and attaches
11319// resolver elements to a strictly-contained root (outside the normal document
11320// flow) so neither the attach nor the detach invalidate styles on the rest of
11321// the page. Without containment, appending to `document.body` triggered a
11322// page-wide style recalc on every canonicalization pass.
11323function computeStyleValues(property, values) {
11324  const fragment = document.createDocumentFragment();
11325
11326  const elements = values.map(value => {
11327    const element = createElement("span", { style: `display: none; ${property}: ${value};` });
11328    fragment.appendChild(element);
11329    return element
11330  });
11331
11332  styleResolverRoot().appendChild(fragment);
11333
11334  const computed = elements.map(element =>
11335    window.getComputedStyle(element).getPropertyValue(property)
11336  );
11337
11338  elements.forEach(element => element.remove());
11339  return computed
11340}
11341
11342const TOGGLE_HIGHLIGHT_COMMAND = re$5();
11343const REMOVE_HIGHLIGHT_COMMAND = re$5();
11344const BLANK_STYLES = { "color": null, "background-color": null };
11345
11346const hasPastedStylesState = ot$3("hasPastedStyles", {
11347  parse: (value) => value || false
11348});
11349
11350// Stores pending highlight ranges extracted during HTML import, keyed by CodeNode key.
11351// The highlight-preserving tokenizer consumes this map when the code retokenizer
11352// first tokenizes the block. Scoped per editor instance so entries don't leak
11353// across editors or outlive a torn-down editor.
11354const pendingCodeHighlights = new WeakMap();
11355
11356class HighlightExtension extends LexxyExtension {
11357  get enabled() {
11358    return this.editorElement.supportsRichText
11359  }
11360
11361  get lexicalExtension() {
11362    const extension = dc({
11363      dependencies: [ Xt$2 ],
11364      name: "lexxy/highlight",
11365      config: {
11366        color: { buttons: [], permit: [] },
11367        "background-color": { buttons: [], permit: [] }
11368      },
11369      html: {
11370        import: {
11371          mark: $markConversion
11372        }
11373      },
11374      register(editor, config) {
11375        // keep the ref to the canonicalizers for optimized css conversion
11376        const canonicalizers = buildCanonicalizers(config);
11377
11378        // Register the <pre> converter directly in the conversion cache so it
11379        // coexists with other extensions' "pre" converters (the extension-level
11380        // html.import uses Object.assign, which means only one "pre" per key).
11381        $registerPreConversion(editor);
11382
11383        return Cc(
11384          editor.registerCommand(TOGGLE_HIGHLIGHT_COMMAND, (styles) => $toggleSelectionStyles(editor, styles), oo),
11385          editor.registerCommand(REMOVE_HIGHLIGHT_COMMAND, () => $toggleSelectionStyles(editor, BLANK_STYLES), oo),
11386          editor.registerNodeTransform(gr, $syncHighlightWithStyle),
11387          editor.registerNodeTransform(K$1, $syncHighlightWithCodeHighlightNode),
11388          editor.registerNodeTransform(gr, (textNode) => $canonicalizePastedStyles(textNode, canonicalizers))
11389        )
11390      }
11391    });
11392
11393    return [ extension, this.editorConfig.get("highlight") ]
11394  }
11395}
11396
11397function $applyHighlightStyle(textNode, element) {
11398  const elementStyles = {
11399    color: element.style?.color,
11400    "background-color": element.style?.backgroundColor
11401  };
11402
11403  if (Es(jn)) { $setPastedStyles(textNode); }
11404  const highlightStyle = F$6(elementStyles);
11405
11406  if (highlightStyle.length) {
11407    return textNode.setStyle(textNode.getStyle() + highlightStyle)
11408  }
11409}
11410
11411function $markConversion() {
11412  return {
11413    conversion: extendTextNodeConversion("mark", $applyHighlightStyle),
11414    priority: 1
11415  }
11416}
11417
11418// Register a custom <pre> converter directly in the editor's HTML conversion
11419// cache. We can't use the extension-level html.import because Object.assign
11420// merges all extensions' converters by tag, and a later extension (e.g.
11421// TrixContentExtension) would overwrite ours.
11422function $registerPreConversion(editor) {
11423  if (!editor._htmlConversions) return
11424
11425  let preEntries = editor._htmlConversions.get("pre");
11426  if (!preEntries) {
11427    preEntries = [];
11428    editor._htmlConversions.set("pre", preEntries);
11429  }
11430  preEntries.push($preConversionWithHighlightsFactory(editor));
11431}
11432
11433// Returns a <pre> converter factory scoped to a specific editor instance.
11434// The factory extracts highlight ranges from <mark> elements before the code
11435// retokenizer can destroy them. The ranges are stored in pendingCodeHighlights
11436// and restored by the highlight-preserving tokenizer during retokenization.
11437function $preConversionWithHighlightsFactory(editor) {
11438  return function $preConversionWithHighlights(domNode) {
11439    const highlights = extractHighlightRanges(domNode);
11440    if (highlights.length === 0) return null
11441
11442    return {
11443      conversion: (domNode) => {
11444        const language = domNode.getAttribute("data-language");
11445        const codeNode = I$1(language);
11446        $getPendingHighlights(editor).set(codeNode.getKey(), highlights);
11447        return { node: codeNode }
11448      },
11449      priority: 2
11450    }
11451  }
11452}
11453
11454// Walk the DOM tree inside a <pre> element and build a list of
11455// { start, end, style } ranges for every <mark> element found.
11456function extractHighlightRanges(preElement) {
11457  const ranges = [];
11458  const codeElement = preElement.querySelector("code") || preElement;
11459
11460  let offset = 0;
11461
11462  function walk(node) {
11463    if (node.nodeType === Node.TEXT_NODE) {
11464      offset += node.textContent.length;
11465    } else if (node.nodeType === Node.ELEMENT_NODE) {
11466      // <br> maps to a LineBreakNode (1 character) in Lexical
11467      if (node.tagName === "BR") {
11468        offset += 1;
11469        return
11470      }
11471
11472      const isMark = node.tagName === "MARK";
11473      const start = offset;
11474
11475      for (const child of node.childNodes) {
11476        walk(child);
11477      }
11478
11479      if (isMark) {
11480        const style = extractHighlightStyleFromElement(node);
11481        if (style) {
11482          ranges.push({ start, end: offset, style });
11483        }
11484      }
11485    }
11486  }
11487
11488  for (const child of codeElement.childNodes) {
11489    walk(child);
11490  }
11491
11492  return ranges
11493}
11494
11495function $getPendingHighlights(editor) {
11496  let map = pendingCodeHighlights.get(editor);
11497  if (!map) {
11498    map = new Map();
11499    pendingCodeHighlights.set(editor, map);
11500  }
11501  return map
11502}
11503
11504function extractHighlightStyleFromElement(element) {
11505  const styles = {};
11506  if (element.style?.color) styles.color = element.style.color;
11507  if (element.style?.backgroundColor) styles["background-color"] = element.style.backgroundColor;
11508  const css = F$6(styles);
11509  return css.length > 0 ? css : null
11510}
11511
11512// The code retokenizer replaces a code block's children with freshly created
11513// tokens that carry no styles, which would drop color highlights on every
11514// edit. This tokenizer wraps the stock Prism tokenizer to restore them: it
11515// recovers the block's highlight ranges — staged during HTML import, or read
11516// from the children the fresh tokens are about to replace — and reapplies
11517// them to the fresh tokens before the retokenizer splices them in.
11518function buildHighlightPreservingTokenizer(editor) {
11519  return {
11520    defaultLanguage: r.defaultLanguage,
11521    tokenize(code, language) {
11522      return r.tokenize(code, language)
11523    },
11524    $tokenize(codeNode, language) {
11525      const tokens = r.$tokenize(codeNode, language);
11526      const highlights = $takeHighlightRanges(editor, codeNode);
11527      return $applyHighlightRangesToTokens(tokens, highlights)
11528    }
11529  }
11530}
11531
11532function $takeHighlightRanges(editor, codeNode) {
11533  const pending = $getPendingHighlights(editor);
11534  const key = codeNode.getKey();
11535
11536  if (pending.has(key)) {
11537    const highlights = pending.get(key);
11538    pending.delete(key);
11539    return highlights
11540  } else if (codeNode.getChildren().some(X$1)) {
11541    return $extractHighlightRangesFromCodeNode(codeNode)
11542  } else {
11543    // A block that was never tokenized has only plain text children. Styles
11544    // on those come from import paths that didn't stage ranges (e.g. colored
11545    // spans in Trix HTML), and the first tokenization discards them.
11546    return []
11547  }
11548}
11549
11550function $applyHighlightRangesToTokens(tokens, highlights) {
11551  if (highlights.length === 0) return tokens
11552
11553  const styledTokens = [];
11554  let offset = 0;
11555
11556  for (const token of tokens) {
11557    if (X$1(token)) {
11558      styledTokens.push(...$splitTokenAtHighlightBoundaries(token, offset, highlights));
11559    } else {
11560      styledTokens.push(token);
11561    }
11562    offset += token.getTextContentSize();
11563  }
11564
11565  return styledTokens
11566}
11567
11568// Split a token into segments at highlight boundaries, styling the covered
11569// segments. We can't use TextNode.splitText() because the fresh tokens aren't
11570// attached to the tree yet, so we create CodeHighlightNode replacements.
11571function $splitTokenAtHighlightBoundaries(token, tokenStart, highlights) {
11572  const text = token.getTextContent();
11573  const segments = segmentTextByHighlights(text, tokenStart, highlights);
11574
11575  if (segments.length === 1) {
11576    const [ segment ] = segments;
11577    if (segment.style) {
11578      $applyHighlightStyleToToken(token, segment.style);
11579    }
11580    return [ token ]
11581  } else {
11582    return segments.map((segment) => {
11583      const segmentToken = V$2(text.slice(segment.start, segment.end), token.getHighlightType());
11584      if (segment.style) {
11585        $applyHighlightStyleToToken(segmentToken, segment.style);
11586      }
11587      return segmentToken
11588    })
11589  }
11590}
11591
11592// Partition a token's text into consecutive { start, end, style } segments,
11593// where offsets are relative to the token and style is null for the stretches
11594// no highlight covers.
11595function segmentTextByHighlights(text, tokenStart, highlights) {
11596  const segments = [];
11597  let cursor = 0;
11598
11599  for (const { start, end, style } of highlights) {
11600    const from = Math.max(start - tokenStart, cursor);
11601    const to = Math.min(end - tokenStart, text.length);
11602
11603    if (from < to) {
11604      if (from > cursor) {
11605        segments.push({ start: cursor, end: from, style: null });
11606      }
11607      segments.push({ start: from, end: to, style });
11608      cursor = to;
11609    }
11610  }
11611
11612  if (cursor < text.length) {
11613    segments.push({ start: cursor, end: text.length, style: null });
11614  }
11615
11616  return segments
11617}
11618
11619function $applyHighlightStyleToToken(token, style) {
11620  token.setStyle(style);
11621  $setCodeHighlightFormat(token, true);
11622}
11623
11624function $buildChildRanges(codeNode) {
11625  const childRanges = [];
11626  let charOffset = 0;
11627
11628  for (const child of codeNode.getChildren()) {
11629    if (X$1(child) || Tr(child)) {
11630      const text = child.getTextContent();
11631      childRanges.push({ node: child, start: charOffset, end: charOffset + text.length });
11632      charOffset += text.length;
11633    } else {
11634      // LineBreakNode, TabNode - count as 1 character each (\n, \t)
11635      charOffset += 1;
11636    }
11637  }
11638
11639  return childRanges
11640}
11641
11642// Extract highlight ranges from the Lexical node tree of a CodeNode.
11643// This mirrors extractHighlightRanges (which works on DOM elements during
11644// HTML import) but reads from live CodeHighlightNode children instead.
11645function $extractHighlightRangesFromCodeNode(codeNode) {
11646  const ranges = [];
11647  const childRanges = $buildChildRanges(codeNode);
11648
11649  for (const { node, start, end } of childRanges) {
11650    const style = node.getStyle();
11651    if (style && hasHighlightStyles(style)) {
11652      ranges.push({ start, end, style });
11653    }
11654  }
11655
11656  return ranges
11657}
11658
11659function buildCanonicalizers(config) {
11660  return [
11661    new StyleCanonicalizer("color", [ ...config.buttons.color, ...config.permit.color ]),
11662    new StyleCanonicalizer("background-color", [ ...config.buttons["background-color"], ...config.permit["background-color"] ])
11663  ]
11664}
11665
11666function $toggleSelectionStyles(editor, styles) {
11667  const selection = Qr();
11668  if (!Fr(selection)) return
11669
11670  const patch = {};
11671  for (const property in styles) {
11672    const oldValue = ne$4(selection, property);
11673    patch[property] = toggleOrReplace(oldValue, styles[property]);
11674  }
11675
11676  if ($selectionIsInCodeBlock(selection)) {
11677    $patchCodeHighlightStyles(editor, selection, patch);
11678  } else {
11679    $$3(selection, patch);
11680  }
11681}
11682
11683function $selectionIsInCodeBlock(selection) {
11684  const nodes = selection.getNodes();
11685  return nodes.some((node) => {
11686    // A text node inside a code block may be either a CodeHighlightNode
11687    // (after retokenization) or a plain TextNode (after splitText or before
11688    // the retokenizer has run). Check the parent in both cases.
11689    if (X$1(node) || Tr(node)) {
11690      return W$1(node.getParent())
11691    }
11692    return W$1(node)
11693  })
11694}
11695
11696function $patchCodeHighlightStyles(editor, selection, patch) {
11697  // Capture selection state and node keys before the nested update.
11698  // Accept both CodeHighlightNode and TextNode children of a CodeNode
11699  // because splitText creates TextNode instances and the retokenizer
11700  // may not have converted them back to CodeHighlightNodes yet.
11701  const nodeKeys = selection.getNodes()
11702    .filter((node) => (X$1(node) || Tr(node)) && W$1(node.getParent()))
11703    .map((node) => ({
11704      key: node.getKey(),
11705      startOffset: $getNodeSelectionOffsets(node, selection)[0],
11706      endOffset: $getNodeSelectionOffsets(node, selection)[1],
11707      textSize: node.getTextContentSize()
11708    }));
11709
11710  // Use skipTransforms so the retokenizer doesn't rebuild the block in the
11711  // middle of the toggle, and discrete to force a synchronous commit so the
11712  // styles are in place before editor.focus() triggers a second update cycle.
11713  editor.update(() => {
11714    for (const { key, startOffset, endOffset, textSize } of nodeKeys) {
11715      const node = Yo(key);
11716      if (!node) continue
11717
11718      const parent = node.getParent();
11719      if (!W$1(parent)) continue
11720      if (startOffset === endOffset) continue
11721
11722      if (startOffset === 0 && endOffset === textSize) {
11723        $applyStylePatchToNode(node, patch);
11724      } else {
11725        const splitNodes = node.splitText(startOffset, endOffset);
11726        const targetNode = splitNodes[startOffset === 0 ? 0 : 1];
11727        $applyStylePatchToNode(targetNode, patch);
11728      }
11729    }
11730  }, { skipTransforms: true, discrete: true });
11731}
11732
11733function $getNodeSelectionOffsets(node, selection) {
11734  const nodeKey = node.getKey();
11735  const anchorKey = selection.anchor.key;
11736  const focusKey = selection.focus.key;
11737  const textSize = node.getTextContentSize();
11738
11739  const isAnchor = nodeKey === anchorKey;
11740  const isFocus = nodeKey === focusKey;
11741
11742  // Determine if selection is forward or backward
11743  const isForward = selection.isBackward() === false;
11744
11745  let start = 0;
11746  let end = textSize;
11747
11748  if (isForward) {
11749    if (isAnchor) start = selection.anchor.offset;
11750    if (isFocus) end = selection.focus.offset;
11751  } else {
11752    if (isFocus) start = selection.focus.offset;
11753    if (isAnchor) end = selection.anchor.offset;
11754  }
11755
11756  return [ start, end ]
11757}
11758
11759function $applyStylePatchToNode(node, patch) {
11760  const prevStyles = oe$5(node.getStyle());
11761  const newStyles = { ...prevStyles };
11762
11763  for (const [ key, value ] of Object.entries(patch)) {
11764    if (value === null) {
11765      delete newStyles[key];
11766    } else {
11767      newStyles[key] = value;
11768    }
11769  }
11770
11771  const newCSSText = F$6(newStyles);
11772  node.setStyle(newCSSText);
11773
11774  // Sync the highlight format using TextNode's setFormat to bypass
11775  // CodeHighlightNode's no-op override
11776  const shouldHaveHighlight = hasHighlightStyles(newCSSText);
11777  const hasHighlight = node.hasFormat("highlight");
11778
11779  if (shouldHaveHighlight !== hasHighlight) {
11780    $setCodeHighlightFormat(node, shouldHaveHighlight);
11781  }
11782}
11783
11784function $setCodeHighlightFormat(node, shouldHaveHighlight) {
11785  const writable = node.getWritable();
11786  const IS_HIGHLIGHT = 1 << 7;
11787
11788  if (shouldHaveHighlight) {
11789    writable.__format |= IS_HIGHLIGHT;
11790  } else {
11791    writable.__format &= ~IS_HIGHLIGHT;
11792  }
11793}
11794
11795function toggleOrReplace(oldValue, newValue) {
11796  return oldValue === newValue ? null : newValue
11797}
11798
11799function $syncHighlightWithStyle(textNode) {
11800  if (hasHighlightStyles(textNode.getStyle()) !== textNode.hasFormat("highlight")) {
11801    textNode.toggleFormat("highlight");
11802  }
11803}
11804
11805function $syncHighlightWithCodeHighlightNode(node) {
11806  const parent = node.getParent();
11807  if (!W$1(parent)) return
11808
11809  const shouldHaveHighlight = hasHighlightStyles(node.getStyle());
11810  const hasHighlight = node.hasFormat("highlight");
11811
11812  if (shouldHaveHighlight !== hasHighlight) {
11813    $setCodeHighlightFormat(node, shouldHaveHighlight);
11814  }
11815}
11816
11817function $canonicalizePastedStyles(textNode, canonicalizers = []) {
11818  if ($hasPastedStyles(textNode)) {
11819    $setPastedStyles(textNode, false);
11820
11821    const canonicalizedCSS = applyCanonicalizers(textNode.getStyle(), canonicalizers);
11822    textNode.setStyle(canonicalizedCSS);
11823
11824    const selection = Qr();
11825    if (textNode.isSelected(selection)) {
11826      selection.setStyle(textNode.getStyle());
11827      selection.setFormat(textNode.getFormat());
11828    }
11829  }
11830}
11831
11832function $setPastedStyles(textNode, value = true) {
11833  ct$2(textNode, hasPastedStylesState, value);
11834}
11835
11836function $hasPastedStyles(textNode) {
11837  return st$2(textNode, hasPastedStylesState)
11838}
11839
11840const COMMANDS = [
11841  "bold",
11842  "italic",
11843  "strikethrough",
11844  "underline",
11845  "link",
11846  "unlink",
11847  "toggleHighlight",
11848  "removeHighlight",
11849  "setFormatHeadingLarge",
11850  "setFormatHeadingMedium",
11851  "setFormatHeadingSmall",
11852  "setFormatParagraph",
11853  "applyHeadingFormat",
11854  "clearFormatting",
11855  "insertUnorderedList",
11856  "insertOrderedList",
11857  "insertQuoteBlock",
11858  "insertCodeBlock",
11859  "setCodeLanguage",
11860  "insertHorizontalDivider",
11861  "uploadImage",
11862  "uploadFile",
11863
11864  "insertTable",
11865
11866  "undo",
11867  "redo"
11868];
11869
11870class CommandDispatcher {
11871  #selectionBeforeDrag = null
11872  #listeners = new ListenerBin()
11873
11874  static configureFor(editorElement) {
11875    return new CommandDispatcher(editorElement)
11876  }
11877
11878  constructor(editorElement) {
11879    this.editorElement = editorElement;
11880    this.editor = editorElement.editor;
11881    this.selection = editorElement.selection;
11882    this.contents = editorElement.contents;
11883
11884    this.#registerCommands();
11885    this.#registerKeyboardCommands();
11886    this.#registerDragAndDropHandlers();
11887  }
11888
11889  dispatchBold() {
11890    this.editor.dispatchCommand(xe, "bold");
11891  }
11892
11893  dispatchItalic() {
11894    this.editor.dispatchCommand(xe, "italic");
11895  }
11896
11897  dispatchStrikethrough() {
11898    this.editor.dispatchCommand(xe, "strikethrough");
11899  }
11900
11901  dispatchUnderline() {
11902    this.editor.dispatchCommand(xe, "underline");
11903  }
11904
11905  dispatchToggleHighlight(styles) {
11906    this.editor.dispatchCommand(TOGGLE_HIGHLIGHT_COMMAND, styles);
11907  }
11908
11909  dispatchRemoveHighlight() {
11910    this.editor.dispatchCommand(REMOVE_HIGHLIGHT_COMMAND);
11911  }
11912
11913  dispatchLink(url) {
11914    this.editor.update(() => {
11915      const selection = Qr();
11916      if (!Fr(selection)) return
11917
11918      const anchorNode = selection.anchor.getNode();
11919
11920      if (selection.isCollapsed() && !At$2(anchorNode, F$4)) {
11921        const autoLinkNode = H$5(url);
11922        const textNode = kr(url);
11923        autoLinkNode.append(textNode);
11924        selection.insertNodes([ autoLinkNode ]);
11925      } else {
11926        Q$6(url);
11927      }
11928    });
11929  }
11930
11931  dispatchUnlink() {
11932    this.editor.update(() => {
11933      // Let adapters signal whether unlink should target a frozen link key.
11934      if (this.editorElement.adapter.unlinkFrozenNode?.()) {
11935        return
11936      }
11937
11938      Q$6(null);
11939    });
11940  }
11941
11942  dispatchInsertUnorderedList() {
11943    const selection = Qr();
11944    if (!Fr(selection)) return
11945
11946    const anchorNode = selection.anchor.getNode();
11947
11948    if (this.selection.isInsideList && anchorNode && getListType(anchorNode) === "bullet") {
11949      this.contents.applyParagraphFormat();
11950    } else {
11951      this.contents.applyUnorderedListFormat();
11952    }
11953  }
11954
11955  dispatchInsertOrderedList() {
11956    const selection = Qr();
11957    if (!Fr(selection)) return
11958
11959    const anchorNode = selection.anchor.getNode();
11960
11961    if (this.selection.isInsideList && anchorNode && getListType(anchorNode) === "number") {
11962      this.contents.applyParagraphFormat();
11963    } else {
11964      this.contents.applyOrderedListFormat();
11965    }
11966  }
11967
11968  dispatchInsertQuoteBlock() {
11969    this.contents.toggleBlockquote();
11970  }
11971
11972  dispatchInsertCodeBlock() {
11973    if (this.selection.hasSelectedWordsInSingleLine) {
11974      this.#toggleInlineCode();
11975    } else {
11976      this.contents.toggleCodeBlock();
11977    }
11978  }
11979
11980  #toggleInlineCode() {
11981    const selection = Qr();
11982    if (!Fr(selection)) return
11983
11984    if (!selection.isCollapsed()) {
11985      const textNodes = selection.getNodes().filter(Tr);
11986      const applyingCode = !textNodes.every((node) => node.hasFormat("code"));
11987
11988      if (applyingCode) {
11989        this.#stripInlineFormattingFromSelection(selection, textNodes);
11990      }
11991    }
11992
11993    this.editor.dispatchCommand(xe, "code");
11994  }
11995
11996  // Strip all inline formatting (bold, italic, etc.) from the selected text
11997  // nodes so that applying code produces a single merged <code> element instead
11998  // of one per differently-formatted span.
11999  #stripInlineFormattingFromSelection(selection, textNodes) {
12000    const isBackward = selection.isBackward();
12001    const startPoint = isBackward ? selection.focus : selection.anchor;
12002    const endPoint = isBackward ? selection.anchor : selection.focus;
12003
12004    for (let i = 0; i < textNodes.length; i++) {
12005      const node = textNodes[i];
12006      if (node.getFormat() === 0) continue
12007
12008      const isFirst = i === 0;
12009      const isLast = i === textNodes.length - 1;
12010      const startOffset = isFirst && startPoint.type === "text" ? startPoint.offset : 0;
12011      const endOffset = isLast && endPoint.type === "text" ? endPoint.offset : node.getTextContentSize();
12012
12013      if (startOffset === 0 && endOffset === node.getTextContentSize()) {
12014        node.setFormat(0);
12015      } else {
12016        const splits = node.splitText(startOffset, endOffset);
12017        const target = startOffset === 0 ? splits[0] : splits[1];
12018        target.setFormat(0);
12019
12020        if (isFirst && startPoint.type === "text") {
12021          startPoint.set(target.getKey(), 0, "text");
12022        }
12023        if (isLast && endPoint.type === "text") {
12024          endPoint.set(target.getKey(), endOffset - startOffset, "text");
12025        }
12026      }
12027    }
12028  }
12029
12030  dispatchSetCodeLanguage(language) {
12031    this.editor.update(() => {
12032      if (!this.selection.isInsideCodeBlock) return
12033
12034      const codeNode = this.selection.nearestNodeOfType(z$1);
12035      if (!codeNode) return
12036
12037      codeNode.setLanguage(language);
12038    });
12039  }
12040
12041  dispatchInsertHorizontalDivider() {
12042    Pt$3(new HorizontalDividerNode);
12043  }
12044
12045  dispatchSetFormatHeadingLarge() {
12046    this.#applyConfiguredHeadingFormat(0);
12047  }
12048
12049  dispatchSetFormatHeadingMedium() {
12050    this.#applyConfiguredHeadingFormat(1);
12051  }
12052
12053  dispatchSetFormatHeadingSmall() {
12054    this.#applyConfiguredHeadingFormat(2);
12055  }
12056
12057  dispatchSetFormatParagraph() {
12058    this.contents.applyParagraphFormat();
12059  }
12060
12061  dispatchApplyHeadingFormat(tag) {
12062    this.contents.applyHeadingFormat(tag);
12063  }
12064
12065  dispatchClearFormatting() {
12066    this.contents.clearFormatting();
12067  }
12068
12069  dispatchUploadImage() {
12070    this.#dispatchUploadAttachment("image/*,video/*");
12071  }
12072
12073  dispatchUploadFile() {
12074    this.#dispatchUploadAttachment();
12075  }
12076
12077  #dispatchUploadAttachment(accept = null) {
12078    const attributes = {
12079      type: "file",
12080      multiple: true,
12081      style: "display: none;",
12082      onchange: ({ target: { files } }) => {
12083        this.contents.uploadFiles(files, { selectLast: true });
12084      }
12085    };
12086
12087    if (accept) attributes.accept = accept;
12088
12089    const input = createElement("input", attributes);
12090
12091    // Append and remove to make testable
12092    this.editorElement.appendChild(input);
12093    input.click();
12094    setTimeout(() => input.remove(), 1000);
12095  }
12096
12097  dispatchInsertTable() {
12098    this.editor.dispatchCommand(ze$1, { "rows": 3, "columns": 3, "includeHeaders": true });
12099  }
12100
12101  dispatchUndo() {
12102    this.editor.dispatchCommand(Ce$2, undefined);
12103  }
12104
12105  dispatchRedo() {
12106    this.editor.dispatchCommand(Se$2, undefined);
12107  }
12108
12109  dispose() {
12110    this.#listeners.dispose();
12111  }
12112
12113  #applyConfiguredHeadingFormat(index) {
12114    const tag = this.editorElement.config.get("headings")[index];
12115    if (tag) this.contents.applyHeadingFormat(tag);
12116  }
12117
12118  #registerCommands() {
12119    for (const command of COMMANDS) {
12120      const methodName = `dispatch${capitalize(command)}`;
12121      this.#registerCommandHandler(command, 0, this[methodName].bind(this));
12122    }
12123  }
12124
12125  #registerCommandHandler(command, priority, handler) {
12126    this.#listeners.track(this.editor.registerCommand(command, handler, priority));
12127  }
12128
12129  #registerKeyboardCommands() {
12130    this.#registerCommandHandler(ke$2, oo, this.#handleArrowRightKey.bind(this));
12131    this.#registerCommandHandler(Fe$2, oo, this.#handleTabKey.bind(this));
12132
12133    // Run before Lexical's built-in insert handlers to descend an element point on a
12134    // block container to a leaf, avoiding error #211 on Enter / Shift+Enter in a quote.
12135    this.#registerCommandHandler(de$4, so, this.#normalizeBlockContainerSelection.bind(this));
12136    this.#registerCommandHandler(he$3, so, this.#normalizeBlockContainerSelection.bind(this));
12137  }
12138
12139  #normalizeBlockContainerSelection() {
12140    $normalizeBlockContainerSelection();
12141    return false
12142  }
12143
12144  #handleArrowRightKey(event) {
12145    const selection = Qr();
12146    if (!Fr(selection) || !selection.isCollapsed()) return false
12147    if (this.selection.isInsideCodeBlock || !selection.hasFormat("code")) return false
12148
12149    const anchorNode = selection.anchor.getNode();
12150    if (!Tr(anchorNode) || selection.anchor.offset !== anchorNode.getTextContentSize()) return false
12151    if (anchorNode.getNextSibling() !== null) return false
12152
12153    event.preventDefault();
12154    selection.toggleFormat("code");
12155    return true
12156  }
12157
12158  #registerDragAndDropHandlers() {
12159    if (this.editorElement.supportsAttachments) {
12160      this.dragCounter = 0;
12161      this.#listeners.track(
12162        this.editor.registerRootListener((rootElement) => {
12163          if (rootElement) {
12164            const teardowns = [
12165              registerEventListener(rootElement, "dragover", this.#handleDragOver.bind(this)),
12166              registerEventListener(rootElement, "drop", this.#handleDrop.bind(this)),
12167              registerEventListener(rootElement, "dragenter", this.#handleDragEnter.bind(this)),
12168              registerEventListener(rootElement, "dragleave", this.#handleDragLeave.bind(this))
12169            ];
12170            return () => teardowns.forEach((teardown) => teardown())
12171          }
12172        })
12173      );
12174    }
12175  }
12176
12177  #handleDragEnter(event) {
12178    if (this.#isInternalDrag(event)) return
12179
12180    this.dragCounter++;
12181    if (this.dragCounter === 1) {
12182      this.#saveSelectionBeforeDrag();
12183      this.editor.getRootElement().classList.add("lexxy-editor--drag-over");
12184    }
12185  }
12186
12187  #handleDragLeave(event) {
12188    if (this.#isInternalDrag(event)) return
12189
12190    this.dragCounter--;
12191    if (this.dragCounter === 0) {
12192      this.#selectionBeforeDrag = null;
12193      this.editor.getRootElement().classList.remove("lexxy-editor--drag-over");
12194    }
12195  }
12196
12197  #handleDragOver(event) {
12198    if (this.#isInternalDrag(event)) return
12199
12200    event.preventDefault();
12201  }
12202
12203  #handleDrop(event) {
12204    if (this.#isInternalDrag(event)) return
12205
12206    event.preventDefault();
12207
12208    this.dragCounter = 0;
12209    this.editor.getRootElement().classList.remove("lexxy-editor--drag-over");
12210
12211    const dataTransfer = event.dataTransfer;
12212    if (!dataTransfer) return
12213
12214    const files = Array.from(dataTransfer.files);
12215    if (!files.length) return
12216
12217    this.#restoreSelectionBeforeDrag();
12218    this.contents.uploadFiles(files, { selectLast: true });
12219
12220    this.editor.focus();
12221  }
12222
12223  #saveSelectionBeforeDrag() {
12224    this.editor.getEditorState().read(() => {
12225      this.#selectionBeforeDrag = Qr()?.clone();
12226    });
12227  }
12228
12229  #restoreSelectionBeforeDrag() {
12230    if (!this.#selectionBeforeDrag) return
12231
12232    this.editor.update(() => {
12233      es(this.#selectionBeforeDrag);
12234    });
12235
12236    this.#selectionBeforeDrag = null;
12237  }
12238
12239  #isInternalDrag(event) {
12240    return event.dataTransfer?.types.some((type) => type.startsWith("application/x-lexxy-"))
12241  }
12242
12243  #handleTabKey(event) {
12244    if (this.selection.isInsideList) {
12245      return this.#handleTabForList(event)
12246    } else if (this.selection.isInsideCodeBlock) {
12247      return this.#handleTabForCode()
12248    }
12249    return false
12250  }
12251
12252  #handleTabForList(event) {
12253    if (event.shiftKey && !this.selection.isIndentedList) return false
12254
12255    event.preventDefault();
12256    const command = event.shiftKey? Ke$2 : Ie$3;
12257    return this.editor.dispatchCommand(command)
12258  }
12259
12260  #handleTabForCode() {
12261    const selection = Qr();
12262    return Fr(selection) && selection.isCollapsed()
12263  }
12264
12265}
12266
12267function capitalize(str) {
12268  return str.charAt(0).toUpperCase() + str.slice(1)
12269}
12270
12271class Selection {
12272  #listeners = new ListenerBin()
12273
12274  constructor(editorElement) {
12275    this.editorElement = editorElement;
12276    this.editorContentElement = editorElement.editorContentElement;
12277    this.editor = this.editorElement.editor;
12278    this.previouslySelectedKeys = new Set();
12279
12280    this.#listenForNodeSelections();
12281    this.#processSelectionChangeCommands();
12282    this.#containEditorFocus();
12283    this.#clearStaleInlineCodeFormat();
12284  }
12285
12286  get hasNodeSelection() {
12287    return this.editor.getEditorState().read(() => {
12288      const selection = Qr();
12289      return selection !== null && Ir(selection)
12290    })
12291  }
12292
12293  get cursorPosition() {
12294    let position = null;
12295
12296    this.editor.getEditorState().read(() => {
12297      const range = this.#getValidSelectionRange();
12298      if (!range) return
12299
12300      const rect = this.#getReliableRectFromRange(range);
12301      if (this.#isRectUnreliable(rect)) return
12302
12303      position = this.#calculateCursorPosition(rect, range);
12304    });
12305
12306    return position
12307  }
12308
12309  placeCursorAtTheEnd() {
12310    this.editor.update(() => {
12311      const root = Zo();
12312      const lastDescendant = root.getLastDescendant();
12313
12314      if (lastDescendant && Tr(lastDescendant)) {
12315        lastDescendant.selectEnd();
12316      } else {
12317        root.selectEnd();
12318      }
12319    });
12320  }
12321
12322  selectedNodeWithOffset() {
12323    const selection = Qr();
12324    if (!selection) return { node: null, offset: 0 }
12325
12326    if (Fr(selection)) {
12327      return {
12328        node: selection.anchor.getNode(),
12329        offset: selection.anchor.offset
12330      }
12331    } else if (Ir(selection)) {
12332      const [ node ] = selection.getNodes();
12333      return {
12334        node,
12335        offset: 0
12336      }
12337    }
12338
12339    return { node: null, offset: 0 }
12340  }
12341
12342  getFormat() {
12343    const selection = Qr();
12344    if (!Fr(selection)) return {}
12345
12346    const anchorNode = selection.anchor.getNode();
12347    if (!anchorNode.getParent()) return {}
12348
12349    const topLevelElement = anchorNode.getTopLevelElementOrThrow();
12350    const listType = getListType(anchorNode);
12351    const headingNode = this.#getNearestHeadingNode(anchorNode);
12352
12353    return {
12354      isBold: selection.hasFormat("bold"),
12355      isItalic: selection.hasFormat("italic"),
12356      isStrikethrough: selection.hasFormat("strikethrough"),
12357      isUnderline: selection.hasFormat("underline"),
12358      isHighlight: isSelectionHighlighted(selection),
12359      isInLink: At$2(anchorNode, F$4) !== null,
12360      isInQuote: Mt$2(topLevelElement),
12361      isInHeading: headingNode !== null,
12362      isInCode: this.#isInCode(selection, anchorNode),
12363      headingTag: headingNode?.getTag() ?? null,
12364      isInList: listType !== null,
12365      listType,
12366      isInTable: Ye(anchorNode) !== null
12367    }
12368  }
12369
12370  nearestNodeOfType(nodeType) {
12371    const anchorNode = Qr()?.anchor?.getNode();
12372    return At$2(anchorNode, nodeType)
12373  }
12374
12375  get hasSelectedWordsInSingleLine() {
12376    const selection = Qr();
12377    if (!Fr(selection)) return false
12378
12379    if (selection.isCollapsed()) return false
12380
12381    const anchorNode = selection.anchor.getNode();
12382    const focusNode = selection.focus.getNode();
12383
12384    if (anchorNode.getTopLevelElement() !== focusNode.getTopLevelElement()) {
12385      return false
12386    }
12387
12388    const anchorElement = anchorNode.getTopLevelElement();
12389    if (!anchorElement) return false
12390
12391    // When anchor and focus are in different block-level children of the same
12392    // top-level element (e.g. two paragraphs inside a blockquote), this is a
12393    // multi-line selection, not a single-line one.
12394    const anchorBlock = Wi(anchorNode) ? anchorNode : anchorNode.getParent();
12395    const focusBlock = Wi(focusNode) ? focusNode : focusNode.getParent();
12396    if (anchorBlock !== focusBlock && anchorBlock !== anchorElement) {
12397      return false
12398    }
12399
12400    const nodes = selection.getNodes();
12401    for (const node of nodes) {
12402      if (sr(node)) {
12403        return false
12404      }
12405    }
12406
12407    return true
12408  }
12409
12410  get isInsideList() {
12411    return this.nearestNodeOfType(ge$2)
12412  }
12413
12414  get isInsideBlockQuote() {
12415    return this.nearestNodeOfType(At$1)
12416  }
12417
12418  get isIndentedList() {
12419    const closestListNode = this.nearestNodeOfType(me$2);
12420    return closestListNode && (G$7(closestListNode) > 1)
12421  }
12422
12423  get isInsideCodeBlock() {
12424    return this.nearestNodeOfType(z$1) !== null
12425  }
12426
12427  get isTableCellSelected() {
12428    const selection = Qr();
12429    const { anchor, focus } = selection;
12430    if (!Fr(selection) || anchor.key !== focus.key) return false
12431
12432    return this.nearestNodeOfType(Ee$1) !== null
12433  }
12434
12435  get isOnPreviewableImage() {
12436    return this.previewableImageNode != null
12437  }
12438
12439  get previewableImageNode() {
12440    const firstNode = Qr()?.getNodes().at(0);
12441    return $isActionTextAttachmentNode(firstNode) && firstNode.isPreviewableImage ? firstNode : null
12442  }
12443
12444  get isAtNodeStart() {
12445    const { anchorNode, offset } = this.#getCollapsedSelectionData();
12446    return anchorNode && offset === 0
12447  }
12448
12449  get nodeAfterCursor() {
12450    const { anchorNode, offset } = this.#getCollapsedSelectionData();
12451    if (!anchorNode) return null
12452
12453    if (Tr(anchorNode)) {
12454      return this.#getNodeAfterTextNode(anchorNode, offset)
12455    }
12456
12457    if (Wi(anchorNode)) {
12458      return this.#getNodeAfterElementNode(anchorNode, offset)
12459    }
12460
12461    return this.#findNextSiblingUp(anchorNode)
12462  }
12463
12464  get topLevelNodeAfterCursor() {
12465    const { anchorNode, offset } = this.#getCollapsedSelectionData();
12466    if (!anchorNode) return null
12467
12468    if (Tr(anchorNode)) {
12469      if (offset === anchorNode.getTextContentSize()) return this.#getNextNodeFromTextEnd(anchorNode)
12470      if (this.#isCursorOnLastVisualLineOfBlock(anchorNode)) {
12471        const topLevelElement = anchorNode.getTopLevelElement();
12472        return topLevelElement ? topLevelElement.getNextSibling() : null
12473      }
12474      return null
12475    }
12476
12477    if (Wi(anchorNode)) {
12478      return this.#getNodeAfterElementNode(anchorNode, offset)
12479    }
12480
12481    return this.#findNextSiblingUp(anchorNode)
12482  }
12483
12484  get nodeBeforeCursor() {
12485    const { anchorNode, offset } = this.#getCollapsedSelectionData();
12486    if (!anchorNode) return null
12487
12488    if (Tr(anchorNode)) {
12489      return this.#getNodeBeforeTextNode(anchorNode, offset)
12490    }
12491
12492    if (Wi(anchorNode)) {
12493      return this.#getNodeBeforeElementNode(anchorNode, offset)
12494    }
12495
12496    return this.#findPreviousSiblingUp(anchorNode)
12497  }
12498
12499  get topLevelNodeBeforeCursor() {
12500    const { anchorNode, offset } = this.#getCollapsedSelectionData();
12501    if (!anchorNode) return null
12502
12503    if (Tr(anchorNode)) {
12504      if (offset === 0) return this.#getPreviousNodeFromTextStart(anchorNode)
12505      if (this.#isCursorOnFirstVisualLineOfBlock(anchorNode)) {
12506        const topLevelElement = anchorNode.getTopLevelElement();
12507        return topLevelElement ? topLevelElement.getPreviousSibling() : null
12508      }
12509      return null
12510    }
12511
12512    if (Wi(anchorNode)) {
12513      return this.#getNodeBeforeElementNode(anchorNode, offset)
12514    }
12515
12516    return this.#findPreviousSiblingUp(anchorNode)
12517  }
12518
12519  dispose() {
12520    this.editorElement = null;
12521    this.editorContentElement = null;
12522    this.editor = null;
12523    this.previouslySelectedKeys = null;
12524
12525    this.#listeners.dispose();
12526  }
12527
12528  // When all inline code text is deleted, Lexical's selection retains the stale
12529  // code format flag. Verify the flag is backed by actual code-formatted content:
12530  // a code block ancestor or a text node that carries the code format.
12531  #isInCode(selection, anchorNode) {
12532    if (At$2(anchorNode, z$1) !== null) return true
12533    if (!selection.hasFormat("code")) return false
12534
12535    return Tr(anchorNode) && anchorNode.hasFormat("code")
12536  }
12537
12538  // After deleting all inline code text, Lexical preserves the code format on
12539  // the selection even though no code-formatted content remains. This listener
12540  // detects that stale state and clears it so newly typed text won't be
12541  // code-formatted.
12542  #clearStaleInlineCodeFormat() {
12543    this.#listeners.track(this.editor.registerUpdateListener(({ editorState, tags }) => {
12544      if (tags.has("history-merge") || tags.has("skip-dom-selection")) return
12545
12546      let isStale = false;
12547
12548      editorState.read(() => {
12549        const selection = Qr();
12550        if (!Fr(selection) || !selection.isCollapsed()) return
12551        if (!selection.hasFormat("code")) return
12552
12553        const anchorNode = selection.anchor.getNode();
12554        if (this.#isInCode(selection, anchorNode)) return
12555
12556        isStale = true;
12557      });
12558
12559      if (isStale) {
12560        setTimeout(() => {
12561          this.editor.update(() => {
12562            const selection = Qr();
12563            if (!Fr(selection) || !selection.hasFormat("code")) return
12564
12565            const anchorNode = selection.anchor.getNode();
12566            if (this.#isInCode(selection, anchorNode)) return
12567
12568            selection.toggleFormat("code");
12569          });
12570        }, 0);
12571      }
12572    }));
12573  }
12574
12575  get #currentlySelectedKeys() {
12576    if (this.currentlySelectedKeys) { return this.currentlySelectedKeys }
12577
12578    this.currentlySelectedKeys = new Set();
12579
12580    const selection = Qr();
12581    if (selection && Ir(selection)) {
12582      for (const node of selection.getNodes()) {
12583        this.currentlySelectedKeys.add(node.getKey());
12584      }
12585    }
12586
12587    return this.currentlySelectedKeys
12588  }
12589
12590  #processSelectionChangeCommands() {
12591    this.#listeners.track(
12592      this.editor.registerCommand(Ne$1, handlingDefault(this.#selectPreviousNode.bind(this)), io),
12593      this.editor.registerCommand(ke$2, handlingDefault(this.#selectNextNode.bind(this)), io),
12594      this.editor.registerCommand(we$1, handlingDefault(this.#selectPreviousTopLevelNode.bind(this)), io),
12595      this.editor.registerCommand(Ee$3, handlingDefault(this.#selectNextTopLevelNode.bind(this)), io),
12596
12597      this.editor.registerCommand(fe$4, this.#selectDecoratorNodeBeforeDeletion.bind(this), io),
12598
12599      this.editor.registerCommand(ie$4, () => {
12600        this.#syncSelectedClasses();
12601      }, io),
12602
12603      this.editor.registerCommand(ie$4, () => {
12604        this.#preserveFocusOfOtherFields();
12605        return false
12606      }, lo)
12607    );
12608  }
12609
12610  // Firefox (152+) keeps window.getSelection() anchored inside the editor after focus
12611  // moves to another field, and fires document selectionchange for every keystroke
12612  // typed there. Lexical reads that stale selection, reconciles, and pulls focus back
12613  // into the editor — stealing it mid-typing. When another text-entry field owns focus,
12614  // tag the update so Lexical leaves the DOM selection (and with it, focus) alone.
12615  #preserveFocusOfOtherFields() {
12616    if (this.#anotherFieldIsFocused) {
12617      Os(qn);
12618    }
12619  }
12620
12621  get #anotherFieldIsFocused() {
12622    const rootElement = this.editor.getRootElement();
12623    const activeElement = rootElement?.ownerDocument.activeElement;
12624
12625    return activeElement && !rootElement.contains(activeElement) &&
12626      (activeElement.tagName === "INPUT" || activeElement.tagName === "TEXTAREA" || activeElement.isContentEditable)
12627  }
12628
12629  #listenForNodeSelections() {
12630    this.#listeners.track(this.editor.registerCommand(se$5, ({ target }) => {
12631      if (!qs(target)) return false
12632
12633      const targetNode = Go(target);
12634      return ji(targetNode) && this.#selectInLexical(targetNode)
12635    }, io));
12636
12637    this.#listeners.track(
12638      this.editor.registerRootListener((rootElement) => {
12639        if (rootElement) {
12640          return registerEventListener(rootElement, "lexxy:internal:move-to-next-line", () => this.#selectOrAppendNextLine())
12641        }
12642      })
12643    );
12644  }
12645
12646  #containEditorFocus() {
12647    // Workaround for a bizarre Chrome bug where the cursor abandons the editor to focus on not-focusable elements
12648    // above when navigating UP/DOWN when Lexical shows its fake cursor on custom decorator nodes.
12649    this.#listeners.track(
12650      this.editor.registerRootListener((rootElement) => {
12651        if (rootElement) {
12652          const handler = (event) => this.#handleArrowKeyOnLexicalCursor(event);
12653          rootElement.addEventListener("keydown", handler, true);
12654          return () => rootElement.removeEventListener("keydown", handler, true)
12655        }
12656      })
12657    );
12658  }
12659
12660  #handleArrowKeyOnLexicalCursor(event) {
12661    if (event.key === "ArrowUp") {
12662      const lexicalCursor = this.editor.getRootElement().querySelector("[data-lexical-cursor]");
12663
12664      if (lexicalCursor) {
12665        let currentElement = lexicalCursor.previousElementSibling;
12666        while (currentElement && currentElement.hasAttribute("data-lexical-cursor")) {
12667          currentElement = currentElement.previousElementSibling;
12668        }
12669
12670        if (!currentElement) {
12671          event.preventDefault();
12672        }
12673      }
12674    }
12675
12676    if (event.key === "ArrowDown") {
12677      const lexicalCursor = this.editor.getRootElement().querySelector("[data-lexical-cursor]");
12678
12679      if (lexicalCursor) {
12680        let currentElement = lexicalCursor.nextElementSibling;
12681        while (currentElement && currentElement.hasAttribute("data-lexical-cursor")) {
12682          currentElement = currentElement.nextElementSibling;
12683        }
12684
12685        if (!currentElement) {
12686          event.preventDefault();
12687        }
12688      }
12689    }
12690  }
12691
12692  #syncSelectedClasses() {
12693    this.#clearPreviouslyHighlightedItems();
12694    this.#highlightNewItems();
12695
12696    this.previouslySelectedKeys = this.#currentlySelectedKeys;
12697    this.currentlySelectedKeys = null;
12698  }
12699
12700  #clearPreviouslyHighlightedItems() {
12701    for (const key of this.previouslySelectedKeys) {
12702      if (!this.#currentlySelectedKeys.has(key)) {
12703        const dom = this.editor.getElementByKey(key);
12704        if (dom) dom.classList.remove("node--selected");
12705      }
12706    }
12707  }
12708
12709  #highlightNewItems() {
12710    for (const key of this.#currentlySelectedKeys) {
12711      if (!this.previouslySelectedKeys.has(key)) {
12712        const nodeElement = this.editor.getElementByKey(key);
12713        if (nodeElement) nodeElement.classList.add("node--selected");
12714      }
12715    }
12716  }
12717
12718  #selectPreviousNode(event) {
12719    if (event.shiftKey) {
12720      return this.#withCurrentNodeSelectionNode((currentNode) => {
12721        const selection = this.#rangeSelectDecorator(currentNode, "forward");
12722
12723        // Can't rely on native pass-through with Playwright on firefox
12724        selection.modify("extend", true, "character");
12725        return true
12726      })
12727    } else {
12728      return this.#withCurrentNodeSelectionNode((currentNode) => currentNode.selectPrevious())
12729        || this.#selectInLexical(this.nodeBeforeCursor)
12730    }
12731  }
12732
12733  #selectNextNode(event) {
12734    if (event.shiftKey) {
12735      return this.#withCurrentNodeSelectionNode((currentNode) => {
12736        const selection = this.#rangeSelectDecorator(currentNode, "forward");
12737
12738        // Can't rely on native pass-through with Playwright on firefox
12739        selection.modify("extend", false, "character");
12740        return true
12741      })
12742    } else {
12743      return this.#withCurrentNodeSelectionNode((currentNode) => currentNode.selectNext(0, 0))
12744        || this.#selectInLexical(this.nodeAfterCursor)
12745    }
12746  }
12747
12748  #selectPreviousTopLevelNode() {
12749    return this.#withCurrentNodeSelectionNode((currentNode) => currentNode.getTopLevelElement().selectPrevious())
12750      || this.#selectInLexical(this.topLevelNodeBeforeCursor)
12751  }
12752
12753  #selectNextTopLevelNode() {
12754    return this.#withCurrentNodeSelectionNode((currentNode) => currentNode.getTopLevelElement().selectNext(0, 0))
12755      || this.#selectInLexical(this.topLevelNodeAfterCursor)
12756  }
12757
12758  #withCurrentNodeSelectionNode(fn) {
12759    if (this.hasNodeSelection) {
12760      return fn(Qr().getNodes()[0])
12761    }
12762  }
12763
12764  #rangeSelectDecorator(node, direction = "forward") {
12765    if (ji(node)) {
12766        const [ anchorOffset, focusOffset ] = direction === "forward" ? [ 0, 1 ] : [ 1, 0 ];
12767        const indexAtNode = node.getIndexWithinParent();
12768
12769        return node.getParent().select(indexAtNode + anchorOffset, indexAtNode + focusOffset)
12770    }
12771  }
12772
12773  async #selectOrAppendNextLine() {
12774    this.editor.update(() => {
12775      const topLevelElement = this.#getTopLevelElementFromSelection();
12776      if (!topLevelElement) return
12777
12778      this.#moveToOrCreateNextLine(topLevelElement);
12779    });
12780  }
12781
12782  #getTopLevelElementFromSelection() {
12783    const selection = Qr();
12784    if (!selection) return null
12785
12786    if (Ir(selection)) {
12787      return this.#getTopLevelFromNodeSelection(selection)
12788    }
12789
12790    if (Fr(selection)) {
12791      return this.#getTopLevelFromRangeSelection(selection)
12792    }
12793
12794    return null
12795  }
12796
12797  #getTopLevelFromNodeSelection(selection) {
12798    const nodes = selection.getNodes();
12799    return nodes.length > 0 ? nodes[0].getTopLevelElement() : null
12800  }
12801
12802  #getTopLevelFromRangeSelection(selection) {
12803    const anchorNode = selection.anchor.getNode();
12804    return anchorNode.getTopLevelElement()
12805  }
12806
12807  #getNearestHeadingNode(anchorNode) {
12808    const topLevelElement = anchorNode.getTopLevelElementOrThrow();
12809
12810    let headingNode = Lt$2(topLevelElement) ? topLevelElement : null;
12811    if (!headingNode) {
12812      let current = anchorNode.getParent();
12813      while (current) {
12814        if (Lt$2(current)) {
12815          headingNode = current;
12816          break
12817        }
12818        current = current.getParent();
12819      }
12820    }
12821
12822    return headingNode
12823  }
12824
12825  #moveToOrCreateNextLine(topLevelElement) {
12826    const nextSibling = topLevelElement.getNextSibling();
12827
12828    if (nextSibling) {
12829      nextSibling.selectStart();
12830    } else {
12831      this.#createAndSelectNewParagraph();
12832    }
12833  }
12834
12835  #createAndSelectNewParagraph() {
12836    const root = Zo();
12837    const newParagraph = eo();
12838    root.append(newParagraph);
12839    newParagraph.selectStart();
12840  }
12841
12842  #selectInLexical(node) {
12843    if (ji(node)) {
12844      Os(Jn);
12845      const selection = $createNodeSelectionWith(node);
12846      es(selection);
12847      return selection
12848    } else {
12849      return false
12850    }
12851  }
12852
12853  #selectDecoratorNodeBeforeDeletion(backwards) {
12854    if (backwards && this.#removeEmptyListItem()) return true
12855
12856    const node = backwards ? this.nodeBeforeCursor : this.nodeAfterCursor;
12857    if (!ji(node)) return false
12858
12859    if (this.#collapseListItemToParagraph(node)) return true
12860
12861    this.#removeEmptyElementAnchorNode();
12862
12863    const selection = this.#selectInLexical(node);
12864    return Boolean(selection)
12865  }
12866
12867  // When backspace is pressed on an empty list item that has siblings,
12868  // handle the deletion appropriately:
12869  //
12870  // - Middle/end items (has previous sibling): remove the empty item and
12871  //   place the cursor at the end of the previous sibling. Without this,
12872  //   Lexical's default collapseAtStart converts the empty item into a
12873  //   paragraph above the list, causing the cursor to jump away.
12874  //
12875  // - First item (no previous sibling): convert to a paragraph above the
12876  //   list, matching the standard "unwrap list formatting" behavior that
12877  //   users expect from pressing backspace at the start of a list item.
12878  //   Inside a blockquote we instead just remove the empty item and move
12879  //   the cursor into the next one — stranding a paragraph there would
12880  //   leave the blank line the user is trying to close.
12881  //
12882  // When the empty item is the last/only one in the list, we return false
12883  // and let Lexical's default (convert to paragraph) provide the standard
12884  // "exit list" behavior.
12885  #removeEmptyListItem() {
12886    const selection = Qr();
12887    if (!Fr(selection) || !selection.isCollapsed()) return false
12888
12889    const anchorNode = selection.anchor.getNode();
12890    const listItem = At$2(anchorNode, ge$2);
12891    if (!listItem) return false
12892
12893    if (!$isListItemStructurallyEmpty(listItem)) return false
12894
12895    const nextSibling = listItem.getNextSibling();
12896    if (!nextSibling) return false
12897
12898    const previousSibling = listItem.getPreviousSibling();
12899    const listNode = At$2(listItem, me$2);
12900    if (!listNode) return false
12901
12902    if (previousSibling) {
12903      previousSibling.selectEnd();
12904      listItem.remove();
12905    } else if (Mt$2(listNode.getParent())) {
12906      nextSibling.selectStart();
12907      listItem.remove();
12908    } else {
12909      const paragraph = eo();
12910      listNode.insertBefore(paragraph);
12911      listItem.remove();
12912      paragraph.selectStart();
12913    }
12914
12915    return true
12916  }
12917
12918  // When the cursor is inside a list item, collapse the list item into a
12919  // paragraph instead of selecting the decorator. This lets the user
12920  // delete a list that immediately follows an attachment without the
12921  // attachment becoming selected. Only applies when the decorator is
12922  // outside the list item (e.g. a block attachment before the list),
12923  // not when it's an inline mention inside the list item.
12924  #collapseListItemToParagraph(decoratorNode) {
12925    const anchorNode = Qr()?.anchor?.getNode();
12926    const listItem = anchorNode && At$2(anchorNode, ge$2);
12927    if (!listItem) return false
12928
12929    if (listItem.isParentOf(decoratorNode)) return false
12930
12931    const listNode = At$2(listItem, me$2);
12932    if (!listNode) return false
12933
12934    const paragraph = eo();
12935    const children = listItem.getChildren();
12936    children.forEach(child => paragraph.append(child));
12937
12938    if (listNode.getChildrenSize() === 1) {
12939      listNode.insertBefore(paragraph);
12940      listNode.remove();
12941    } else {
12942      listNode.insertBefore(paragraph);
12943      listItem.remove();
12944    }
12945
12946    paragraph.selectStart();
12947    return true
12948  }
12949
12950  #removeEmptyElementAnchorNode(anchor = Qr()?.anchor) {
12951    const anchorNode = anchor?.getNode();
12952    if (Wi(anchorNode) && anchorNode?.isEmpty()) anchorNode.remove();
12953  }
12954
12955  #getValidSelectionRange() {
12956    const lexicalSelection = Qr();
12957    if (!lexicalSelection || !lexicalSelection.isCollapsed()) return null
12958
12959    const nativeSelection = window.getSelection();
12960    if (!nativeSelection || nativeSelection.rangeCount === 0) return null
12961
12962    return nativeSelection.getRangeAt(0)
12963  }
12964
12965  #getReliableRectFromRange(range) {
12966    let rect = range.getBoundingClientRect();
12967
12968    if (this.#isRectUnreliable(rect)) {
12969      const marker = this.#createAndInsertMarker(range);
12970      rect = marker.getBoundingClientRect();
12971      this.#restoreSelectionAfterMarker(marker);
12972      marker.remove();
12973    }
12974
12975    return rect
12976  }
12977
12978  #isRectUnreliable(rect) {
12979    return rect.width === 0 && rect.height === 0 || rect.top === 0 && rect.left === 0
12980  }
12981
12982  #createAndInsertMarker(range) {
12983    const marker = this.#createMarker();
12984    range.insertNode(marker);
12985    return marker
12986  }
12987
12988  #createMarker() {
12989    const marker = document.createElement("span");
12990    marker.textContent = "\u200b";
12991    marker.style.display = "inline-block";
12992    marker.style.width = "1px";
12993    marker.style.height = "1em";
12994    marker.style.lineHeight = "normal";
12995    marker.setAttribute("nonce", getNonce());
12996    return marker
12997  }
12998
12999  #restoreSelectionAfterMarker(marker) {
13000    const nativeSelection = window.getSelection();
13001    nativeSelection.removeAllRanges();
13002    const newRange = document.createRange();
13003    newRange.setStartAfter(marker);
13004    newRange.collapse(true);
13005    nativeSelection.addRange(newRange);
13006  }
13007
13008  #calculateCursorPosition(rect, range) {
13009    const rootRect = this.editor.getRootElement().getBoundingClientRect();
13010    const x = rect.left - rootRect.left;
13011    let y = rect.top - rootRect.top;
13012
13013    const fontSize = this.#getFontSizeForCursor(range);
13014    if (!isNaN(fontSize)) {
13015      y += fontSize;
13016    }
13017
13018    return { x, y, fontSize }
13019  }
13020
13021  #getFontSizeForCursor(range) {
13022    const nativeSelection = window.getSelection();
13023    const anchorNode = nativeSelection.anchorNode;
13024    const parentElement = this.#getElementFromNode(anchorNode);
13025
13026    if (parentElement instanceof HTMLElement) {
13027      const computed = window.getComputedStyle(parentElement);
13028      return parseFloat(computed.fontSize)
13029    }
13030
13031    return 0
13032  }
13033
13034  #getElementFromNode(node) {
13035    return node?.nodeType === Node.TEXT_NODE ? node.parentElement : node
13036  }
13037
13038  #getCollapsedSelectionData() {
13039    const selection = Qr();
13040    if (!Fr(selection) || !selection.isCollapsed()) {
13041      return { anchorNode: null, offset: 0 }
13042    }
13043
13044    const { anchor } = selection;
13045    return { anchorNode: anchor.getNode(), offset: anchor.offset }
13046  }
13047
13048  #getNodeAfterTextNode(anchorNode, offset) {
13049    if (offset === anchorNode.getTextContentSize()) {
13050      return this.#getNextNodeFromTextEnd(anchorNode)
13051    }
13052    return null
13053  }
13054
13055  #getNextNodeFromTextEnd(anchorNode) {
13056    const nextSibling = anchorNode.getNextSibling();
13057    if (ji(nextSibling)) {
13058      return nextSibling
13059    }
13060    if (nextSibling != null) {
13061      return null
13062    }
13063    const parent = anchorNode.getParent();
13064    return parent ? parent.getNextSibling() : null
13065  }
13066
13067  #getNodeAfterElementNode(anchorNode, offset) {
13068    if (offset < anchorNode.getChildrenSize()) {
13069      return anchorNode.getChildAtIndex(offset)
13070    }
13071    return this.#findNextSiblingUp(anchorNode)
13072  }
13073
13074  #getNodeBeforeTextNode(anchorNode, offset) {
13075    if (offset === 0) {
13076      return this.#getPreviousNodeFromTextStart(anchorNode)
13077    }
13078    return null
13079  }
13080
13081  #getPreviousNodeFromTextStart(anchorNode) {
13082    const previousSibling = anchorNode.getPreviousSibling();
13083    if (ji(previousSibling)) {
13084      return previousSibling
13085    }
13086    if (previousSibling != null) {
13087      return null
13088    }
13089    const parent = anchorNode.getParent();
13090    return parent ? parent.getPreviousSibling() : null
13091  }
13092
13093  #getNodeBeforeElementNode(anchorNode, offset) {
13094    if (offset > 0) {
13095      return anchorNode.getChildAtIndex(offset - 1)
13096    }
13097    return this.#findPreviousSiblingUp(anchorNode)
13098  }
13099
13100  #findNextSiblingUp(node) {
13101    let current = node;
13102    while (current && current.getNextSibling() == null) {
13103      current = current.getParent();
13104    }
13105    return current ? current.getNextSibling() : null
13106  }
13107
13108  #findPreviousSiblingUp(node) {
13109    let current = node;
13110    while (current && current.getPreviousSibling() == null) {
13111      current = current.getParent();
13112    }
13113    return current ? current.getPreviousSibling() : null
13114  }
13115
13116  #isCursorOnFirstVisualLineOfBlock(anchorNode) {
13117    return this.#isCursorOnEdgeLineOfBlock(anchorNode, "first")
13118  }
13119
13120  #isCursorOnLastVisualLineOfBlock(anchorNode) {
13121    return this.#isCursorOnEdgeLineOfBlock(anchorNode, "last")
13122  }
13123
13124  // Check whether the cursor sits on the first or last visual line of its
13125  // top-level block by comparing the Y position of the cursor with the Y
13126  // position of the block's start (first line) or end (last line).
13127  #isCursorOnEdgeLineOfBlock(anchorNode, edge) {
13128    const topLevelElement = anchorNode.getTopLevelElement();
13129    if (!topLevelElement) return false
13130
13131    const domElement = this.editor.getElementByKey(topLevelElement.getKey());
13132    if (!domElement) return false
13133
13134    const nativeSelection = window.getSelection();
13135    if (!nativeSelection?.rangeCount) return false
13136
13137    const cursorRect = this.#getReliableRectFromRange(nativeSelection.getRangeAt(0));
13138    if (!cursorRect || this.#isRectUnreliable(cursorRect)) return false
13139
13140    const edgeRect = this.#getEdgeCharRect(domElement, edge);
13141    if (!edgeRect || this.#isRectUnreliable(edgeRect)) return false
13142
13143    const tolerance = edgeRect.height > 0 ? edgeRect.height * 0.5 : 5;
13144    return Math.abs(cursorRect.top - edgeRect.top) < tolerance
13145  }
13146
13147  // Get a reliable bounding rect for the first or last character in a DOM
13148  // element by creating a non-collapsed range around it.
13149  #getEdgeCharRect(element, edge) {
13150    const walker = document.createTreeWalker(element, 4 /* NodeFilter.SHOW_TEXT */);
13151    let textNode;
13152
13153    if (edge === "first") {
13154      textNode = walker.nextNode();
13155    } else {
13156      while (walker.nextNode()) textNode = walker.currentNode;
13157    }
13158
13159    if (!textNode || textNode.length === 0) return null
13160
13161    const range = document.createRange();
13162    if (edge === "first") {
13163      range.setStart(textNode, 0);
13164      range.setEnd(textNode, 1);
13165    } else {
13166      range.setStart(textNode, textNode.length - 1);
13167      range.setEnd(textNode, textNode.length);
13168    }
13169
13170    return range.getBoundingClientRect()
13171  }
13172}
13173
13174class EditorConfiguration {
13175  #editorElement
13176  #config
13177
13178  constructor(editorElement) {
13179    this.#editorElement = editorElement;
13180    this.#config = new Configuration(
13181      Lexxy.presets.get("default"),
13182      Lexxy.presets.get(editorElement.preset),
13183      this.#overrides
13184    );
13185  }
13186
13187  get(path) {
13188    return this.#config.get(path)
13189  }
13190
13191  get #overrides() {
13192    const overrides = {};
13193    for (const option of this.#defaultOptions) {
13194      const attribute = dasherize(option);
13195      if (this.#editorElement.hasAttribute(attribute)) {
13196        overrides[option] = this.#parseAttribute(attribute);
13197      }
13198    }
13199    return overrides
13200  }
13201
13202  get #defaultOptions() {
13203    return Object.keys(Lexxy.presets.get("default"))
13204  }
13205
13206  #parseAttribute(attribute) {
13207    const value = this.#editorElement.getAttribute(attribute);
13208    try {
13209      return JSON.parse(value)
13210    } catch {
13211      return value
13212    }
13213  }
13214}
13215
13216class ImageGalleryNode extends Bi {
13217  $config() {
13218    return this.config("image_gallery", {
13219      extends: Bi,
13220    })
13221  }
13222
13223  static transform() {
13224    return (gallery) => {
13225      gallery.unwrapEmptyNode()
13226        || gallery.replaceWithSingularChild()
13227        || gallery.splitAroundInvalidChild();
13228    }
13229  }
13230
13231  static importDOM() {
13232    return {
13233      div: (element) => {
13234        if (!this.#isGalleryElement(element)) return null
13235
13236        return {
13237          conversion: () => {
13238            return {
13239              node: $createImageGalleryNode()
13240            }
13241          },
13242          priority: 2
13243        }
13244      }
13245    }
13246  }
13247
13248  static canCollapseWith(node) {
13249    return $isImageGalleryNode(node) || this.isValidChild(node)
13250  }
13251
13252  static isValidChild(node) {
13253    return $isActionTextAttachmentNode(node) && node.isPreviewableImage
13254  }
13255
13256  static #isGalleryElement(element) {
13257    const attachmentChildren = element.querySelectorAll(`:scope > :is(${this.#attachmentTags.join()})`);
13258    return element.textContent.trim() === ""
13259      && attachmentChildren.length > 0
13260      && element.children.length === attachmentChildren.length
13261  }
13262
13263  static get #attachmentTags() {
13264    return Object.keys(ActionTextAttachmentNode.importDOM())
13265  }
13266
13267  createDOM() {
13268    const div = document.createElement("div");
13269    div.className = this.#galleryClassNames;
13270    return div
13271  }
13272
13273  updateDOM(_prevNode, dom) {
13274    dom.className = this.#galleryClassNames;
13275    return false
13276  }
13277
13278  canBeEmpty() {
13279    // Return `true` to conform to `$isBlock(node)`
13280    // We clean-up empty galleries with a transform
13281    return true
13282  }
13283
13284  collapseAtStart(_selection) {
13285    return true
13286  }
13287
13288  insertNewAfter(selection, restoreSelection) {
13289    const selectionBeforeLastChild = selection.anchor.getNode().is(this) && selection.anchor.offset == this.getChildrenSize() - 1;
13290    if (selectionBeforeLastChild) {
13291      const paragraph = eo();
13292      this.insertAfter(paragraph, false);
13293      paragraph.insertAfter(this.getLastChild(), false);
13294      paragraph.selectEnd();
13295
13296      // return null as selection has been managed
13297      return null
13298    }
13299
13300    const newNode = $createImageGalleryNode();
13301    this.insertAfter(newNode, restoreSelection);
13302    return newNode
13303  }
13304
13305  getImageAttachments() {
13306    const children = this.getChildren();
13307    return children.filter($isActionTextAttachmentNode)
13308  }
13309
13310  exportDOM() {
13311    const div = document.createElement("div");
13312    div.className = this.#galleryClassNames;
13313    return { element: div }
13314  }
13315
13316  collapseWith(node, backwards) {
13317    if (!ImageGalleryNode.canCollapseWith(node)) return false
13318
13319    if (backwards) {
13320      $t$2(this, node);
13321    } else {
13322      this.append(node);
13323    }
13324
13325    Ot$3(this, ImageGalleryNode.isValidChild);
13326
13327    return true
13328  }
13329
13330  unwrapEmptyNode() {
13331    if (this.isEmpty()) {
13332      const paragraph = eo();
13333      return this.replace(paragraph)
13334    }
13335  }
13336
13337  replaceWithSingularChild() {
13338    if (this.#hasSingularChild) {
13339      const child = this.getFirstChild();
13340      return this.replace($makeSafeForRoot(child))
13341    }
13342  }
13343
13344  splitAroundInvalidChild() {
13345    for (const child of jt$2(this)) {
13346      if (ImageGalleryNode.isValidChild(child)) continue
13347
13348      const poppedNode = $makeSafeForRoot(child);
13349      const [ topGallery, secondGallery ] = this.splitAtIndex(poppedNode.getIndexWithinParent());
13350      topGallery.insertAfter(poppedNode);
13351      poppedNode.selectEnd();
13352
13353      // remove an empty gallery rather than let it unwrap to a paragraph
13354      if (secondGallery.isEmpty()) secondGallery.remove();
13355
13356      break
13357    }
13358  }
13359
13360  splitAtIndex(index) {
13361    return Us(this, index)
13362  }
13363
13364  get #hasSingularChild() {
13365    return this.getChildrenSize() === 1
13366  }
13367
13368  get #galleryClassNames() {
13369    return `attachment-gallery attachment-gallery--${this.getChildrenSize()}`
13370  }
13371}
13372
13373function $createImageGalleryNode() {
13374  return new ImageGalleryNode()
13375}
13376
13377function $isImageGalleryNode(node) {
13378  return node instanceof ImageGalleryNode
13379}
13380
13381function $findOrCreateGalleryForImage(node) {
13382  if (!ImageGalleryNode.canCollapseWith(node)) return null
13383
13384  const existingGallery = At$2(node, ImageGalleryNode);
13385  return existingGallery ?? Tt$4(node, $createImageGalleryNode)
13386}
13387
13388class Uploader {
13389  #files
13390
13391  static for(editorElement, files, options = {}) {
13392    const UploaderKlass = GalleryUploader.handle(editorElement, files) ? GalleryUploader : Uploader;
13393    return new UploaderKlass(editorElement, files, options)
13394  }
13395
13396  constructor(editorElement, files, options = {}) {
13397    this.#files = files;
13398    this.options = options;
13399
13400    this.editorElement = editorElement;
13401    this.contents = editorElement.contents;
13402    this.selection = editorElement.selection;
13403  }
13404
13405  get files() {
13406    return Array.from(this.#files)
13407  }
13408
13409  $uploadFiles() {
13410    this.$createUploadNodes();
13411    this.$insertUploadNodes();
13412  }
13413
13414  $createUploadNodes() {
13415    this.nodes = this.files.map(file => this.#createUploadNode(file));
13416  }
13417
13418  #createUploadNode(file) {
13419    return this.options.pending
13420      ? this.contents.$createPendingUploadNode(file)
13421      : this.contents.$createUploadNode(file)
13422  }
13423
13424  $insertUploadNodes() {
13425    this.contents.insertAtCursor(...this.nodes);
13426  }
13427}
13428
13429class GalleryUploader extends Uploader {
13430  #gallery
13431
13432  static handle(editorElement, files) {
13433    return this.isMultipleImageUpload(files) || this.gallerySelection(editorElement.selection)
13434  }
13435
13436  static isMultipleImageUpload(files) {
13437    let imageFileCount = 0;
13438    for (const file of files) {
13439      if (isPreviewableImage(file.type)) imageFileCount++;
13440      if (imageFileCount > 1) return true
13441    }
13442    return false
13443  }
13444
13445  static gallerySelection(selection) {
13446    return selection.isOnPreviewableImage || this.selectionIsAfterGalleryEdge(selection)
13447  }
13448
13449  static selectionIsAfterGalleryEdge(selection) {
13450    return selection.isAtNodeStart && ImageGalleryNode.canCollapseWith(selection.nodeBeforeCursor)
13451  }
13452
13453  $insertUploadNodes() {
13454    this.#findOrCreateGallery();
13455    this.#insertImagesInGallery();
13456    this.#insertNonImagesAfterGallery();
13457  }
13458
13459  #findOrCreateGallery() {
13460    if (this.selection.isOnPreviewableImage) {
13461      // Resolve from the previewable image itself (the selection's first node), not from
13462      // #selectedNode (the anchor) — those differ when the selection runs from an image
13463      // into following text, and the anchor text node can't join a gallery (returns null).
13464      this.#gallery = $findOrCreateGalleryForImage(this.selection.previewableImageNode);
13465    } else if (this.#selectionIsAfterGalleryEdge) {
13466      this.#gallery = $findOrCreateGalleryForImage(this.selection.nodeBeforeCursor);
13467    } else {
13468      this.#gallery = $createImageGalleryNode();
13469      this.contents.insertAtCursor(this.#gallery);
13470    }
13471  }
13472
13473  get #selectionIsAfterGalleryEdge() {
13474    return this.constructor.selectionIsAfterGalleryEdge(this.selection)
13475  }
13476
13477  get #selectedNode() {
13478    const { node } = this.selection.selectedNodeWithOffset();
13479    return node
13480  }
13481
13482  get #galleryInsertPosition() {
13483    if (this.#selectionIsAfterGalleryEdge) return this.#gallery.getChildrenSize()
13484
13485    const anchor = Qr()?.anchor;
13486    const galleryHasElementSelection = anchor?.getNode().is(this.#gallery);
13487    if (galleryHasElementSelection) return anchor.offset
13488
13489    const selectedNode = this.#selectedNode;
13490    const childIndex = this.#gallery.isParentOf(selectedNode) && selectedNode.getIndexWithinParent();
13491    return childIndex !== false ? (childIndex + 1) : 0
13492  }
13493
13494  get #imageNodes() {
13495    return this.nodes.filter(node => ImageGalleryNode.isValidChild(node))
13496  }
13497
13498  get #nonImageNodes() {
13499    return this.nodes.filter(node => !ImageGalleryNode.isValidChild(node))
13500  }
13501
13502  #insertImagesInGallery() {
13503    this.#gallery.splice(this.#galleryInsertPosition, 0, this.#imageNodes);
13504  }
13505
13506  #insertNonImagesAfterGallery() {
13507    let beforeNode = this.#gallery;
13508
13509    for (const node of this.#nonImageNodes) {
13510      beforeNode.insertAfter(node);
13511      beforeNode = node;
13512    }
13513  }
13514}
13515
13516async function loadFileIntoImage(file, image) {
13517  return new Promise((resolve) => {
13518    const reader = new FileReader();
13519
13520    image.addEventListener("load", () => {
13521      resolve(image);
13522    });
13523
13524    reader.onload = (event) => {
13525      image.src = event.target.result || null;
13526    };
13527
13528    reader.readAsDataURL(file);
13529  })
13530}
13531
13532class ActionTextAttachmentUploadNode extends ActionTextAttachmentNode {
13533  static getType() {
13534    return "action_text_attachment_upload"
13535  }
13536
13537  static clone(node) {
13538    return new ActionTextAttachmentUploadNode({ ...node }, node.__key)
13539  }
13540
13541  static importJSON(serializedNode) {
13542    return new ActionTextAttachmentUploadNode({ ...serializedNode })
13543  }
13544
13545  // Should never run since this is a transient node. Defined to remove console warning.
13546  static importDOM() {
13547    return null
13548  }
13549
13550  constructor(node = {}, key) {
13551    const { file, uploadUrl, blobUrlTemplate, progress, width, height, uploadError, fileName, contentType } = node;
13552    super({ ...node, contentType: file?.type ?? contentType }, key);
13553    this.file = file ?? null;
13554    this.fileName = file?.name ?? fileName;
13555    this.uploadUrl = uploadUrl;
13556    this.blobUrlTemplate = blobUrlTemplate;
13557    this.progress = progress ?? null;
13558    this.width = width;
13559    this.height = height;
13560    this.uploadError = uploadError;
13561  }
13562
13563  createDOM() {
13564    if (this.uploadError) return this.createDOMForError()
13565
13566    // This side-effect is trigged on DOM load to fire only once and avoid multiple
13567    // uploads through cloning. The upload is guarded from restarting in case the
13568    // node is reloaded from saved state such as from history.
13569    this.#startUploadIfNeeded();
13570
13571    // Bridge-managed uploads (uploadUrl is null) and restored or remote
13572    // instances (no local File) don't have file data to show an image
13573    // preview, so always show the file icon during upload.
13574    const canPreviewFile = this.isPreviewableAttachment && this.uploadUrl != null && this.file != null;
13575    const figure = this.createAttachmentFigure(canPreviewFile);
13576
13577    if (canPreviewFile) {
13578      const img = figure.appendChild(this.#createDOMForImage());
13579
13580      // load file locally to set dimensions and prevent vertical shifting
13581      loadFileIntoImage(this.file, img).then(img => this.#setDimensionsFromImage(img));
13582    } else {
13583      figure.appendChild(this.#createDOMForFile());
13584    }
13585
13586    figure.appendChild(this.#createCaption());
13587    figure.appendChild(this.#createProgressBar());
13588
13589    return figure
13590  }
13591
13592  updateDOM(prevNode, dom) {
13593    if (this.uploadError !== prevNode.uploadError) return true
13594
13595    if (prevNode.progress !== this.progress) {
13596      const progress = dom.querySelector("progress");
13597      progress.value = this.progress ?? 0;
13598    }
13599
13600    return false
13601  }
13602
13603  exportDOM() {
13604    return { element: null }
13605  }
13606
13607  exportJSON() {
13608    return {
13609      ...super.exportJSON(),
13610      type: "action_text_attachment_upload",
13611      version: 1,
13612      fileName: this.fileName,
13613      contentType: this.contentType,
13614      uploadUrl: this.uploadUrl,
13615      blobUrlTemplate: this.blobUrlTemplate,
13616      progress: this.progress,
13617      width: this.width,
13618      height: this.height,
13619      uploadError: this.uploadError
13620    }
13621  }
13622
13623  get #uploadStarted() {
13624    return this.progress !== null
13625  }
13626
13627  #createDOMForImage() {
13628    return createElement("img")
13629  }
13630
13631  #createDOMForFile() {
13632    const extension = this.#getFileExtension();
13633    const span = createElement("span", { className: "attachment__icon", textContent: extension });
13634    return span
13635  }
13636
13637  #getFileExtension() {
13638    return (this.fileName || "").split(".").pop().toLowerCase()
13639  }
13640
13641  #createCaption() {
13642    const figcaption = createElement("figcaption", { className: "attachment__caption" });
13643
13644    const nameSpan = createElement("span", { className: "attachment__name", textContent: this.caption || this.fileName || "" });
13645    figcaption.appendChild(nameSpan);
13646
13647    if (this.file) {
13648      const sizeSpan = createElement("span", { className: "attachment__size", textContent: bytesToHumanSize(this.file.size) });
13649      figcaption.appendChild(sizeSpan);
13650    }
13651
13652    return figcaption
13653  }
13654
13655  #createProgressBar() {
13656    return createElement("progress", { value: this.progress ?? 0, max: 100 })
13657  }
13658
13659  #setDimensionsFromImage({ width, height }) {
13660    if (this.#hasDimensions) return
13661
13662    this.patchAndRewriteHistory({ width, height });
13663  }
13664
13665  get #hasDimensions() {
13666    return Boolean(this.width && this.height)
13667  }
13668
13669  async #startUploadIfNeeded() {
13670    if (this.#uploadStarted) return
13671    if (!this.uploadUrl) return // Bridge-managed upload — skip DirectUpload
13672    if (!this.file) return // Restored or remote instance — no local File to upload
13673
13674    this.#setUploadStarted();
13675
13676    const { DirectUpload } = await import('@rails/activestorage');
13677
13678    const upload = new DirectUpload(this.file, this.uploadUrl, this);
13679    upload.delegate = this.#createUploadDelegate();
13680
13681    this.#dispatchEvent("lexxy:upload-start", { file: this.file });
13682
13683    upload.create((error, blob) => {
13684      this.#forgetUploadRequest();
13685
13686      if (error) {
13687        this.#dispatchEvent("lexxy:upload-end", { file: this.file, error });
13688        this.#handleUploadError(error);
13689      } else {
13690        this.#dispatchEvent("lexxy:upload-end", { file: this.file, error: null });
13691        this.editor.update(() => {
13692          this.$showUploadedAttachment(blob);
13693        });
13694      }
13695    });
13696  }
13697
13698  #createUploadDelegate() {
13699    const shouldAuthenticateUploads = Lexxy.global.get("authenticatedUploads");
13700
13701    return {
13702      directUploadWillCreateBlobWithXHR: (request) => {
13703        if (shouldAuthenticateUploads) request.withCredentials = true;
13704      },
13705      directUploadWillStoreFileWithXHR: (request) => {
13706        if (shouldAuthenticateUploads) request.withCredentials = true;
13707
13708        this.#rememberUploadRequest(request);
13709
13710        const uploadProgressHandler = (event) => this.#handleUploadProgress(event, request);
13711        request.upload.addEventListener("progress", uploadProgressHandler);
13712      }
13713    }
13714  }
13715
13716  #forgetUploadRequest() {
13717    this.#editorElement?.uploadRequests.forget(this.getKey());
13718  }
13719
13720  #rememberUploadRequest(request) {
13721    this.#editorElement?.uploadRequests.track(this.getKey(), request);
13722  }
13723
13724  get #editorElement() {
13725    return this.editor.getRootElement()?.closest("lexxy-editor")
13726  }
13727
13728  #setUploadStarted() {
13729    this.#setProgress(1);
13730  }
13731
13732  #handleUploadProgress(event, request) {
13733    const progress = Math.round(event.loaded / event.total * 100);
13734    try {
13735      this.#setProgress(progress);
13736      this.#dispatchEvent("lexxy:upload-progress", { file: this.file, progress });
13737    } catch {
13738      request.abort();
13739    }
13740  }
13741
13742  #setProgress(progress) {
13743    this.patchAndRewriteHistory({ progress });
13744  }
13745
13746  #handleUploadError(error) {
13747    console.warn(`Upload error for ${this.file?.name ?? "file"}: ${error}`);
13748
13749    this.patchAndRewriteHistory({ uploadError: true });
13750  }
13751
13752  $showUploadedAttachment(blob) {
13753    const previewSrc = this.isPreviewableImage && this.file ? URL.createObjectURL(this.file) : null;
13754
13755    const replacementNode = this.#toActionTextAttachmentNodeWith(blob, previewSrc);
13756    this.replaceAndRewriteHistory(replacementNode);
13757
13758    return replacementNode.getKey()
13759  }
13760
13761  #toActionTextAttachmentNodeWith(blob, previewSrc) {
13762    const conversion = new AttachmentNodeConversion(this, blob, previewSrc);
13763    return conversion.toAttachmentNode()
13764  }
13765
13766  #dispatchEvent(name, detail) {
13767    const figure = this.editor.getElementByKey(this.getKey());
13768    if (figure) dispatch(figure, name, detail);
13769  }
13770}
13771
13772class AttachmentNodeConversion {
13773  constructor(uploadNode, blob, previewSrc) {
13774    this.uploadNode = uploadNode;
13775    this.blob = blob;
13776    this.previewSrc = previewSrc;
13777  }
13778
13779  toAttachmentNode() {
13780    return new ActionTextAttachmentNode({
13781      ...this.uploadNode,
13782      ...this.#propertiesFromBlob,
13783      src: this.#src,
13784      previewSrc: this.previewSrc,
13785      pendingPreview: this.blob.previewable && !this.uploadNode.isPreviewableImage
13786    })
13787  }
13788
13789  get #propertiesFromBlob() {
13790    const { blob } = this;
13791    return {
13792      sgid: blob.attachable_sgid,
13793      altText: blob.filename,
13794      contentType: blob.content_type,
13795      fileName: blob.filename,
13796      fileSize: blob.byte_size,
13797      previewable: blob.previewable,
13798      previewStatusUrl: blob.preview_status_url
13799    }
13800  }
13801
13802  get #src() {
13803    return this.blob.previewable ? this.blob.url : this.#blobSrc
13804  }
13805
13806  get #blobSrc() {
13807    return this.uploadNode.blobUrlTemplate
13808      .replace(":signed_id", this.blob.signed_id)
13809      .replace(":filename", encodeURIComponent(this.blob.filename))
13810  }
13811}
13812
13813function $createActionTextAttachmentUploadNode(...args) {
13814  return new ActionTextAttachmentUploadNode(...args)
13815}
13816
13817class BaseNodeInserter {
13818  constructor(selection) {
13819    this.selection = selection;
13820  }
13821}
13822
13823class CodeNodeInserter extends BaseNodeInserter {
13824  static handles(selection) {
13825    return At$2(selection.anchor?.getNode(), z$1)
13826  }
13827
13828  insertNodes(nodes) {
13829    if (!this.selection.isCollapsed()) { this.selection.removeText(); }
13830
13831    j$6(this.selection);
13832    const focusNode = this.selection.focus.getNode();
13833    const codeNode = At$2(focusNode, z$1);
13834    const insertionIndex = focusNode.is(codeNode) ? 0 : focusNode.getIndexWithinParent();
13835
13836    const caret = lc(codeNode, insertionIndex + 1, "previous");
13837
13838    // Nodes that are already in the document come from the format-toggle path (existing
13839    // content converted into this code block). Brand-new nodes (dropped/pasted content)
13840    // were never attached.
13841    const existingNodes = new Set(nodes.filter(node => node.isAttached()));
13842    const trailingNodes = [];
13843
13844    for (const node of nodes) {
13845      if (existingNodes.has(node)) {
13846        if (!node.isAttached()) continue // already pulled in when a converted ancestor was removed
13847      } else if (!this.#canJoinCodeBlock(node)) {
13848        trailingNodes.push(node); // e.g. a dropped attachment, which a code block can't hold
13849        continue
13850      }
13851
13852      if (caret.getNodeAtCaret() && Wi(node)) { caret.insert(or()); }
13853      caret.insert(this.#convertNodeToCodeChild(node));
13854    }
13855
13856    const lastTrailingNode = this.#insertAfterCodeBlock(codeNode, trailingNodes);
13857    const nodeToSelect = lastTrailingNode ?? caret.getNodeAtCaret();
13858    nodeToSelect?.selectEnd();
13859  }
13860
13861  #canJoinCodeBlock(node) {
13862    return Tr(node) || sr(node)
13863  }
13864
13865  #insertAfterCodeBlock(codeNode, nodes) {
13866    let previousNode = codeNode;
13867    for (const node of nodes) {
13868      previousNode.insertAfter(node);
13869      previousNode = node;
13870    }
13871    return nodes.at(-1)
13872  }
13873
13874  #convertNodeToCodeChild(node) {
13875    if (sr(node)) {
13876      return node
13877    } else {
13878      node.remove();
13879      return kr(node.getTextContent())
13880    }
13881  }
13882}
13883
13884class ShadowRootNodeInserter extends BaseNodeInserter {
13885  static handles(selection) {
13886    return $isShadowRoot(selection?.anchor?.getNode())
13887  }
13888
13889  insertNodes(nodes) {
13890    const anchorNode = this.selection.anchor.getNode();
13891    const paragraph = eo();
13892    anchorNode.append(paragraph);
13893
13894    paragraph.selectStart().insertNodes(nodes);
13895  }
13896}
13897
13898class NodeSelectionNodeInserter extends BaseNodeInserter {
13899  static handles(selection) {
13900    return Ir(selection) && selection.getNodes().length > 0
13901  }
13902
13903  insertNodes(nodes) {
13904    // Overrides Lexical's default behavior of _removing_ the currently selected nodes
13905    // https://github.com/facebook/lexical/blob/v0.38.2/packages/lexical/src/LexicalSelection.ts#L412
13906    let lastNode = this.selection.getNodes().at(-1);
13907
13908    for (const node of nodes) {
13909      // Inserting after a top-level node would make this one a root child. Inline nodes
13910      // can't live there (Lexical error #99), so wrap them in their required parent first.
13911      const nodeToInsert = this.#insertsIntoRoot(lastNode) ? $makeSafeForRoot(node) : node;
13912      lastNode = lastNode.insertAfter(nodeToInsert);
13913    }
13914  }
13915
13916  #insertsIntoRoot(node) {
13917    return node.is(node.getTopLevelElement())
13918  }
13919}
13920
13921// A list item can only hold inline content, so a block node (such as an image
13922// attachment) dropped into one corrupts the list: Lexical lifts it into the
13923// wrong list item and orphans an empty bullet. Block nodes belong at the top
13924// level instead, splitting the list around the cursor. Inline content keeps
13925// Lexical's default behavior and stays within the list item.
13926class ListItemNodeInserter extends BaseNodeInserter {
13927  static handles(selection) {
13928    return Fr(selection) &&
13929      At$2(selection.anchor.getNode(), ge$2)
13930  }
13931
13932  insertNodes(nodes) {
13933    if (nodes.some(node => this.#isBlockDecorator(node))) {
13934      this.#insertAroundList(nodes);
13935    } else {
13936      this.selection.insertNodes(nodes);
13937    }
13938  }
13939
13940  #insertAroundList(nodes) {
13941    if (!this.selection.isCollapsed()) { this.selection.removeText(); }
13942
13943    // Break out of any nesting to the outermost list. Splitting an inner list
13944    // would leave the block stranded inside an ancestor list item, which is the
13945    // very corruption we are avoiding. The block must land at the list's level.
13946    const anchorNode = this.selection.anchor.getNode();
13947    const outerList = this.#outermostList(anchorNode);
13948    const topItem = this.#topLevelItemFor(anchorNode, outerList);
13949
13950    // A blank top-level bullet is just the insertion point (e.g. the user pressed
13951    // Enter to leave the list); break out of it entirely. A bullet with content —
13952    // including one wrapping a nested list — splits so its content stays in the list.
13953    const splitAfterItem = $isBlankNode(topItem) ? topItem.getPreviousSibling() : topItem;
13954    const splitIndex = splitAfterItem ? splitAfterItem.getIndexWithinParent() + 1 : 0;
13955    const [ listBefore, listAfter ] = Us(outerList, splitIndex);
13956    if ($isBlankNode(topItem)) { topItem.remove(); }
13957
13958    let anchor = listBefore ?? listAfter;
13959    for (const node of nodes) {
13960      anchor.insertAfter(node);
13961      anchor = node;
13962    }
13963
13964    this.#removeEmptyList(listBefore);
13965    this.#removeEmptyList(listAfter);
13966    nodes.at(-1).selectNext();
13967  }
13968
13969  #outermostList(node) {
13970    return [ node, ...node.getParents() ].reverse().find(Se$1)
13971  }
13972
13973  #topLevelItemFor(node, outerList) {
13974    return [ node, ...node.getParents() ].find(ancestor =>
13975      pe$2(ancestor) && ancestor.getParent()?.is(outerList)
13976    )
13977  }
13978
13979  #removeEmptyList(list) {
13980    if (Se$1(list) && list.isEmpty()) list.remove();
13981  }
13982
13983  // Only block decorator nodes (image/file attachments) are intercepted. A list
13984  // item cannot hold them, so they must break out. Pasted element blocks
13985  // (paragraphs, quotes) keep Lexical's own list-escape semantics.
13986  #isBlockDecorator(node) {
13987    return ji(node) && !node.isInline()
13988  }
13989}
13990
13991// Lexical's RangeSelection.insertNodes requires every selection point to have a block
13992// ancestor with inline children. An element point on a container of block nodes — e.g.
13993// a quote holding paragraphs — has none, so Lexical throws invariant #211 or #212.
13994// Descend such points to a leaf position before inserting.
13995class BlockContainerNodeInserter extends BaseNodeInserter {
13996  static handles(selection) {
13997    return $hasPointOnBlockContainer(selection)
13998  }
13999
14000  insertNodes(nodes) {
14001    St$3
vendor: 13,995 bytes, lines 14001-14413
14001(this.selection);
14002    this.selection.insertNodes(nodes);
14003  }
14004}
14005
14006const INSERTERS = [
14007  CodeNodeInserter,
14008  ShadowRootNodeInserter,
14009  NodeSelectionNodeInserter,
14010  ListItemNodeInserter,
14011  BlockContainerNodeInserter
14012];
14013
14014// Defined here rather than on the base class so the base can stay free of any
14015// dependency on its subclasses (they import the base), avoiding an import cycle.
14016BaseNodeInserter.for = (selection) => {
14017  const inserterClass = INSERTERS.find(inserter => inserter.handles(selection));
14018  return inserterClass ? new inserterClass(selection) : selection
14019};
14020
14021// Word and Outlook never emit <ul>/<ol>/<li>. They simulate lists with flat
14022// paragraphs that declare their depth in an inline `mso-list:l0 level2 lfo1`
14023// and carry the bullet or number glyph in a <span style="mso-list:Ignore">.
14024// Nothing downstream understands either, so the items land as plain paragraphs
14025// with the marker baked into the text. Rebuild real lists from the level each
14026// paragraph declares.
14027//
14028// Everything this reads lives in inline attributes, so it stays correct after
14029// the pasted content formatter has dropped Office's style sheet.
14030class OfficeFormatter {
14031  constructor(doc) {
14032    this.doc = doc;
14033  }
14034
14035  format() {
14036    for (const run of this.#listRuns()) {
14037      this.#replaceWithLists(run);
14038    }
14039  }
14040
14041  // A run is a stretch of Office list paragraphs that are siblings with nothing
14042  // but whitespace and Word's conditional comments between them. Anything else
14043  // in between (a heading, a plain paragraph) ends one list and starts another.
14044  #listRuns() {
14045    const runs = [];
14046    const claimed = new Set();
14047
14048    for (const paragraph of this.doc.querySelectorAll("p[style*='mso-list']")) {
14049      if (claimed.has(paragraph) || this.#listLevel(paragraph) === null) continue
14050
14051      const run = [];
14052      let node = paragraph;
14053      while (node) {
14054        run.push(node);
14055        claimed.add(node);
14056        node = this.#nextListParagraph(node);
14057      }
14058      runs.push(run);
14059    }
14060
14061    return runs
14062  }
14063
14064  #nextListParagraph(paragraph) {
14065    let sibling = paragraph.nextSibling;
14066    while (sibling && this.#isIgnorableBetweenListParagraphs(sibling)) {
14067      sibling = sibling.nextSibling;
14068    }
14069
14070    if (sibling && sibling.nodeType === Node.ELEMENT_NODE && this.#listLevel(sibling) !== null) {
14071      return sibling
14072    }
14073
14074    return null
14075  }
14076
14077  #isIgnorableBetweenListParagraphs(node) {
14078    if (node.nodeType === Node.COMMENT_NODE) {
14079      return true
14080    }
14081    return node.nodeType === Node.TEXT_NODE && node.textContent.trim() === ""
14082  }
14083
14084  // Word numbers levels from 1, but a copied selection often starts partway down
14085  // a list, so every paragraph declares level3 with no level1 above it. Anchoring
14086  // the run at its own shallowest level is what keeps the result from arriving
14087  // needlessly deep.
14088  #replaceWithLists(paragraphs) {
14089    const levels = paragraphs.map((paragraph) => this.#listLevel(paragraph));
14090    const baseLevel = Math.min(...levels);
14091    const roots = [];
14092    const stack = [];
14093
14094    paragraphs.forEach((paragraph, index) => {
14095      const depth = levels[index] - baseLevel + 1;
14096      const tagName = this.#listTagName(paragraph);
14097
14098      while (stack.length > depth) {
14099        stack.pop();
14100      }
14101      if (stack.length === depth && stack[depth - 1].tagName !== tagName.toUpperCase()) {
14102        stack.pop();
14103      }
14104
14105      while (stack.length < depth) {
14106        const list = this.doc.createElement(tagName);
14107        if (stack.length === 0) {
14108          roots.push(list);
14109        } else {
14110          this.#lastItemOf(stack[stack.length - 1]).appendChild(list);
14111        }
14112        stack.push(list);
14113      }
14114
14115      stack[stack.length - 1].appendChild(this.#createListItem(paragraph));
14116    });
14117
14118    paragraphs[0].replaceWith(...roots);
14119    for (const paragraph of paragraphs.slice(1)) {
14120      paragraph.remove();
14121    }
14122  }
14123
14124  #lastItemOf(list) {
14125    if (!list.lastElementChild) {
14126      list.appendChild(this.doc.createElement("li"));
14127    }
14128    return list.lastElementChild
14129  }
14130
14131  // Word writes bullets as the raw glyph of the marker font (Symbol's "·",
14132  // Wingdings' "§", Courier New's "o") and numbers as the rendered counter
14133  // ("1.", "a)", "iv)"). A bare letter with no delimiter after it is Courier
14134  // New's bullet, not a counter, so the delimiter is what tells them apart.
14135  #listTagName(paragraph) {
14136    const marker = paragraph.querySelector("[style*='mso-list:Ignore']");
14137    const text = marker?.textContent || "";
14138
14139    if (/\d/.test(text) || /^\(?[A-Za-z]+[.)]/.test(text)) {
14140      return "ol"
14141    }
14142    return "ul"
14143  }
14144
14145  #createListItem(paragraph) {
14146    for (const marker of paragraph.querySelectorAll("[style*='mso-list:Ignore']")) {
14147      marker.remove();
14148    }
14149
14150    const item = this.doc.createElement("li");
14151    item.append(...paragraph.childNodes);
14152    return item
14153  }
14154
14155  #listLevel(element) {
14156    const match = /mso-list:[^;"']*\blevel(\d+)/.exec(element.getAttribute("style") || "");
14157    if (match) {
14158      return parseInt(match[1], 10)
14159    }
14160    return null
14161  }
14162}
14163
14164// Properties worth rescuing from a foreign style sheet before #stripStyleElements
14165// drops it, keyed by the elements that carry them. Word and Outlook declare
14166// paragraph spacing in the sheet (p.MsoNormal { margin: 0cm }) and never inline,
14167// so once the sheet goes there is nothing left to say how tightly the author's
14168// paragraphs sat, and hosts that turn pasted paragraph margins into explicit
14169// blank lines read tight Office paragraphs as spaced ones and multiply every
14170// line break.
14171const PRESERVABLE_STYLES = {
14172  p: [ "margin-top", "margin-bottom" ]
14173};
14174
14175class PastedContentFormatter {
14176  constructor(doc) {
14177    this.doc = doc;
14178  }
14179
14180  format() {
14181    this.#inlinePreservableStyles();
14182    this.#stripStyleElements();
14183    this.#unwrapPlaceholderAnchors();
14184    this.#stripTableCellColorStyles();
14185    new OfficeFormatter(this.doc).format();
14186    this.#unwrapWrappedListChildren();
14187    this.#nestStrayListChildren();
14188    this.#stripStrayListChildren();
14189    this.#replaceGmailEmojiImgTags();
14190    return this.doc
14191  }
14192
14193  // Runs before #stripStyleElements, to inline anything we still need
14194  // from an external style before we remove it
14195  #inlinePreservableStyles() {
14196    const rules = this.#styleRules();
14197    if (rules.length === 0) return
14198
14199    for (const [ selector, properties ] of Object.entries(PRESERVABLE_STYLES)) {
14200      for (const element of this.doc.querySelectorAll(selector)) {
14201        this.#inlineDeclaredStyles(element, properties, rules);
14202      }
14203    }
14204  }
14205
14206  // Spreadsheets (e.g. Excel) copy a <style> block whose rules (td { color:
14207  // black }, .xlNN { ... }) cascade onto the imported text. That color rides
14208  // in through the cascade rather than an inline style, so it slips past both
14209  // the cell-level stripping below and the paste style canonicalizer, leaving
14210  // pasted tables with foreign text colors that don't adapt to the theme. Drop
14211  // foreign style sheets so nothing cascades into imported content.
14212  #stripStyleElements() {
14213    for (const style of this.doc.querySelectorAll("style")) {
14214      style.remove();
14215    }
14216  }
14217
14218  // Anchors with non-meaningful hrefs (e.g. "#", "") appear in content copied
14219  // from rendered views where mentions and interactive elements are wrapped in
14220  // <a href="#"> tags. Unwrap them so their text content pastes as plain text
14221  // and real links are preserved.
14222  #unwrapPlaceholderAnchors() {
14223    for (const anchor of this.doc.querySelectorAll("a")) {
14224      const href = anchor.getAttribute("href") || "";
14225      if (href === "" || href === "#") {
14226        anchor.replaceWith(...anchor.childNodes);
14227      }
14228    }
14229  }
14230
14231  // Table cells copied from a page inherit the source theme's inline color
14232  // styles (e.g. dark-mode backgrounds). Strip them so pasted tables adopt
14233  // the current theme instead of carrying stale colors.
14234  #stripTableCellColorStyles() {
14235    for (const cell of this.doc.querySelectorAll("td, th")) {
14236      cell.style.removeProperty("background-color");
14237      cell.style.removeProperty("background");
14238      cell.style.removeProperty("color");
14239    }
14240  }
14241
14242  // Some sources wrap runs of <li>s in a stray element (e.g. a <div> directly
14243  // inside the list). Dissolve such wrappers so their items become direct
14244  // list children and any nested list they hide becomes visible to
14245  // #nestStrayListChildren below.
14246  #unwrapWrappedListChildren() {
14247    for (const list of this.doc.querySelectorAll("ol, ul")) {
14248      let wrapper = this.#wrappedListChild(list);
14249      while (wrapper) {
14250        wrapper.replaceWith(...wrapper.childNodes);
14251        wrapper = this.#wrappedListChild(list);
14252      }
14253    }
14254  }
14255
14256  #wrappedListChild(list) {
14257    for (const child of list.children) {
14258      if (child.tagName !== "LI" && !this.#isNestedList(child) && this.#containsListItems(child)) {
14259        return child
14260      }
14261    }
14262    return null
14263  }
14264
14265  // Some sources (e.g. Gmail) nest a sublist as a direct child of the parent
14266  // <ol>/<ul> instead of inside a <li>. Move each nested list into its
14267  // preceding <li> so the import preserves the nesting instead of dropping it.
14268  #nestStrayListChildren() {
14269    for (const list of this.doc.querySelectorAll("ol, ul")) {
14270      for (const child of Array.from(list.children)) {
14271        if (child.tagName !== "OL" && child.tagName !== "UL") continue
14272
14273        const previousItem = child.previousElementSibling;
14274        if (previousItem && previousItem.tagName === "LI") {
14275          previousItem.appendChild(child);
14276        }
14277      }
14278    }
14279  }
14280
14281  // Only <li> is a valid child of a list. Unwrap remaining stray children
14282  // that still hold list items (a nested list with no preceding <li> to nest
14283  // under) so the items survive, and drop stray <br>/whitespace so the import
14284  // doesn't wrap them into an empty leading item.
14285  #stripStrayListChildren() {
14286    for (const list of this.doc.querySelectorAll("ol, ul")) {
14287      let stray = this.#firstStrayListChild(list);
14288      while (stray) {
14289        if (this.#containsListItems(stray)) {
14290          stray.replaceWith(...stray.childNodes);
14291        } else {
14292          stray.remove();
14293        }
14294
14295        stray = this.#firstStrayListChild(list);
14296      }
14297    }
14298  }
14299
14300  // Read the rules from a sheet we build rather than from this.doc.styleSheets: the
14301  // document came from DOMParser, so it has no browsing context, and WebKit leaves
14302  // its styleSheets empty. Parsing the text ourselves still expands the shorthands
14303  // Word writes (margin: 0cm) into the longhands we ask for.
14304  #styleRules() {
14305    const css = Array.from(this.doc.querySelectorAll("style"), (style) => style.textContent).join("\n");
14306    if (css.trim() === "") return []
14307
14308    const sheet = new CSSStyleSheet();
14309    sheet.replaceSync(css);
14310
14311    const rules = [];
14312    for (const rule of sheet.cssRules) {
14313      if (rule instanceof CSSStyleRule) {
14314        rules.push(rule);
14315      }
14316    }
14317    return rules
14318  }
14319
14320  // A declaration the element already carries inline is the author's own and wins.
14321  #inlineDeclaredStyles(element, properties, rules) {
14322    for (const property of properties) {
14323      if (element.style.getPropertyValue(property) === "") {
14324        const value = this.#declaredValue(rules, element, property);
14325        if (value) {
14326          this.#appendStyleProperty(element, property, value);
14327        }
14328      }
14329    }
14330  }
14331
14332  // Source order alone doesn't decide the cascade, so when the matching rules
14333  // disagree we can't say which value wins without resolving specificity. Skip
14334  // the property rather than guess: guessing is permanent, since the sheet is
14335  // about to go, and skipping only leaves the host on its own default.
14336  #declaredValue(rules, element, property) {
14337    const declared = new Set();
14338    for (const rule of rules) {
14339      const value = rule.style.getPropertyValue(property);
14340      if (value !== "" && element.matches(rule.selectorText)) {
14341        declared.add(value);
14342      }
14343    }
14344
14345    if (declared.size === 1) {
14346      return declared.values().next().value
14347    } else {
14348      return null
14349    }
14350  }
14351
14352  // Assigning through element.style would reserialize the style attribute and
14353  // drop the mso-* declarations Word leaves inline (they aren't valid CSS),
14354  // and OfficeFormatter still needs to read mso-list from them. Append to the
14355  // attribute instead so the original declarations survive untouched.
14356  #appendStyleProperty(element, property, value) {
14357    const style = element.getAttribute("style");
14358    const declaration = `${property}:${value}`;
14359    if (style === null || style.trim() === "") {
14360      element.setAttribute("style", declaration);
14361    } else {
14362      element.setAttribute("style", `${style.replace(/;\s*$/, "")};${declaration}`);
14363    }
14364  }
14365
14366  #firstStrayListChild(list) {
14367    for (const child of list.childNodes) {
14368      if (child.nodeType !== Node.ELEMENT_NODE || child.tagName !== "LI") {
14369        return child
14370      }
14371    }
14372    return null
14373  }
14374
14375  #isNestedList(node) {
14376    return node.nodeType === Node.ELEMENT_NODE && (node.tagName === "OL" || node.tagName === "UL")
14377  }
14378
14379  #containsListItems(node) {
14380    return node.nodeType === Node.ELEMENT_NODE && node.querySelector("li") !== null
14381  }
14382
14383  // Emoji in gmail: <img data-emoji="😂" class="an1" alt="😂" aria-label="😂" draggable="false" src="https://fonts.gstatic.com/s/e/notoemoji/17.0/1f602/32.png" loading="lazy" style="height: 1.2em; width: 1.2em; vertical-align: middle;">
14384  #replaceGmailEmojiImgTags() {
14385    for (const emojiImg of this.doc.querySelectorAll("img[data-emoji]")) {
14386      const emoji = emojiImg.dataset.emoji;
14387      if (emoji === emojiImg.alt) {
14388        emojiImg.replaceWith(emoji);
14389      }
14390    }
14391  }
14392}
14393
14394class Contents {
14395  constructor(editorElement) {
14396    this.editorElement = editorElement;
14397    this.editor = editorElement.editor;
14398  }
14399
14400  dispose() {
14401    this.editorElement = null;
14402    this.editor = null;
14403  }
14404
14405  get selection() { return this.editorElement.selection }
14406
14407  insertHtml(html, { tag } = {}) {
14408    this.insertDOM(parseHtml(html), { tag });
14409  }
14410
14411  insertDOM(doc, { tag } = {}) {
14412    this.editor.update(() => {
14413      if (
vendor: 14,478 bytes, lines 14413-14929
14413Es(jn)) this.#formatPastedDOM(doc);
14414
14415      const nodes = this.editorElement.$generateNodesFromDOM(doc);
14416
14417      if (!Es(jn) || !this.#dispatchPastedNodesCommand(nodes)) {
14418        this.#insertUploadNodes(nodes) || this.insertAtCursor(...nodes);
14419      }
14420    }, { tag });
14421  }
14422
14423  insertText(text, { tag } = {}) {
14424    this.editor.update(() => {
14425      const paragraph = eo();
14426      text.split(/\r\n|\r|\n/).forEach((line, index) => {
14427        if (index > 0) paragraph.append(or());
14428        paragraph.append(kr(line));
14429      });
14430      this.insertAtCursor(paragraph);
14431    }, { tag });
14432  }
14433
14434  insertAtCursor(...nodes) {
14435    const selection = this.#insertableSelection();
14436    const inserter = BaseNodeInserter.for(selection);
14437
14438    inserter.insertNodes(nodes);
14439  }
14440
14441  applyParagraphFormat() {
14442    const selection = Qr();
14443    if (!Fr(selection)) return
14444
14445    $expandSelectionToLineBreaksAndSplitAtEdges(selection, (node) => Nt$2(node));
14446    H$6(selection, () => eo());
14447  }
14448
14449  applyHeadingFormat(tag) {
14450    const selection = Qr();
14451    if (!Fr(selection)) return
14452
14453    $expandSelectionToLineBreaksAndSplitAtEdges(selection);
14454    H$6(selection, () => Jt$2(tag));
14455  }
14456
14457  applyUnorderedListFormat() {
14458    this.#applyListFormat("bullet", Ee$2);
14459  }
14460
14461  applyOrderedListFormat() {
14462    this.#applyListFormat("number", Oe$1);
14463  }
14464
14465  clearFormatting() {
14466    const selection = Qr();
14467    if (!Fr(selection)) return
14468
14469    D$3(node => {
14470      node.setFormat(0);
14471      node.setStyle("");
14472    });
14473
14474    Q$6(null);
14475
14476    this.#topLevelElementsInSelection(selection).filter(Mt$2).forEach(node => this.#unwrap(node));
14477
14478    H$6(selection, () => eo());
14479  }
14480
14481  toggleCodeBlock() {
14482    const selection = Qr();
14483    if (!Fr(selection)) return
14484
14485    if (this.#insertNodeIfRoot(I$1("plain"))) return
14486
14487    const blockElements = this.#blockLevelElementsInSelection(selection);
14488    const allCode = blockElements.every(W$1);
14489
14490    if (allCode) {
14491      blockElements.forEach(node => this.#unwrapCodeBlock(node));
14492    } else {
14493      $expandSelectionToLineBreaksAndSplitAtEdges(selection);
14494      const elements = this.#outermostElements(this.#blockLevelElementsInSelection(selection));
14495      if (elements.length === 0) return
14496
14497      const codeNode = I$1("plain");
14498      elements.at(-1).insertAfter(codeNode);
14499      codeNode.selectEnd();
14500      this.insertAtCursor(...elements);
14501    }
14502  }
14503
14504  toggleBlockquote() {
14505    const selection = Qr();
14506    if (!Fr(selection)) return
14507
14508    if (this.#insertNodeIfRoot(St$1())) return
14509
14510    const topLevelElements = this.#topLevelElementsInSelection(selection);
14511
14512    const allQuoted = topLevelElements.length > 0 && topLevelElements.every(Mt$2);
14513
14514    if (allQuoted) {
14515      topLevelElements.forEach(node => this.#unwrap(node));
14516    } else {
14517      topLevelElements.filter(Mt$2).forEach(node => this.#unwrap(node));
14518
14519       $expandSelectionToLineBreaksAndSplitAtEdges(selection);
14520      const elements = this.#topLevelElementsInSelection(selection);
14521      if (elements.length === 0) return
14522
14523      const blockquote = St$1();
14524      elements[0].insertBefore(blockquote);
14525      elements.forEach((element) => blockquote.append(element));
14526    }
14527  }
14528
14529  hasSelectedText() {
14530    let result = false;
14531
14532    this.editor.read(() => {
14533      const selection = Qr();
14534      result = Fr(selection) && !selection.isCollapsed();
14535    });
14536
14537    return result
14538  }
14539
14540  createLink(url) {
14541    let linkNodeKey = null;
14542
14543    this.editor.update(() => {
14544      const textNode = kr(url);
14545      const linkNode = $$2(url);
14546      linkNode.append(textNode);
14547
14548      const selection = Qr();
14549      if (Fr(selection)) {
14550        BaseNodeInserter.for(selection).insertNodes([ linkNode ]);
14551        linkNodeKey = linkNode.getKey();
14552      }
14553    });
14554
14555    return linkNodeKey
14556  }
14557
14558  createLinkWithSelectedText(url) {
14559    if (!this.hasSelectedText()) return
14560
14561    this.editor.update(() => {
14562      Q$6(null);
14563      Q$6(url);
14564    });
14565  }
14566
14567  textBackUntil(string) {
14568    let result = "";
14569
14570    this.editor.getEditorState().read(() => {
14571      const selection = Qr();
14572      if (!selection || !selection.isCollapsed()) return
14573
14574      const anchor = selection.anchor;
14575      const anchorNode = anchor.getNode();
14576
14577      if (!Tr(anchorNode)) return
14578
14579      const fullText = anchorNode.getTextContent();
14580      const offset = anchor.offset;
14581
14582      const lastIndex = fullText.slice(0, offset).lastIndexOf(string);
14583      if (lastIndex !== -1) {
14584        result = fullText.slice(lastIndex + string.length, this.#endOffsetAt(fullText, offset));
14585      }
14586    });
14587
14588    return result
14589  }
14590
14591  // The query runs from the trigger up to the next boundary, even when the
14592  // cursor sits inside an existing word — inserting "@" before "Jack" must
14593  // filter by "Jack" rather than treating the prompt as empty.
14594  #endOffsetAt(fullText, cursorOffset) {
14595    for (let offset = cursorOffset; offset < fullText.length; offset++) {
14596      if (this.#isQueryBoundary(fullText, offset)) {
14597        return offset
14598      }
14599    }
14600
14601    return fullText.length
14602  }
14603
14604  // Whitespace always ends the query. Punctuation ends it too: with "@" typed
14605  // right before a period, extending across it would glue "." onto everything
14606  // typed ("B" would query "B."), matching the wrong names or nothing at all.
14607  // But punctuation joining two word characters is part of a name — "@" before
14608  // "Anne-Marie" or "O'Connor" must keep the whole name as the query.
14609  #isQueryBoundary(fullText, offset) {
14610    const character = fullText[offset];
14611    if (/\s/.test(character)) return true
14612    if (!/\p{P}/u.test(character)) return false
14613
14614    return !(this.#isWordCharacter(fullText[offset - 1]) && this.#isWordCharacter(fullText[offset + 1]))
14615  }
14616
14617  #isWordCharacter(character) {
14618    return character != null && /[\p{L}\p{N}]/u.test(character)
14619  }
14620
14621  containsTextBackUntil(string) {
14622    let result = false;
14623
14624    this.editor.getEditorState().read(() => {
14625      const selection = Qr();
14626      if (!selection || !selection.isCollapsed()) return
14627
14628      const anchor = selection.anchor;
14629      const anchorNode = anchor.getNode();
14630
14631      if (!Tr(anchorNode)) return
14632
14633      const fullText = anchorNode.getTextContent();
14634      const offset = anchor.offset;
14635
14636      const textBeforeCursor = fullText.slice(0, offset);
14637
14638      result = textBeforeCursor.includes(string);
14639    });
14640
14641    return result
14642  }
14643
14644  replaceTextBackUntil(stringToReplace, replacementNodes) {
14645    replacementNodes = Array.isArray(replacementNodes) ? replacementNodes : [ replacementNodes ];
14646
14647    const { anchorNode, offset } = this.#getTextAnchorData();
14648    if (!anchorNode) return
14649
14650    const lastIndex = this.#findReplacementStart(anchorNode, offset, stringToReplace);
14651    if (lastIndex === -1) return
14652
14653    this.#performTextReplacement(anchorNode, lastIndex, stringToReplace, replacementNodes);
14654  }
14655
14656  uploadFiles(files, { selectLast } = {}) {
14657    if (!this.editorElement) return // Disposed (e.g. on turbo:before-cache); a late drop can still land here
14658
14659    if (!this.editorElement.supportsAttachments) {
14660      console.warn("This editor does not supports attachments (it's configured with [attachments=false])");
14661      return
14662    }
14663    const validFiles = Array.from(files).filter(file => this.editorElement.acceptsFile(file));
14664
14665    this.editor.update(() => {
14666      const uploader = Uploader.for(this.editorElement, validFiles);
14667      uploader.$uploadFiles();
14668
14669      if (selectLast && uploader.nodes?.length) {
14670        const lastNode = uploader.nodes.at(-1);
14671        lastNode.selectEnd();
14672        this.#normalizeSelectionInShadowRoot();
14673      }
14674    });
14675  }
14676
14677  $createUploadNode(file) {
14678    return $createActionTextAttachmentUploadNode({
14679      file,
14680      uploadUrl: this.editorElement.directUploadUrl,
14681      blobUrlTemplate: this.editorElement.blobUrlTemplate,
14682      contentType: file.type,
14683    })
14684  }
14685
14686  $createPendingUploadNode(file) {
14687    return $createActionTextAttachmentUploadNode({
14688      file,
14689      uploadUrl: null,
14690      blobUrlTemplate: this.editorElement.blobUrlTemplate,
14691      contentType: file.type,
14692    })
14693  }
14694
14695  insertPendingAttachment(file) {
14696    if (!this.editorElement.supportsAttachments) return null
14697
14698    let nodeKey = null;
14699    this.editor.update(() => {
14700      const uploadNode = this.$createPendingUploadNode(file);
14701      this.insertAtCursor(uploadNode);
14702      nodeKey = uploadNode.getKey();
14703    });
14704
14705    return nodeKey ? this.#pendingAttachmentHandle(nodeKey) : null
14706  }
14707
14708  insertPendingAttachments(files) {
14709    const fileList = Array.from(files);
14710    if (!this.editorElement.supportsAttachments || fileList.length === 0) return []
14711
14712    let nodeKeys = [];
14713    this.editor.update(() => {
14714      const uploader = Uploader.for(this.editorElement, fileList, { pending: true });
14715      uploader.$uploadFiles();
14716      nodeKeys = (uploader.nodes ?? []).map(node => node.getKey());
14717    });
14718
14719    return nodeKeys.map(nodeKey => this.#pendingAttachmentHandle(nodeKey))
14720  }
14721
14722  #pendingAttachmentHandle(initialNodeKey) {
14723    const editor = this.editor;
14724    let nodeKey = initialNodeKey;
14725
14726    return {
14727      setAttributes(blob) {
14728        editor.update(() => {
14729          const node = Yo(nodeKey);
14730          if (!(node instanceof ActionTextAttachmentUploadNode)) return
14731
14732          const replacementNodeKey = node.$showUploadedAttachment(blob);
14733          if (replacementNodeKey) {
14734            nodeKey = replacementNodeKey;
14735          }
14736        }, { tag: Jn });
14737      },
14738      setUploadProgress(progress) {
14739        editor.update(() => {
14740          const node = Yo(nodeKey);
14741          if (!(node instanceof ActionTextAttachmentUploadNode)) return
14742
14743          node.getWritable().progress = progress;
14744        }, { tag: Jn });
14745      },
14746      remove() {
14747        editor.update(() => {
14748          const node = Yo(nodeKey);
14749          if (node) node.remove();
14750        });
14751      }
14752    }
14753  }
14754
14755  replaceNodeWithHTML(nodeKey, html, options = {}) {
14756    this.editor.update(() => {
14757      const node = Yo(nodeKey);
14758      if (!node) return
14759
14760      const selection = Qr();
14761      let wasSelected = false;
14762
14763      if (Fr(selection)) {
14764        const selectedNodes = selection.getNodes();
14765        wasSelected = selectedNodes.includes(node) || selectedNodes.some(n => n.getParent() === node);
14766
14767        if (wasSelected) {
14768          es(null);
14769        }
14770      }
14771
14772      const replacementNode = options.attachment ? this.#createCustomAttachmentNodeWithHtml(html, options.attachment) : this.#createHtmlNodeWith(html);
14773      node.replace(replacementNode);
14774
14775      if (wasSelected) {
14776        replacementNode.selectEnd();
14777      }
14778    });
14779  }
14780
14781  insertHTMLBelowNode(nodeKey, html, options = {}) {
14782    this.editor.update(() => {
14783      const node = Yo(nodeKey);
14784      if (!node) return
14785
14786      const previousNode = node.getTopLevelElement() || node;
14787
14788      const newNode = options.attachment ? this.#createCustomAttachmentNodeWithHtml(html, options.attachment) : this.#createHtmlNodeWith(html);
14789      previousNode.insertAfter(newNode);
14790    });
14791  }
14792
14793  #insertableSelection() {
14794    const selection = Qr();
14795    if (Ir(selection) && selection.getNodes().length === 0) {
14796      return Zo().selectEnd()
14797    }
14798
14799    return selection ?? Zo().selectEnd()
14800  }
14801
14802  #formatPastedDOM(doc) {
14803    new PastedContentFormatter(doc).format();
14804  }
14805
14806  #dispatchPastedNodesCommand(nodes) {
14807    return this.editor.dispatchCommand(oe$6, {
14808      nodes, selection: Qr()
14809    })
14810  }
14811
14812  #insertNodeIfRoot(node) {
14813    const selection = Qr();
14814    if (!Fr(selection)) return false
14815
14816    const anchorNode = selection.anchor.getNode();
14817    if (Is(anchorNode)) {
14818      anchorNode.append(node);
14819      node.selectEnd();
14820
14821      return true
14822    }
14823
14824    return false
14825  }
14826
14827  #unwrapCodeBlock(codeNode) {
14828    const children = codeNode.getChildren();
14829    const groups = [ [] ];
14830
14831    for (const child of children) {
14832      if (sr(child)) {
14833        groups.push([]);
14834      } else {
14835        groups[groups.length - 1].push(child.getTextContent());
14836      }
14837    }
14838
14839    for (const group of groups) {
14840      const paragraph = eo();
14841      const text = group.join("");
14842      if (text) {
14843        paragraph.append(kr(text));
14844      }
14845      codeNode.insertBefore(paragraph);
14846    }
14847
14848    codeNode.remove();
14849  }
14850
14851  #applyListFormat(listType, command) {
14852    if (this.selection.isInsideBlockQuote) {
14853      this.#insertListInsideQuote(listType);
14854    } else {
14855      this.#splitParagraphsAtLineBreaksUnlessInsideList();
14856      this.editor.dispatchCommand(command);
14857    }
14858  }
14859
14860  #insertListInsideQuote(listType) {
14861    for (const group of $consecutiveSiblingGroups(this.#quotedBlocksInSelection())) {
14862      this.#wrapBlocksInList(group, listType);
14863    }
14864  }
14865
14866  #quotedBlocksInSelection() {
14867    const selection = Qr();
14868    if (!Fr(selection)) return []
14869
14870    const blocks = this.#outermostElements(this.#blockLevelElementsInSelection(selection));
14871    return blocks.filter((block) => Mt$2(block.getParent()))
14872  }
14873
14874  #wrapBlocksInList(blocks, listType) {
14875    const list = Te$1(listType);
14876    blocks[0].insertBefore(list);
14877
14878    for (const block of blocks) {
14879      const listItem = fe$2();
14880      if (Se$1(block)) {
14881        listItem.append(...block.getChildren().flatMap((item) => item.getChildren()));
14882      } else {
14883        listItem.append(...block.getChildren());
14884      }
14885      list.append(listItem);
14886      block.remove();
14887    }
14888  }
14889
14890  #splitParagraphsAtLineBreaksUnlessInsideList() {
14891    if (this.selection.isInsideList) return
14892
14893    const selection = Qr();
14894    if (!Fr(selection)) return
14895
14896    $expandSelectionToLineBreaksAndSplitAtEdges(selection);
14897    $splitSelectedParagraphsAtInnerLineBreaks(selection);
14898  }
14899
14900  #blockLevelElementsInSelection(selection) {
14901    const blocks = new Set();
14902    for (const node of selection.getNodes()) {
14903      blocks.add(Nt$2(node));
14904    }
14905
14906    return Array.from(blocks)
14907  }
14908
14909  #topLevelElementsInSelection(selection) {
14910    const elements = new Set();
14911    for (const node of selection.getNodes()) {
14912      const topLevel = node.getTopLevelElement();
14913      if (topLevel) elements.add(topLevel);
14914    }
14915    return Array.from(elements)
14916  }
14917
14918  // Selections spanning nested structures (a quote and its inner paragraphs,
14919  // nested list items) yield both an element and its ancestor. Converting the
14920  // ancestor detaches its whole subtree — including a node freshly inserted
14921  // inside it — which can leave the selection on removed nodes (Lexical
14922  // invariant #19). The outermost elements already cover their descendants'
14923  // text content, so keep only those.
14924  #outermostElements(elements) {
14925    return elements.filter((element) => {
14926      return elements.every((other) => other === element || !element.getParents().includes(other))
14927    })
14928  }
14929
14930  #insertUploadNodes(nodes) {
14931    if (nodes.every($isActionTextAttachmentNode)) {
14932      const uploader = Uploader.for(this.editorElement, []);
14933      uploader.nodes = nodes;
14934      uploader.$insertUploadNodes();
14935      return true
14936    }
14937  }
14938
14939  #unwrap(node) {
14940    const children = node.getChildren();
14941
14942    if (children.length == 0) {
14943      node.insertBefore(eo());
14944    } else {
14945      children.forEach((child) => {
14946        if (Tr(child) && child.getTextContent().trim() !== "") {
14947          const newParagraph = eo();
14948          newParagraph.append(child);
14949          node.insertBefore(newParagraph);
14950        } else if (!sr(child)) {
14951          node.insertBefore(child);
14952        }
14953      });
14954    }
14955
14956    node.remove();
14957  }
14958
14959  #getTextAnchorData() {
14960    const selection = Qr();
14961    if (!selection || !selection.isCollapsed()) return { anchorNode: null, offset: 0 }
14962
14963    const anchor = selection.anchor;
14964    const anchorNode = anchor.getNode();
14965
14966    if (!Tr(anchorNode)) return { anchorNode: null, offset: 0 }
14967
14968    return { anchorNode, offset: anchor.offset }
14969  }
14970
14971  // The replaced span must start before the cursor but can extend past it
14972  // (e.g. "@Jack" when "@" was just inserted before "Jack"), so we bound the
14973  // match's start with lastIndexOf's fromIndex rather than slicing the text.
14974  #findReplacementStart(anchorNode, offset, stringToReplace) {
14975    if (offset === 0) {
14976      // A negative fromIndex clamps to 0 and could match at the cursor
14977      return -1
14978    } else {
14979      return anchorNode.getTextContent().lastIndexOf(stringToReplace, offset - 1)
14980    }
14981  }
14982
14983  #performTextReplacement(anchorNode, startIndex, stringToReplace, replacementNodes) {
14984    const fullText = anchorNode.getTextContent();
14985    const textBeforeString = fullText.slice(0, startIndex);
14986    const textAfterString = fullText.slice(startIndex + stringToReplace.length);
14987
14988    const textNodeBefore = this.#cloneTextNodeFormatting(anchorNode, textBeforeString);
14989    const textNodeAfter = this.#cloneTextNodeFormatting(anchorNode, textAfterString || " ");
14990
14991    anchorNode.replace(textNodeBefore);
14992
14993    const lastInsertedNode = this.#insertReplacementNodes(textNodeBefore, replacementNodes);
14994    lastInsertedNode.insertAfter(textNodeAfter);
14995
14996    this.#appendLineBreakIfNeeded(textNodeAfter.getParentOrThrow());
14997    const cursorOffset = textAfterString ? 0 : 1;
14998    textNodeAfter.select(cursorOffset, cursorOffset);
14999  }
15000
15001  #cloneTextNodeFormatting(anchorNode, text) {
15002    return kr(text)
15003      .setFormat(anchorNode.getFormat())
15004      .setDetail(anchorNode.getDetail())
15005      .setMode(anchorNode.getMode())
15006      .setStyle(anchorNode.getStyle())
15007  }
15008
15009  #insertReplacementNodes(startNode, replacementNodes) {
15010    let previousNode = startNode;
15011    for (const node of replacementNodes) {
15012      previousNode.insertAfter(node);
15013      previousNode = node;
15014    }
15015    return previousNode
15016  }
15017
15018  #appendLineBreakIfNeeded(paragraph) {
15019    if (no(paragraph) && this.editorElement.supportsMultiLine) {
15020      const children = paragraph.getChildren();
15021      const last = children[children.length - 1];
15022      const beforeLast = children[children.length - 2];
15023
15024      if (Tr(last) && last.getTextContent() === "" && (beforeLast && !Tr(beforeLast))) {
15025        paragraph.append(or());
15026      }
15027    }
15028  }
15029
15030  #createCustomAttachmentNodeWithHtml(html, options = {}) {
15031    const attachmentConfig = typeof options === "object" ? options : {};
15032    const contentType = attachmentConfig.contentType || "text/html";
15033    if (!this.editorElement.permitsAttachmentContentType(contentType)) {
15034      return this.#createHtmlNodeWith(html)
15035    }
15036    return new CustomActionTextAttachmentNode({
15037      sgid: attachmentConfig.sgid || null,
15038      contentType,
15039      innerHtml: html,
15040    })
15041  }
15042
15043  #createHtmlNodeWith(html) {
15044    const htmlNodes = this.editorElement.$generateNodesFromDOM(parseHtml(html));
15045    return htmlNodes[0] || eo()
15046  }
15047
15048  // When the selection anchor is on a shadow root (e.g. a table cell), Lexical's
15049  // insertNodes can't find a block parent and fails silently. Normalize the
15050  // selection to point inside the shadow root's content instead.
15051  #normalizeSelectionInShadowRoot() {
15052    const selection = Qr();
15053    if (!Fr(selection)) return
15054
15055    const anchorNode = selection.anchor.getNode();
15056    if (!$isShadowRoot(anchorNode)) return
15057
15058    // Append a paragraph inside the shadow root so there's a valid text-level
15059    // target for subsequent insertions. This is necessary because decorator
15060    // nodes (e.g. attachments) at the end of a table cell leave the selection
15061    // on the cell itself with no block-level descendant to anchor to.
15062    const paragraph = eo();
15063    anchorNode.append(paragraph);
15064    paragraph.selectStart();
15065  }
15066}
15067
15068/**
15069 * marked v16.4.1 - a markdown parser
15070 * Copyright (c) 2011-2025, Christopher Jeffrey. (MIT Licensed)
15071 * https://github.com/markedjs/marked
15072 */
15073
15074/**
15075 * DO NOT EDIT THIS FILE
15076 * The code in this file is generated from files in ./src/
15077 */
15078
15079function L(){return {async:false,breaks:false,extensions:null,gfm:true,hooks:null,pedantic:false,renderer:null,silent:false,tokenizer:null,walkTokens:null}}var T=L();function G(u){T=u;}var I={exec:()=>null};function h(u,e=""){let t=typeof u=="string"?u:u.source,n={replace:(r,i)=>{let s=typeof i=="string"?i:i.source;return s=s.replace(m.caret,"$1"),t=t.replace(r,s),n},getRegex:()=>new RegExp(t,e)};return n}var m={codeRemoveIndent:/^(?: {1,4}| {0,3}\t)/gm,outputLinkReplace:/\\([\[\]])/g,indentCodeCompensation:/^(\s+)(?:```)/,beginningSpace:/^\s+/,endingHash:/#$/,startingSpaceChar:/^ /,endingSpaceChar:/ $/,nonSpaceChar:/[^ ]/,newLineCharGlobal:/\n/g,tabCharGlobal:/\t/g,multipleSpaceGlobal:/\s+/g,blankLine:/^[ \t]*$/,doubleBlankLine:/\n[ \t]*\n[ \t]*$/,blockquoteStart:/^ {0,3}>/,blockquoteSetextReplace:/\n {0,3}((?:=+|-+) *)(?=\n|$)/g,blockquoteSetextReplace2:/^ {0,3}>[ \t]?/gm,listReplaceTabs:/^\t+/,listReplaceNesting:/^ {1,4}(?=( {4})*[^ ])/g,listIsTask:/^\[[ xX]\] /,listReplaceTask:/^\[[ xX]\] +/,anyLine
vendor: 4,627 bytes, line 15079
15079:/\n.*\n/,hrefBrackets:/^<(.*)>$/,tableDelimiter:/[:|]/,tableAlignChars:/^\||\| *$/g,tableRowBlankLine:/\n[ \t]*$/,tableAlignRight:/^ *-+: *$/,tableAlignCenter:/^ *:-+: *$/,tableAlignLeft:/^ *:-+ *$/,startATag:/^<a /i,endATag:/^<\/a>/i,startPreScriptTag:/^<(pre|code|kbd|script)(\s|>)/i,endPreScriptTag:/^<\/(pre|code|kbd|script)(\s|>)/i,startAngleBracket:/^</,endAngleBracket:/>$/,pedanticHrefTitle:/^([^'"]*[^\s])\s+(['"])(.*)\2/,unicodeAlphaNumeric:/[\p{L}\p{N}]/u,escapeTest:/[&<>"']/,escapeReplace:/[&<>"']/g,escapeTestNoEncode:/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/,escapeReplaceNoEncode:/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/g,unescapeTest:/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig,caret:/(^|[^\[])\^/g,percentDecode:/%25/g,findPipe:/\|/g,splitPipe:/ \|/,slashPipe:/\\\|/g,carriageReturn:/\r\n|\r/g,spaceLine:/^ +$/gm,notSpaceStart:/^\S*/,endingNewline:/\n$/,listItemRegex:u=>new RegExp(`^( {0,3}${u})((?:[	 ][^\\n]*)?(?:\\n|$))`),nextBulletRegex:u=>new RegExp(`^ {0,${Math.min(3,u-1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ 	][^\\n]*)?(?:\\n|$))`),hrRegex:u=>new RegExp(`^ {0,${Math.min(3,u-1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`),fencesBeginRegex:u=>new RegExp(`^ {0,${Math.min(3,u-1)}}(?:\`\`\`|~~~)`),headingBeginRegex:u=>new RegExp(`^ {0,${Math.min(3,u-1)}}#`),htmlBeginRegex:u=>new RegExp(`^ {0,${Math.min(3,u-1)}}<(?:[a-z].*>|!--)`,"i")},be=/^(?:[ \t]*(?:\n|$))+/,Re=/^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/,Te=/^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/,E=/^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,Oe=/^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,F=/(?:[*+-]|\d{1,9}[.)])/,ie=/^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/,oe=h(ie).replace(/bull/g,F).replace(/blockCode/g,/(?: {4}| {0,3}\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}/).replace(/html/g,/ {0,3}<[^\n>]+>\n/).replace(/\|table/g,"").getRegex(),we=h(ie).replace(/bull/g,F).replace(/blockCode/g,/(?: {4}| {0,3}\t)/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}/).replace(/html/g,/ {0,3}<[^\n>]+>\n/).replace(/table/g,/ {0,3}\|?(?:[:\- ]*\|)+[\:\- ]*\n/).getRegex(),j=/^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,ye=/^[^\n]+/,Q=/(?!\s*\])(?:\\[\s\S]|[^\[\]\\])+/,Pe=h(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace("label",Q).replace("title",/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex(),Se=h(/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/).replace(/bull/g,F).getRegex(),v="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",U=/<!--(?:-?>|[\s\S]*?(?:-->|$))/,$e=h("^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|<![A-Z][\\s\\S]*?(?:>\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n[ 	]*)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ 	]*)+\\n|$)|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ 	]*)+\\n|$))","i").replace("comment",U).replace("tag",v).replace("attribute",/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),ae=h(j).replace("hr",E).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("|lheading","").replace("|table","").replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html","</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",v).getRegex(),_e=h(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph",ae).getRegex(),K={blockquote:_e,code:Re,def:Pe,fences:Te,heading:Oe,hr:E,html:$e,lheading:oe,list:Se,newline:be,paragraph:ae,table:I,text:ye},re=h("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr",E
vendor: 7,033 bytes, lines 15079-15081
15079).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("blockquote"," {0,3}>").replace("code","(?: {4}| {0,3}	)[^\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html","</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",v).getRegex(),Le={...K,lheading:we,table:re,paragraph:h(j).replace("hr",E).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("|lheading","").replace("table",re).replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html","</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",v).getRegex()},Me={...K,html:h(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:"[^"]*"|'[^']*'|\\s[^'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace("comment",U).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),def:/^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,heading:/^(#{1,6})(.*)(?:\n+|$)/,fences:I,lheading:/^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,paragraph:h(j).replace("hr",E).replace("heading",` *#{1,6} *[^
15080]`).replace("lheading",oe).replace("|table","").replace("blockquote"," {0,3}>").replace("|fences","").replace("|list","").replace("|html","").replace("|tag","").getRegex()},ze=/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,Ae=/^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,le=/^( {2,}|\\)\n(?!\s*$)/,Ie=/^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/,D=/[\p{P}\p{S}]/u,W=/[\s\p{P}\p{S}]/u,ue=/[^\s\p{P}\p{S}]/u,Ee=h(/^((?![*_])punctSpace)/,"u").replace(/punctSpace/g,W).getRegex(),pe=/(?!~)[\p{P}\p{S}]/u,Ce=/(?!~)[\s\p{P}\p{S}]/u,Be=/(?:[^\s\p{P}\p{S}]|~)/u,qe=h(/link|code|html/,"g").replace("link",/\[(?:[^\[\]`]|(?<!`)(?<a>`+)[^`]+\k<a>(?!`))*?\]\((?:\\[\s\S]|[^\\\(\)]|\((?:\\[\s\S]|[^\\\(\)])*\))*\)/).replace("code",/(?<!`)(?<b>`+)[^`]+\k<b>(?!`)/).replace("html",/<(?! )[^<>]*?>/).getRegex(),ce=/^(?:\*+(?:((?!\*)punct)|[^\s*]))|^_+(?:((?!_)punct)|([^\s_]))/,ve=h(ce,"u").replace(/punct/g,D).getRegex(),De=h(ce,"u").replace(/punct/g,pe).getRegex(),he="^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)punct(\\*+)(?=[\\s]|$)|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)|[\\s](\\*+)(?!\\*)(?=punct)|(?!\\*)punct(\\*+)(?!\\*)(?=punct)|notPunctSpace(\\*+)(?=notPunctSpace)",He=h(he,"gu").replace(/notPunctSpace/g,ue).replace(/punctSpace/g,W).replace(/punct/g,D).getRegex(),Ze=h(he,"gu").replace(/notPunctSpace/g,Be).replace(/punctSpace/g,Ce).replace(/punct/g,pe).getRegex(),Ge=h("^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)","gu").replace(/notPunctSpace/g,ue).replace(/punctSpace/g,W).replace(/punct/g,D).getRegex(),Ne=h(/\\(punct)/,"gu").replace(/punct/g,D).getRegex(),Fe=h(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace("scheme",/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email",/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex(),je=h(U).replace("(?:-->|$)","-->").getRegex(),Qe=h("^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>").replace("comment",je).replace("attribute",/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex(),q=/(?:\[(?:\\[\s\S]|[^\[\]\\])*\]|\\[\s\S]|`+[^`]*?`+(?!`)|[^\[\]\\`])*?/,Ue=h(/^!?\[(label)\]\(\s*(href)(?:(?:[ \t]*(?:\n[ \t]*)?)(title))?\s*\)/).replace("label",q).replace("href",/<(?:\\.|[^\n<>\\])+>|[^ \t\n\x00-\x1f]*/).replace("title",/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex(),de=h(/^!?\[(label)\]\[(ref)\]/).replace("label",q).replace("ref",Q).getRegex(),ke=h(/^!?\[(ref)\](?:\[\])?/).replace("ref",Q).getRegex(),Ke=h("reflink|nolink(?!\\()","g").replace("reflink",de).replace("nolink",ke).getRegex(),se=/[hH][tT][tT][pP][sS]?|[fF][tT][pP]/,X={_backpedal:I,anyPunctuation:Ne,autolink:Fe,blockSkip:qe,br:le,code:Ae,del:I,emStrongLDelim:ve,emStrongRDelimAst:He,emStrongRDelimUnd:Ge,escape:ze,link:Ue,nolink:ke,punctuation:Ee,reflink:de,reflinkSearch:Ke,tag:Qe,text:Ie,url:I},We={...X,link:h(/^!?\[(label)\]\((.*?)\)/).replace("label",q).getRegex(),reflink:h(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label",q).getRegex()},N={...X,emStrongRDelimAst:Ze,emStrongLDelim:De,url:h(/^((?:protocol):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/).replace("protocol",se).replace("email",/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(),_backpedal:/(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,del:/^(~~?)(?=[^\s~])((?:\\[\s\S]|[^\\])*?(?:\\[\s\S]|[^\s~\\]))\1(?=[^~]|$)/,text:h(/^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|protocol:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/).replace("protocol",se).getRegex()},Xe={...N,br:h(le).replace("{2,}","*").getRegex(),text:h(N.text).replace("\\b_","\\b_| {2,}\\n").replace(/\{2,\}/g,"*").getRegex()},C={normal:K,gfm:Le,pedantic:Me},M={normal:X,gfm:N,breaks:Xe,pedantic:We};var Je={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"},ge=u=>Je[u];function w(u,e){if(e){if(m.escapeTest.test(u))return u.replace(m.escapeReplace,ge)}else if(m.escapeTestNoEncode.test(u))return u.replace(m.escapeReplaceNoEncode,ge);return u}function J(u){try{u=encodeURI(u).replace(m.percentDecode,"%");}catch{return null}return u}function V(u,e){let t=u.replace(m.findPipe,(i,s,o)=>{let a=false,l=s;for(;--l>=0&&o[l]==="\\";)a=!a;return a?"|":" |"}),n=t.split(m.splitPipe),r=0;if(n[0].trim()||n.shift(),n.length>0&&!n.at(-1)?.trim()&&n.pop(),e)if(n.length>e)n.splice(e);else for(;n.length<e;)n.push("");for(;r<n.length;r++)n[r]=n[r].trim().replace(m.slashPipe,"|");return n}function z(u,e,t){let n=u.length;if(n===0)return "";let r=0;for(;r<n;){let i=u.charAt(n-r-1);if(i===e&&true)r++;else break}return u.slice(0,n-r)}function fe(u,e){if(u.indexOf(e[1])===-1)return  -1;let t=0;for(let n=0;n<u.length;n++)if(u[n]==="\\")n++;else if(u[n]===e[0])t++;else if(u[n]===e[1]&&(t--,t<0))return n;return t>0?-2:-1}function me(u,e,t,n,r){let i=e.href,s=e.title||null,o=u[1].replace(r.other.outputLinkReplace,"$1");n.state.inLink=true;let a={type:u[0].charAt(0)==="!"?"image":"link",raw:t,href:i,title:s,text:o,tokens:n.inlineTokens(o)};return n.state.inLink=false,a}function Ve(u,e,t){let n=u.match(t.other.indentCodeCompensation);if(n===null)return e;let r=n[1];return e.split(`
15081`).map(i=>{let s=i.match(t.other.beginningSpace);if(s===null)return i;let[o]=s;return o.length>
vendor: 6,982 bytes, lines 15081-15104
15081=r.length?i.slice(r.length):i}).join(`
15082`)}var y=class{options;rules;lexer;constructor(e){this.options=e||T;}space(e){let t=this.rules.block.newline.exec(e);if(t&&t[0].length>0)return {type:"space",raw:t[0]}}code(e){let t=this.rules.block.code.exec(e);if(t){let n=t[0].replace(this.rules.other.codeRemoveIndent,"");return {type:"code",raw:t[0],codeBlockStyle:"indented",text:this.options.pedantic?n:z(n,`
15083`)}}}fences(e){let t=this.rules.block.fences.exec(e);if(t){let n=t[0],r=Ve(n,t[3]||"",this.rules);return {type:"code",raw:n,lang:t[2]?t[2].trim().replace(this.rules.inline.anyPunctuation,"$1"):t[2],text:r}}}heading(e){let t=this.rules.block.heading.exec(e);if(t){let n=t[2].trim();if(this.rules.other.endingHash.test(n)){let r=z(n,"#");(this.options.pedantic||!r||this.rules.other.endingSpaceChar.test(r))&&(n=r.trim());}return {type:"heading",raw:t[0],depth:t[1].length,text:n,tokens:this.lexer.inline(n)}}}hr(e){let t=this.rules.block.hr.exec(e);if(t)return {type:"hr",raw:z(t[0],`
15084`)}}blockquote(e){let t=this.rules.block.blockquote.exec(e);if(t){let n=z(t[0],`
15085`).split(`
15086`),r="",i="",s=[];for(;n.length>0;){let o=false,a=[],l;for(l=0;l<n.length;l++)if(this.rules.other.blockquoteStart.test(n[l]))a.push(n[l]),o=true;else if(!o)a.push(n[l]);else break;n=n.slice(l);let c=a.join(`
15087`),p=c.replace(this.rules.other.blockquoteSetextReplace,`
15088    $1`).replace(this.rules.other.blockquoteSetextReplace2,"");r=r?`${r}
15089${c}`:c,i=i?`${i}
15090${p}`:p;let g=this.lexer.state.top;if(this.lexer.state.top=true,this.lexer.blockTokens(p,s,true),this.lexer.state.top=g,n.length===0)break;let d=s.at(-1);if(d?.type==="code")break;if(d?.type==="blockquote"){let R=d,f=R.raw+`
15091`+n.join(`
15092`),O=this.blockquote(f);s[s.length-1]=O,r=r.substring(0,r.length-R.raw.length)+O.raw,i=i.substring(0,i.length-R.text.length)+O.text;break}else if(d?.type==="list"){let R=d,f=R.raw+`
15093`+n.join(`
15094`),O=this.list(f);s[s.length-1]=O,r=r.substring(0,r.length-d.raw.length)+O.raw,i=i.substring(0,i.length-R.raw.length)+O.raw,n=f.substring(s.at(-1).raw.length).split(`
15095`);continue}}return {type:"blockquote",raw:r,tokens:s,text:i}}}list(e){let t=this.rules.block.list.exec(e);if(t){let n=t[1].trim(),r=n.length>1,i={type:"list",raw:"",ordered:r,start:r?+n.slice(0,-1):"",loose:false,items:[]};n=r?`\\d{1,9}\\${n.slice(-1)}`:`\\${n}`,this.options.pedantic&&(n=r?n:"[*+-]");let s=this.rules.other.listItemRegex(n),o=false;for(;e;){let l=false,c="",p="";if(!(t=s.exec(e))||this.rules.block.hr.test(e))break;c=t[0],e=e.substring(c.length);let g=t[2].split(`
15096`,1)[0].replace(this.rules.other.listReplaceTabs,H=>" ".repeat(3*H.length)),d=e.split(`
15097`,1)[0],R=!g.trim(),f=0;if(this.options.pedantic?(f=2,p=g.trimStart()):R?f=t[1].length+1:(f=t[2].search(this.rules.other.nonSpaceChar),f=f>4?1:f,p=g.slice(f),f+=t[1].length),R&&this.rules.other.blankLine.test(d)&&(c+=d+`
15098`,e=e.substring(d.length+1),l=true),!l){let H=this.rules.other.nextBulletRegex(f),ee=this.rules.other.hrRegex(f),te=this.rules.other.fencesBeginRegex(f),ne=this.rules.other.headingBeginRegex(f),xe=this.rules.other.htmlBeginRegex(f);for(;e;){let Z=e.split(`
15099`,1)[0],A;if(d=Z,this.options.pedantic?(d=d.replace(this.rules.other.listReplaceNesting,"  "),A=d):A=d.replace(this.rules.other.tabCharGlobal,"    "),te.test(d)||ne.test(d)||xe.test(d)||H.test(d)||ee.test(d))break;if(A.search(this.rules.other.nonSpaceChar)>=f||!d.trim())p+=`
15100`+A.slice(f);else {if(R||g.replace(this.rules.other.tabCharGlobal,"    ").search(this.rules.other.nonSpaceChar)>=4||te.test(g)||ne.test(g)||ee.test(g))break;p+=`
15101`+d;}!R&&!d.trim()&&(R=true),c+=Z+`
15102`,e=e.substring(Z.length+1),g=A.slice(f);}}i.loose||(o?i.loose=true:this.rules.other.doubleBlankLine.test(c)&&(o=true));let O=null,Y;this.options.gfm&&(O=this.rules.other.listIsTask.exec(p),O&&(Y=O[0]!=="[ ] ",p=p.replace(this.rules.other.listReplaceTask,""))),i.items.push({type:"list_item",raw:c,task:!!O,checked:Y,loose:false,text:p,tokens:[]}),i.raw+=c;}let a=i.items.at(-1);if(a)a.raw=a.raw.trimEnd(),a.text=a.text.trimEnd();else return;i.raw=i.raw.trimEnd();for(let l=0;l<i.items.length;l++)if(this.lexer.state.top=false,i.items[l].tokens=this.lexer.blockTokens(i.items[l].text,[]),!i.loose){let c=i.items[l].tokens.filter(g=>g.type==="space"),p=c.length>0&&c.some(g=>this.rules.other.anyLine.test(g.raw));i.loose=p;}if(i.loose)for(let l=0;l<i.items.length;l++)i.items[l].loose=true;return i}}html(e){let t=this.rules.block.html.exec(e);if(t)return {type:"html",block:true,raw:t[0],pre:t[1]==="pre"||t[1]==="script"||t[1]==="style",text:t[0]}}def(e){let t=this.rules.block.def.exec(e);if(t){let n=t[1].toLowerCase().replace(this.rules.other.multipleSpaceGlobal," "),r=t[2]?t[2].replace(this.rules.other.hrefBrackets,"$1").replace(this.rules.inline.anyPunctuation,"$1"):"",i=t[3]?t[3].substring(1,t[3].length-1).replace(this.rules.inline.anyPunctuation,"$1"):t[3];return {type:"def",tag:n,raw:t[0],href:r,title:i}}}table(e){let t=this.rules.block.table.exec(e);if(!t||!this.rules.other.tableDelimiter.test(t[2]))return;let n=V(t[1]),r=t[2].replace(this.rules.other.tableAlignChars,"").split("|"),i=t[3]?.trim()?t[3].replace(this.rules.other.tableRowBlankLine,"").split(`
15103`):[],s={type:"table",raw:t[0],header:[],align:[],rows:[]};if(n.length===r.length){for(let o of r)this.rules.other.tableAlignRight.test(o)?s.align.push("right"):this.rules.other.tableAlignCenter.test(o)?s.align.push("center"):this.rules.other.tableAlignLeft.test(o)?s.align.push("left"):s.align.push(null);for(let o=0;o<n.length;o++)s.header.push({text:n[o],tokens:this.lexer.inline(n[o]),header:true,align:s.align[o]});for(let o of i)s.rows.push(V(o,s.header.length).map((a,l)=>({text:a,tokens:this.lexer.inline(a),header:false,align:s.align[l]})));return s}}lheading(e){let t=this.rules.block.lheading.exec(e);if(t)return {type:"heading",raw:t[0],depth:t[2].charAt(0)==="="?1:2,text:t[1],tokens:this.lexer.inline(t[1])}}paragraph(e){let t=this.rules.block.paragraph.exec(e);if(t){let n=t[1].charAt(t[1].length-1)===`
15104`?t[1].slice(0,-1):t[1];return {type:"paragraph",raw:t[0],text:n,tokens:this.lexer.inline(n)}}}text(e){let t=this.rules.block.text.exec(e);if(t)return {type:"text",raw:t[0],text:t[0],tokens:this.lexer.inline(t[0])}}escape(e){let t=this.rules.inline.escape.exec(e);if(t)return {type:"escape",raw:t[0],text:t[1]}}tag(e){let t=this.rules.inline.tag.exec(e);if(t)return !this.lexer.state.inLink&&this.rules.other.startATag.test(t[0])?this.lexer.state.inLink=true:this.lexer.state.inLink&&this.rules.other.endATag.test(t[0])&&(this.lexer.state.inLink=false),!this.lexer.state.inRawBlock&&this.rules.other.startPreScriptTag.test(t[0])?this.lexer.state.inRawBlock=true:this.lexer.state.inRawBlock&&this.rules.other.endPreScriptTag.test(t[0])&&(this.lexer.state.inRawBlock=false),{type:"html",raw:t[0],inLink:this.lexer.state.inLink,inRawBlock:this.lexer.state.inRawBlock,block:false,text:t[0]}}link(e){let t=this.rules.inline.link.exec(e);if(t){let n=t[2].trim();if(!this.options.pedantic&&this.rules.other.startAngleBracket.test(n)){if
vendor: 19,520 bytes, lines 15104-15138
15104(!this.rules.other.endAngleBracket.test(n))return;let s=z(n.slice(0,-1),"\\");if((n.length-s.length)%2===0)return}else {let s=fe(t[2],"()");if(s===-2)return;if(s>-1){let a=(t[0].indexOf("!")===0?5:4)+t[1].length+s;t[2]=t[2].substring(0,s),t[0]=t[0].substring(0,a).trim(),t[3]="";}}let r=t[2],i="";if(this.options.pedantic){let s=this.rules.other.pedanticHrefTitle.exec(r);s&&(r=s[1],i=s[3]);}else i=t[3]?t[3].slice(1,-1):"";return r=r.trim(),this.rules.other.startAngleBracket.test(r)&&(this.options.pedantic&&!this.rules.other.endAngleBracket.test(n)?r=r.slice(1):r=r.slice(1,-1)),me(t,{href:r&&r.replace(this.rules.inline.anyPunctuation,"$1"),title:i&&i.replace(this.rules.inline.anyPunctuation,"$1")},t[0],this.lexer,this.rules)}}reflink(e,t){let n;if((n=this.rules.inline.reflink.exec(e))||(n=this.rules.inline.nolink.exec(e))){let r=(n[2]||n[1]).replace(this.rules.other.multipleSpaceGlobal," "),i=t[r.toLowerCase()];if(!i){let s=n[0].charAt(0);return {type:"text",raw:s,text:s}}return me(n,i,n[0],this.lexer,this.rules)}}emStrong(e,t,n=""){let r=this.rules.inline.emStrongLDelim.exec(e);if(!r||r[3]&&n.match(this.rules.other.unicodeAlphaNumeric))return;if(!(r[1]||r[2]||"")||!n||this.rules.inline.punctuation.exec(n)){let s=[...r[0]].length-1,o,a,l=s,c=0,p=r[0][0]==="*"?this.rules.inline.emStrongRDelimAst:this.rules.inline.emStrongRDelimUnd;for(p.lastIndex=0,t=t.slice(-1*e.length+s);(r=p.exec(t))!=null;){if(o=r[1]||r[2]||r[3]||r[4]||r[5]||r[6],!o)continue;if(a=[...o].length,r[3]||r[4]){l+=a;continue}else if((r[5]||r[6])&&s%3&&!((s+a)%3)){c+=a;continue}if(l-=a,l>0)continue;a=Math.min(a,a+l+c);let g=[...r[0]][0].length,d=e.slice(0,s+r.index+g+a);if(Math.min(s,a)%2){let f=d.slice(1,-1);return {type:"em",raw:d,text:f,tokens:this.lexer.inlineTokens(f)}}let R=d.slice(2,-2);return {type:"strong",raw:d,text:R,tokens:this.lexer.inlineTokens(R)}}}}codespan(e){let t=this.rules.inline.code.exec(e);if(t){let n=t[2].replace(this.rules.other.newLineCharGlobal," "),r=this.rules.other.nonSpaceChar.test(n),i=this.rules.other.startingSpaceChar.test(n)&&this.rules.other.endingSpaceChar.test(n);return r&&i&&(n=n.substring(1,n.length-1)),{type:"codespan",raw:t[0],text:n}}}br(e){let t=this.rules.inline.br.exec(e);if(t)return {type:"br",raw:t[0]}}del(e){let t=this.rules.inline.del.exec(e);if(t)return {type:"del",raw:t[0],text:t[2],tokens:this.lexer.inlineTokens(t[2])}}autolink(e){let t=this.rules.inline.autolink.exec(e);if(t){let n,r;return t[2]==="@"?(n=t[1],r="mailto:"+n):(n=t[1],r=n),{type:"link",raw:t[0],text:n,href:r,tokens:[{type:"text",raw:n,text:n}]}}}url(e){let t;if(t=this.rules.inline.url.exec(e)){let n,r;if(t[2]==="@")n=t[0],r="mailto:"+n;else {let i;do i=t[0],t[0]=this.rules.inline._backpedal.exec(t[0])?.[0]??"";while(i!==t[0]);n=t[0],t[1]==="www."?r="http://"+t[0]:r=t[0];}return {type:"link",raw:t[0],text:n,href:r,tokens:[{type:"text",raw:n,text:n}]}}}inlineText(e){let t=this.rules.inline.text.exec(e);if(t){let n=this.lexer.state.inRawBlock;return {type:"text",raw:t[0],text:t[0],escaped:n}}}};var x=class u{tokens;options;state;tokenizer;inlineQueue;constructor(e){this.tokens=[],this.tokens.links=Object.create(null),this.options=e||T,this.options.tokenizer=this.options.tokenizer||new y,this.tokenizer=this.options.tokenizer,this.tokenizer.options=this.options,this.tokenizer.lexer=this,this.inlineQueue=[],this.state={inLink:false,inRawBlock:false,top:true};let t={other:m,block:C.normal,inline:M.normal};this.options.pedantic?(t.block=C.pedantic,t.inline=M.pedantic):this.options.gfm&&(t.block=C.gfm,this.options.breaks?t.inline=M.breaks:t.inline=M.gfm),this.tokenizer.rules=t;}static get rules(){return {block:C,inline:M}}static lex(e,t){return new u(t).lex(e)}static lexInline(e,t){return new u(t).inlineTokens(e)}lex(e){e=e.replace(m.carriageReturn,`
15105`),this.blockTokens(e,this.tokens);for(let t=0;t<this.inlineQueue.length;t++){let n=this.inlineQueue[t];this.inlineTokens(n.src,n.tokens);}return this.inlineQueue=[],this.tokens}blockTokens(e,t=[],n=false){for(this.options.pedantic&&(e=e.replace(m.tabCharGlobal,"    ").replace(m.spaceLine,""));e;){let r;if(this.options.extensions?.block?.some(s=>(r=s.call({lexer:this},e,t))?(e=e.substring(r.raw.length),t.push(r),true):false))continue;if(r=this.tokenizer.space(e)){e=e.substring(r.raw.length);let s=t.at(-1);r.raw.length===1&&s!==void 0?s.raw+=`
15106`:t.push(r);continue}if(r=this.tokenizer.code(e)){e=e.substring(r.raw.length);let s=t.at(-1);s?.type==="paragraph"||s?.type==="text"?(s.raw+=(s.raw.endsWith(`
15107`)?"":`
15108`)+r.raw,s.text+=`
15109`+r.text,this.inlineQueue.at(-1).src=s.text):t.push(r);continue}if(r=this.tokenizer.fences(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.heading(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.hr(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.blockquote(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.list(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.html(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.def(e)){e=e.substring(r.raw.length);let s=t.at(-1);s?.type==="paragraph"||s?.type==="text"?(s.raw+=(s.raw.endsWith(`
15110`)?"":`
15111`)+r.raw,s.text+=`
15112`+r.raw,this.inlineQueue.at(-1).src=s.text):this.tokens.links[r.tag]||(this.tokens.links[r.tag]={href:r.href,title:r.title},t.push(r));continue}if(r=this.tokenizer.table(e)){e=e.substring(r.raw.length),t.push(r);continue}if(r=this.tokenizer.lheading(e)){e=e.substring(r.raw.length),t.push(r);continue}let i=e;if(this.options.extensions?.startBlock){let s=1/0,o=e.slice(1),a;this.options.extensions.startBlock.forEach(l=>{a=l.call({lexer:this},o),typeof a=="number"&&a>=0&&(s=Math.min(s,a));}),s<1/0&&s>=0&&(i=e.substring(0,s+1));}if(this.state.top&&(r=this.tokenizer.paragraph(i))){let s=t.at(-1);n&&s?.type==="paragraph"?(s.raw+=(s.raw.endsWith(`
15113`)?"":`
15114`)+r.raw,s.text+=`
15115`+r.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=s.text):t.push(r),n=i.length!==e.length,e=e.substring(r.raw.length);continue}if(r=this.tokenizer.text(e)){e=e.substring(r.raw.length);let s=t.at(-1);s?.type==="text"?(s.raw+=(s.raw.endsWith(`
15116`)?"":`
15117`)+r.raw,s.text+=`
15118`+r.text,this.inlineQueue.pop(),this.inlineQueue.at(-1).src=s.text):t.push(r);continue}if(e){let s="Infinite loop on byte: "+e.charCodeAt(0);if(this.options.silent){console.error(s);break}else throw new Error(s)}}return this.state.top=true,t}inline(e,t=[]){return this.inlineQueue.push({src:e,tokens:t}),t}inlineTokens(e,t=[]){let n=e,r=null;if(this.tokens.links){let o=Object.keys(this.tokens.links);if(o.length>0)for(;(r=this.tokenizer.rules.inline.reflinkSearch.exec(n))!=null;)o.includes(r[0].slice(r[0].lastIndexOf("[")+1,-1))&&(n=n.slice(0,r.index)+"["+"a".repeat(r[0].length-2)+"]"+n.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex));}for(;(r=this.tokenizer.rules.inline.anyPunctuation.exec(n))!=null;)n=n.slice(0,r.index)+"++"+n.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);for(;(r=this.tokenizer.rules.inline.blockSkip.exec(n))!=null;)n=n.slice(0,r.index)+"["+"a".repeat(r[0].length-2)+"]"+n.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);n=this.options.hooks?.emStrongMask?.call({lexer:this},n)??n;let i=false,s="";for(;e;){i||(s=""),i=false;let o;if(this.options.extensions?.inline?.some(l=>(o=l.call({lexer:this},e,t))?(e=e.substring(o.raw.length),t.push(o),true):false))continue;if(o=this.tokenizer.escape(e)){e=e.substring(o.raw.length),t.push(o);continue}if(o=this.tokenizer.tag(e)){e=e.substring(o.raw.length),t.push(o);continue}if(o=this.tokenizer.link(e)){e=e.substring(o.raw.length),t.push(o);continue}if(o=this.tokenizer.reflink(e,this.tokens.links)){e=e.substring(o.raw.length);let l=t.at(-1);o.type==="text"&&l?.type==="text"?(l.raw+=o.raw,l.text+=o.text):t.push(o);continue}if(o=this.tokenizer.emStrong(e,n,s)){e=e.substring(o.raw.length),t.push(o);continue}if(o=this.tokenizer.codespan(e)){e=e.substring(o.raw.length),t.push(o);continue}if(o=this.tokenizer.br(e)){e=e.substring(o.raw.length),t.push(o);continue}if(o=this.tokenizer.del(e)){e=e.substring(o.raw.length),t.push(o);continue}if(o=this.tokenizer.autolink(e)){e=e.substring(o.raw.length),t.push(o);continue}if(!this.state.inLink&&(o=this.tokenizer.url(e))){e=e.substring(o.raw.length),t.push(o);continue}let a=e;if(this.options.extensions?.startInline){let l=1/0,c=e.slice(1),p;this.options.extensions.startInline.forEach(g=>{p=g.call({lexer:this},c),typeof p=="number"&&p>=0&&(l=Math.min(l,p));}),l<1/0&&l>=0&&(a=e.substring(0,l+1));}if(o=this.tokenizer.inlineText(a)){e=e.substring(o.raw.length),o.raw.slice(-1)!=="_"&&(s=o.raw.slice(-1)),i=true;let l=t.at(-1);l?.type==="text"?(l.raw+=o.raw,l.text+=o.text):t.push(o);continue}if(e){let l="Infinite loop on byte: "+e.charCodeAt(0);if(this.options.silent){console.error(l);break}else throw new Error(l)}}return t}};var P=class{options;parser;constructor(e){this.options=e||T;}space(e){return ""}code({text:e,lang:t,escaped:n}){let r=(t||"").match(m.notSpaceStart)?.[0],i=e.replace(m.endingNewline,"")+`
15119`;return r?'<pre><code class="language-'+w(r)+'">'+(n?i:w(i,true))+`</code></pre>
15120`:"<pre><code>"+(n?i:w(i,true))+`</code></pre>
15121`}blockquote({tokens:e}){return `<blockquote>
15122${this.parser.parse(e)}</blockquote>
15123`}html({text:e}){return e}def(e){return ""}heading({tokens:e,depth:t}){return `<h${t}>${this.parser.parseInline(e)}</h${t}>
15124`}hr(e){return `<hr>
15125`}list(e){let t=e.ordered,n=e.start,r="";for(let o=0;o<e.items.length;o++){let a=e.items[o];r+=this.listitem(a);}let i=t?"ol":"ul",s=t&&n!==1?' start="'+n+'"':"";return "<"+i+s+`>
15126`+r+"</"+i+`>
15127`}listitem(e){let t="";if(e.task){let n=this.checkbox({checked:!!e.checked});e.loose?e.tokens[0]?.type==="paragraph"?(e.tokens[0].text=n+" "+e.tokens[0].text,e.tokens[0].tokens&&e.tokens[0].tokens.length>0&&e.tokens[0].tokens[0].type==="text"&&(e.tokens[0].tokens[0].text=n+" "+w(e.tokens[0].tokens[0].text),e.tokens[0].tokens[0].escaped=true)):e.tokens.unshift({type:"text",raw:n+" ",text:n+" ",escaped:true}):t+=n+" ";}return t+=this.parser.parse(e.tokens,!!e.loose),`<li>${t}</li>
15128`}checkbox({checked:e}){return "<input "+(e?'checked="" ':"")+'disabled="" type="checkbox">'}paragraph({tokens:e}){return `<p>${this.parser.parseInline(e)}</p>
15129`}table(e){let t="",n="";for(let i=0;i<e.header.length;i++)n+=this.tablecell(e.header[i]);t+=this.tablerow({text:n});let r="";for(let i=0;i<e.rows.length;i++){let s=e.rows[i];n="";for(let o=0;o<s.length;o++)n+=this.tablecell(s[o]);r+=this.tablerow({text:n});}return r&&(r=`<tbody>${r}</tbody>`),`<table>
15130<thead>
15131`+t+`</thead>
15132`+r+`</table>
15133`}tablerow({text:e}){return `<tr>
15134${e}</tr>
15135`}tablecell(e){let t=this.parser.parseInline(e.tokens),n=e.header?"th":"td";return (e.align?`<${n} align="${e.align}">`:`<${n}>`)+t+`</${n}>
15136`}strong({tokens:e}){return `<strong>${this.parser.parseInline(e)}</strong>`}em({tokens:e}){return `<em>${this.parser.parseInline(e)}</em>`}codespan({text:e}){return `<code>${w(e,true)}</code>`}br(e){return "<br>"}del({tokens:e}){return `<del>${this.parser.parseInline(e)}</del>`}link({href:e,title:t,tokens:n}){let r=this.parser.parseInline(n),i=J(e);if(i===null)return r;e=i;let s='<a href="'+e+'"';return t&&(s+=' title="'+w(t)+'"'),s+=">"+r+"</a>",s}image({href:e,title:t,text:n,tokens:r}){r&&(n=this.parser.parseInline(r,this.parser.textRenderer));let i=J(e);if(i===null)return w(n);e=i;let s=`<img src="${e}" alt="${n}"`;return t&&(s+=` title="${w(t)}"`),s+=">",s}text(e){return "tokens"in e&&e.tokens?this.parser.parseInline(e.tokens):"escaped"in e&&e.escaped?e.text:w(e.text)}};var $=class{strong({text:e}){return e}em({text:e}){return e}codespan({text:e}){return e}del({text:e}){return e}html({text:e}){return e}text({text:e}){return e}link({text:e}){return ""+e}image({text:e}){return ""+e}br(){return ""}};var b=class u{options;renderer;textRenderer;constructor(e){this.options=e||T,this.options.renderer=this.options.renderer||new P,this.renderer=this.options.renderer,this.renderer.options=this.options,this.renderer.parser=this,this.textRenderer=new $;}static parse(e,t){return new u(t).parse(e)}static parseInline(e,t){return new u(t).parseInline(e)}parse(e,t=true){let n="";for(let r=0;r<e.length;r++){let i=e[r];if(this.options.extensions?.renderers?.[i.type]){let o=i,a=this.options.extensions.renderers[o.type].call({parser:this},o);if(a!==false||!["space","hr","heading","code","table","blockquote","list","html","def","paragraph","text"].includes(o.type)){n+=a||"";continue}}let s=i;switch(s.type){case "space":{n+=this.renderer.space(s);continue}case "hr":{n+=this.renderer.hr(s);continue}case "heading":{n+=this.renderer.heading(s);continue}case "code":{n+=this.renderer.code(s);continue}case "table":{n+=this.renderer.table(s);continue}case "blockquote":{n+=this.renderer.blockquote(s);continue}case "list":{n+=this.renderer.list(s);continue}case "html":{n+=this.renderer.html(s);continue}case "def":{n+=this.renderer.def(s);continue}case "paragraph":{n+=this.renderer.paragraph(s);continue}case "text":{let o=s,a=this.renderer.text(o);for(;r+1<e.length&&e[r+1].type==="text";)o=e[++r],a+=`
15137`+this.renderer.text(o);t?n+=this.renderer.paragraph({type:"paragraph",raw:a,text:a,tokens:[{type:"text",raw:a,text:a,escaped:true}]}):n+=a;continue}default:{let o='Token with "'+s.type+'" type was not found.';if(this.options.silent)return console.error(o),"";throw new Error(o)}}}return n}parseInline(e,t=this.renderer){let n="";for(let r=0;r<e.length;r++){let i=e[r];if(this.options.extensions?.renderers?.[i.type]){let o=this.options.extensions.renderers[i.type].call({parser:this},i);if(o!==false||!["escape","html","link","image","strong","em","codespan","br","del","text"].includes(i.type)){n+=o||"";continue}}let s=i;switch(s.type){case "escape":{n+=t.text(s);break}case "html":{n+=t.html(s);break}case "link":{n+=t.link(s);break}case "image":{n+=t.image(s);break}case "strong":{n+=t.strong(s);break}case "em":{n+=t.em(s);break}case "codespan":{n+=t.codespan(s);break}case "br":{n+=t.br(s);break}case "del":{n+=t.del(s);break}case "text":{n+=t.text(s);break}default:{let o='Token with "'+s.type+'" type was not found.';if(this.options.silent)return console.error(o),"";throw new Error(o)}}}return n}};var S=class{options;block;constructor(e){this.options=e||T;}static passThroughHooks=new Set(["preprocess","postprocess","processAllTokens","emStrongMask"]);static passThroughHooksRespectAsync=new Set(["preprocess","postprocess","processAllTokens"]);preprocess(e){return e}postprocess(e){return e}processAllTokens(e){return e}emStrongMask(e){return e}provideLexer(){return this.block?x.lex:x.lexInline}provideParser(){return this.block?b.parse:b.parseInline}};var B=class{defaults=L();options=this.setOptions;parse=this.parseMarkdown(true);parseInline=this.parseMarkdown(false);Parser=b;Renderer=P;TextRenderer=$;Lexer=x;Tokenizer=y;Hooks=S;constructor(...e){this.use(...e);}walkTokens(e,t){let n=[];for(let r of e)switch(n=n.concat(t.call(this,r)),r.type){case "table":{let i=r;for(let s of i.header)n=n.concat(this.walkTokens(s.tokens,t));for(let s of i.rows)for(let o of s)n=n.concat(this.walkTokens(o.tokens,t));break}case "list":{let i=r;n=n.concat(this.walkTokens(i.items,t));break}default:{let i=r;this.defaults.extensions?.childTokens?.[i.type]?this.defaults.extensions.childTokens[i.type].forEach(s=>{let o=i[s].flat(1/0);n=n.concat(this.walkTokens(o,t));}):i.tokens&&(n=n.concat(this.walkTokens(i.tokens,t)));}}return n}use(...e){let t=this.defaults.extensions||{renderers:{},childTokens:{}};return e.forEach(n=>{let r={...n};if(r.async=this.defaults.async||r.async||false,n.extensions&&(n.extensions.forEach(i=>{if(!i.name)throw new Error("extension name required");if("renderer"in i){let s=t.renderers[i.name];s?t.renderers[i.name]=function(...o){let a=i.renderer.apply(this,o);return a===false&&(a=s.apply(this,o)),a}:t.renderers[i.name]=i.renderer;}if("tokenizer"in i){if(!i.level||i.level!=="block"&&i.level!=="inline")throw new Error("extension level must be 'block' or 'inline'");let s=t[i.level];s?s.unshift(i.tokenizer):t[i.level]=[i.tokenizer],i.start&&(i.level==="block"?t.startBlock?t.startBlock.push(i.start):t.startBlock=[i.start]:i.level==="inline"&&(t.startInline?t.startInline.push(i.start):t.startInline=[i.start]));}"childTokens"in i&&i.childTokens&&(t.childTokens[i.name]=i.childTokens);}),r.extensions=t),n.renderer){let i=this.defaults.renderer||new P(this.defaults);for(let s in n.renderer){if(!(s in i))throw new Error(`renderer '${s}' does not exist`);if(["options","parser"].includes(s))continue;let o=s,a=n.renderer[o],l=i[o];i[o]=(...c)=>{let p=a.apply(i,c);return p===false&&(p=l.apply(i,c)),p||""};}r.renderer=i;}if(n.tokenizer){let i=this.defaults.tokenizer||new y(this.defaults);for(let s in n.tokenizer){if(!(s in i))throw new Error(`tokenizer '${s}' does not exist`);if(["options","rules","lexer"].includes(s))continue;let o=s,a=n.tokenizer[o],l=i[o];i[o]=(...c)=>{let p=a.apply(i,c);return p===false&&(p=l.apply(i,c)),p};}r.tokenizer=i;}if(n.hooks){let i=this.defaults.hooks||new S;for(let s in n.hooks){if(!(s in i))throw new Error(`hook '${s}' does not exist`);if(["options","block"].includes(s))continue;let o=s,a=n.hooks[o],l=i[o];S.passThroughHooks.has(s)?i[o]=c=>{if(this.defaults.async&&S.passThroughHooksRespectAsync.has(s))return (async()=>{let g=await a.call(i,c);return l.call(i,g)})();let p=a.call(i,c);return l.call(i,p)}:i[o]=(...c)=>{if(this.defaults.async)return (async()=>{let g=await a.apply(i,c);return g===false&&(g=await l.apply(i,c)),g})();let p=a.apply(i,c);return p===false&&(p=l.apply(i,c)),p};}r.hooks=i;}if(n.walkTokens){let i=this.defaults.walkTokens,s=n.walkTokens;r.walkTokens=function(o){let a=[];return a.push(s.call(this,o)),i&&(a=a.concat(i.call(this,o))),a};}this.defaults={...this.defaults,...r};}),this}setOptions(e){return this.defaults={...this.defaults,...e},this}lexer(e,t){return x.lex(e,t??this.defaults)}parser(e,t){return b.parse(e,t??this.defaults)}parseMarkdown(e){return (n,r)=>{let i={...r},s={...this.defaults,...i},o=this.onError(!!s.silent,!!s.async);if(this.defaults.async===true&&i.async===false)return o(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));if(typeof n>"u"||n===null)return o(new Error("marked(): input parameter is undefined or null"));if(typeof n!="string")return o(new Error("marked(): input parameter is of type "+Object.prototype.toString.call(n)+", string expected"));if(s.hooks&&(s.hooks.options=s,s.hooks.block=e),s.async)return (async()=>{let a=s.hooks?await s.hooks.preprocess(n):n,c=await(s.hooks?await s.hooks.provideLexer():e?x.lex:x.lexInline)(a,s),p=s.hooks?await s.hooks.processAllTokens(c):c;s.walkTokens&&await Promise.all(this.walkTokens(p,s.walkTokens));let d=await(s.hooks?await s.hooks.provideParser():e?b.parse:b.parseInline)(p,s);return s.hooks?await s.hooks.postprocess(d):d})().catch(o);try{s.hooks&&(n=s.hooks.preprocess(n));let l=(s.hooks?s.hooks.provideLexer():e?x.lex:x.lexInline)(n,s);s.hooks&&(l=s.hooks.processAllTokens(l)),s.walkTokens&&this.walkTokens(l,s.walkTokens);let p=(s.hooks?s.hooks.provideParser():e?b.parse:b.parseInline)(l,s);return s.hooks&&(p=s.hooks.postprocess(p)),p}catch(a){return o(a)}}}onError(e,t){return n=>{if(n.message+=`
15138Please report this to https://github.com/markedjs/marked.`,e){let r="<p>An error occurred:</p><pre>"+w(n.message+"",true)+"</pre>";return t?Promise.resolve(r):r}if(t)return Promise.reject(n);throw n}}};var _=new B;function k(u,e){return _.parse(u,e)}
15138k.options=k.setOptions=function(u){return _.setOptions(u),k.defaults=_.defaults,G(k.defaults),k};k.getDefaults=L;k.defaults=T;k.use=function(...u){return _.use(...u),k.defaults=_.defaults,G(k.defaults),k};k.walkTokens=function(u,e){return _.walkTokens(u,e)};k.parseInline=_.parseInline;k.Parser=b;k.parser=b.parse;k.Renderer=P;k.TextRenderer=$;k.Lexer=x;k.lexer=x.lex;k.Tokenizer=y;k.Hooks=S;k.parse=k;k.options;k.setOptions;k.use;k.walkTokens;k.parseInline;b.parse;x.lex;
15139
15140// Markdown reads any line indented by a tab or four spaces as a code block. Pasted
15141// plain text is full of incidental indentation — outlines, notes, logs — and nobody
15142// indents a note meaning "this is code"; they fence it. Keep fences, drop the
15143// indentation rule.
15144const pastedMarkdown = new B({ breaks: true }).use({ tokenizer: { code: () => undefined } });
15145
15146class Clipboard {
15147  #listeners = new ListenerBin()
15148
15149  constructor(editorElement) {
15150    this.editorElement = editorElement;
15151    this.editor = editorElement.editor;
15152    this.contents = editorElement.contents;
15153
15154    this.#registerPasteCommands();
15155  }
15156
15157  dispose() {
15158    this.editorElement = null;
15159    this.editor = null;
15160    this.contents = null;
15161
15162    this.#listeners.dispose();
15163  }
15164
15165  paste(event) {
15166    const clipboardData = event.clipboardData;
15167
15168    if (!clipboardData) return false
15169
15170    if (this.#isPastingIntoCodeBlock()) {
15171      this.#pastePlainTextIntoCodeBlock(clipboardData);
15172      event.preventDefault();
15173      return true
15174    }
15175
15176    if (this.#isPlainTextOrURLPasted(clipboardData)) {
15177      this.#pastePlainTextOrURL(clipboardData);
15178      event.preventDefault();
15179      return true
15180    }
15181
15182    const handled = this.#handlePastedFiles(clipboardData);
15183    if (handled) event.preventDefault();
15184    return handled
15185  }
15186
15187  #registerPasteCommands() {
15188    this.#listeners.track(
15189      this.editor.registerCommand(_e$2, this.paste.bind(this), oo),
15190      this.editor.registerCommand(
15191        oe$6,
15192        (payload) => this.#handleParsedClipboardNodes(payload),
15193        oo
15194      )
15195    );
15196  }
15197
15198  #handleParsedClipboardNodes({ nodes, selection }) {
15199    const url = $bareUrlFromSingleLink(nodes);
15200    if (url && Fr(selection)) {
15201      this.#insertSingleLinkAt(selection, url);
15202      return true
15203    }
15204  }
15205
15206  #isPlainTextOrURLPasted(clipboardData) {
15207    return this.#isOnlyPlainTextPasted(clipboardData) || this.#isOnlyURLPasted(clipboardData)
15208  }
15209
15210  #isOnlyPlainTextPasted(clipboardData) {
15211    const types = Array.from(clipboardData.types);
15212    return types.length === 1 && types[0] === "text/plain"
15213  }
15214
15215  // Browsers expose a copied URL in several shapes:
15216  //   Safari          [ text/plain, text/uri-list ]
15217  //   App ShareSheet  [ text/uri-list ]
15218  //   Chromium macOS  [ text/plain, text/html, (?:text/link-preview) ]
15219  #isOnlyURLPasted(clipboardData) {
15220    if (this.#isLexicalClipboardData(clipboardData)) return false
15221
15222    const types = Array.from(clipboardData.types);
15223    if (types.includes("text/uri-list")) {
15224      return types.every(type =>
vendor: 34,167 bytes, lines 15224-16330
15224 type === "text/plain" || type === "text/uri-list")
15225    }
15226
15227    if (clipboardData.files.length) return false
15228
15229    const text = clipboardData.getData("text/plain").trim();
15230    if (!isAutolinkableURL(text)) return false
15231
15232    const html = clipboardData.getData("text/html");
15233    return !html || this.#htmlIsBareLinkToURL(html, text)
15234  }
15235
15236  #htmlIsBareLinkToURL(html, url) {
15237    const doc = parseHtml(html);
15238    if (doc.body.textContent.trim() !== url) return false
15239
15240    const links = doc.body.querySelectorAll("a");
15241    if (links.length === 0) return true
15242    return links.length === 1 && links[0].getAttribute("href") === url
15243  }
15244
15245  #isPastingIntoCodeBlock() {
15246    let result = false;
15247
15248    this.editor.getEditorState().read(() => {
15249      const selection = Qr();
15250      if (!Fr(selection)) return
15251
15252      let currentNode = selection.anchor.getNode();
15253
15254      while (currentNode) {
15255        if (W$1(currentNode)) {
15256          result = true;
15257          return
15258        }
15259        currentNode = currentNode.getParent();
15260      }
15261    });
15262
15263    return result
15264  }
15265
15266  #pastePlainTextIntoCodeBlock(clipboardData) {
15267    const text = clipboardData.getData("text/plain");
15268    if (!text) return
15269
15270    this.editor.update(() => {
15271      const selection = Qr();
15272      if (Fr(selection)) selection.insertRawText(text);
15273    }, { tag: jn });
15274  }
15275
15276  #pastePlainTextOrURL(clipboardData) {
15277    const item = this.#plainTextOrURLItem(clipboardData);
15278    item.getAsString((text) => {
15279      const url = text.trim();
15280      if (isAutolinkableURL(url)) {
15281        this.#pasteURL(url);
15282      } else if (this.editorElement.supportsMarkdown) {
15283        this.#pasteMarkdown(text);
15284      } else {
15285        this.#pasteRichText(clipboardData);
15286      }
15287    });
15288  }
15289
15290  #plainTextOrURLItem(clipboardData) {
15291    const items = Array.from(clipboardData.items);
15292    return items.find((item) => item.type === "text/plain") || items.find((item) => item.type === "text/uri-list")
15293  }
15294
15295  #pasteURL(url) {
15296    if (this.contents.hasSelectedText()) {
15297      this.contents.createLinkWithSelectedText(url);
15298    } else {
15299      const nodeKey = this.contents.createLink(url);
15300      this.#dispatchLinkInsertEvent(nodeKey, { url });
15301    }
15302  }
15303
15304  #insertSingleLinkAt(selection, url) {
15305    if (!Fr(selection)) return
15306
15307    if (!selection.isCollapsed()) {
15308      Q$6(null);
15309      Q$6(url);
15310      return
15311    }
15312
15313    const linkNode = $$2(url).append(kr(url));
15314    BaseNodeInserter.for(selection).insertNodes([ linkNode ]);
15315
15316    Ms(() => this.#dispatchLinkInsertEvent(linkNode.getKey(), { url }));
15317  }
15318
15319  #dispatchLinkInsertEvent(nodeKey, payload) {
15320    const linkManipulationMethods = {
15321      replaceLinkWith: (html, options) => this.contents.replaceNodeWithHTML(nodeKey, html, options),
15322      insertBelowLink: (html, options) => this.contents.insertHTMLBelowNode(nodeKey, html, options)
15323    };
15324
15325    dispatch(this.editorElement, "lexxy:insert-link", {
15326      ...payload,
15327      ...linkManipulationMethods
15328    });
15329  }
15330
15331  #pasteMarkdown(text) {
15332    const html = pastedMarkdown.parse(text);
15333    const doc = parseHtml(html);
15334
15335    if (this.#isPlainTextWithoutMarkdown(doc)) {
15336      this.contents.insertText(text, { tag: jn });
15337    } else {
15338      const detail = Object.freeze({
15339        markdown: text,
15340        document: doc,
15341        addBlockSpacing: () => addBlockSpacing(doc)
15342      });
15343
15344      dispatch(this.editorElement, "lexxy:insert-markdown", detail);
15345      this.contents.insertDOM(doc, { tag: jn });
15346    }
15347  }
15348
15349  // Markdown conversion collapses runs of whitespace and unescapes backslashes,
15350  // silently corrupting plain text such as Windows/UNC file paths. When the text
15351  // carries no Markdown structure, paste it verbatim instead. A path that wrapped
15352  // across lines renders as a single paragraph with <br> line breaks (marked runs
15353  // with breaks: true), which is still plain text we should preserve untouched.
15354  #isPlainTextWithoutMarkdown(doc) {
15355    const elements = Array.from(doc.body.children);
15356    if (elements.length !== 1) return false
15357
15358    const paragraph = elements[0];
15359    return paragraph.nodeName === "P"
15360      && Array.from(paragraph.childNodes).every((node) => node.nodeType === Node.TEXT_NODE || node.nodeName === "BR")
15361  }
15362
15363  #pasteRichText(clipboardData) {
15364    this.editor.update(() => {
15365      const selection = Qr();
15366      I$3(clipboardData, selection, this.editor);
15367    }, { tag: jn });
15368  }
15369
15370  #handlePastedFiles(clipboardData) {
15371    if (!this.editorElement.supportsAttachments) return false
15372
15373    const html = clipboardData.getData("text/html");
15374    const files = clipboardData.files;
15375
15376    if (files.length && this.#isCopiedImageHTML(html)) {
15377      this.#uploadFilesPreservingScroll(files);
15378      return true
15379    }
15380
15381    if (html && !this.#isLexicalClipboardData(clipboardData)) {
15382      this.contents.insertHtml(html, { tag: jn });
15383      return true
15384    }
15385
15386    if (files.length) {
15387      this.#uploadFilesPreservingScroll(files);
15388      return true
15389    }
15390
15391    return false
15392  }
15393
15394  #isLexicalClipboardData(clipboardData) {
15395    return Array.from(clipboardData.types).includes("application/x-lexical-editor")
15396  }
15397
15398  #isCopiedImageHTML(html) {
15399    if (!html) return false
15400
15401    const doc = parseHtml(html);
15402    const elementChildren = Array.from(doc.body.children);
15403
15404    return elementChildren.length === 1 && elementChildren[0].tagName === "IMG"
15405  }
15406
15407  #uploadFilesPreservingScroll(files) {
15408    this.#preservingScrollPosition(() => {
15409      if (files.length) {
15410        this.contents.uploadFiles(files, { selectLast: true });
15411      }
15412    });
15413  }
15414
15415  // Deals with an issue in Safari where it scrolls to the tops after pasting attachments
15416  async #preservingScrollPosition(callback) {
15417    const scrollY = window.scrollY;
15418    const scrollX = window.scrollX;
15419
15420    callback();
15421
15422    await nextFrame();
15423
15424    window.scrollTo(scrollX, scrollY);
15425    this.editor.focus();
15426  }
15427}
15428
15429function $bareUrlFromSingleLink(nodes) {
15430  if (nodes.length !== 1) return null
15431
15432  const node = nodes[0];
15433  if (z$5(node)) return $bareUrlFromLink(node)
15434
15435  if (no(node)) {
15436    const children = node.getChildren();
15437    if (children.length === 1 && z$5(children[0])) {
15438      return $bareUrlFromLink(children[0])
15439    }
15440  }
15441
15442  return null
15443}
15444
15445function $bareUrlFromLink(linkNode) {
15446  const url = linkNode.getURL();
15447  if (!url) return null
15448  return linkNode.getTextContent() === url ? url : null
15449}
15450
15451class Extensions {
15452
15453  constructor(lexxyElement) {
15454    this.lexxyElement = lexxyElement;
15455
15456    this.enabledExtensions = this.#initializeExtensions();
15457  }
15458
15459  get lexicalExtensions() {
15460    return this.enabledExtensions.map(ext => ext.lexicalExtension).filter(Boolean)
15461  }
15462
15463  initializeToolbars() {
15464    const toolbar = this.#lexxyToolbar;
15465    if (!toolbar) return
15466
15467    this.#clearPreviousExtensionToolbarButtons(toolbar);
15468    this.#addExtensionToolbarButtons(toolbar);
15469    toolbar.requestOverflowRefresh();
15470  }
15471
15472  dispose() {
15473    while (this.enabledExtensions.length) {
15474      this.enabledExtensions.pop().dispose();
15475    }
15476  }
15477
15478  #clearPreviousExtensionToolbarButtons(toolbar) {
15479    toolbar.querySelectorAll("[data-lexxy-extension]").forEach(el => el.remove());
15480  }
15481
15482  #addExtensionToolbarButtons(toolbar) {
15483    this.enabledExtensions.forEach(ext => {
15484      const childrenBefore = new Set(toolbar.children);
15485      ext.initializeToolbar(toolbar);
15486      for (const child of toolbar.children) {
15487        if (!childrenBefore.has(child)) {
15488          child.setAttribute("data-lexxy-extension", "");
15489        }
15490      }
15491    });
15492  }
15493
15494  get allowedElements() {
15495    return this.enabledExtensions.flatMap(ext => ext.allowedElements)
15496  }
15497
15498  get #lexxyToolbar() {
15499    return this.lexxyElement.toolbar
15500  }
15501
15502  get #baseExtensions() {
15503    return this.lexxyElement.baseExtensions
15504  }
15505
15506  get #configuredExtensions() {
15507    return Lexxy.global.get("extensions")
15508  }
15509
15510  #initializeExtensions() {
15511    const extensionDefinitions = this.#baseExtensions.concat(this.#configuredExtensions);
15512
15513    return extensionDefinitions.map(
15514      extension => new extension(this.lexxyElement)
15515    ).filter(extension => extension.enabled)
15516  }
15517}
15518
15519class BrowserAdapter {
15520  frozenLinkKey = null
15521
15522  dispatchAttributesChange(attributes, linkHref, highlight, headingTag) {}
15523  dispatchEditorInitialized(detail) {}
15524  freeze() {}
15525  thaw() {}
15526  unlinkFrozenNode() {
15527    return false
15528  }
15529}
15530
15531// Custom TextNode exportDOM that avoids redundant wrapping.
15532//
15533// Lexical's built-in TextNode.exportDOM() calls createDOM() which produces semantic tags
15534// like <strong> for bold and <em> for italic, then unconditionally wraps the result
15535// with presentational tags (<b>, <i>) for the same formats. This produces redundant markup
15536// like <b><strong>text</strong></b>.
15537//
15538// This custom export skips <b> when <strong> is already present and <i> when <em> is
15539// already present, while preserving <s> and <u> wrappers which have no semantic equivalents
15540// in createDOM's output.
15541//
15542// Any <span> elements produced by createDOM() are unwrapped, since they only carry
15543// editor classes that aren't meaningful in exported HTML.
15544
15545function exportTextNodeDOM(editor, textNode) {
15546  const element = textNode.createDOM(editor._config, editor);
15547  element.style.whiteSpace = "pre-wrap";
15548
15549  if (textNode.hasFormat("lowercase")) {
15550    element.style.textTransform = "lowercase";
15551  } else if (textNode.hasFormat("uppercase")) {
15552    element.style.textTransform = "uppercase";
15553  } else if (textNode.hasFormat("capitalize")) {
15554    element.style.textTransform = "capitalize";
15555  }
15556
15557  let result = element;
15558
15559  if (textNode.hasFormat("bold") && !containsTag(element, "strong")) {
15560    result = wrapWith(result, "b");
15561  }
15562  if (textNode.hasFormat("italic") && !containsTag(element, "em")) {
15563    result = wrapWith(result, "i");
15564  }
15565  if (textNode.hasFormat("strikethrough")) {
15566    result = wrapWith(result, "s");
15567  }
15568  if (textNode.hasFormat("underline")) {
15569    result = wrapWith(result, "u");
15570  }
15571
15572  return { element: unwrapSpans(result) }
15573}
15574
15575function containsTag(element, tagName) {
15576  const upperTag = tagName.toUpperCase();
15577  if (element.tagName === upperTag) return true
15578
15579  return element.querySelector(tagName) !== null
15580}
15581
15582function wrapWith(element, tag) {
15583  const wrapper = document.createElement(tag);
15584  wrapper.appendChild(element);
15585  return wrapper
15586}
15587
15588function unwrapSpans(element) {
15589  if (element.tagName === "SPAN") return element.firstChild
15590
15591  for (const span of element.querySelectorAll("span")) {
15592    span.replaceWith(...span.childNodes);
15593  }
15594
15595  return element
15596}
15597
15598class ProvisionalParagraphNode extends Zi {
15599  $config() {
15600    return this.config("provisonal_paragraph", {
15601      extends: Zi,
15602      importDOM: () => null,
15603      $transform: (node) => {
15604        node.concretizeIfEdited(node);
15605        node.removeUnlessRequired(node);
15606      }
15607    })
15608  }
15609
15610  static neededBetween(nodeBefore, nodeAfter) {
15611    return !$isSelectableElement(nodeBefore, "next")
15612      && !$isSelectableElement(nodeAfter, "previous")
15613  }
15614
15615  createDOM(editor) {
15616    const p = super.createDOM(editor);
15617    const selected = this.isSelected(Qr());
15618    p.classList.add("provisional-paragraph");
15619    p.classList.toggle("hidden", !selected);
15620    return p
15621  }
15622
15623  updateDOM(_prevNode, dom) {
15624    const selected = this.isSelected(Qr());
15625    dom.classList.toggle("hidden", !selected);
15626    return false
15627  }
15628
15629  getTextContent() {
15630    return ""
15631  }
15632
15633  exportDOM() {
15634    return {
15635      element: null
15636    }
15637  }
15638
15639  // override as Lexical has an interesting view of collapsed selection in ElementNodes
15640  // https://github.com/facebook/lexical/blob/f1e4f66014377b1f2595aec2b0ee17f5b7ef4dfc/packages/lexical/src/LexicalNode.ts#L646
15641  isSelected(selection = null) {
15642    const targetSelection = selection || Qr();
15643    if (!targetSelection) return false
15644
15645    if (targetSelection.getNodes().some(node => node.is(this) || this.isParentOf(node))) return true
15646
15647    // A collapsed range selection on the parent element at an offset adjacent to
15648    // this node means the caret is visually at this paragraph's position. Treat it
15649    // as selected so the paragraph is visible and the caret renders correctly.
15650    //
15651    // Both the offset matching our index (cursor just before us) and index + 1
15652    // (cursor just after us) count, because the provisional paragraph is an
15653    // invisible spacer: the browser resolves both offsets to the same visual spot.
15654    if (Fr(targetSelection) && targetSelection.isCollapsed()) {
15655      const { anchor } = targetSelection;
15656      const parent = this.getParent();
15657      if (parent && anchor.getNode().is(parent) && anchor.type === "element") {
15658        const index = this.getIndexWithinParent();
15659        return anchor.offset === index || anchor.offset === index + 1
15660      }
15661    }
15662
15663    return false
15664  }
15665
15666  removeUnlessRequired(self = this.getLatest()) {
15667    if (!self.required) self.remove();
15668  }
15669
15670  concretizeIfEdited(self = this.getLatest()) {
15671    if (self.getTextContentSize() > 0) {
15672      self.replace(eo(), true);
15673    }
15674  }
15675
15676
15677  get required() {
15678    return this.isDirectRootChild && ProvisionalParagraphNode.neededBetween(...this.immediateSiblings)
15679  }
15680
15681  get isDirectRootChild() {
15682    const parent = this.getParent();
15683    return Is(parent)
15684  }
15685
15686  get immediateSiblings() {
15687    return [ this.getPreviousSibling(), this.getNextSibling() ]
15688  }
15689}
15690
15691function $isProvisionalParagraphNode(node) {
15692  return node instanceof ProvisionalParagraphNode
15693}
15694
15695function $isSelectableElement(node, direction) {
15696  return Wi(node) && (direction === "next" ? node.canInsertTextBefore() : node.canInsertTextAfter())
15697}
15698
15699class ProvisionalParagraphExtension extends LexxyExtension {
15700  get lexicalExtension() {
15701    return dc({
15702      name: "lexxy/provisional-paragraph",
15703      nodes: [
15704        ProvisionalParagraphNode
15705      ],
15706      register(editor) {
15707        return Cc(
15708          // Process Provisional Paragraph Nodes on RootNode changes as sibling status influences whether
15709          // they are required and their visible/hidden status
15710          editor.registerNodeTransform(Ui, $insertRequiredProvisionalParagraphs),
15711          editor.registerNodeTransform(Ui, $removeUnneededProvisionalParagraphs),
15712          editor.registerCommand(ie$4, $markAllProvisionalParagraphsDirty, so)
15713        )
15714      }
15715    })
15716  }
15717}
15718
15719function $insertRequiredProvisionalParagraphs(rootNode) {
15720  const nodeBeforeRootSelection = $nodeBeforeRootSelection(rootNode);
15721
15722  const firstNode = rootNode.getFirstChild();
15723  if (ProvisionalParagraphNode.neededBetween(null, firstNode)) {
15724    $t$2(rootNode, new ProvisionalParagraphNode);
15725  }
15726
15727  for (const node of jt$2(rootNode)) {
15728    const nextNode = node.getNextSibling();
15729    if (ProvisionalParagraphNode.neededBetween(node, nextNode)) {
15730      node.insertAfter(new ProvisionalParagraphNode);
15731      if (node.is(nodeBeforeRootSelection)) node.selectNext();
15732    }
15733  }
15734}
15735
15736function $nodeBeforeRootSelection(rootNode) {
15737  const selection = Qr();
15738  if (!Is(selection?.anchor?.getNode())) return null
15739
15740  return rootNode.getChildAtIndex(selection.anchor.offset - 1)
15741}
15742
15743function $removeUnneededProvisionalParagraphs(rootNode) {
15744  for (const provisionalParagraph of $getAllProvisionalParagraphs(rootNode)) {
15745    provisionalParagraph.removeUnlessRequired();
15746  }
15747}
15748
15749function $markAllProvisionalParagraphsDirty() {
15750  // Selection-driven visibility updates must not become standalone undo steps.
15751  Os(Jn);
15752
15753  for (const provisionalParagraph of $getAllProvisionalParagraphs()) {
15754    provisionalParagraph.markDirty();
15755  }
15756}
15757
15758function $getAllProvisionalParagraphs(rootNode = Zo()) {
15759  return Ht$3(rootNode.getChildren(), $isProvisionalParagraphNode)
15760}
15761
15762// Registers code highlighting through the extension system so its node
15763// transforms exist before the initial editor state is applied. Registering
15764// after editor creation misses code blocks loaded from the initial value:
15765// their transform pass has already run, and Lexical's catch-up dirtying
15766// only sees the committed (still empty) state.
15767class CodeHighlightingExtension extends LexxyExtension {
15768  get enabled() {
15769    return this.editorElement.supportsRichText
15770  }
15771
15772  get lexicalExtension() {
15773    return dc({
15774      name: "lexxy/code-highlighting",
15775      register(editor) {
15776        return L$1(editor, buildHighlightPreservingTokenizer(editor))
15777      }
15778    })
15779  }
15780}
15781
15782const TRIX_LANGUAGE_ATTR = "language";
15783
15784class TrixContentExtension extends LexxyExtension {
15785
15786  get enabled() {
15787    return this.editorElement.supportsRichText
15788  }
15789
15790  get lexicalExtension() {
15791    return dc({
15792      name: "lexxy/trix-content",
15793      html: {
15794        import: {
15795          em: (element) => onlyStyledElements(element, {
15796            conversion: extendTextNodeConversion("i", $applyHighlightStyle),
15797            priority: 1
15798          }),
15799          span: (element) => onlyStyledElements(element, {
15800            conversion: extendTextNodeConversion("mark", $applyHighlightStyle),
15801            priority: 1
15802          }),
15803          strong: (element) => onlyStyledElements(element, {
15804            conversion: extendTextNodeConversion("b", $applyHighlightStyle),
15805            priority: 1
15806          }),
15807          del: () => ({
15808            conversion: extendTextNodeConversion("s", $applyStrikethrough, $applyHighlightStyle),
15809            priority: 1
15810          }),
15811          pre: (element) => onlyPreLanguageElements(element, {
15812            conversion: extendConversion(z$1, "pre", $applyLanguage),
15813            priority: 1
15814          })
15815        }
15816      }
15817    })
15818  }
15819}
15820
15821function onlyStyledElements(element, conversion) {
15822  const elementHighlighted = element.style.color !== "" || element.style.backgroundColor !== "";
15823  return elementHighlighted ? conversion : null
15824}
15825
15826function $applyStrikethrough(textNode) {
15827  if (!textNode.hasFormat("strikethrough")) textNode.toggleFormat("strikethrough");
15828  return textNode
15829}
15830
15831function onlyPreLanguageElements(element, conversion) {
15832  return element.hasAttribute(TRIX_LANGUAGE_ATTR) ? conversion : null
15833}
15834
15835function $applyLanguage(conversionOutput, element) {
15836  const language = a(element.getAttribute(TRIX_LANGUAGE_ATTR));
15837  conversionOutput.node.setLanguage(language);
15838}
15839
15840class WrappedTableNode extends vn {
15841  $config() {
15842    return this.config("wrapped_table_node", { extends: vn })
15843  }
15844
15845  static importDOM() {
15846    return super.importDOM()
15847  }
15848
15849  canInsertTextBefore() {
15850    return false
15851  }
15852
15853  canInsertTextAfter() {
15854    return false
15855  }
15856
15857  exportDOM(editor) {
15858    const superExport = super.exportDOM(editor);
15859
15860    return {
15861      ...superExport,
15862      after: (tableElement) => {
15863        if (superExport.after) {
15864          tableElement = superExport.after(tableElement);
15865          const clonedTable = tableElement.cloneNode(true);
15866          const wrappedTable = createElement("figure", { className: "lexxy-content__table-wrapper" }, clonedTable.outerHTML);
15867          return wrappedTable
15868        }
15869
15870        return tableElement
15871      }
15872    }
15873  }
15874}
15875
15876class TablesExtension extends LexxyExtension {
15877
15878  get enabled() {
15879    return this.editorElement.supportsRichText
15880  }
15881
15882  get allowedElements() {
15883    return [ "figure", "tbody" ]
15884  }
15885
15886  get lexicalExtension() {
15887    return dc({
15888      name: "lexxy/tables",
15889      nodes: [
15890        WrappedTableNode,
15891        {
15892          replace: vn,
15893          with: () => new WrappedTableNode(),
15894          withKlass: WrappedTableNode
15895        },
15896        Ee$1,
15897        He$1
15898      ],
15899      register(editor) {
15900        Nn(editor);
15901
15902        return Cc(
15903          Wn(editor),
15904
15905          // Lexxy registers extensions before setRootElement(), but table
15906          // drag-selection needs a root before wiring its pointer handlers.
15907          editor.registerRootListener((rootElement) => {
15908            if (rootElement) {
15909              return $n(editor, true)
15910            }
15911          }),
15912
15913          // A table in Lexxy is a Lexxy table: cell shading can't be set in the
15914          // editor, so any cell background only ever comes from foreign content
15915          // (pasted spreadsheets, loaded documents). Normalize every cell to no
15916          // background so it adopts the current theme. This also clears
15917          // Lexical's hardcoded default header background (Lexical #8089).
15918          editor.registerNodeTransform(Ee$1, (node) => {
15919            if (node.getBackgroundColor() !== "") {
15920              node.setBackgroundColor("");
15921            }
15922          }),
15923
15924          // Bug fix: Fix column header states (Lexical #8090)
15925          editor.registerNodeTransform(Ee$1, (node) => {
15926            const headerState = node.getHeaderStyles();
15927
15928            if (headerState !== Ae$1.ROW) return
15929
15930            const rowParent = node.getParent();
15931            const tableNode = rowParent?.getParent();
15932            if (!tableNode) return
15933
15934            const rows = tableNode.getChildren();
15935            const cellIndex = rowParent.getChildren().indexOf(node);
15936
15937            const cellsInRow = rowParent.getChildren();
15938            const isHeaderRow = cellsInRow.every(cell =>
15939              cell.getHeaderStyles() !== Ae$1.NO_STATUS
15940            );
15941
15942            const isHeaderColumn = rows.every(row => {
15943              const cell = row.getChildren()[cellIndex];
15944              return cell && cell.getHeaderStyles() !== Ae$1.NO_STATUS
15945            });
15946
15947            let newHeaderState = Ae$1.NO_STATUS;
15948
15949            if (isHeaderRow) newHeaderState |= Ae$1.ROW;
15950            if (isHeaderColumn) newHeaderState |= Ae$1.COLUMN;
15951
15952            if (newHeaderState !== headerState) {
15953              node.setHeaderStyles(newHeaderState, Ae$1.BOTH);
15954            }
15955          }),
15956
15957          editor.registerCommand("insertTableRowAfter", () => {
15958            nt(true);
15959          }, oo),
15960
15961          editor.registerCommand("insertTableRowBefore", () => {
15962            nt(false);
15963          }, oo),
15964
15965          editor.registerCommand("insertTableColumnAfter", () => {
15966            st(true);
15967          }, oo),
15968
15969          editor.registerCommand("insertTableColumnBefore", () => {
15970            st(false);
15971          }, oo),
15972
15973          editor.registerCommand("deleteTableRow", () => {
15974            ut();
15975          }, oo),
15976
15977          editor.registerCommand("deleteTableColumn", () => {
15978            dt();
15979          }, oo),
15980
15981          editor.registerCommand("deleteTable", () => {
15982            const selection = Qr();
15983            if (!Fr(selection)) return false
15984            hn(selection.anchor.getNode())?.remove();
15985          }, oo)
15986        )
15987      }
15988    })
15989  }
15990}
15991
15992const MIME_TYPE$1 = "application/x-lexxy-node-key";
15993
15994class AttachmentDragAndDrop {
15995  #editor
15996  #draggedNodeKey = null
15997  #rafId = null
15998  #draggingRafId = null
15999  #listeners = new ListenerBin()
16000
16001  constructor(editor) {
16002    this.#editor = editor;
16003
16004    // Register Lexical commands at HIGH priority to intercept before the
16005    // base @lexical/rich-text handlers (which return true and consume the events).
16006    this.#listeners.track(
16007      editor.registerCommand(Be$2, (event) => this.#handleDragStart(event), so),
16008      editor.registerCommand(ze$2, (event) => this.#handleDrop(event), so),
16009    );
16010
16011    // Use a root listener to register DOM-level dragover/dragend handlers
16012    // (these events need throttled rAF handling that works better as DOM listeners).
16013    this.#listeners.track(editor.registerRootListener((root, prevRoot) => {
16014      if (prevRoot) {
16015        prevRoot.removeEventListener("dragover", this.#onDragOver);
16016        prevRoot.removeEventListener("dragend", this.#onDragEnd);
16017      }
16018      if (root) {
16019        root.addEventListener("dragover", this.#onDragOver);
16020        root.addEventListener("dragend", this.#onDragEnd);
16021      }
16022    }));
16023  }
16024
16025  destroy() {
16026    this.#cleanup();
16027    this.#listeners.dispose();
16028  }
16029
16030  // -- Event handlers --------------------------------------------------------
16031
16032  #handleDragStart(event) {
16033    if (event.target.closest?.("textarea")) return false
16034
16035    const figure = event.target.closest?.("figure.attachment[data-lexical-node-key]");
16036    if (!figure) return false
16037
16038    this.#draggedNodeKey = figure.dataset.lexicalNodeKey;
16039    event.dataTransfer.setData(MIME_TYPE$1, this.#draggedNodeKey);
16040    event.dataTransfer.effectAllowed = "move";
16041
16042    // Add dragging class after a tick so it doesn't affect the drag image
16043    this.#draggingRafId = requestAnimationFrame(() => {
16044      this.#draggingRafId = null;
16045      figure.classList.add("lexxy-dragging");
16046    });
16047
16048    return true
16049  }
16050
16051  #onDragOver = (event) => {
16052    if (!this.#draggedNodeKey) return
16053
16054    event.preventDefault();
16055    event.dataTransfer.dropEffect = "move";
16056
16057    if (!this.#rafId) {
16058      this.#rafId = requestAnimationFrame(() => {
16059        this.#rafId = null;
16060        this.#updateDropTarget(event);
16061      });
16062    }
16063  }
16064
16065  #handleDrop(event) {
16066    if (!this.#draggedNodeKey) return false
16067
16068    event.preventDefault();
16069
16070    const target = this.#resolveDropTarget(event);
16071    const draggedKey = this.#draggedNodeKey;
16072    this.#cleanup();
16073
16074    if (target) {
16075      this.#performDrop(draggedKey, target);
16076    }
16077    return true
16078  }
16079
16080  #onDragEnd = () => {
16081    this.#cleanup();
16082  }
16083
16084  // -- Drop target resolution -----------------------------------------------
16085
16086  #updateDropTarget(event) {
16087    this.#clearDropIndicators();
16088
16089    const target = this.#resolveDropTarget(event);
16090    if (!target) return
16091
16092    if (target.type === "gallery" || target.type === "gallery-reorder") {
16093      target.element.classList.add(`lexxy-drop-target--gallery-${target.position}`);
16094    } else if (target.type === "list-item") {
16095      target.element.classList.add(`lexxy-drop-target--list-${target.position}`);
16096    } else {
16097      target.element.classList.add(`lexxy-drop-target--block-${target.position}`);
16098    }
16099  }
16100
16101  #resolveDropTarget(event) {
16102    const element = document.elementFromPoint(event.clientX, event.clientY);
16103    if (!element) return null
16104
16105    const rootElement = this.#editor.getRootElement();
16106    if (!rootElement || !rootElement.contains(element)) return null
16107
16108    // Check if hovering over a previewable image (for gallery merge or reorder)
16109    const targetFigure = element.closest("figure.attachment--preview[data-lexical-node-key]");
16110    if (targetFigure && targetFigure.dataset.lexicalNodeKey !== this.#draggedNodeKey) {
16111      const targetGallery = targetFigure.closest(".attachment-gallery");
16112      if (targetGallery) {
16113        // If the dragged image is in the same gallery, this is a reorder
16114        const draggedFigure = rootElement.querySelector(`[data-lexical-node-key="${this.#draggedNodeKey}"]`);
16115        if (draggedFigure && targetGallery.contains(draggedFigure)) {
16116          const position = this.#computeHorizontalPosition(targetFigure, event.clientX);
16117          return { type: "gallery-reorder", element: targetFigure, nodeKey: targetFigure.dataset.lexicalNodeKey, position }
16118        }
16119      }
16120      const position = this.#computeHorizontalPosition(targetFigure, event.clientX);
16121      return { type: "gallery", element: targetFigure, nodeKey: targetFigure.dataset.lexicalNodeKey, position }
16122    }
16123
16124    // Hovering over the dragged image itself inside a gallery — treat as no-op
16125    // to prevent fallthrough to the block handler, which would eject it from the gallery.
16126    if (targetFigure && targetFigure.closest(".attachment-gallery")) return null
16127
16128    // Check if hovering over a gallery's empty space (for reorder within gallery)
16129    const targetGallery = element.closest(".attachment-gallery");
16130    if (targetGallery) {
16131      let galleryFigure = element.closest("figure.attachment[data-lexical-node-key]");
16132      if (!galleryFigure) {
16133        galleryFigure = this.#findNearestFigureInGallery(targetGallery, event.clientX);
16134      }
16135      if (galleryFigure && galleryFigure.dataset.lexicalNodeKey !== this.#draggedNodeKey) {
16136        const position = this.#computeHorizontalPosition(galleryFigure, event.clientX);
16137        return { type: "gallery-reorder", element: galleryFigure, nodeKey: galleryFigure.dataset.lexicalNodeKey, position }
16138      }
16139      // Nearest figure is the dragged image — no-op to avoid block handler fallthrough
16140      if (galleryFigure) return null
16141    }
16142
16143    // Check if hovering over a list item (for list splitting)
16144    const listItem = element.closest("li");
16145    if (listItem && rootElement.contains(listItem)) {
16146      const position = this.#computeVerticalPosition(listItem, event.clientY);
16147      return { type: "list-item", element: listItem, position }
16148    }
16149
16150    // Otherwise, find nearest block-level element for between-block insertion.
16151    // Normalize so each gap has exactly one indicator: prefer "after" on the
16152    // previous sibling, falling back to "before" only for the first block.
16153    const block = this.#findNearestBlock(element, rootElement, event.clientY);
16154    if (!block) return null
16155
16156    const position = this.#computeVerticalPosition(block, event.clientY);
16157    if (position === "before" && block.previousElementSibling) {
16158      return { type: "block", element: block.previousElementSibling, position: "after" }
16159    }
16160    return { type: "block", element: block, position }
16161  }
16162
16163  #findNearestBlock(element, rootElement, clientY) {
16164    let current = element;
16165    while (current && current !== rootElement) {
16166      if (current.parentElement === rootElement) return current
16167      current = current.parentElement;
16168    }
16169
16170    // elementFromPoint landed on the root itself (e.g. a margin gap between
16171    // blocks). Fall back to the nearest child by vertical distance.
16172    let nearest = null;
16173    let minDistance = Infinity;
16174    for (const child of rootElement.children) {
16175      const rect = child.getBoundingClientRect();
16176      const distance = Math.min(Math.abs(clientY - rect.top), Math.abs(clientY - rect.bottom));
16177      if (distance < minDistance) {
16178        minDistance = distance;
16179        nearest = child;
16180      }
16181    }
16182    return nearest
16183  }
16184
16185  #computeVerticalPosition(element, clientY) {
16186    const rect = element.getBoundingClientRect();
16187    return clientY < rect.top + rect.height / 2 ? "before" : "after"
16188  }
16189
16190  #computeHorizontalPosition(element, clientX) {
16191    const rect = element.getBoundingClientRect();
16192    return clientX < rect.left + rect.width / 2 ? "before" : "after"
16193  }
16194
16195  #findNearestFigureInGallery(gallery, clientX) {
16196    const figures = gallery.querySelectorAll("figure.attachment[data-lexical-node-key]");
16197    let nearest = null;
16198    let minDistance = Infinity;
16199    for (const figure of figures) {
16200      const rect = figure.getBoundingClientRect();
16201      const center = rect.left + rect.width / 2;
16202      const distance = Math.abs(clientX - center);
16203      if (distance < minDistance) {
16204        minDistance = distance;
16205        nearest = figure;
16206      }
16207    }
16208    return nearest
16209  }
16210
16211  // -- Drop indicator --------------------------------------------------------
16212
16213  static #DROP_CLASSES = [
16214    "lexxy-drop-target--gallery-before", "lexxy-drop-target--gallery-after",
16215    "lexxy-drop-target--list-before", "lexxy-drop-target--list-after",
16216    "lexxy-drop-target--block-before", "lexxy-drop-target--block-after",
16217  ]
16218
16219  #clearDropIndicators() {
16220    const rootElement = this.#editor.getRootElement();
16221    if (!rootElement) return
16222
16223    for (const el of rootElement.querySelectorAll("[class*='lexxy-drop-target--']")) {
16224      el.classList.remove(...AttachmentDragAndDrop.#DROP_CLASSES);
16225    }
16226  }
16227
16228  // -- Node operations -------------------------------------------------------
16229
16230  #performDrop(draggedKey, target) {
16231    const draggedNode = Yo(draggedKey);
16232    if (!draggedNode || !$isActionTextAttachmentNode(draggedNode)) return
16233
16234    if (target.type === "gallery") {
16235      this.#dropOntoImage(draggedNode, target.nodeKey, target.position);
16236    } else if (target.type === "gallery-reorder") {
16237      this.#reorderInGallery(draggedNode, target.nodeKey, target.position);
16238    } else if (target.type === "list-item") {
16239      this.#dropIntoList(draggedNode, target);
16240    } else {
16241      this.#dropBetweenBlocks(draggedNode, target);
16242    }
16243
16244    // Clear selection to prevent a second history entry. Lexical dispatches
16245    // SELECTION_CHANGE_COMMAND during commit for non-range selections, which
16246    // creates a separate update. Null selection avoids that dispatch entirely
16247    // and also prevents Firefox's follow-up selectionchange from dirtying nodes.
16248    es(null);
16249  }
16250
16251  #dropOntoImage(draggedNode, targetKey, position) {
16252    const targetNode = Yo(targetKey);
16253    if (!targetNode || !$isActionTextAttachmentNode(targetNode)) return
16254    if (draggedNode.is(targetNode)) return
16255
16256    draggedNode.remove();
16257
16258    const gallery = $findOrCreateGalleryForImage(targetNode);
16259    if (gallery) {
16260      if (position === "before") {
16261        targetNode.insertBefore(draggedNode);
16262      } else {
16263        targetNode.insertAfter(draggedNode);
16264      }
16265    }
16266  }
16267
16268  #reorderInGallery(draggedNode, targetKey, position) {
16269    const targetNode = Yo(targetKey);
16270    if (!targetNode || draggedNode.is(targetNode)) return
16271
16272    draggedNode.remove();
16273
16274    if (position === "before") {
16275      targetNode.insertBefore(draggedNode);
16276    } else {
16277      targetNode.insertAfter(draggedNode);
16278    }
16279  }
16280
16281  #dropIntoList(draggedNode, target) {
16282    const listItemNode = Go(target.element);
16283    if (!listItemNode || !pe$2(listItemNode)) return
16284
16285    const listNode = listItemNode.getParent();
16286    if (!listNode || !Se$1(listNode)) return
16287
16288    const children = listNode.getChildren();
16289    const index = children.indexOf(listItemNode);
16290    if (index === -1) return
16291
16292    const splitIndex = target.position === "before" ? index : index + 1;
16293
16294    draggedNode.remove();
16295
16296    if (splitIndex === 0) {
16297      listNode.insertBefore(draggedNode);
16298    } else if (splitIndex >= children.length) {
16299      listNode.insertAfter(draggedNode);
16300    } else {
16301      const [ , listAfter ] = Us(listNode, splitIndex);
16302      listAfter.insertBefore(draggedNode);
16303    }
16304  }
16305
16306  #dropBetweenBlocks(draggedNode, target) {
16307    const targetNode = Go(target.element);
16308    if (!targetNode) return
16309
16310    const topLevelTarget = targetNode.getTopLevelElement?.() || targetNode;
16311    if (draggedNode.is(topLevelTarget)) return
16312
16313    draggedNode.remove();
16314
16315    if (target.position === "before") {
16316      topLevelTarget.insertBefore(draggedNode);
16317    } else {
16318      topLevelTarget.insertAfter(draggedNode);
16319    }
16320  }
16321
16322  // -- Lifecycle helpers -----------------------------------------------------
16323
16324  #cleanup() {
16325    this.#clearDropIndicators();
16326
16327    if (this.#draggedNodeKey) {
16328      const rootElement = this.#editor.getRootElement();
16329      if (rootElement) {
16330        const figure = rootElement.querySelector(`[data-lexical-node
16330-key="${this.#draggedNodeKey}"]`);
16331        figure?.classList.remove("lexxy-dragging");
16332      }
16333    }
16334
16335    this.#draggedNodeKey = null;
16336
16337    if (this.#rafId) {
16338      cancelAnimationFrame(this.#rafId);
16339      this.#rafId = null;
16340    }
16341
16342    if (this.#draggingRafId) {
16343      cancelAnimationFrame(this.#draggingRafId);
16344      this.#draggingRafId = null;
16345    }
16346  }
16347}
16348
16349const ATTACHMENT_ATTRIBUTES = [ "alt", "caption", "content", "content-type", "data-direct-upload-id",
16350  "data-sgid", "filename", "filesize", "height", "presentation", "previewable", "sgid", "url", "width" ];
16351
16352const UPLOADS_BUSY_MESSAGE = "Please wait for all files to upload";
16353
16354class AttachmentsExtension extends LexxyExtension {
16355  #uploadsCount = 0
16356
16357  get enabled() {
16358    return this.editorElement.supportsAttachments
16359  }
16360
16361  get allowedElements() {
16362    return [ { tag: ActionTextAttachmentNode.TAG_NAME, attributes: ATTACHMENT_ATTRIBUTES } ]
16363  }
16364
16365  get lexicalExtension() {
16366    return dc({
16367      name: "lexxy/action-text-attachments",
16368      nodes: [
16369        ActionTextAttachmentNode,
16370        ActionTextAttachmentUploadNode,
16371        ImageGalleryNode
16372      ],
16373      register: (editor) => {
16374        const dragAndDrop = new AttachmentDragAndDrop(editor);
16375
16376        return Cc(
16377          editor.registerNodeTransform(ActionTextAttachmentNode, $extractAttachmentFromParagraph),
16378          editor.registerCommand(fe$4, $collapseIntoGallery, oo),
16379          editor.registerMutationListener(ActionTextAttachmentUploadNode, this.#handleUploadMutations.bind(this)),
16380          () => dragAndDrop.destroy()
16381        )
16382      }
16383    })
16384  }
16385
16386  #handleUploadMutations(mutations) {
16387    const previousUploadsCount = this.#uploadsCount;
16388    for (const [ key, mutation ] of mutations) {
16389      if (mutation === "created") {
16390        this.#uploadsCount++;
16391      } else if (mutation === "destroyed") {
16392        this.#uploadsCount--;
16393        this.editorElement.uploadRequests.abort(key);
16394      }
16395    }
16396
16397    if (this.#uploadsCount !== previousUploadsCount) {
16398      this.#setUploadsValidity();
16399    }
16400  }
16401
16402  #setUploadsValidity() {
16403    if (this.#uploadsCount) {
16404      this.setEditorValidity({ customError: true }, UPLOADS_BUSY_MESSAGE);
16405    } else {
16406      this.setEditorValidity({});
16407    }
16408  }
16409}
16410
16411// Decorator nodes can be wrapped in a Paragraph Node by Lexical when contained in a <div>
16412// We remove them, splitting the node as needed
16413function $extractAttachmentFromParagraph(attachmentNode) {
16414  const parentNode = attachmentNode.getParent();
16415  if (!no(parentNode)) return
16416
16417  if (parentNode.getChildrenSize() === 1) {
16418    parentNode.replace(attachmentNode);
16419  } else {
16420    const index = attachmentNode.getIndexWithinParent();
16421    const [ topParagraph, bottomParagraph ] = Us(parentNode, index);
16422    topParagraph.insertAfter(attachmentNode);
16423
16424    for (const p of [ topParagraph, bottomParagraph ]) {
16425      if (p.isEmpty()) p.remove();
16426    }
16427  }
16428}
16429
16430function $collapseIntoGallery(backwards) {
16431  const anchor = Qr()?.anchor;
16432  if (!anchor) return false
16433
16434  if ($collapseAtGalleryEdge(anchor, backwards)) {
16435    return true
16436  } else if (backwards) {
16437    return $collapseAroundEmptyParagraph(anchor)
16438      || $moveSelectionBeforeGallery(anchor)
16439  }
16440
16441  return false
16442}
16443
16444function $collapseAroundEmptyParagraph(anchor) {
16445  const anchorNode = anchor.getNode();
16446  if (!anchorNode) return false
16447
16448  const isWithinEmptyParagraph = no(anchorNode) && anchorNode.isEmpty();
16449  const previousSibling = anchorNode.getPreviousSibling();
16450  const topGallery = $findOrCreateGalleryForImage(previousSibling);
16451  const selectionIndex = topGallery?.getChildrenSize();
16452
16453  if (isWithinEmptyParagraph && topGallery?.collapseWith(anchorNode.getNextSibling())) {
16454    topGallery.select(selectionIndex, selectionIndex);
16455    anchorNode.remove();
16456    return true
16457  } else {
16458    return false
16459  }
16460}
16461
16462function $collapseAtGalleryEdge(anchor, backwards) {
16463  const anchorNode = anchor.getNode();
16464  if (!$isImageGalleryNode(anchorNode)) return false
16465
16466  const isAtGalleryEdge = $isAtNodeEdge(anchor, backwards);
16467  const sibling = backwards ? anchorNode.getPreviousSibling() : anchorNode.getNextSibling();
16468
16469  if (isAtGalleryEdge && anchorNode.collapseWith(sibling, backwards)) {
16470    const selectionOffset = backwards ? 1 : anchorNode.getChildrenSize() - 1;
16471    anchorNode.select(selectionOffset, selectionOffset);
16472    return true
16473  } else {
16474    return false
16475  }
16476}
16477
16478// Manual selection handling to prevent Lexical merging the gallery with a <p> and unwrapping it
16479function $moveSelectionBeforeGallery(anchor) {
16480  const previousNode = anchor.getNode().getPreviousSibling();
16481  if (!$isImageGalleryNode(anchor.getNode()) || !$isAtNodeEdge(anchor, true) || !previousNode) return false
16482
16483  if (ji(previousNode)) {
16484    // Handled by Lexxy decorator selection behavior
16485    return false
16486  } else if (previousNode.isEmpty()) {
16487    previousNode.remove();
16488  } else {
16489    previousNode.selectEnd();
16490  }
16491
16492  return true
16493}
16494
vendor: 71,654 bytes, lines 16495-18937
16495class EarlyEscapeCodeNode extends z$1 {
16496  $config() {
16497    return this.config("early_escape_code", { extends: z$1 })
16498  }
16499
16500  static $fromSelection(selection) {
16501    const anchorNode = selection.anchor.getNode();
16502    return At$2(anchorNode, EarlyEscapeCodeNode)
16503      || (anchorNode instanceof EarlyEscapeCodeNode ? anchorNode : null)
16504  }
16505
16506  insertNewAfter(selection, restoreSelection) {
16507    if (Es(jn) || !selection.isCollapsed()) {
16508      return super.insertNewAfter(selection, restoreSelection)
16509    } else if (this.#isCursorAtStart(selection)) {
16510      return this.#insertParagraphBefore()
16511    } else if (this.#isCursorOnWhitespaceOnlyLastLine(selection)) {
16512      return this.#insertBlankLineBelow(selection, restoreSelection)
16513    } else if (this.#isCursorOnEmptyLastLine(selection)) {
16514      return this.#escapeToNewParagraphAfter()
16515    } else {
16516      return super.insertNewAfter(selection, restoreSelection)
16517    }
16518  }
16519
16520  #isCursorAtStart(selection) {
16521    const { anchor } = selection;
16522    if (!$isAtNodeStart(anchor)) return false
16523
16524    const anchorNode = anchor.getNode();
16525    return this.is(anchorNode) || this.getFirstChild()?.is(anchorNode)
16526  }
16527
16528  #isCursorOnEmptyLastLine(selection) {
16529    if (!$isCursorOnLastLine(selection)) return false
16530
16531    const textContent = this.getTextContent();
16532    return textContent === "" || textContent.endsWith("\n")
16533  }
16534
16535  #isCursorOnWhitespaceOnlyLastLine(selection) {
16536    if (!$isCursorOnLastLine(selection)) return false
16537
16538    const textContent = this.getTextContent();
16539    const lastNewlineIndex = textContent.lastIndexOf("\n");
16540    const lastLine = lastNewlineIndex === -1 ? textContent : textContent.slice(lastNewlineIndex + 1);
16541    return lastLine.length > 0 && lastLine.trim() === ""
16542  }
16543
16544  #insertParagraphBefore() {
16545    this.insertBefore(eo());
16546    return null
16547  }
16548
16549  #insertBlankLineBelow(selection, restoreSelection) {
16550    super.insertNewAfter(selection, restoreSelection);
16551    this.getLastChild().remove();
16552    return null
16553  }
16554
16555  #escapeToNewParagraphAfter() {
16556    $trimTrailingBlankNodes(this);
16557    const paragraph = eo();
16558    this.insertAfter(paragraph);
16559    return paragraph
16560  }
16561}
16562
16563class EarlyEscapeListItemNode extends ge$2 {
16564  $config() {
16565    return this.config("early_escape_listitem", { extends: ge$2 })
16566  }
16567
16568  insertNewAfter(selection, restoreSelection) {
16569    if (this.#shouldEscape(selection)) {
16570      return this.#escapeFromList()
16571    }
16572
16573    return super.insertNewAfter(selection, restoreSelection)
16574  }
16575
16576  get #isInBlockquote() {
16577    return Boolean(At$2(this, At$1))
16578  }
16579
16580  #shouldEscape(selection) {
16581    if (this.#isInPasteOperation() || !this.#isInBlockquote) {
16582      return false
16583    } else if ($isBlankNode(this)) {
16584      return true
16585    } else {
16586      const paragraph = At$2(selection.anchor.getNode(), Zi);
16587      return paragraph && $isBlankNode(paragraph) && pe$2(paragraph.getParent())
16588    }
16589  }
16590
16591  #isInPasteOperation() {
16592    return Es(jn)
16593  }
16594
16595  #escapeFromList() {
16596    const parentList = this.getParent();
16597    if (!parentList || !Se$1(parentList)) return
16598
16599    const blockquote = parentList.getParent();
16600    const isInBlockquote = blockquote && Mt$2(blockquote);
16601
16602    if (isInBlockquote) {
16603      const hasNonEmptyListItems = this.getNextSiblings().some(
16604        sibling => pe$2(sibling) && !$isBlankNode(sibling)
16605      );
16606
16607      if (hasNonEmptyListItems) {
16608        return this.#splitBlockquoteWithList()
16609      }
16610    }
16611
16612    const paragraph = eo();
16613    parentList.insertAfter(paragraph);
16614
16615    this.remove();
16616    return paragraph
16617  }
16618
16619  #splitBlockquoteWithList() {
16620    const splitQuotes = Us(this.getParent(), this.getIndexWithinParent());
16621    this.remove();
16622
16623    const middleParagraph = eo();
16624    splitQuotes[0].insertAfter(middleParagraph);
16625
16626    splitQuotes.forEach($trimTrailingBlankNodes);
16627
16628    return middleParagraph
16629  }
16630
16631}
16632
16633class FormatEscapeExtension extends LexxyExtension {
16634
16635  get enabled() {
16636    return this.editorElement.supportsRichText
16637  }
16638
16639  get allowedElements() {
16640    return [ { tag: "ol", attributes: [ "start" ] }, { tag: "li", attributes: [ "value" ] } ]
16641  }
16642
16643  get lexicalExtension() {
16644    return dc({
16645      name: "lexxy/format-escape",
16646      nodes: [
16647        EarlyEscapeCodeNode,
16648        { replace: z$1, with: (node) => new EarlyEscapeCodeNode(node.getLanguage()), withKlass: EarlyEscapeCodeNode },
16649        EarlyEscapeListItemNode,
16650        { replace: ge$2, with: () => new EarlyEscapeListItemNode(), withKlass: EarlyEscapeListItemNode },
16651      ],
16652      register(editor) {
16653        return Cc(
16654          editor.registerCommand(
16655            he$3,
16656            () => $escapeFromBlockquote(),
16657            so
16658          ),
16659          editor.registerCommand(
16660            Ee$3,
16661            (event) => $handleArrowDownInCodeBlock(event),
16662            oo
16663          ),
16664          editor.registerNodeTransform(At$1, $ensureQuoteHasParagraphChild)
16665        )
16666      }
16667    })
16668  }
16669}
16670
16671function $escapeFromBlockquote() {
16672  return $escapeBeforeBlockquoteStart() || $escapeFromBlankBlockquoteParagraph()
16673}
16674
16675function $escapeBeforeBlockquoteStart() {
16676  const selection = Qr();
16677  if (!Fr(selection) || !selection.isCollapsed() || selection.anchor.offset !== 0) return false
16678
16679  const paragraph = At$2(selection.anchor.getNode(), Zi);
16680  if (paragraph && !$isBlankNode(paragraph) && !paragraph.getPreviousSibling()) {
16681    const blockquote = paragraph.getParent();
16682    if (Mt$2(blockquote)) {
16683      blockquote.insertBefore(eo());
16684      return true
16685    }
16686  }
16687
16688  return false
16689}
16690
16691function $escapeFromBlankBlockquoteParagraph() {
16692  const anchorNode = Qr().anchor.getNode();
16693
16694  const paragraph = At$2(anchorNode, Zi);
16695  if (!paragraph || !$isBlankNode(paragraph)) return false
16696
16697  const blockquote = paragraph.getParent();
16698  if (Mt$2(blockquote)) {
16699    const nonEmptySiblings = paragraph.getNextSiblings().filter(sibling => !$isBlankNode(sibling));
16700
16701    if (nonEmptySiblings.length > 0) {
16702      $splitQuoteNode(blockquote, paragraph);
16703    } else {
16704      blockquote.insertAfter(paragraph);
16705      paragraph.selectStart();
16706    }
16707
16708    return true
16709  }
16710
16711  return false
16712}
16713
16714function $splitQuoteNode(node, paragraph) {
16715  const splitQuotes = Us(node, paragraph.getIndexWithinParent());
16716  splitQuotes[0].insertAfter(paragraph);
16717  splitQuotes.forEach($trimTrailingBlankNodes);
16718  paragraph.selectEnd();
16719}
16720
16721function $handleArrowDownInCodeBlock(event) {
16722  const selection = Qr();
16723  if (!Fr(selection) || !selection.isCollapsed()) return false
16724
16725  const codeNode = EarlyEscapeCodeNode.$fromSelection(selection);
16726  if (!codeNode) return false
16727
16728  if ($isCursorOnLastLine(selection) && !codeNode.getNextSibling()) {
16729    event?.preventDefault();
16730    const paragraph = eo();
16731    codeNode.insertAfter(paragraph);
16732    paragraph.selectEnd();
16733    return true
16734  }
16735
16736  return false
16737}
16738
16739function $ensureQuoteHasParagraphChild(quoteNode) {
16740  if (!quoteNode.isEmpty()) return
16741
16742  quoteNode.append(eo());
16743  if ($containsRangeSelection(quoteNode)) quoteNode.getFirstChild().select();
16744}
16745
16746class LinkOpenerExtension extends LexxyExtension {
16747  get enabled() {
16748    return this.editorElement.supportsRichText
16749  }
16750
16751  get lexicalExtension() {
16752    return dc({
16753      name: "lexxy/link-opener",
16754      register: (editor) => Cc(
16755        editor.registerCommand(se$5, this.#handleClick.bind(this), oo),
16756        registerEventListener(this.editorElement.editorContentElement, "auxclick", this.#handleAuxClick.bind(this)),
16757        registerEventListener(window, "keydown", this.#handleKey.bind(this)),
16758        registerEventListener(window, "keyup", this.#handleKey.bind(this)),
16759        registerEventListener(window, "focus", this.#handleFocus.bind(this))
16760      )
16761    })
16762  }
16763
16764  #handleClick(event) {
16765    if (this.#isModified(event)) {
16766      return $openLink(event.target)
16767    } else {
16768      return false
16769    }
16770  }
16771
16772  #handleAuxClick(event) {
16773    if (event.button === 1) {
16774      this.editorElement.editor.read(() => $openLink(event.target));
16775    }
16776  }
16777
16778  #handleKey(event) {
16779    this.#updateOpenableAttribute(event);
16780  }
16781
16782  // Chrome dispatches events without modifier keys *for a while* after changing tabs
16783  async #handleFocus() {
16784    await delay(200);
16785    this.editorElement.addEventListener("mousemove", this.#updateOpenableAttribute.bind(this), { once: true });
16786  }
16787
16788  #updateOpenableAttribute(event) {
16789    this.editorElement.toggleAttribute("data-links-openable", this.#isModified(event));
16790  }
16791
16792  #isModified(event) {
16793    return lt$2 ? event.metaKey : event.ctrlKey
16794  }
16795}
16796
16797function $openLink(target) {
16798  const node = Go(target);
16799  const linkNode = dl(node, z$5);
16800  if (linkNode) {
16801    const url = linkNode.sanitizeUrl(linkNode.getURL());
16802    window.open(url, "_blank", "noopener,noreferrer");
16803    return true
16804  } else {
16805    return false
16806  }
16807}
16808
16809class PreventLexicalTripleClickExtension extends LexxyExtension {
16810  get lexicalExtension() {
16811    return dc({
16812      name: "lexxy/prevent-lexical-triple-click",
16813      register: (editor) => editor.registerRootListener((rootElement) => {
16814        if (rootElement) {
16815          return registerEventListener(
16816            rootElement,
16817            "click",
16818            this.#handleTripleClick.bind(this),
16819            { capture: true }
16820          )
16821        }
16822      })
16823    })
16824  }
16825
16826  // Stop propagation of the triple-click to prevent Lexical's handler from running.
16827  //
16828  // Lexical's onClick handler implements a triple-click handler that is trivial/anemic/naïve. The
16829  // intention of the change, made in facebook/lexical#4512, seems to be to deal with browsers'
16830  // "overselection" behavior, where a triple-click selection might end at offset 0 of the following
16831  // block, which can cause issues when transforming the selection. But the implementation breaks
16832  // many common real-world use cases and Lexxy does not demonstrate the behavior it's intended to
16833  // work around (in headers or tables).
16834  #handleTripleClick(event) {
16835    if (event.detail === 3) {
16836      event.stopPropagation();
16837    }
16838  }
16839}
16840
16841function caretRect(node, offset) {
16842  const range = document.createRange();
16843  range.setStart(node, offset);
16844  range.collapse(true);
16845
16846  const rect = range.getBoundingClientRect();
16847  if (rect.height > 0) {
16848    return rect
16849  } else {
16850    return null
16851  }
16852}
16853
16854function caretFromPoint(clientX, clientY) {
16855  if (document.caretPositionFromPoint) {
16856    const position = document.caretPositionFromPoint(clientX, clientY);
16857    if (position) return { node: position.offsetNode, offset: position.offset }
16858  } else if (document.caretRangeFromPoint) {
16859    const range = document.caretRangeFromPoint(clientX, clientY);
16860    if (range) return { node: range.startContainer, offset: range.startOffset }
16861  }
16862
16863  return null
16864}
16865
16866const MIME_TYPE = "application/x-lexxy-custom-attachment-key";
16867
16868// Custom inline attachments reorder by dropping at a text caret, unlike block
16869// attachments which insert between blocks or into galleries.
16870class CustomAttachmentDragAndDrop {
16871  #editor
16872  #draggedNodeKey = null
16873  #draggingRafId = null
16874  #dragOverRafId = null
16875  #dropIndicator = null
16876  #listeners = new ListenerBin()
16877
16878  constructor(editor) {
16879    this.#editor = editor;
16880
16881    // Register at HIGH priority to intercept before the base @lexical/rich-text
16882    // handlers, which consume drag events. The block-attachment handler also
16883    // registers here but bails for inline custom attachments, so we get our turn.
16884    this.#listeners.track(
16885      editor.registerCommand(Be$2, (event) => this.#handleDragStart(event), so),
16886      editor.registerCommand(ze$2, (event) => this.#handleDrop(event), so)
16887    );
16888
16889    this.#listeners.track(editor.registerRootListener((root, prevRoot) => {
16890      if (prevRoot) {
16891        prevRoot.removeEventListener("dragover", this.#onDragOver);
16892        prevRoot.removeEventListener("dragend", this.#onDragEnd);
16893      }
16894      if (root) {
16895        root.addEventListener("dragover", this.#onDragOver);
16896        root.addEventListener("dragend", this.#onDragEnd);
16897      }
16898    }));
16899  }
16900
16901  destroy() {
16902    this.#cleanup();
16903    this.#dropIndicator?.remove();
16904    this.#dropIndicator = null;
16905    this.#listeners.dispose();
16906  }
16907
16908  #handleDragStart(event) {
16909    const attachment = this.#customAttachmentElementFrom(event.target);
16910    if (!attachment) return false
16911
16912    this.#draggedNodeKey = attachment.dataset.lexicalNodeKey;
16913    event.dataTransfer.setData(MIME_TYPE, this.#draggedNodeKey);
16914    event.dataTransfer.effectAllowed = "move";
16915
16916    this.#draggingRafId = requestAnimationFrame(() => {
16917      this.#draggingRafId = null;
16918      attachment.classList.add("lexxy-dragging");
16919    });
16920
16921    return true
16922  }
16923
16924  #onDragOver = (event) => {
16925    if (!this.#draggedNodeKey) return
16926
16927    event.preventDefault();
16928    event.dataTransfer.dropEffect = "move";
16929
16930    if (!this.#dragOverRafId) {
16931      this.#dragOverRafId = requestAnimationFrame(() => {
16932        this.#dragOverRafId = null;
16933        this.#updateDropIndicator(event);
16934      });
16935    }
16936  }
16937
16938  #onDragEnd = () => {
16939    this.#cleanup();
16940  }
16941
16942  #handleDrop(event) {
16943    if (!this.#draggedNodeKey) return false
16944
16945    event.preventDefault();
16946
16947    const dropPoint = this.#resolveDropPoint(event);
16948    const draggedKey = this.#draggedNodeKey;
16949    this.#cleanup();
16950
16951    if (dropPoint) {
16952      this.#moveAttachment(draggedKey, dropPoint);
16953    }
16954
16955    return true
16956  }
16957
16958  #resolveDropPoint(event) {
16959    const rootElement = this.#editor.getRootElement();
16960    if (!rootElement) return null
16961
16962    const caret = caretFromPoint(event.clientX, event.clientY);
16963    if (!caret || !rootElement.contains(caret.node)) return null
16964
16965    // A caret on the root itself points between blocks. Mentions behave like text:
16966    // they only drop onto an existing line, so snap to the nearest one.
16967    if (caret.node === rootElement) {
16968      return this.#nearestLineCaret(rootElement, event.clientY)
16969    }
16970
16971    // When mentions sit next to each other with no text between them, the caret
16972    // lands inside the neighbouring decorator's DOM. Lexical can't resolve a point
16973    // inside a decorator to an editable position, and the cursor has no business
16974    // showing there anyway, so snap to just before or after that mention.
16975    const decorator = this.#decoratorElementContaining(caret.node);
16976    if (decorator) {
16977      return this.#dropPointBesideDecorator(decorator, event.clientX)
16978    } else {
16979      return caret
16980    }
16981  }
16982
16983  #nearestLineCaret(rootElement, clientY) {
16984    let nearestLine = null;
16985    let nearestDistance = Infinity;
16986
16987    for (const line of rootElement.children) {
16988      const rect = line.getBoundingClientRect();
16989      const distance = Math.min(Math.abs(clientY - rect.top), Math.abs(clientY - rect.bottom));
16990      if (distance < nearestDistance) {
16991        nearestDistance = distance;
16992        nearestLine = line;
16993      }
16994    }
16995
16996    if (!nearestLine) return null
16997
16998    const rect = nearestLine.getBoundingClientRect();
16999    if (clientY < rect.top) {
17000      return { node: nearestLine, offset: 0 }
17001    } else {
17002      return { node: nearestLine, offset: nearestLine.childNodes.length }
17003    }
17004  }
17005
17006  #decoratorElementContaining(node) {
17007    const element = node.nodeType === Node.ELEMENT_NODE ? node : node.parentElement;
17008    return element?.closest("[data-lexxy-decorator][data-lexical-node-key]")
17009  }
17010
17011  #dropPointBesideDecorator(decorator, clientX) {
17012    const rect = decorator.getBoundingClientRect();
17013    const placement = clientX > rect.left + rect.width / 2 ? "after" : "before";
17014    return { decoratorKey: decorator.dataset.lexicalNodeKey, placement }
17015  }
17016
17017  #moveAttachment(draggedKey, dropPoint) {
17018    this.#editor.update(() => {
17019      const draggedNode = Yo(draggedKey);
17020      if (!$isCustomActionTextAttachmentNode(draggedNode)) return
17021
17022      if (dropPoint.decoratorKey) {
17023        this.#moveBesideNode(draggedNode, dropPoint);
17024      } else {
17025        this.#moveToCaret(draggedNode, dropPoint);
17026      }
17027    });
17028  }
17029
17030  #moveBesideNode(draggedNode, { decoratorKey, placement }) {
17031    const targetNode = Yo(decoratorKey);
17032    if (!targetNode || targetNode === draggedNode) return
17033
17034    draggedNode.remove();
17035    if (placement === "after") {
17036      targetNode.insertAfter(draggedNode);
17037    } else {
17038      targetNode.insertBefore(draggedNode);
17039    }
17040  }
17041
17042  #moveToCaret(draggedNode, dropPoint) {
17043    const selection = Gr({
17044      anchorNode: dropPoint.node,
17045      anchorOffset: dropPoint.offset,
17046      focusNode: dropPoint.node,
17047      focusOffset: dropPoint.offset
17048    }, this.#editor);
17049    if (!selection) return
17050
17051    es(selection);
17052
17053    draggedNode.remove();
17054    selection.insertNodes([ draggedNode ]);
17055  }
17056
17057  #updateDropIndicator(event) {
17058    this.#hideCaret();
17059
17060    const dropPoint = this.#resolveDropPoint(event);
17061    if (dropPoint) this.#showCaret(this.#caretRectFor(dropPoint));
17062  }
17063
17064  #caretRectFor(dropPoint) {
17065    if (dropPoint.decoratorKey) {
17066      return this.#decoratorEdgeRect(dropPoint)
17067    }
17068
17069    const { node, offset } = dropPoint;
17070    const rect = caretRect(node, offset);
17071    if (rect) return rect
17072
17073    // A blank line has no text to measure, so fall back to the line's own box.
17074    const line = node.nodeType === Node.TEXT_NODE ? node.parentElement : node;
17075    if (!line) return null
17076
17077    const lineRect = line.getBoundingClientRect();
17078    return { left: lineRect.left, top: lineRect.top, height: lineRect.height }
17079  }
17080
17081  #decoratorEdgeRect({ decoratorKey, placement }) {
17082    const decorator = this.#editor.getRootElement()?.querySelector(`[data-lexical-node-key="${decoratorKey}"]`);
17083    if (!decorator) return null
17084
17085    const rect = decorator.getBoundingClientRect();
17086    const left = placement === "after" ? rect.right : rect.left;
17087    return { left, top: rect.top, height: rect.height }
17088  }
17089
17090  #showCaret(rect) {
17091    if (!rect) return
17092
17093    const caret = this.#ensureCaretIndicator();
17094    caret.style.blockSize = `${rect.height}px`;
17095    caret.style.insetInlineStart = `${rect.left}px`;
17096    caret.style.insetBlockStart = `${rect.top}px`;
17097  }
17098
17099  #ensureCaretIndicator() {
17100    this.#dropIndicator ||= createElement("div", { className: "lexxy-drop-caret" });
17101
17102    this.#editorElement().appendChild(this.#dropIndicator);
17103    this.#dropIndicator.style.display = "block";
17104    return this.#dropIndicator
17105  }
17106
17107  #editorElement() {
17108    return this.#editor.getRootElement().closest("lexxy-editor")
17109  }
17110
17111  #hideCaret() {
17112    if (this.#dropIndicator) this.#dropIndicator.style.display = "none";
17113  }
17114
17115  #customAttachmentElementFrom(target) {
17116    return target?.closest?.("[data-lexxy-decorator][data-lexical-node-key]")
17117  }
17118
17119  #cleanup() {
17120    if (this.#draggedNodeKey) {
17121      const rootElement = this.#editor.getRootElement();
17122      const attachment = rootElement?.querySelector(`[data-lexical-node-key="${this.#draggedNodeKey}"]`);
17123      attachment?.classList.remove("lexxy-dragging");
17124    }
17125
17126    this.#hideCaret();
17127    this.#draggedNodeKey = null;
17128
17129    if (this.#draggingRafId) {
17130      cancelAnimationFrame(this.#draggingRafId);
17131      this.#draggingRafId = null;
17132    }
17133
17134    if (this.#dragOverRafId) {
17135      cancelAnimationFrame(this.#dragOverRafId);
17136      this.#dragOverRafId = null;
17137    }
17138  }
17139}
17140
17141class CustomAttachmentDragAndDropExtension extends LexxyExtension {
17142  get enabled() {
17143    return this.editorElement.supportsRichText
17144  }
17145
17146  get lexicalExtension() {
17147    return dc({
17148      name: "lexxy/custom-attachment-drag-and-drop",
17149      register: (editor) => {
17150        const dragAndDrop = new CustomAttachmentDragAndDrop(editor);
17151        return () => dragAndDrop.destroy()
17152      }
17153    })
17154  }
17155}
17156
17157const LINE_SEPARATORS = /\r\n|[\n\r\u2028\u2029]/;
17158
17159// A literal line separator inside a text node renders as a break in the editor, or not at all,
17160// but never survives serialization to HTML. macOS text replacements deliver U+2028 LINE SEPARATOR,
17161// and other insertions can carry "\n", so however the text arrives, a transform converts whatever
17162// lands in a text node into line break nodes.
17163class LineSeparatorsExtension extends LexxyExtension {
17164  get lexicalExtension() {
17165    return this.defineExtension({
17166      name: "lexxy/line-separators",
17167      register(editor) {
17168        return editor.registerNodeTransform(gr, $replaceLineSeparatorWithLineBreak)
17169      }
17170    })
17171  }
17172}
17173
17174// Replaces the first separator only: the split leaves dirty text nodes behind, so Lexical re-runs
17175// the transform until none remain.
17176function $replaceLineSeparatorWithLineBreak(textNode) {
17177  const match = textNode.getTextContent().match(LINE_SEPARATORS);
17178
17179  if (match) {
17180    let separatorNode;
17181    if (match.index === 0) {
17182      [ separatorNode ] = textNode.splitText(match[0].length);
17183    } else {
17184      [ , separatorNode ] = textNode.splitText(match.index, match.index + match[0].length);
17185    }
17186    separatorNode.replace(or());
17187  }
17188}
17189
17190class LexicalEditorElement extends HTMLElement {
17191  static formAssociated = true
17192  static debug = false
17193  static commands = [ "bold", "italic", "strikethrough" ]
17194
17195  static observedAttributes = [ "autocapitalize", "connected", "required" ]
17196
17197  #initialValue = ""
17198  #previousInternalFormValue = null
17199
17200  #initializeEventDispatched = false
17201  #editorInitializedDispatched = false
17202  #listeners = new ListenerBin()
17203  #disposables = []
17204  #historyState = { undo: false, redo: false }
17205
17206  #validity = new Map()
17207  #validationTextArea = document.createElement("textarea")
17208  #uploadRequests
17209
17210  constructor() {
17211    super();
17212    this.internals = this.attachInternals();
17213    this.internals.role = "presentation";
17214  }
17215
17216  get uploadRequests() {
17217    return this.#uploadRequests
17218  }
17219
17220  connectedCallback() {
17221    this.id ||= generateDomId("lexxy-editor");
17222    this.config = new EditorConfiguration(this);
17223    this.extensions = new Extensions(this);
17224    this.#disposables.push(this.extensions);
17225
17226    this.editor = this.#createEditor();
17227    this.#disposables.push(this.editor);
17228    this.#disposables.push(this.#listeners);
17229
17230    this.contents = new Contents(this);
17231    this.#disposables.push(this.contents);
17232
17233    this.selection = new Selection(this);
17234    this.#disposables.push(this.selection);
17235
17236    this.clipboard = new Clipboard(this);
17237    this.#disposables.push(this.clipboard);
17238
17239    this.adapter = new BrowserAdapter();
17240    this.#uploadRequests = new UploadRequests();
17241
17242    const commandDispatcher = CommandDispatcher.configureFor(this);
17243    this.#disposables.push(commandDispatcher);
17244
17245    this.#initialize();
17246
17247    this.toggleAttribute("connected", true);
17248
17249    requestAnimationFrame(() => {
17250      this.#mountRoot();
17251      this.#handleAutofocus();
17252      this.#dispatchInitialize();
17253    });
17254  }
17255
17256  disconnectedCallback() {
17257    this.#initializeEventDispatched = false;
17258    this.#editorInitializedDispatched = false;
17259
17260    this.#previousInternalFormValue = null;
17261    this.valueBeforeDisconnect = this.value;
17262
17263    this.#clearCachedValues();
17264    this.#reset(); // Prevent hangs with Safari when morphing
17265  }
17266
17267  attributeChangedCallback(name, oldValue, newValue) {
17268    if (typeof this[`${name}ChangedCallback`] === "function") {
17269      this[`${name}ChangedCallback`](oldValue, newValue);
17270    }
17271  }
17272
17273  autocapitalizeChangedCallback() {
17274    if (this.editorContentElement) {
17275      this.#transferAttributeToContentEditable(this.editorContentElement, "autocapitalize");
17276    }
17277  }
17278
17279  connectedChangedCallback(oldValue, newValue) {
17280    if (this.isConnected && oldValue != null && oldValue !== newValue) {
17281      requestAnimationFrame(() => this.#reconnect());
17282    }
17283  }
17284
17285  requiredChangedCallback() {
17286    if (this.isConnected) this.#requestValidityRefresh();
17287  }
17288
17289  formResetCallback() {
17290    this.value = this.#initialValue;
17291    this.editor.dispatchCommand(Ye$1, undefined);
17292  }
17293
17294  toString() {
17295    return this.cachedStringValue ??= this.editor?.read(() => {
17296      return $getReadableTextContent(Zo())
17297    })
17298  }
17299
17300  get form() {
17301    return this.internals.form
17302  }
17303
17304  get name() {
17305    return this.getAttribute("name")
17306  }
17307
17308  get required() {
17309    return this.hasAttribute("required")
17310  }
17311
17312  get validity() {
17313    return this.internals.validity
17314  }
17315
17316  checkValidity() {
17317    return this.internals.checkValidity()
17318  }
17319
17320  reportValidity() {
17321    return this.internals.reportValidity()
17322  }
17323
17324  setElementValidity(key, flags, message) {
17325    this.#validity.set(key, { flags, message });
17326    this.#requestValidityRefresh();
17327  }
17328
17329  get toolbarElement() {
17330    if (!this.#hasToolbar) return null
17331
17332    this.toolbar ??= this.#findOrCreateDefaultToolbar();
17333    return this.toolbar
17334  }
17335
17336  get baseExtensions() {
17337    return [
17338      ProvisionalParagraphExtension,
17339      CodeHighlightingExtension,
17340      HighlightExtension,
17341      TrixContentExtension,
17342      TablesExtension,
17343      RewritableHistoryExtension,
17344      AttachmentsExtension,
17345      FormatEscapeExtension,
17346      LinkOpenerExtension,
17347      PreventLexicalTripleClickExtension,
17348      CustomAttachmentDragAndDropExtension,
17349      LineSeparatorsExtension
17350    ]
17351  }
17352
17353  get directUploadUrl() {
17354    return this.dataset.directUploadUrl
17355  }
17356
17357  get blobUrlTemplate() {
17358    return this.dataset.blobUrlTemplate
17359  }
17360
17361  get permittedAttachmentTypes() {
17362    const raw = this.config.get("permittedAttachmentTypes");
17363    if (raw == null) {
17364      return null
17365    } else {
17366      const tokens = Array.isArray(raw) ? raw : String(raw).split(/\s+/);
17367      return Object.freeze(tokens.filter(t => t && t !== "false"))
17368    }
17369  }
17370
17371  permitsAttachmentContentType(contentType) {
17372    if (!this.supportsAttachments) {
17373      return false
17374    } else {
17375      const list = this.permittedAttachmentTypes;
17376      return list === null || list.includes(contentType)
17377    }
17378  }
17379
17380  acceptsFile(file) {
17381    return dispatch(this, "lexxy:file-accept", { file }, true)
17382  }
17383
17384  $generateNodesFromDOM(doc, { editor = this.editor } = {}) {
17385    let nodes = dt$1(editor, doc);
17386    if (Es(jn)) nodes = $convertInlineImageDataURIs(nodes, this);
17387    return filterDisallowedAttachmentNodes(nodes, this)
17388  }
17389
17390  get isEmpty() {
17391    return [ "<p><br></p>", "<p></p>", "" ].includes(this.value.trim())
17392  }
17393
17394  get isBlank() {
17395    return this.isEmpty || this.toString().match(/^\s*$/g) !== null
17396  }
17397
17398  get hasOpenPrompt() {
17399    return this.querySelector(".lexxy-prompt-menu.lexxy-prompt-menu--visible") !== null
17400  }
17401
17402  get preset() {
17403    return this.getAttribute("preset") || "default"
17404  }
17405
17406  get supportsAttachments() {
17407    return this.config.get("attachments")
17408  }
17409
17410  get supportsMarkdown() {
17411    return this.supportsRichText && this.config.get("markdown")
17412  }
17413
17414  get supportsMultiLine() {
17415    return this.config.get("multiLine") && !this.isSingleLineMode
17416  }
17417
17418  get supportsRichText() {
17419    return this.config.get("richText")
17420  }
17421
17422  registerAdapter(adapter) {
17423    this.adapter = adapter;
17424
17425    if (!this.editor) return
17426
17427    this.#dispatchEditorInitialized();
17428    this.#dispatchAttributesChange();
17429  }
17430
17431  freezeSelection() {
17432    this.adapter.freeze();
17433  }
17434
17435  thawSelection() {
17436    this.adapter.thaw();
17437  }
17438
17439  dispatchAttributesChange() {
17440    this.#dispatchAttributesChange();
17441  }
17442
17443  dispatchEditorInitialized() {
17444    this.#dispatchEditorInitialized();
17445  }
17446
17447  // TODO: Deprecate `single-line` attribute
17448  get isSingleLineMode() {
17449    return this.hasAttribute("single-line")
17450  }
17451
17452  get contentTabIndex() {
17453    return parseInt(this.editorContentElement?.getAttribute("tabindex") ?? "0")
17454  }
17455
17456  focus() {
17457    // `editor.focus()` commits a reconciler update to position the cursor.
17458    // Skip if the contenteditable already owns focus — the update would be a
17459    // no-op but still triggers a full style/layout pass on pages with large
17460    // DOMs.
17461    if (this.#isContentFocused) return
17462
17463    this.editor.focus(() => this.#onFocus());
17464  }
17465
17466  get #isContentFocused() {
17467    return !!this.editor && isEditorFocused(this.editor)
17468  }
17469
17470  get value() {
17471    return this.cachedValue ??= this.#readSanitizedEditorValue()
17472  }
17473
17474  set value(html) {
17475    const editorHasFocus = this.#isContentFocused;
17476
17477    this.editor.update(() => {
17478      if (editorHasFocus) {
17479        // Address Safari inconsistently placing the cursor in the contenteditable by forcing focus back onto the editor
17480        // Use direct `editor.focus` to bypass the pre-existing focus optimization and skip the callback
17481        Ms(() => this.editor.focus());
17482      } else {
17483        Os(qn);
17484      }
17485
17486
17487      this.#setEditorHtml(html);
17488      this.#toggleEmptyStatus();
17489    }, { discrete: true });
17490  }
17491
17492  get canUndo() {
17493    return this.#historyState.undo
17494  }
17495
17496  get canRedo() {
17497    return this.#historyState.redo
17498  }
17499
17500  #readSanitizedEditorValue() {
17501    return this.editor?.read(() => {
17502      return this.sanitizer.sanitize(ht$1(this.editor, null))
17503    }) ?? null
17504  }
17505
17506  #parseHtmlIntoLexicalNodes(html, { editor = this.editor } = {}) {
17507    if (!html) html = "<p></p>";
17508    const nodes = this.$generateNodesFromDOM(parseHtml(`${html}`), { editor });
17509
17510    return nodes
17511      .filter(this.#isNotWhitespaceOnlyNode)
17512      .map(this.#wrapTextNode)
17513  }
17514
17515  // Whitespace-only text nodes (e.g. "\n" between block elements like <div>) and stray line break
17516  // nodes are formatting artifacts from the HTML source. They can't be appended to the root node
17517  // and have no semantic meaning, so we strip them during import.
17518  #isNotWhitespaceOnlyNode(node) {
17519    if (sr(node)) return false
17520    if (Tr(node) && node.getTextContent().trim() === "") return false
17521    return true
17522  }
17523
17524  // Raw string values produce TextNodes which cannot be appended directly to the RootNode.
17525  // We wrap those in <p>
17526  #wrapTextNode(node) {
17527    if (!Tr(node)) return node
17528
17529    const paragraph = eo();
17530    paragraph.append(node);
17531    return paragraph
17532  }
17533
17534  #initialize() {
17535    this.#registerComponents();
17536    this.#handleEnter();
17537    this.#registerFocusEvents();
17538    this.#registerHistoryEvents();
17539    this.#registerFileAcceptFilter();
17540    this.#attachDebugHooks();
17541    this.#attachToolbar();
17542    this.#resetBeforeTurboCaches();
17543
17544    this.#setInternalFormValue(this.value, { suppressEvent: true });
17545    this.#synchronizeWithChanges();
17546  }
17547
17548  #registerFileAcceptFilter() {
17549    this.#listeners.track(
17550      registerEventListener(this, "lexxy:file-accept", (event) => {
17551        if (!this.permitsAttachmentContentType(event.detail.file.type)) {
17552          event.preventDefault();
17553        }
17554      })
17555    );
17556  }
17557
17558  #createEditor() {
17559    this.editorContentElement ||= this.#createEditorContentElement();
17560    this.appendChild(this.editorContentElement);
17561
17562    const editor = oe$4({
17563      name: "lexxy/core",
17564      namespace: "Lexxy",
17565      theme: theme,
17566      nodes: this.#lexicalNodes,
17567      html: {
17568        export: new Map([ [ gr, exportTextNodeDOM ], [ K$1, exportTextNodeDOM ] ])
17569      },
17570      $initialEditorState: (editor) => {
17571        this.#configureSanitizer(editor);
17572        this.#loadInitialValue(editor);
17573      },
17574    },
17575      ...this.extensions.lexicalExtensions
17576    );
17577
17578    return editor
17579  }
17580
17581  // Toggling editable around setRootElement skips Lexical's DOM-selection sync,
17582  // which would otherwise steal focus from elsewhere on the page.
17583  #mountRoot() {
17584    this.editor.setEditable(false);
17585    this.editor.setRootElement(this.editorContentElement);
17586    this.editor.setEditable(true);
17587  }
17588
17589  get #lexicalNodes() {
17590    const nodes = [ CustomActionTextAttachmentNode ];
17591
17592    if (this.supportsRichText) {
17593      nodes.push(
17594        At$1,
17595        It$1,
17596        me$2,
17597        ge$2,
17598        z$1,
17599        K$1,
17600        F$4,
17601        j$5,
17602        HorizontalDividerNode
17603      );
17604    }
17605
17606    return nodes
17607  }
17608
17609  #createEditorContentElement() {
17610    const editorContentElement = createElement("div", {
17611      id: `${this.id}-content`,
17612      classList: "lexxy-editor__content",
17613      contenteditable: true,
17614      role: "textbox",
17615      "aria-multiline": true,
17616      "aria-label": this.#labelText,
17617      placeholder: this.getAttribute("placeholder")
17618    });
17619
17620    this.#ariaAttributes.forEach(attribute => editorContentElement.setAttribute(attribute.name, attribute.value));
17621
17622    this.#transferAttributeToContentEditable(editorContentElement, "autocapitalize");
17623    this.#transferAttributeToContentEditable(editorContentElement, "tabindex", { defaultValue: 0, removeSource: true });
17624
17625    return editorContentElement
17626  }
17627
17628  #transferAttributeToContentEditable(element, qualifiedName, { defaultValue = null, removeSource = false } = {}) {
17629    if (this.hasAttribute(qualifiedName)) {
17630      element.setAttribute(qualifiedName, this.getAttribute(qualifiedName));
17631    } else if (defaultValue !== null) {
17632      element.setAttribute(qualifiedName, defaultValue);
17633    } else {
17634      element.removeAttribute(qualifiedName);
17635    }
17636
17637    if (removeSource) this.removeAttribute(qualifiedName);
17638  }
17639
17640  get #labelText() {
17641    return Array.from(this.internals.labels).map(label => label.textContent).join(" ")
17642  }
17643
17644  get #ariaAttributes() {
17645    return Array.from(this.attributes).filter(attribute => attribute.name.startsWith("aria-"))
17646  }
17647
17648  #setInternalFormValue(html, { suppressEvent = false } = {}) {
17649    const changed = html !== this.#previousInternalFormValue;
17650
17651    this.internals.setFormValue(html);
17652    this.#previousInternalFormValue = html;
17653
17654    if (changed && !suppressEvent) {
17655      dispatch(this, "lexxy:change");
17656    }
17657  }
17658
17659  #loadInitialValue(editor) {
17660    const initialHtml = this.valueBeforeDisconnect || this.getAttribute("value") || "<p><br></p>";
17661
17662    this.#initialValue = initialHtml;
17663    this.#setEditorHtml(initialHtml, { editor });
17664  }
17665
17666  #setEditorHtml(html, { editor = this.editor } = { }) {
17667    Zo()
17668      .clear()
17669      .selectEnd()
17670      .insertNodes(this.#parseHtmlIntoLexicalNodes(html, { editor }));
17671  }
17672
17673  #resetBeforeTurboCaches() {
17674    this.#listeners.track(
17675      registerEventListener(document, "turbo:before-cache", this.#handleTurboBeforeCache)
17676    );
17677  }
17678
17679  #handleTurboBeforeCache = (event) => {
17680    if (!this.closest("[data-turbo-permanent]")) {
17681      this.#reset();
17682    }
17683  }
17684
17685  #synchronizeWithChanges() {
17686    this.#listeners.track(this.editor.registerUpdateListener(({ editorState }) => {
17687      this.#clearCachedValues();
17688      this.#setInternalFormValue(this.value);
17689      this.#toggleEmptyStatus();
17690      this.#requestValidityRefresh();
17691      this.#dispatchAttributesChange();
17692    }));
17693  }
17694
17695  async #requestValidityRefresh() {
17696    await nextFrame();
17697
17698    if (this.isConnected) this.#refreshValidity();
17699  }
17700
17701  #refreshValidity() {
17702    this.#refreshInternalValidity();
17703    const { validity, message } = this.#calculateValidity();
17704    this.internals.setValidity(validity, message, this.editorContentElement);
17705  }
17706
17707  #refreshInternalValidity() {
17708    this.#validationTextArea.required = this.required && this.isBlank;
17709    const flags = this.#validationTextArea.validity;
17710    const message = this.#validationTextArea.validationMessage;
17711
17712    this.#validity.set(this, { flags, message });
17713  }
17714
17715  #calculateValidity() {
17716    const validity = {};
17717    const messages = [];
17718
17719    for (const { flags, message } of this.#validity.values()) {
17720      // internal TextArea's ValidityState can contain `valid: true`
17721      if (flags.valid === true) continue
17722
17723      for (const flag in flags) {
17724        if (flags[flag]) {
17725          validity[flag] = true;
17726          messages.push(message);
17727        }
17728      }
17729    }
17730
17731    return { validity, message: messages.join("\n") }
17732  }
17733
17734  #clearCachedValues() {
17735    this.cachedValue = null;
17736    this.cachedStringValue = null;
17737  }
17738
17739  #registerComponents() {
17740    const registered = [];
17741
17742    if (this.supportsRichText) {
17743      registered.push(
17744        zt$2(this.editor),
17745        Ie$2(this.editor)
17746      );
17747      this.#registerTableComponents();
17748      this.#registerCodeLanguagePicker();
17749      if (this.supportsMarkdown) {
17750        const transformers = [ ...te, HORIZONTAL_DIVIDER ];
17751        registered.push(
17752          se$1(this.editor, transformers),
17753          registerMarkdownLeadingTagHandler(this.editor, transformers)
17754        );
17755      }
17756    } else {
17757      registered.push(H$2(this.editor));
17758    }
17759
17760    this.#listeners.track(...registered);
17761  }
17762
17763  #registerTableComponents() {
17764    let tableTools = this.querySelector("lexxy-table-tools");
17765    tableTools ??= createElement("lexxy-table-tools");
17766    this.append(tableTools);
17767    this.#disposables.push(tableTools);
17768  }
17769
17770  #registerCodeLanguagePicker() {
17771    let codeLanguagePicker = this.querySelector("lexxy-code-language-picker");
17772    codeLanguagePicker ??= createElement("lexxy-code-language-picker");
17773    this.append(codeLanguagePicker);
17774    this.#disposables.push(codeLanguagePicker);
17775  }
17776
17777  #handleEnter() {
17778    // We can't prevent these externally using regular keydown because Lexical handles it first.
17779    this.#listeners.track(this.editor.registerCommand(
17780      Oe$2,
17781      (event) => {
17782        // Prevent CTRL+ENTER
17783        if (event.ctrlKey || event.metaKey) {
17784          event.preventDefault();
17785          return true
17786        }
17787
17788        // In single line mode, prevent ENTER
17789        if (!this.supportsMultiLine) {
17790          event.preventDefault();
17791          return true
17792        }
17793
17794        return false
17795      },
17796      oo
17797    ));
17798  }
17799
17800  #registerFocusEvents() {
17801    this.#listeners.track(
17802      registerEventListener(this, "focusin", this.#handleFocusIn),
17803      registerEventListener(this, "focusout", this.#handleFocusOut)
17804    );
17805  }
17806
17807  #handleFocusIn(event) {
17808    if (this.#elementInEditorOrToolbar(event.target) && !this.currentlyFocused) {
17809      this.#dispatchAttributesChange();
17810      dispatch(this, "lexxy:focus");
17811      this.currentlyFocused = true;
17812    }
17813  }
17814
17815  #handleFocusOut(event) {
17816    if (!this.#elementInEditorOrToolbar(event.relatedTarget)) {
17817      dispatch(this, "lexxy:blur");
17818      this.currentlyFocused = false;
17819    }
17820  }
17821
17822  #elementInEditorOrToolbar(element) {
17823    return this.contains(element) || this.toolbarElement?.contains(element)
17824  }
17825
17826  #onFocus() {
17827    if (this.isEmpty) {
17828      this.selection.placeCursorAtTheEnd();
17829    }
17830  }
17831
17832  #handleAutofocus() {
17833    if (!document.querySelector(":focus")) {
17834      if (this.hasAttribute("autofocus") && document.querySelector("[autofocus]") === this) {
17835        this.focus();
17836      }
17837    }
17838  }
17839
17840  #registerHistoryEvents() {
17841    this.#listeners.track(
17842      this.editor.registerCommand(He$2, (enabled) => { this.#historyState.undo = enabled; }, oo),
17843      this.editor.registerCommand(qe$2, (enabled) => { this.#historyState.redo = enabled; }, oo)
17844    );
17845  }
17846
17847  #attachDebugHooks() {
17848    return
17849  }
17850
17851  #attachToolbar() {
17852    if (this.#hasToolbar) {
17853      this.toolbarElement.setEditor(this);
17854      if (typeof this.toolbarElement.dispose === "function") {
17855        this.#disposables.push(this.toolbarElement);
17856      }
17857
17858      this.extensions.initializeToolbars();
17859    }
17860  }
17861
17862  #findOrCreateDefaultToolbar() {
17863    const toolbarConfig = this.config.get("toolbar");
17864    if (typeof toolbarConfig === "string") {
17865      return document.getElementById(toolbarConfig)
17866    } else {
17867      return this.querySelector("lexxy-toolbar") ?? this.#createDefaultToolbar()
17868    }
17869  }
17870
17871  get #hasToolbar() {
17872    return this.supportsRichText && !!this.config.get("toolbar")
17873  }
17874
17875  #createDefaultToolbar() {
17876    const toolbar = createElement("lexxy-toolbar");
17877    toolbar.innerHTML = LexicalToolbarElement.defaultTemplate;
17878    toolbar.setAttribute("data-attachments", this.supportsAttachments); // Drives toolbar CSS styles
17879    toolbar.configure(this.config.get("toolbar"));
17880    this.prepend(toolbar);
17881    return toolbar
17882  }
17883
17884  #toggleEmptyStatus() {
17885    this.classList.toggle("lexxy-editor--empty", this.isEmpty);
17886  }
17887
17888  #configureSanitizer(editor) {
17889    this.sanitizer = EditorSanitizer.register(editor, this.extensions.allowedElements);
17890  }
17891
17892  #dispatchAttributesChange() {
17893    let attributes = null;
17894    let linkHref = null;
17895    let highlight = null;
17896    let headingTag = null;
17897
17898    this.editor.getEditorState().read(() => {
17899      const selection = Qr();
17900      if (!Fr(selection)) return
17901
17902      const format = this.selection.getFormat();
17903      if (Object.keys(format).length === 0) return
17904
17905      const anchorNode = selection.anchor.getNode();
17906      const linkNode = At$2(anchorNode, F$4);
17907
17908      attributes = {
17909        bold: { active: format.isBold, enabled: true },
17910        italic: { active: format.isItalic, enabled: true },
17911        strikethrough: { active: format.isStrikethrough, enabled: true },
17912        code: { active: format.isInCode, enabled: true },
17913        highlight: { active: format.isHighlight, enabled: true },
17914        link: { active: format.isInLink, enabled: true },
17915        quote: { active: format.isInQuote, enabled: true },
17916        heading: { active: format.isInHeading, enabled: true },
17917        "unordered-list": { active: format.isInList && format.listType === "bullet", enabled: true },
17918        "ordered-list": { active: format.isInList && format.listType === "number", enabled: true },
17919        undo: { active: false, enabled: this.canUndo },
17920        redo: { active: false, enabled: this.canRedo }
17921      };
17922
17923      linkHref = linkNode ? linkNode.getURL() : null;
17924      highlight = format.isHighlight ? getHighlightStyles(selection) : null;
17925      headingTag = format.headingTag ?? null;
17926    });
17927
17928    if (attributes) {
17929      this.adapter.dispatchAttributesChange(attributes, linkHref, highlight, headingTag);
17930    }
17931  }
17932
17933  #dispatchEditorInitialized() {
17934    if (!this.adapter) return
17935
17936    this.#editorInitializedDispatched = true;
17937
17938    this.adapter.dispatchEditorInitialized({
17939      highlightColors: this.#resolvedHighlightColors,
17940      headingFormats: this.#supportedHeadingFormats
17941    });
17942  }
17943
17944  #dispatchInitialize() {
17945    if (this.isConnected && this.adapter) {
17946      if (!this.#initializeEventDispatched) {
17947        this.#initializeEventDispatched = true;
17948        dispatch(this, "lexxy:initialize");
17949      }
17950
17951      if (!this.#editorInitializedDispatched) {
17952        this.#dispatchEditorInitialized();
17953      }
17954    }
17955  }
17956
17957  get #resolvedHighlightColors() {
17958    const buttons = this.config.get("highlight.buttons");
17959    if (!buttons) return null
17960
17961    const colors = this.#resolveColors("color", buttons.color || []);
17962    const backgroundColors = this.#resolveColors("background-color", buttons["background-color"] || []);
17963    return { colors, backgroundColors }
17964  }
17965
17966  get #supportedHeadingFormats() {
17967    if (!this.supportsRichText) return []
17968
17969    const headings = this.config.get("headings");
17970    return [
17971      { label: "Normal", command: "setFormatParagraph", tag: null },
17972      ...headings.map((tag, index) => ({
17973        label: HeadingDropdown.labelFor(tag, index),
17974        command: HeadingDropdown.commandFor(index),
17975        tag
17976      }))
17977    ]
17978  }
17979
17980  // Builds one resolver element per CSS value inside a hidden container, attaches
17981  // the container in a single DOM write, then reads all computed values in one pass
17982  // — triggering at most one forced reflow. The previous implementation interleaved
17983  // setProperty/getComputedStyle/removeProperty on the same element, forcing a style
17984  // recalc on every iteration during editor initialization.
17985  #resolveColors(property, cssValues) {
17986    const container = document.createElement("span");
17987    container.style.display = "none";
17988
17989    const resolvers = cssValues.map(cssValue => {
17990      const element = document.createElement("span");
17991      element.style.setProperty(property, cssValue);
17992      container.appendChild(element);
17993      return { element, name: cssValue }
17994    });
17995
17996    styleResolverRoot().appendChild(container);
17997
17998    const resolved = resolvers.map(({ element, name }) => ({
17999      name,
18000      value: window.getComputedStyle(element).getPropertyValue(property)
18001    }));
18002
18003    container.remove();
18004    return resolved
18005  }
18006
18007  #reset() {
18008    this.#dispose();
18009    this.#resetValidity();
18010    this.#uploadRequests?.clear();
18011    this.editorContentElement?.remove();
18012    this.editorContentElement = null;
18013
18014    // Prevents issues with turbo morphing receiving an empty <lexxy-editor> which wipes
18015    // out the DOM for the tools, and the old toolbar reference will cause issues
18016    this.toolbar = null;
18017  }
18018
18019  #dispose() {
18020    while (this.#disposables.length) {
18021      this.#disposables.pop().dispose();
18022    }
18023  }
18024
18025  #reconnect() {
18026    this.disconnectedCallback();
18027    this.valueBeforeDisconnect = null;
18028    this.connectedCallback();
18029  }
18030
18031  #resetValidity() {
18032    this.#validity = new Map();
18033  }
18034}
18035
18036// Like $getRoot().getTextContent() but uses readable text for custom attachment nodes
18037// (e.g., mentions) instead of their single-character cursor placeholder.
18038function $getReadableTextContent(node) {
18039  if (node instanceof CustomActionTextAttachmentNode) {
18040    return node.getReadableTextContent()
18041  }
18042
18043  if (Wi(node)) {
18044    let text = "";
18045    const children = node.getChildren();
18046    for (let i = 0; i < children.length; i++) {
18047      const child = children[i];
18048      const previousChild = children[i - 1];
18049
18050      if (isAttachmentSpacerTextNode(child, previousChild, i, children.length)) continue
18051
18052      text += $getReadableTextContent(child);
18053      if (Wi(child) && i !== children.length - 1 && !child.isInline()) {
18054        text += "\n\n";
18055      }
18056    }
18057    return text
18058  }
18059
18060  return node.getTextContent()
18061}
18062
18063class BaseSource {
18064  // Template method to override
18065  async buildListItems(filter = "") {
18066    return Promise.resolve([])
18067  }
18068
18069  // Template method to override
18070  promptItemFor(listItem) {
18071    return null
18072  }
18073
18074  // Protected
18075
18076  buildListItemElementFor(promptItemElement) {
18077    const template = promptItemElement.querySelector("template[type='menu']");
18078    const fragment = template.content.cloneNode(true);
18079    const listItemElement = createElement("li", { role: "option", id: generateDomId("prompt-item"), tabindex: "0" });
18080    listItemElement.classList.add("lexxy-prompt-menu__item");
18081    listItemElement.appendChild(fragment);
18082    return listItemElement
18083  }
18084
18085  async loadPromptItemsFromUrl(url) {
18086    try {
18087      const response = await fetch(url);
18088      const html = await response.text();
18089      const promptItems = parseHtml(html).querySelectorAll("lexxy-prompt-item");
18090      return Promise.resolve(Array.from(promptItems))
18091    } catch (error) {
18092      return Promise.reject(error)
18093    }
18094  }
18095}
18096
18097const MAX_RENDERED_SUGGESTIONS$1 = 100;
18098
18099class LocalFilterSource extends BaseSource {
18100  async buildListItems(filter = "") {
18101    const promptItems = await this.fetchPromptItems();
18102    return this.#buildListItemsFromPromptItems(promptItems, filter)
18103  }
18104
18105  // Template method to override
18106  async fetchPromptItems(filter) {
18107    return Promise.resolve([])
18108  }
18109
18110  promptItemFor(listItem) {
18111    return this.promptItemByListItem.get(listItem)
18112  }
18113
18114  #buildListItemsFromPromptItems(promptItems, filter) {
18115    this.promptItemByListItem = new WeakMap();
18116
18117    if (!filter) {
18118      return this.#buildAllListItems(promptItems)
18119    }
18120
18121    const matches = [];
18122    for (const promptItem of promptItems) {
18123      const searchableText = promptItem.getAttribute("search");
18124      const position = filterMatchPosition(searchableText, filter);
18125      if (position >= 0) {
18126        matches.push({ promptItem, position });
18127      }
18128    }
18129
18130    matches.sort((a, b) => a.position - b.position);
18131
18132    const listItems = [];
18133    for (const { promptItem } of matches) {
18134      if (listItems.length >= MAX_RENDERED_SUGGESTIONS$1) break
18135      const listItem = this.buildListItemElementFor(promptItem);
18136      this.promptItemByListItem.set(listItem, promptItem);
18137      listItems.push(listItem);
18138    }
18139    return listItems
18140  }
18141
18142  #buildAllListItems(promptItems) {
18143    const listItems = [];
18144    for (const promptItem of promptItems) {
18145      if (listItems.length >= MAX_RENDERED_SUGGESTIONS$1) break
18146      const listItem = this.buildListItemElementFor(promptItem);
18147      this.promptItemByListItem.set(listItem, promptItem);
18148      listItems.push(listItem);
18149    }
18150    return listItems
18151  }
18152}
18153
18154class InlinePromptSource extends LocalFilterSource {
18155  constructor(inlinePromptItems) {
18156    super();
18157    this.inlinePromptItemElements = Array.from(inlinePromptItems);
18158  }
18159
18160  async fetchPromptItems() {
18161    return Promise.resolve(this.inlinePromptItemElements)
18162  }
18163}
18164
18165class DeferredPromptSource extends LocalFilterSource {
18166  constructor(url) {
18167    super();
18168    this.url = url;
18169
18170    this.fetchPromptItems();
18171  }
18172
18173  async fetchPromptItems() {
18174    this.promptItems ??= await this.loadPromptItemsFromUrl(this.url);
18175
18176    return Promise.resolve(this.promptItems)
18177  }
18178}
18179
18180const DEBOUNCE_INTERVAL = 200;
18181const MAX_RENDERED_SUGGESTIONS = 100;
18182
18183class RemoteFilterSource extends BaseSource {
18184  constructor(url) {
18185    super();
18186
18187    this.baseURL = url;
18188    this.loadAndFilterListItems = debounceAsync(this.fetchFilteredListItems.bind(this), DEBOUNCE_INTERVAL);
18189  }
18190
18191  async buildListItems(filter = "") {
18192    return await this.loadAndFilterListItems(filter)
18193  }
18194
18195  promptItemFor(listItem) {
18196    return this.promptItemByListItem.get(listItem)
18197  }
18198
18199  async fetchFilteredListItems(filter) {
18200    const promptItems = await this.loadPromptItemsFromUrl(this.#urlFor(filter));
18201    return this.#buildListItemsFromPromptItems(promptItems)
18202  }
18203
18204  #urlFor(filter) {
18205    const url = new URL(this.baseURL, window.location.origin);
18206    url.searchParams.append("filter", filter);
18207    return url.toString()
18208  }
18209
18210  #buildListItemsFromPromptItems(promptItems) {
18211    const listItems = [];
18212    this.promptItemByListItem = new WeakMap();
18213
18214    for (const promptItem of promptItems) {
18215      if (listItems.length >= MAX_RENDERED_SUGGESTIONS) break
18216
18217      const listItem = this.buildListItemElementFor(promptItem);
18218      this.promptItemByListItem.set(listItem, promptItem);
18219      listItems.push(listItem);
18220    }
18221
18222    return listItems
18223  }
18224}
18225
18226const NOTHING_FOUND_DEFAULT_MESSAGE = "Nothing found";
18227const FILTER_DEBOUNCE_INTERVAL = 50;
18228
18229// Start of line, or after a space or newline.
18230const DEFAULT_ONLY_AT_PATTERN = "^|[ \\n]";
18231
18232class LexicalPromptElement extends HTMLElement {
18233  #globalListeners = new ListenerBin()
18234  #popoverListeners = new ListenerBin()
18235  #debouncedFilterOptions = debounce(() => this.#filterOptions(), FILTER_DEBOUNCE_INTERVAL)
18236
18237  constructor() {
18238    super();
18239    this.showPopoverId = 0;
18240  }
18241
18242  static observedAttributes = [ "connected" ]
18243
18244  connectedCallback() {
18245    this.source = this.#createSource();
18246
18247    this.#addTriggerListener();
18248    this.#removePopoverBeforeTurboCaches();
18249    this.toggleAttribute("connected", true);
18250  }
18251
18252  disconnectedCallback() {
18253    this.#popoverListeners.dispose();
18254    this.#globalListeners.dispose();
18255    this.source = null;
18256    this.#removePopover();
18257  }
18258
18259
18260  attributeChangedCallback(name, oldValue, newValue) {
18261    if (name === "connected" && this.isConnected && oldValue != null && oldValue !== newValue) {
18262      requestAnimationFrame(() => this.#reconnect());
18263    }
18264  }
18265
18266  get name() {
18267    return this.getAttribute("name")
18268  }
18269
18270  get trigger() {
18271    return this.getAttribute("trigger")
18272  }
18273
18274  get supportsSpaceInSearches() {
18275    return this.hasAttribute("supports-space-in-searches")
18276  }
18277
18278  get onlyAt() {
18279    return this.getAttribute("only-at")
18280  }
18281
18282  get verticalDirection() {
18283    return this.getAttribute("vertical-direction")
18284  }
18285
18286  get open() {
18287    return this.popoverElement?.classList?.contains("lexxy-prompt-menu--visible")
18288  }
18289
18290  get closed() {
18291    return !this.open
18292  }
18293
18294  get #doesSpaceSelect() {
18295    return !this.supportsSpaceInSearches
18296  }
18297
18298  #createSource() {
18299    const src = this.getAttribute("src");
18300    if (src) {
18301      if (this.hasAttribute("remote-filtering")) {
18302        return new RemoteFilterSource(src)
18303      } else {
18304        return new DeferredPromptSource(src)
18305      }
18306    } else {
18307      return new InlinePromptSource(this.querySelectorAll("lexxy-prompt-item"))
18308    }
18309  }
18310
18311  #addTriggerListener() {
18312    if (!this.#promptContentTypePermitted) return
18313
18314    this.#popoverListeners.track(this.#editor.registerUpdateListener(({ editorState }) => {
18315      editorState.read(() => {
18316        if (this.#selection.isInsideCodeBlock) return
18317
18318        const { node, offset } = this.#selection.selectedNodeWithOffset();
18319        if (!node) return
18320
18321        if (Tr(node)) {
18322          const fullText = node.getTextContent();
18323          const triggerLength = this.trigger.length;
18324
18325          // Check if we have enough characters for the trigger
18326          if (offset >= triggerLength) {
18327            const textBeforeCursor = fullText.slice(offset - triggerLength, offset);
18328
18329            if (textBeforeCursor === this.trigger) {
18330              const textBeforeTrigger = $textBeforeOffset(node, offset - triggerLength);
18331
18332              if (this.#onlyAtRegExp.test(textBeforeTrigger)) {
18333                this.#popoverListeners.dispose();
18334                this.#showPopover();
18335              }
18336            }
18337          }
18338        }
18339      });
18340    }));
18341  }
18342
18343  get #onlyAtRegExp() {
18344    return new RegExp(`(?:${this.onlyAt ?? DEFAULT_ONLY_AT_PATTERN})$`)
18345  }
18346
18347  get #promptContentTypePermitted() {
18348    // `insert-editable-text` prompts never create attachments, so the
18349    // editor's attachment support and content-type allowlist don't apply.
18350    if (this.hasAttribute("insert-editable-text")) return true
18351
18352    const el = this.#editorElement;
18353    if (!el.supportsAttachments) {
18354      return false
18355    } else {
18356      const templates = Array.from(this.querySelectorAll("template[type='editor']"));
18357      const types = templates.length
18358        ? templates.map(t => t.getAttribute("content-type") || this.#defaultPromptContentType)
18359        : [ this.#defaultPromptContentType ];
18360      return types.some(t => el.permitsAttachmentContentType(t))
18361    }
18362  }
18363
18364  #addCursorPositionListener() {
18365    this.#popoverListeners.track(this.#editor.registerUpdateListener(({ editorState }) => {
18366      if (this.closed) return
18367
18368      editorState.read(() => {
18369        if (this.#selection.isInsideCodeBlock) {
18370          this.#hidePopover();
18371          return
18372        }
18373
18374        const { node, offset } = this.#selection.selectedNodeWithOffset();
18375        if (!node) return
18376
18377        if (this.#cursorIsTypingSearchTerm(node, offset)) {
18378          if (!this.popoverElement.hasAttribute("data-anchored")) {
18379            this.#positionPopover();
18380          }
18381        } else {
18382          this.#hidePopover();
18383        }
18384      });
18385    }));
18386  }
18387
18388  // The popover should stay open only while the cursor sits at the end of the
18389  // trigger and its search term. When the cursor moves away — before the
18390  // trigger, or past the token into later text — the text between the trigger
18391  // and the cursor breaks that run and we dismiss. A newline always breaks the
18392  // run; a space breaks it only for triggers that don't support spaces in
18393  // searches, since those that do (e.g. `person:`) expect multi-word terms.
18394  #cursorIsTypingSearchTerm(node, offset) {
18395    if (!Tr(node) || offset === 0) return false
18396
18397    const textBeforeCursor = node.getTextContent().slice(0, offset);
18398    const lastTriggerIndex = textBeforeCursor.lastIndexOf(this.trigger);
18399    if (lastTriggerIndex === -1) return false
18400
18401    const searchTerm = textBeforeCursor.slice(lastTriggerIndex + this.trigger.length);
18402    const breakPattern = this.supportsSpaceInSearches ? /\n/ : /[ \n]/;
18403    return !breakPattern.test(searchTerm)
18404  }
18405
18406  get #editor() {
18407    return this.#editorElement.editor
18408  }
18409
18410  get #editorElement() {
18411    return this.closest("lexxy-editor")
18412  }
18413
18414  get #selection() {
18415    return this.#editorElement.selection
18416  }
18417
18418  async #showPopover() {
18419    const showId = ++this.showPopoverId;
18420    this.popoverElement ??= await this.#buildPopover();
18421    if (this.showPopoverId !== showId) return
18422
18423    this.#resetPopoverPosition();
18424    await this.#filterOptions();
18425    if (this.showPopoverId !== showId) return
18426
18427    this.popoverElement.classList.toggle("lexxy-prompt-menu--visible", true);
18428    this.#selectFirstOption();
18429
18430    this.#popoverListeners.track(
18431      registerEventListener(this.#editorElement, "keydown", this.#handleKeydownOnPopover),
18432      registerEventListener(this.#editorElement, "lexxy:change", this.#debouncedFilterOptions)
18433    );
18434
18435    this.#registerKeyListeners();
18436    this.#addCursorPositionListener();
18437  }
18438
18439  #registerKeyListeners() {
18440    // We can't use a regular keydown for Enter as Lexical handles it first
18441    this.#popoverListeners.track(
18442      this.#editor.registerCommand(Oe$2, this.#handleSelectedOption.bind(this), lo),
18443      this.#editor.registerCommand(Fe$2, this.#handleSelectedOption.bind(this), lo)
18444    );
18445
18446    if (this.#doesSpaceSelect) {
18447      this.#popoverListeners.track(this.#editor.registerCommand(Me$2, this.#handleSelectedOption.bind(this), lo));
18448      this.#popoverListeners.track(this.#editor.registerCommand(ce$4, this.#handleInputCommand.bind(this), lo));
18449    }
18450
18451    // Register arrow keys with CRITICAL priority to prevent Lexical's selection handlers from running
18452    this.#popoverListeners.track(
18453      this.#editor.registerCommand(we$1, this.#handleArrowUp.bind(this), lo),
18454      this.#editor.registerCommand(Ee$3, this.#handleArrowDown.bind(this), lo)
18455    );
18456  }
18457
18458  #handleArrowUp(event) {
18459    this.#moveSelectionUp();
18460    event.preventDefault();
18461    return true
18462  }
18463
18464  #handleArrowDown(event) {
18465    this.#moveSelectionDown();
18466    event.preventDefault();
18467    return true
18468  }
18469
18470  #selectFirstOption() {
18471    const firstOption = this.#listItemElements[0];
18472
18473    if (firstOption) {
18474      this.#selectOption(firstOption);
18475    }
18476  }
18477
18478  get #listItemElements() {
18479    return Array.from(this.popoverElement.querySelectorAll(".lexxy-prompt-menu__item"))
18480  }
18481
18482  #selectOption(listItem, { scrollIntoView = false } = {}) {
18483    this.#clearListItemSelection();
18484    listItem.toggleAttribute("aria-selected", true);
18485    if (scrollIntoView) {
18486      listItem.scrollIntoView({ block: "nearest", container: "nearest", behavior: "smooth" });
18487    }
18488
18489    this.#setEditorAssociationAttribute("aria-controls", this.popoverElement.id);
18490    this.#setEditorAssociationAttribute("aria-activedescendant", listItem.id);
18491    this.#setEditorAssociationAttribute("aria-haspopup", "listbox");
18492  }
18493
18494  #clearListItemSelection() {
18495    this.#listItemElements.forEach((item) => { item.toggleAttribute("aria-selected", false); });
18496  }
18497
18498  #clearSelection() {
18499    this.#clearListItemSelection();
18500    this.#editorContentElement.removeAttribute("aria-controls");
18501    this.#editorContentElement.removeAttribute("aria-activedescendant");
18502    this.#editorContentElement.removeAttribute("aria-haspopup");
18503  }
18504
18505  #setEditorAssociationAttribute(name, value) {
18506    if (this.#editorContentElement.getAttribute(name) !== value) {
18507      this.#editorContentElement.setAttribute(name, value);
18508    }
18509  }
18510
18511  // Right after a Turbo history restore the editor reconnects before the DOM selection
18512  // is re-established, so the cursor geometry is momentarily unavailable. Anchoring then
18513  // would pin the menu to the editor's left edge for the rest of the open cycle, so we
18514  // skip it and let a later reposition anchor it once the selection is ready. The menu
18515  // stays hidden until anchored (see the `[data-anchored]` rule in the stylesheet).
18516  #positionPopover() {
18517    const cursorPosition = this.#selection.cursorPosition;
18518    if (!cursorPosition) return
18519
18520    const { x, y, fontSize } = cursorPosition;
18521    const editorRect = this.#editorElement.getBoundingClientRect();
18522    const contentRect = this.#editorContentElement.getBoundingClientRect();
18523    const verticalOffset = contentRect.top - editorRect.top;
18524
18525    if (!this.popoverElement.hasAttribute("data-anchored")) {
18526      this.#setPopoverOffsetX(x);
18527      this.#setPopoverOffsetY(y + verticalOffset);
18528      this.popoverElement.toggleAttribute("data-anchored", true);
18529    }
18530
18531    const popoverRect = this.popoverElement.getBoundingClientRect();
18532
18533    if (popoverRect.right > editorRect.right) {
18534      this.popoverElement.toggleAttribute("data-clipped-at-right", true);
18535    }
18536
18537    const forceTop = this.verticalDirection === "top";
18538    const forceBottom = this.verticalDirection === "bottom";
18539    const overflowsWindow = popoverRect.bottom > window.innerHeight;
18540
18541    if (!forceBottom && (forceTop || overflowsWindow)) {
18542      this.#setPopoverOffsetY(contentRect.height - y + fontSize);
18543      this.popoverElement.toggleAttribute("data-clipped-at-bottom", true);
18544    }
18545  }
18546
18547  #setPopoverOffsetX(value) {
18548    this.popoverElement.style.setProperty("--lexxy-prompt-offset-x", `${value}px`);
18549  }
18550
18551  #setPopoverOffsetY(value) {
18552    this.popoverElement.style.setProperty("--lexxy-prompt-offset-y", `${value}px`);
18553  }
18554
18555  #resetPopoverPosition() {
18556    this.popoverElement.removeAttribute("data-clipped-at-bottom");
18557    this.popoverElement.removeAttribute("data-clipped-at-right");
18558    this.popoverElement.removeAttribute("data-anchored");
18559  }
18560
18561  async #hidePopover() {
18562    this.showPopoverId++;
18563    this.#clearSelection();
18564    this.popoverElement.classList.toggle("lexxy-prompt-menu--visible", false);
18565    this.#popoverListeners.dispose();
18566
18567    await nextFrame();
18568    this.#addTriggerListener();
18569  }
18570
18571  // The popover is appended to the <lexxy-editor> subtree, so Turbo serializes it
18572  // into the page cache. Removing it before caching prevents an orphaned, unmanaged
18573  // popover from being restored on history back/forward.
18574  #removePopoverBeforeTurboCaches() {
18575    this.#globalListeners.track(
18576      registerEventListener(document, "turbo:before-cache", () => this.#removePopover())
18577    );
18578  }
18579
18580  #removePopover() {
18581    this.#popoverListeners.dispose();
18582    this.popoverElement?.remove();
18583    this.popoverElement = null;
18584  }
18585
18586  #filterOptions = async () => {
18587    if (this.initialPrompt) {
18588      this.initialPrompt = false;
18589      return
18590    }
18591
18592    if (this.#editorContents.containsTextBackUntil(this.trigger)) {
18593      await this.#showFilteredOptions();
18594
18595      // Re-check after async operation — the trigger may have been consumed
18596      // (e.g. markdown heading shortcut converted "# " to h1 during the fetch)
18597      if (!this.#editorContents.containsTextBackUntil(this.trigger)) {
18598        this.#hidePopover();
18599        return
18600      }
18601
18602      await nextFrame();
18603      this.#positionPopover();
18604    } else {
18605      this.#hidePopover();
18606    }
18607  }
18608
18609  async #showFilteredOptions() {
18610    const showId = this.showPopoverId;
18611    const filter = this.#editorContents.textBackUntil(this.trigger);
18612    const filteredListItems = await this.source.buildListItems(filter);
18613    if (this.showPopoverId !== showId) return
18614    if (!this.#editorContents.containsTextBackUntil(this.trigger)) return
18615
18616    this.popoverElement.innerHTML = "";
18617
18618    if (filteredListItems.length > 0) {
18619      this.#showResults(filteredListItems);
18620    } else {
18621      this.#showEmptyResults();
18622    }
18623    this.#selectFirstOption();
18624  }
18625
18626  #showResults(filteredListItems) {
18627    this.popoverElement.classList.remove("lexxy-prompt-menu--empty");
18628    this.popoverElement.append(...filteredListItems);
18629  }
18630
18631  #showEmptyResults() {
18632    this.popoverElement.classList.add("lexxy-prompt-menu--empty");
18633    const el = createElement("li", { textContent: this.#emptyResultsMessage });
18634    el.classList.add("lexxy-prompt-menu__item--empty");
18635    this.popoverElement.append(el);
18636  }
18637
18638  get #emptyResultsMessage() {
18639    return this.getAttribute("empty-results") || NOTHING_FOUND_DEFAULT_MESSAGE
18640  }
18641
18642  #handleKeydownOnPopover = (event) => {
18643    if (event.key === "Escape") {
18644      this.#hidePopover();
18645      this.#editorElement.focus();
18646      event.stopPropagation();
18647    } else if (event.key === ",") {
18648      event.preventDefault();
18649      event.stopPropagation();
18650      this.#optionWasSelected();
18651      this.#editor.update(() => {
18652        const selection = Qr();
18653        if (Fr(selection)) {
18654          selection.insertText(",");
18655        }
18656      });
18657    }
18658    // Arrow keys are handled via Lexical commands
18659  }
18660
18661  // Android Mobile keyboard doesn't trigger KEY_SPACE_COMMAND
18662  #handleInputCommand(event) {
18663    if (event.inputType === "insertText" && event.data === " ") return this.#handleSelectedOption(event)
18664  }
18665
18666  #moveSelectionDown() {
18667    const nextIndex = this.#selectedIndex + 1;
18668    if (nextIndex < this.#listItemElements.length) this.#selectOption(this.#listItemElements[nextIndex], { scrollIntoView: true });
18669  }
18670
18671  #moveSelectionUp() {
18672    const previousIndex = this.#selectedIndex - 1;
18673    if (previousIndex >= 0) this.#selectOption(this.#listItemElements[previousIndex], { scrollIntoView: true });
18674  }
18675
18676  get #selectedIndex() {
18677    return this.#listItemElements.findIndex((item) => item.hasAttribute("aria-selected"))
18678  }
18679
18680  get #selectedListItem() {
18681    return this.#listItemElements[this.#selectedIndex]
18682  }
18683
18684  #handleSelectedOption(event) {
18685    event.preventDefault();
18686    event.stopPropagation();
18687    this.#optionWasSelected();
18688    return true
18689  }
18690
18691  #optionWasSelected() {
18692    this.#replaceTriggerWithSelectedItem();
18693    this.#hidePopover();
18694    this.#editorElement.focus();
18695  }
18696
18697  #replaceTriggerWithSelectedItem() {
18698    const promptItem = this.source.promptItemFor(this.#selectedListItem);
18699
18700    if (!promptItem) { return }
18701
18702    const templates = Array.from(promptItem.querySelectorAll("template[type='editor']"));
18703    const stringToReplace = `${this.trigger}${this.#editorContents.textBackUntil(this.trigger)}`;
18704
18705    if (this.hasAttribute("insert-editable-text")) {
18706      this.#insertTemplatesAsEditableText(templates, stringToReplace);
18707    } else {
18708      this.#insertTemplatesAsAttachments(templates, stringToReplace, promptItem.getAttribute("sgid"));
18709    }
18710  }
18711
18712  #insertTemplatesAsEditableText(templates, stringToReplace) {
18713    this.#editor.update(() => {
18714      const nodes = templates.flatMap(template => this.#buildEditableTextNodes(template));
18715      this.#editorContents.replaceTextBackUntil(stringToReplace, nodes);
18716    });
18717  }
18718
18719  #buildEditableTextNodes(template) {
18720    return this.#editorElement.$generateNodesFromDOM(parseHtml(`${template.innerHTML}`))
18721  }
18722
18723  #insertTemplatesAsAttachments(templates, stringToReplace, fallbackSgid = null) {
18724    this.#editor.update(() => {
18725      const attachmentNodes = this.#buildAttachmentNodes(templates, fallbackSgid);
18726      const spacedAttachmentNodes = attachmentNodes.flatMap(node => [ node, this.#getSpacerTextNode() ]).slice(0, -1);
18727      this.#editorContents.replaceTextBackUntil(stringToReplace, spacedAttachmentNodes);
18728    });
18729  }
18730
18731  #buildAttachmentNodes(templates, fallbackSgid = null) {
18732    return templates
18733      .filter(template => this.#editorElement.permitsAttachmentContentType(
18734        template.getAttribute("content-type") || this.#defaultPromptContentType))
18735      .map(template => this.#buildAttachmentNode(
18736        template.innerHTML,
18737        template.getAttribute("content-type") || this.#defaultPromptContentType,
18738        template.getAttribute("sgid") || fallbackSgid
18739      ))
18740  }
18741
18742  #getSpacerTextNode() {
18743    return kr(" ")
18744  }
18745
18746  get #defaultPromptContentType() {
18747    const attachmentContentTypeNamespace = Lexxy.global.get("attachmentContentTypeNamespace");
18748    return `application/vnd.${attachmentContentTypeNamespace}.${this.name}`
18749  }
18750
18751  #buildAttachmentNode(innerHtml, contentType, sgid) {
18752    return new CustomActionTextAttachmentNode({ sgid, contentType, innerHtml })
18753  }
18754
18755  get #editorContents() {
18756    return this.#editorElement.contents
18757  }
18758
18759  get #editorContentElement() {
18760    return this.#editorElement.editorContentElement
18761  }
18762
18763  async #buildPopover() {
18764    const popoverContainer = createElement("ul", { role: "listbox", id: generateDomId("prompt-popover") }); // Avoiding [popover] due to not being able to position at an arbitrary X, Y position.
18765    popoverContainer.classList.add("lexxy-prompt-menu");
18766    popoverContainer.style.position = "absolute";
18767    popoverContainer.setAttribute("nonce", getNonce());
18768    popoverContainer.append(...await this.source.buildListItems());
18769    this.#globalListeners.track(registerEventListener(popoverContainer, "click", this.#handlePopoverClick));
18770    this.#editorElement.appendChild(popoverContainer);
18771    return popoverContainer
18772  }
18773
18774  #handlePopoverClick = (event) => {
18775    const listItem = event.target.closest(".lexxy-prompt-menu__item");
18776    if (listItem) {
18777      this.#selectOption(listItem);
18778      this.#optionWasSelected();
18779    }
18780  }
18781
18782  #reconnect() {
18783    this.disconnectedCallback();
18784    this.connectedCallback();
18785  }
18786}
18787
18788class CodeLanguagePicker extends HTMLElement {
18789  #abortController = null
18790  #listeners = new ListenerBin()
18791
18792  connectedCallback() {
18793    this.editorElement = this.closest("lexxy-editor");
18794    this.editor = this.editorElement.editor;
18795    this.classList.add("lexxy-floating-controls");
18796    this.#abortController = new AbortController();
18797    this.#listeners.track(() => this.#abortController?.abort());
18798
18799    this.#attachLanguagePicker();
18800    this.#hide();
18801    this.#monitorForCodeBlockSelection();
18802  }
18803
18804  disconnectedCallback() {
18805    this.dispose();
18806  }
18807
18808  dispose() {
18809    this.#listeners.dispose();
18810  }
18811
18812  #attachLanguagePicker() {
18813    this.languagePickerElement = this.#findLanguagePicker() ?? this.#createLanguagePicker();
18814
18815    const signal = this.#abortController.signal;
18816
18817    this.#listeners.track(registerEventListener(this.languagePickerElement, "change", () => {
18818      this.#updateCodeBlockLanguage(this.languagePickerElement.value);
18819    }, { signal }));
18820
18821    this.#listeners.track(registerEventListener(this.languagePickerElement, "mousedown", (event) => {
18822      this.#dispatchOpenEvent(event);
18823    }, { signal }));
18824
18825    this.languagePickerElement.setAttribute("nonce", getNonce());
18826    this.appendChild(this.languagePickerElement);
18827  }
18828
18829  #findLanguagePicker() {
18830    return this.querySelector("select")
18831  }
18832
18833  #createLanguagePicker() {
18834    const selectElement = createElement("select", { className: "lexxy-code-language-picker", "aria-label": "Pick a language…", name: "lexxy-code-language" });
18835
18836    for (const [ value, label ] of Object.entries(this.#languages)) {
18837      const option = document.createElement("option");
18838      option.value = value;
18839      option.textContent = label;
18840      selectElement.appendChild(option);
18841    }
18842
18843    return selectElement
18844  }
18845
18846  get #languages() {
18847    const languages = { ...o };
18848
18849    languages.ruby ||= "Ruby";
18850    languages.php ||= "PHP";
18851    languages.go ||= "Go";
18852    languages.bash ||= "Bash";
18853    languages.json ||= "JSON";
18854    languages.diff ||= "Diff";
18855    languages.kotlin ||= "Kotlin";
18856
18857
18858    // Place the "plain" entry first, then the rest of language sorted alphabetically
18859    delete languages.plain;
18860    const sortedEntries = Object.entries(languages)
18861      .sort((a, b) => a[1].localeCompare(b[1]));
18862    return { plain: "Plain text", ...Object.fromEntries(sortedEntries) }
18863  }
18864
18865  #dispatchOpenEvent(event) {
18866    const handled = !dispatch(this.editorElement, "lexxy:code-language-picker-open", {
18867      languages: this.#bridgeLanguages,
18868      currentLanguage: this.languagePickerElement.value
18869    }, true);
18870
18871    if (handled) {
18872      event.preventDefault();
18873    }
18874  }
18875
18876  get #bridgeLanguages() {
18877    return Object.entries(this.#languages).map(([ key, name ]) => ({ key, name }))
18878  }
18879
18880  #updateCodeBlockLanguage(language) {
18881    this.editor.update(() => {
18882      const codeNode = this.#getCurrentCodeNode();
18883
18884      if (codeNode) {
18885        codeNode.setLanguage(language);
18886      }
18887    });
18888  }
18889
18890  #monitorForCodeBlockSelection() {
18891    this.#listeners.track(this.editor.registerUpdateListener(({ editorState }) => {
18892      editorState.read(() => {
18893        const codeNode = this.#getCurrentCodeNode();
18894
18895        if (codeNode) {
18896          this.#codeNodeWasSelected(codeNode);
18897        } else {
18898          this.#hide();
18899        }
18900      });
18901    }));
18902  }
18903
18904  #getCurrentCodeNode() {
18905    return this.editorElement.selection.nearestNodeOfType(z$1)
18906  }
18907
18908  #codeNodeWasSelected(codeNode) {
18909    const language = codeNode.getLanguage();
18910
18911    this.#updateLanguagePickerWith(language);
18912    this.#show();
18913    this.#positionLanguagePicker(codeNode);
18914  }
18915
18916  #updateLanguagePickerWith(language) {
18917    if (this.languagePickerElement && language) {
18918      const normalizedLanguage = a(language);
18919      this.languagePickerElement.value = normalizedLanguage;
18920    }
18921  }
18922
18923  #positionLanguagePicker(codeNode) {
18924    const codeElement = this.editor.getElementByKey(codeNode.getKey());
18925    if (!codeElement) return
18926
18927    const codeRect = codeElement.getBoundingClientRect();
18928    const editorRect = this.editorElement.getBoundingClientRect();
18929    const relativeTop = codeRect.top - editorRect.top;
18930    const relativeRight = editorRect.right - codeRect.right;
18931
18932    this.style.top = `${relativeTop}px`;
18933    this.style.right = `${relativeRight}px`;
18934  }
18935
18936  #show() {
18937    this.hidden = false;
18938  }
18939
18940  #hide() {
18941    this.hidden = true;
18942  }
18943}
18944
18945const DELETE_ICON = `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
18946  <path d="M11.2041 1.01074C12.2128 1.113 13 1.96435 13 3V4H15L15.1025 4.00488C15.6067 4.05621 16 4.48232 16 5C16 5.55228 15.5523 6 15 6H14.8457L14.1416 15.1533C14.0614 16.1953 13.1925 17 12.1475 17H5.85254L5.6582 16.9902C4.76514 16.9041 4.03607 16.2296 3.88184 15.3457L3.8584 15.1533L3.1543 6H3C2.44772 6 2 5.55228 2 5C2 4.44772 2.44772 4 3 4H5V3C5 1.89543 5.89543 1 7 1H11L11.2041 1.01074ZM5.85254 15H12.1475L12.8398 6H5.16016L5.85254 15ZM7 4H11V3H7V4Z"/>
18947</svg>`;
18948
18949class NodeDeleteButton extends HTMLElement {
18950  connectedCallback() {
18951    this.editorElement = this.closest("lexxy-editor");
18952    this.editor = this.editorElement.editor;
18953    this.classList.add("lexxy-floating-controls");
18954
18955    if (!this.querySelector(".lexxy-node-delete")) {
18956      this.#attachDeleteButton();
18957    }
18958  }
18959
18960  disconnectedCallback() {
18961    this.editor = null;
18962    this.editorElement = null;
18963  }
18964
18965  #attachDeleteButton() {
18966    const container = createElement("div", { className: "lexxy-floating-controls__group" });
18967
18968    this.deleteButton = createElement("button", {
18969      className: "lexxy-node-delete",
18970      type: "button",
18971      "aria-label": "Remove"
18972    });
18973    this.deleteButton.tabIndex = -1;
18974    this.deleteButton.innerHTML = DELETE_ICON;
18975
18976    this.handleDeleteClick = () => this.#deleteNode();
18977    this.deleteButton.addEventListener("click", this.handleDeleteClick);
18978    container.appendChild(this.deleteButton);
18979
18980    this.appendChild(container);
18981  }
18982
18983  #deleteNode() {
18984    this.editor.update(() => {
18985      const node = Go(this);
18986      node?.remove();
18987    });
18988  }
18989}
18990
18991class TableController {
18992  #listeners = new ListenerBin()
18993
18994  constructor(editorElement) {
18995    this.editor = editorElement.editor;
18996    this.contents = editorElement.contents;
18997    this.selection = editorElement.selection;
18998
18999    this.currentTableNodeKey = null;
19000    this.currentCellKey = null;
19001
19002    this.#registerKeyHandlers();
19003  }
19004
19005  destroy() {
19006    this.currentTableNodeKey = null;
19007    this.currentCellKey = null;
19008
19009    this.#listeners.dispose();
19010  }
19011
19012  get currentCell() {
19013    if (!this.currentCellKey) return null
19014
19015    return this.editor.getEditorState().read(() => {
19016      const cell = Yo(this.currentCellKey);
19017      return (cell instanceof Ee$1) ? cell : null
19018    })
19019  }
19020
19021  get currentTableNode() {
19022    if (!this.currentTableNodeKey) return null
19023
19024    return this.editor.getEditorState().read(() => {
19025      const tableNode = Yo(this.currentTableNodeKey);
19026      return (tableNode instanceof vn) ? tableNode : null
19027    })
19028  }
19029
19030  get currentRowCells() {
19031    const currentRowIndex = this.currentRowIndex;
19032
19033    const rows = this.tableRows;
19034    if (!rows) return null
19035
19036    return this.editor.getEditorState().read(() => {
19037      return rows[currentRowIndex]?.getChildren() ?? null
19038    }) ?? null
19039  }
19040
19041  get currentRowIndex() {
19042    const currentCell = this.currentCell;
19043    if (!currentCell) return 0
19044
19045    return this.editor.getEditorState().read(() => {
19046      return Ve$1(currentCell)
19047    }) ?? 0
19048  }
19049
19050  get currentColumnCells() {
19051    const columnIndex = this.currentColumnIndex;
19052
19053    const rows = this.tableRows;
19054    if (!rows) return null
19055
19056    return this.editor.getEditorState().read(() => {
19057      return rows.map(row => row.getChildAtIndex(columnIndex))
19058    }) ?? null
19059  }
19060
19061  get currentColumnIndex() {
19062    const currentCell = this.currentCell;
19063    if (!currentCell) return 0
19064
19065    return this.editor.getEditorState().read(() => {
19066      return Ge$1(currentCell)
19067    }) ?? 0
19068  }
19069
19070  get tableRows() {
19071    return this.editor.getEditorState().read(() => {
19072      return this.currentTableNode?.getChildren()
19073    }) ?? null
19074  }
19075
19076  updateSelectedTable() {
vendor: 9,676 bytes, lines 19077-19368
19077    let cellNode = null;
19078    let tableNode = null;
19079
19080    this.editor.getEditorState().read(() => {
19081      const selection = Qr();
19082      if (!selection || !this.selection.isTableCellSelected) return
19083
19084      const node = selection.getNodes()[0];
19085
19086      cellNode = un(node);
19087      tableNode = hn(node);
19088    });
19089
19090    this.currentCellKey = cellNode?.getKey() ?? null;
19091    this.currentTableNodeKey = tableNode?.getKey() ?? null;
19092
19093    return tableNode
19094  }
19095
19096  executeTableCommand(command, customIndex = null) {
19097    if (command.action === "delete" && command.childType === "table") {
19098      this.#deleteTable();
19099      return
19100    }
19101
19102    if (command.action === "toggle") {
19103      this.#executeToggleStyle(command);
19104      return
19105    }
19106
19107    this.#executeCommand(command, customIndex);
19108  }
19109
19110  #executeCommand(command, customIndex = null) {
19111    this.#selectCellAtSelection();
19112    this.editor.dispatchCommand(this.#commandName(command));
19113    this.#selectNextBestCell(command, customIndex);
19114  }
19115
19116  #executeToggleStyle(command) {
19117    const childType = command.childType;
19118
19119    let cells = null;
19120    let headerState = null;
19121
19122    if (childType === "row") {
19123      cells = this.currentRowCells;
19124      headerState = Ae$1.ROW;
19125    } else if (childType === "column") {
19126      cells = this.currentColumnCells;
19127      headerState = Ae$1.COLUMN;
19128    }
19129
19130    if (!cells || cells.length === 0) return
19131
19132    this.editor.update(() => {
19133      const firstCell = Ye(cells[0]);
19134      if (!firstCell) return
19135
19136      const currentStyle = firstCell.getHeaderStyles();
19137      const newStyle = currentStyle ^ headerState;
19138
19139      cells.forEach(cell => {
19140        this.#setHeaderStyle(cell, newStyle, headerState);
19141      });
19142    });
19143  }
19144
19145  #deleteTable() {
19146    this.#selectCellAtSelection();
19147    this.editor.dispatchCommand("deleteTable");
19148  }
19149
19150  #selectCellAtSelection() {
19151    this.editor.update(() => {
19152      const selection = Qr();
19153      if (!selection) return
19154
19155      const node = selection.getNodes()[0];
19156
19157      un(node)?.selectEnd();
19158    });
19159  }
19160
19161  #commandName(command) {
19162    const { action, childType, direction } = command;
19163
19164    const childTypeSuffix = upcaseFirst(childType);
19165    const directionSuffix = action == "insert" ? upcaseFirst(direction) : "";
19166    return `${action}Table${childTypeSuffix}${directionSuffix}`
19167  }
19168
19169  #setHeaderStyle(cell, newStyle, headerState) {
19170    const tableCellNode = Ye(cell);
19171    tableCellNode?.setHeaderStyles(newStyle, headerState);
19172  }
19173
19174  async #selectCellAtIndex(rowIndex, columnIndex) {
19175    // We wait for next frame, otherwise table operations might not have completed yet.
19176    await nextFrame();
19177
19178    if (!this.currentTableNode) return
19179
19180    const rows = this.tableRows;
19181    if (!rows) return
19182
19183    const row = rows[rowIndex];
19184    if (!row) return
19185
19186    this.editor.update(() => {
19187      const cell = Ye(row.getChildAtIndex(columnIndex));
19188      cell?.selectEnd();
19189    });
19190  }
19191
19192  #selectNextBestCell(command, customIndex = null) {
19193    const { childType, direction } = command;
19194
19195    let rowIndex = this.currentRowIndex;
19196    let columnIndex = customIndex !== null ? customIndex : this.currentColumnIndex;
19197
19198    const deleteOffset = command.action === "delete" ? -1 : 0;
19199    const offset = direction === "after" ? 1 : deleteOffset;
19200
19201    if (childType === "row") {
19202      rowIndex += offset;
19203    } else if (childType === "column") {
19204      columnIndex += offset;
19205    }
19206
19207    this.#selectCellAtIndex(rowIndex, columnIndex);
19208  }
19209
19210  #selectNextRow() {
19211    const rows = this.tableRows;
19212    if (!rows) return
19213
19214    const nextRow = rows.at(this.currentRowIndex + 1);
19215    if (!nextRow) return
19216
19217    this.editor.update(() => {
19218      nextRow.getChildAtIndex(this.currentColumnIndex)?.selectEnd();
19219    });
19220  }
19221
19222  #selectPreviousCell() {
19223    const cell = this.currentCell;
19224    if (!cell) return
19225
19226    this.editor.update(() => {
19227      cell.selectPrevious();
19228    });
19229  }
19230
19231  #insertRowAndSelectFirstCell() {
19232    this.executeTableCommand({ action: "insert", childType: "row", direction: "after" }, 0);
19233  }
19234
19235  #deleteRowAndSelectLastCell() {
19236    this.executeTableCommand({ action: "delete", childType: "row" }, -1);
19237  }
19238
19239  #deleteRowAndSelectNextNode() {
19240    const tableNode = this.currentTableNode;
19241    this.executeTableCommand({ action: "delete", childType: "row" });
19242
19243    this.editor.update(() => {
19244      const next = tableNode?.getNextSibling();
19245      if (no(next)) {
19246        next.selectStart();
19247      } else {
19248        const newParagraph = eo();
19249        this.currentTableNode.insertAfter(newParagraph);
19250        newParagraph.selectStart();
19251      }
19252    });
19253  }
19254
19255  #isCurrentCellEmpty() {
19256    if (!this.currentTableNode) return false
19257
19258    const cell = this.currentCell;
19259    if (!cell) return false
19260
19261    return cell.getTextContent().trim() === ""
19262  }
19263
19264  #isCurrentRowLast() {
19265    if (!this.currentTableNode) return false
19266
19267    const rows = this.tableRows;
19268    if (!rows) return false
19269
19270    return rows.length === this.currentRowIndex + 1
19271  }
19272
19273  #isCurrentRowEmpty() {
19274    if (!this.currentTableNode) return false
19275
19276    const cells = this.currentRowCells;
19277    if (!cells) return false
19278
19279    return cells.every(cell => cell.getTextContent().trim() === "")
19280  }
19281
19282  #isFirstCellInRow() {
19283    if (!this.currentTableNode) return false
19284
19285    const cells = this.currentRowCells;
19286    if (!cells) return false
19287
19288    return cells.indexOf(this.currentCell) === 0
19289  }
19290
19291  #registerKeyHandlers() {
19292    // We can't prevent these externally using regular keydown because Lexical handles it first.
19293    this.#listeners.track(
19294      this.editor.registerCommand(Ae$3, (event) => this.#handleBackspaceKey(event), so),
19295      this.editor.registerCommand(Oe$2, (event) => this.#handleEnterKey(event), so)
19296    );
19297  }
19298
19299  #handleBackspaceKey(event) {
19300    if (!this.currentTableNode) return false
19301
19302    if (this.#isCurrentRowEmpty() && this.#isFirstCellInRow()) {
19303      event.preventDefault();
19304      this.#deleteRowAndSelectLastCell();
19305      return true
19306    }
19307
19308    if (this.#isCurrentCellEmpty() && !this.#isFirstCellInRow()) {
19309      event.preventDefault();
19310      this.#selectPreviousCell();
19311      return true
19312    }
19313
19314    return false
19315  }
19316
19317  #handleEnterKey(event) {
19318    if ((event.ctrlKey || event.metaKey) || event.shiftKey || !this.currentTableNode) return false
19319
19320    if (this.selection.isInsideList || this.selection.isInsideCodeBlock) return false
19321
19322    event.preventDefault();
19323
19324    if (this.#isCurrentRowLast() && this.#isCurrentRowEmpty()) {
19325      this.#deleteRowAndSelectNextNode();
19326    } else if (this.#isCurrentRowLast()) {
19327      this.#insertRowAndSelectFirstCell();
19328    } else {
19329      this.#selectNextRow();
19330    }
19331
19332    return true
19333  }
19334}
19335
19336var TableIcons = {
19337  "insert-row-before":
19338    `<svg  viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
19339    <path fill-rule="evenodd" clip-rule="evenodd" d="M7.86804e-07 15C8.29055e-07 15.8284 0.671574 16.5 1.5 16.5H15L15.1533 16.4922C15.8593 16.4205 16.4205 15.8593 16.4922 15.1533L16.5 15V4.5L16.4922 4.34668C16.4154 3.59028 15.7767 3 15 3H13.5L13.5 4.5H15V9H1.5L1.5 4.5L3 4.5V3H1.5C0.671574 3 1.20956e-06 3.67157 1.24577e-06 4.5L7.86804e-07 15ZM15 10.5V15H1.5L1.5 10.5H15Z"/>
19340    <path d="M4.5 4.5H7.5V7.5H9V4.5H12L12 3L9 3V6.55671e-08L7.5 0V3L4.5 3V4.5Z"/>
19341    </svg>`,
19342
19343  "insert-row-after":
19344    `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
19345    <path fill-rule="evenodd" clip-rule="evenodd" d="M7.86804e-07 13.5C7.50592e-07 14.3284 0.671574 15 1.5 15H3V13.5H1.5L1.5 9L15 9V13.5H13.5V15H15C15.7767 15 16.4154 14.4097 16.4922 13.6533L16.5 13.5V3L16.4922 2.84668C16.4205 2.14069 15.8593 1.57949 15.1533 1.50781L15 1.5L1.5 1.5C0.671574 1.5 1.28803e-06 2.17157 1.24577e-06 3L7.86804e-07 13.5ZM15 3V7.5L1.5 7.5L1.5 3L15 3Z"/>
19346    <path d="M7.5 15V18H9V15H12V13.5H9V10.5H7.5V13.5H4.5V15H7.5Z"/>
19347    </svg>`,
19348
19349  "delete-row":
19350    `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
19351    <path d="M16.4922 12.1533C16.4154 12.9097 15.7767 13.5 15 13.5L12 13.5V12H15V6L1.5 6L1.5 12H4.5V13.5H1.5C0.723337 13.5 0.0846104 12.9097 0.00781328 12.1533L7.86804e-07 12L1.04907e-06 6C1.17362e-06 5.22334 0.590278 4.58461 1.34668 4.50781L1.5 4.5L15 4.5C15.8284 4.5 16.5 5.17157 16.5 6V12L16.4922 12.1533Z"/>
19352    <path d="M10.3711 15.9316L8.25 13.8096L6.12793 15.9316L5.06738 14.8711L7.18945 12.75L5.06738 10.6289L6.12793 9.56836L8.25 11.6895L10.3711 9.56836L11.4316 10.6289L9.31055 12.75L11.4316 14.8711L10.3711 15.9316Z"/>
19353    </svg>`,
19354
19355  "toggle-row":
19356    `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
19357    <path fill-rule="evenodd" clip-rule="evenodd" d="M0.00781328 13.6533C0.0846108 14.4097 0.723337 15 1.5 15L15 15L15.1533 14.9922C15.8593 14.9205 16.4205 14.3593 16.4922 13.6533L16.5 13.5V4.5L16.4922 4.34668C16.4205 3.64069 15.8593 3.07949 15.1533 3.00781L15 3L1.5 3C0.671574 3 1.24863e-06 3.67157 1.18021e-06 4.5L7.86804e-07 13.5L0.00781328 13.6533ZM15 9V13.5L1.5 13.5L1.5 9L15 9Z"/>
19358    </svg>`,
19359
19360  "insert-column-before":
19361    `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
19362    <path fill-rule="evenodd" clip-rule="evenodd" d="M4.5 0C3.67157 0 3 0.671573 3 1.5V3H4.5V1.5H9V15H4.5V13.5H3V15C3 15.7767 3.59028 16.4154 4.34668 16.4922L4.5 16.5H15L15.1533 16.4922C15.8593 16.4205 16.4205 15.8593 16.4922 15.1533L16.5 15V1.5C16.5 0.671573 15.8284 6.03989e-09 15 0H4.5ZM15 15H10.5V1.5H15V15Z"/>
19363    <path d="M3 7.5H0V9H3V12H4.5V9H7.5V7.5H4.5V4.5H3V7.5Z"/>
19364    </svg>`,
19365
19366  "insert-column-after":
19367    `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
19368    <path fill-rule="evenodd" clip-rule="evenodd" d="M13.5 0C14.3284 0 15 0.671573 15 1.5V3H13.5V1.5H9V15H13.5V13.5H15V15C15 15.7767 14.4097 16.4154 13.6533 16.4922L13.5 16.5H3L2.84668 16.4922C2.14069 16.4205 1.57949 15.8593 1.50781 15.1533L1.5 15V1.5C1.5 0.671573 2.17157 6.03989e-09 3 0H13.5ZM3 
1936815H7.5V1.5H3V15Z"/>
19369    <path d="M15 7.5H18V9H15V12H13.5V9H10.5V7.5H13.5V4.5H15V7.5Z"/>
19370    </svg>`,
19371
19372  "delete-column":
19373    `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
19374    <path d="M12.1533 0.0078125C12.9097 0.0846097 13.5 0.723336 13.5 1.5V4.5H12V1.5H6V15H12V12H13.5V15C13.5 15.7767 12.9097 16.4154 12.1533 16.4922L12 16.5H6C5.22334 16.5 4.58461 15.9097 4.50781 15.1533L4.5 15V1.5C4.5 0.671573 5.17157 2.41596e-08 6 0H12L12.1533 0.0078125Z"/>
19375    <path d="M15.9316 6.12891L13.8105 8.24902L15.9326 10.3711L14.8711 11.4316L12.75 9.31055L10.6289 11.4316L9.56738 10.3711L11.6885 8.24902L9.56836 6.12891L10.6289 5.06836L12.75 7.18848L14.8711 5.06836L15.9316 6.12891Z"/>
19376    </svg>`,
19377
19378  "toggle-column":
19379    `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
19380    <path fill-rule="evenodd" clip-rule="evenodd" d="M13.6533 17.9922C14.4097 17.9154 15 17.2767 15 16.5L15 3L14.9922 2.84668C14.9205 2.14069 14.3593 1.57949 13.6533 1.50781L13.5 1.5L4.5 1.5L4.34668 1.50781C3.59028 1.58461 3 2.22334 3 3L3 16.5C3 17.2767 3.59028 17.9154 4.34668 17.9922L4.5 18L13.5 18L13.6533 17.9922ZM9 3L13.5 3L13.5 16.5L9 16.5L9 3Z"/>
19381    </svg>`,
19382
19383  "delete-table":
19384    `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
19385      <path d="M11.2041 1.01074C12.2128 1.113 13 1.96435 13 3V4H15L15.1025 4.00488C15.6067 4.05621 16 4.48232 16 5C16 5.55228 15.5523 6 15 6H14.8457L14.1416 15.1533C14.0614 16.1953 13.1925 17 12.1475 17H5.85254L5.6582 16.9902C4.76514 16.9041 4.03607 16.2296 3.88184 15.3457L3.8584 15.1533L3.1543 6H3C2.44772 6 2 5.55228 2 5C2 4.44772 2.44772 4 3 4H5V3C5 1.89543 5.89543 1 7 1H11L11.2041 1.01074ZM5.85254 15H12.1475L12.8398 6H5.16016L5.85254 15ZM7 4H11V3H7V4Z"/>
19386    </svg>`
19387};
19388
19389class TableTools extends HTMLElement {
19390  #listeners = new ListenerBin()
19391
19392  connectedCallback() {
19393    this.tableController = new TableController(this.#editorElement);
19394    this.classList.add("lexxy-floating-controls");
19395    this.role = "toolbar";
19396
19397    this.#setUpButtons();
19398    this.#hide();
19399    this.#monitorForTableSelection();
19400    this.#registerKeyboardShortcuts();
19401  }
19402
19403  disconnectedCallback() {
19404    this.dispose();
19405  }
19406
19407  dispose() {
19408    this.#listeners.dispose();
19409
19410    this.tableController?.destroy();
19411    this.tableController = null;
19412  }
19413
19414  get #editor() {
19415    return this.#editorElement.editor
19416  }
19417
19418  get #editorElement() {
19419    return this.closest("lexxy-editor")
19420  }
19421
19422  get #tableToolsButtons() {
19423    return Array.from(this.querySelectorAll("button, details > summary"))
19424  }
19425
19426  #setUpButtons() {
19427    this.innerHTML = "";
19428
19429    this.appendChild(this.#createRowButtonsContainer());
19430    this.appendChild(this.#createColumnButtonsContainer());
19431
19432    this.appendChild(this.#createDeleteTableButton());
19433    this.#listeners.track(registerEventListener(this, "keydown", this.#handleToolsKeydown));
19434  }
19435
19436  #createButtonsContainer(childType, setCountProperty, moreMenu) {
19437    const container = createElement("div", { className: `lexxy-floating-controls__group lexxy-table-control lexxy-table-control--${childType}` });
19438
19439    const plusButton = this.#createButton(`Add ${childType}`, { action: "insert", childType, direction: "after" }, "+");
19440    const minusButton = this.#createButton(`Remove ${childType}`, { action: "delete", childType }, "−");
19441
19442    const dropdown = createElement("details", { className: "lexxy-table-control__more-menu" });
19443    dropdown.setAttribute("name", "lexxy-dropdown");
19444    dropdown.tabIndex = -1;
19445
19446    const count = createElement("summary", {}, `_ ${childType}s`);
19447    setCountProperty(count);
19448    dropdown.appendChild(count);
19449
19450    dropdown.appendChild(moreMenu);
19451
19452    container.appendChild(minusButton);
19453    container.appendChild(dropdown);
19454    container.appendChild(plusButton);
19455
19456    return container
19457  }
19458
19459  #createRowButtonsContainer() {
19460    return this.#createButtonsContainer(
19461      "row",
19462      (count) => { this.rowCount = count; },
19463      this.#createMoreMenuSection("row")
19464    )
19465  }
19466
19467  #createColumnButtonsContainer() {
19468    return this.#createButtonsContainer(
19469      "column",
19470      (count) => { this.columnCount = count; },
19471      this.#createMoreMenuSection("column")
19472    )
19473  }
19474
19475  #createMoreMenuSection(childType) {
19476    const section = createElement("div", { className: "lexxy-floating-control
vendor: 4,464 bytes, lines 19476-19617
19476s__group lexxy-table-control__more-menu-details" });
19477    const addBeforeButton = this.#createButton(`Add ${childType} before`, { action: "insert", childType, direction: "before" });
19478    const addAfterButton = this.#createButton(`Add ${childType} after`, { action: "insert", childType, direction: "after" });
19479    const toggleStyleButton = this.#createButton(`Toggle ${childType} style`, { action: "toggle", childType });
19480    const deleteButton = this.#createButton(`Remove ${childType}`, { action: "delete", childType });
19481
19482    section.appendChild(addBeforeButton);
19483    section.appendChild(addAfterButton);
19484    section.appendChild(toggleStyleButton);
19485    section.appendChild(deleteButton);
19486
19487    return section
19488  }
19489
19490  #createDeleteTableButton() {
19491    const container = createElement("div", { className: "lexxy-table-control lexxy-floating-controls__group" });
19492
19493    const deleteTableButton = this.#createButton("Delete this table?", { action: "delete", childType: "table" });
19494    deleteTableButton.classList.add("lexxy-table-control__button--delete-table");
19495
19496    container.appendChild(deleteTableButton);
19497
19498    this.deleteContainer = container;
19499
19500    return container
19501  }
19502
19503  #createButton(label, command = {}, icon = this.#icon(command)) {
19504    const button = createElement("button", {
19505      className: "lexxy-table-control__button",
19506      "aria-label": label,
19507      type: "button"
19508    });
19509    button.tabIndex = -1;
19510    button.innerHTML = `${icon} <span>${label}</span>`;
19511
19512    button.dataset.action = command.action;
19513    button.dataset.childType = command.childType;
19514    button.dataset.direction = command.direction;
19515
19516    button.addEventListener("click", () => this.#executeTableCommand(command));
19517
19518    button.addEventListener("mouseover", () => this.#handleCommandButtonHover());
19519    button.addEventListener("focus", () => this.#handleCommandButtonHover());
19520    button.addEventListener("mouseout", () => this.#handleCommandButtonHover());
19521
19522    return button
19523  }
19524
19525  #registerKeyboardShortcuts() {
19526    this.#listeners.track(this.#editor.registerCommand(ve$2, this.#focusToolbarOnAltF10, so));
19527  }
19528
19529  #focusToolbarOnAltF10 = (event) => {
19530    if (this.#hasSelectedTable && event.altKey && event.key === "F10") {
19531      event.preventDefault();
19532      // Ask for the ring explicitly: a programmatic focus coming from a mouse-focused
19533      // editor otherwise inherits the mouse modality and paints no focus ring.
19534      this.#tableToolsButtons[0]?.focus({ focusVisible: true });
19535      return true
19536    } else {
19537      return false
19538    }
19539  }
19540
19541  get #hasSelectedTable() {
19542    return this.tableController?.currentTableNodeKey != null
19543  }
19544
19545  #handleToolsKeydown = (event) => {
19546    if (event.key === "Escape") {
19547      this.#handleEscapeKey();
19548    } else {
19549      handleRollingTabIndex(this.#tableToolsButtons, event);
19550    }
19551  }
19552
19553  #handleEscapeKey() {
19554    const cell = this.tableController.currentCell;
19555    if (!cell) return
19556
19557    this.#editor.update(() => {
19558      cell.select();
19559      this.#editor.focus();
19560    });
19561
19562    this.#update();
19563  }
19564
19565  async #handleCommandButtonHover() {
19566    await nextFrame();
19567
19568    this.#clearCellStyles();
19569
19570    const activeElement = this.querySelector("button:hover, button:focus");
19571    if (!activeElement) return
19572
19573    const command = {
19574      action: activeElement.dataset.action,
19575      childType: activeElement.dataset.childType,
19576      direction: activeElement.dataset.direction
19577    };
19578
19579    let cellsToHighlight = null;
19580
19581    switch (command.childType) {
19582      case "row":
19583        cellsToHighlight = this.tableController.currentRowCells;
19584        break
19585      case "column":
19586        cellsToHighlight = this.tableController.currentColumnCells;
19587        break
19588      case "table":
19589        cellsToHighlight = this.tableController.tableRows;
19590        break
19591    }
19592
19593    if (!cellsToHighlight) return
19594
19595    cellsToHighlight.forEach(cell => {
19596      const cellElement = this.#editor.getElementByKey(cell.getKey());
19597      if (!cellElement) return
19598
19599      cellElement.classList.toggle(theme.tableCellHighlight, true);
19600      Object.assign(cellElement.dataset, command);
19601    });
19602  }
19603
19604  #monitorForTableSelection() {
19605    this.#listeners.track(this.#editor.registerUpdateListener(() => {
19606      const tableNode = this.#editor.getRootElement() && this.tableController.updateSelectedTable();
19607
19608      if (tableNode) {
19609        this.#show();
19610      } else {
19611        this.#hide();
19612      }
19613    }));
19614  }
19615
19616  #executeTableCommand(command) {
19617    this.tableController.executeTableCommand(command);
19618    this.#update();
19619  }
19620
19621  #show() {
19622    this.#updateButtonsPosition();
19623    this.style.display = "flex";
19624    this.#updateRowColumnCount();
19625    this.#closeMoreMenu();
19626    this.#handleCommandButtonHover();
19627  }
19628
19629  #hide() {
19630    this.style.display = "none";
19631    this.#clearCellStyles();
19632  }
19633
19634  #update() {
19635    this.#updateButtonsPosition();
19636    this.#updateRowColumnCount();
19637    this.#closeMoreMenu();
19638    this.#handleCommandButtonHover();
19639  }
19640
19641  #closeMoreMenu() {
19642    this.querySelector("details[open]")?.removeAttribute("open");
19643  }
19644
19645  #updateButtonsPosition() {
19646    const tableNode = this.tableController.currentTableNode;
19647    if (!tableNode) return
19648
19649    const tableElement = this.#editor.getElementByKey(tableNode.getKey());
19650    if (!tableElement) return
19651
19652    const tableRect = tableElement.getBoundingClientRect();
19653    const editorRect = this.#editorElement.getBoundingClientRect();
19654
19655    const relativeTop = tableRect.top - editorRect.top;
19656    const relativeCenter = (tableRect.left + tableRect.right) / 2 - editorRect.left;
19657    this.style.top = `${relativeTop}px`;
19658    this.style.left = `${relativeCenter}px`;
19659  }
19660
19661  #updateRowColumnCount() {
19662    const tableNode = this.tableController.currentTableNode;
19663    if (!tableNode) return
19664
19665    const tableElement = xn(this.#editor, tableNode);
19666    if (!tableElement) return
19667
19668    const rowCount = tableElement.rows;
19669    const columnCount = tableElement.columns;
19670
19671    this.rowCount.textContent = `${rowCount} row${rowCount === 1 ? "" : "s"}`;
19672    this.columnCount.textContent = `${columnCount} column${columnCount === 1 ? "" : "s"}`;
19673  }
19674
19675  #setTableCellFocus() {
19676    const cell = this.tableController.currentCell;
19677    if (!cell) return
19678
19679    const cellElement = this.#editor.getElementByKey(cell.getKey());
19680    if (!cellElement) return
19681
19682    cellElement.classList.add(theme.tableCellFocus);
19683  }
19684
19685  #clearCellStyles() {
19686    this.#editorElement.querySelectorAll(`.${theme.tableCellFocus}`)?.forEach(cell => {
19687      cell.classList.remove(theme.tableCellFocus);
19688    });
19689
19690    this.#editorElement.querySelectorAll(`.${theme.tableCellHighlight}`)?.forEach(cell => {
19691      cell.classList.remove(theme.tableCellHighlight);
19692      cell.removeAttribute("data-action");
19693      cell.removeAttribute("data-child-type");
19694      cell.removeAttribute("data-direction");
19695    });
19696
19697    this.#setTableCellFocus();
19698  }
19699
19700  #icon(command) {
19701    const { action, childType } = command;
19702    const direction = (action == "insert" ? command.direction : null);
19703    const iconId = [ action, childType, direction ].filter(Boolean).join("-");
19704    return TableIcons[iconId]
19705  }
19706}
19707
19708function defineElements() {
19709  const elements = {
19710    // Toolbar must be registered BEFORE Editor
19711    "lexxy-toolbar": LexicalToolbarElement,
19712    "lexxy-toolbar-dropdown": ToolbarDropdown,
19713    "lexxy-heading-dropdown": HeadingDropdown,
19714    "lexxy-highlight-dropdown": HighlightDropdown,
19715    "lexxy-link-dropdown": LinkDropdown,
19716
19717    "lexxy-editor": LexicalEditorElement,
19718
19719    // Prompt must be registered AFTER Editor
19720    "lexxy-prompt": LexicalPromptElement,
19721    "lexxy-code-language-picker": CodeLanguagePicker,
19722    "lexxy-node-delete-button": NodeDeleteButton,
19723    "lexxy-table-tools": TableTools
19724  };
19725
19726  Object.entries(elements).forEach(([ name, element ]) => {
19727    customElements.define(name, element);
19728  });
19729}
19730
19731function highlightCode(root = document) {
19732  const elements = root.querySelectorAll("pre[data-language]:not([data-highlighted])");
19733
19734  elements.forEach(preElement => {
19735    highlightElement(preElement);
19736  });
19737}
19738
19739function highlightElement(preElement) {
19740  if (preElement.dataset.highlighted === "true") return
19741
19742  const language = preElement.getAttribute("data-language");
19743
19744  const grammar = Prism$1.languages?.[language];
19745  if (!grammar) return
19746
19747  // Read the source text and <mark> ranges in a single walk, before Prism
19748  // rewrites the element. Sharing one traversal keeps the highlight offsets
19749  // aligned with the code string and preserves leading whitespace — deriving
19750  // either of them separately (e.g. textContent through DOMParser) collapses
19751  // leading whitespace and shifts every range, re-indenting the rendered block.
19752  const { code, highlights } = extractCodeAndHighlights(preElement);
19753
19754  const highlightedHtml = Prism$1.highlight(code, grammar, language);
19755  preElement.innerHTML = highlightedHtml;
19756
19757  if (highlights.length > 0) {
19758    applyHighlightRanges(preElement, highlights);
19759  }
19760
19761  preElement.dataset.highlighted = "true";
19762}
19763
19764// Walk the <pre> once, building Prism's source text and the <mark> ranges
19765// together: a text node contributes its text verbatim, a <br> contributes a
19766// newline, and a <mark>
19766 records the slice of code it covers. Because both
19767// outputs come from the same walk, every range offset is just a position in
19768// `code` — so the highlights can't drift out of sync with the source, and the
19769// block's leading whitespace survives (HTML parsing would collapse it).
19770function extractCodeAndHighlights(preElement) {
19771  const root = preElement.querySelector("code") || preElement;
19772  const highlights = [];
19773  let code = "";
19774
19775  function walk(node) {
19776    if (node.nodeType === Node.TEXT_NODE) {
19777      code += node.textContent;
19778    } else if (node.nodeType === Node.ELEMENT_NODE) {
19779      if (node.tagName === "BR") {
19780        code += "\n";
19781      } else if (node.tagName === "MARK") {
19782        const start = code.length;
19783        for (const child of node.childNodes) {
19784          walk(child);
19785        }
19786        const style = extractStyle(node);
19787        if (style) {
19788          highlights.push({ start, end: code.length, style });
19789        }
19790      } else {
19791        for (const child of node.childNodes) {
19792          walk(child);
19793        }
19794      }
19795    }
19796  }
19797
19798  for (const child of root.childNodes) {
19799    walk(child);
19800  }
19801
19802  return { code, highlights }
19803}
19804
19805function extractStyle(element) {
19806  const parts = [];
19807  if (element.style?.color) parts.push(`color: ${element.style.color};`);
19808  if (element.style?.backgroundColor) parts.push(`background-color: ${element.style.backgroundColor};`);
19809  return parts.length > 0 ? parts.join(" ") : null
19810}
19811
19812// Wrap character ranges in <mark> elements within a Prism-highlighted DOM tree.
19813// Each range is applied independently, re-collecting text nodes each time to
19814// account for splits from previous ranges.
19815function applyHighlightRanges(element, highlights) {
19816  for (const { start, end, style } of highlights) {
19817    wrapRange(element, start, end, style);
19818  }
19819}
19820
19821function wrapRange(container, rangeStart, rangeEnd, style) {
19822  const textNodes = collectTextNodes(container);
19823
19824  // Process in reverse so DOM mutations don't shift earlier text node offsets
19825  for (let i = textNodes.length - 1; i >= 0; i--) {
19826    const { node, start: nodeStart, end: nodeEnd } = textNodes[i];
19827    const overlapStart = Math.max(rangeStart, nodeStart);
19828    const overlapEnd = Math.min(rangeEnd, nodeEnd);
19829    if (overlapStart >= overlapEnd) continue
19830
19831    const relStart = overlapStart - nodeStart;
19832    const relEnd = overlapEnd - nodeStart;
19833    const text = node.textContent;
19834    const parent = node.parentNode;
19835
19836    const mark = document.createElement("mark");
19837    mark.setAttribute("style", style);
19838    mark.textContent = text.slice(relStart, relEnd);
19839
19840    if (relEnd < text.length) {
19841      parent.insertBefore(document.createTextNode(text.slice(relEnd)), node.nextSibling);
19842    }
19843    parent.insertBefore(mark, node.nextSibling);
19844
19845    if (relStart > 0) {
19846      node.textContent = text.slice(0, relStart);
19847    } else {
19848      parent.removeChild(node);
19849    }
19850  }
19851}
19852
19853function collectTextNodes(root) {
19854  const nodes = [];
19855  let offset = 0;
19856  const walker = document.createTreeWalker(root, 4 /* NodeFilter.SHOW_TEXT */);
19857
19858  let node;
19859  while ((node = walker.nextNode())) {
19860    const length = node.textContent.length;
19861    nodes.push({ node, start: offset, end: offset + length });
19862    offset += length;
19863  }
19864
19865  return nodes
19866}
19867
19868class NativeAdapter {
19869  frozenLinkKey = null
19870
19871  constructor(editorElement) {
19872    this.editorElement = editorElement;
19873    this.editorContentElement = editorElement.editorContentElement;
19874  }
19875
19876  dispatchAttributesChange(attributes, linkHref, highlight, headingTag) {
19877    dispatch(this.editorElement, "lexxy:attributes-change", {
19878      attributes,
19879      link: linkHref ? { href: linkHref } : null,
19880      highlight,
19881      headingTag
19882    });
19883  }
19884
19885  dispatchEditorInitialized(detail) {
19886    dispatch(this.editorElement, "lexxy:editor-initialized", detail);
19887  }
19888
19889  freeze() {
19890    let frozenLinkKey = null;
19891    this.editorElement.editor?.getEditorState().read(() => {
19892      const selection = Qr();
19893      if (!Fr(selection)) return
19894
19895      const linkNode = At$2(selection.anchor.getNode(), F$4);
19896      if (linkNode) {
19897        frozenLinkKey = linkNode.getKey();
19898      }
19899    });
19900
19901    this.frozenLinkKey = frozenLinkKey;
19902    this.editorContentElement.contentEditable = "false";
19903  }
19904
19905  thaw() {
19906    this.editorContentElement.contentEditable = "true";
19907  }
19908
19909  unlinkFrozenNode() {
vendor: 2,125 bytes, lines 19910-19972
19910    const key = this.frozenLinkKey;
19911    if (!key) return false
19912
19913    const linkNode = Yo(key);
19914    if (!z$5(linkNode)) {
19915      this.frozenLinkKey = null;
19916      return false
19917    }
19918
19919    const children = linkNode.getChildren();
19920    for (const child of children) {
19921      linkNode.insertBefore(child);
19922    }
19923    linkNode.remove();
19924
19925    // Select the former link text so a follow-up createLink can re-wrap it.
19926    const firstText = this.#findFirstTextDescendant(children);
19927    const lastText = this.#findLastTextDescendant(children);
19928    if (firstText && lastText) {
19929      const selection = Qr();
19930      if (Fr(selection)) {
19931        selection.anchor.set(firstText.getKey(), 0, "text");
19932        selection.focus.set(lastText.getKey(), lastText.getTextContent().length, "text");
19933      }
19934    }
19935
19936    this.frozenLinkKey = null;
19937    return true
19938  }
19939
19940  #findFirstTextDescendant(nodes) {
19941    for (const node of nodes) {
19942      if (Tr(node)) return node
19943      if (Wi(node)) {
19944        const nestedTextNode = this.#findFirstTextDescendant(node.getChildren());
19945        if (nestedTextNode) return nestedTextNode
19946      }
19947    }
19948
19949    return null
19950  }
19951
19952  #findLastTextDescendant(nodes) {
19953    for (let index = nodes.length - 1; index >= 0; index--) {
19954      const node = nodes[index];
19955      if (Tr(node)) return node
19956      if (Wi(node)) {
19957        const nestedTextNode = this.#findLastTextDescendant(node.getChildren());
19958        if (nestedTextNode) return nestedTextNode
19959      }
19960    }
19961
19962    return null
19963  }
19964}
19965
19966const configure = Lexxy.configure;
19967
19968// Pushing elements definition to after the current call stack to allow global configuration to take place first
19969setTimeout(defineElements, 0);
19970
19971export { $createActionTextAttachmentNode, $createActionTextAttachmentUploadNode, $isActionTextAttachmentNode, $isCustomActionTextAttachmentNode, ActionTextAttachmentNode, ActionTextAttachmentUploadNode, CustomActionTextAttachmentNode, EditorSanitizer, LexxyExtension as Extension, HorizontalDividerNode, Lexical_prod as Lexical, NativeAdapter, REWRITE_HISTORY_COMMAND, configure, highlightCode, highlightElement };
19972//# sourceMappingURL=/assets/lexxy-cf25b7b2.js.map

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.