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, '&').replace(/</g, '<').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, '"') + '"'; 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(/&/, '&'); 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(/&/, '&'); 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: //, 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.3.0 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.3.0
vendor: 17,189 bytes, lines 4830-5128
4830/LICENSE */ 4831 4832const { 4833 entries, 4834 setPrototypeOf, 4835 isFrozen, 4836 getPrototypeOf, 4837 getOwnPropertyDescriptor 4838} = Object; 4839let { 4840 freeze, 4841 seal, 4842 create 4843} = Object; // eslint-disable-line import/no-mutable-exports 4844let { 4845 apply, 4846 construct 4847} = typeof Reflect !== 'undefined' && Reflect; 4848if (!freeze) { 4849 freeze = function freeze(x) { 4850 return x; 4851 }; 4852} 4853if (!seal) { 4854 seal = function seal(x) { 4855 return x; 4856 }; 4857} 4858if (!apply) { 4859 apply = function apply(func, thisArg) { 4860 for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { 4861 args[_key - 2] = arguments[_key]; 4862 } 4863 return func.apply(thisArg, args); 4864 }; 4865} 4866if (!construct) { 4867 construct = function construct(Func) { 4868 for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { 4869 args[_key2 - 1] = arguments[_key2]; 4870 } 4871 return new Func(...args); 4872 }; 4873} 4874const arrayForEach = unapply(Array.prototype.forEach); 4875const arrayLastIndexOf = unapply(Array.prototype.lastIndexOf); 4876const arrayPop = unapply(Array.prototype.pop); 4877const arrayPush = unapply(Array.prototype.push); 4878const arraySplice = unapply(Array.prototype.splice); 4879const stringToLowerCase = unapply(String.prototype.toLowerCase); 4880const stringToString = unapply(String.prototype.toString); 4881const stringMatch = unapply(String.prototype.match); 4882const stringReplace = unapply(String.prototype.replace); 4883const stringIndexOf = unapply(String.prototype.indexOf); 4884const stringTrim = unapply(String.prototype.trim); 4885const objectHasOwnProperty = unapply(Object.prototype.hasOwnProperty); 4886const regExpTest = unapply(RegExp.prototype.test); 4887const typeErrorCreate = unconstruct(TypeError); 4888/** 4889 * Creates a new function that calls the given function with a specified thisArg and arguments. 4890 * 4891 * @param func - The function to be wrapped and called. 4892 * @returns A new function that calls the given function with a specified thisArg and arguments. 4893 */ 4894function unapply(func) { 4895 return function (thisArg) { 4896 if (thisArg instanceof RegExp) { 4897 thisArg.lastIndex = 0; 4898 } 4899 for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) { 4900 args[_key3 - 1] = arguments[_key3]; 4901 } 4902 return apply(func, thisArg, args); 4903 }; 4904} 4905/** 4906 * Creates a new function that constructs an instance of the given constructor function with the provided arguments. 4907 * 4908 * @param func - The constructor function to be wrapped and called. 4909 * @returns A new function that constructs an instance of the given constructor function with the provided arguments. 4910 */ 4911function unconstruct(Func) { 4912 return function () { 4913 for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { 4914 args[_key4] = arguments[_key4]; 4915 } 4916 return construct(Func, args); 4917 }; 4918} 4919/** 4920 * Add properties to a lookup table 4921 * 4922 * @param set - The set to which elements will be added. 4923 * @param array - The array containing elements to be added to the set. 4924 * @param transformCaseFunc - An optional function to transform the case of each element before adding to the set. 4925 * @returns The modified set with added elements. 4926 */ 4927function addToSet(set, array) { 4928 let transformCaseFunc = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : stringToLowerCase; 4929 if (setPrototypeOf) { 4930 // Make 'in' and truthy checks like Boolean(set.constructor) 4931 // independent of any properties defined on Object.prototype. 4932 // Prevent prototype setters from intercepting set as a this value. 4933 setPrototypeOf(set, null); 4934 } 4935 let l = array.length; 4936 while (l--) { 4937 let element = array[l]; 4938 if (typeof element === 'string') { 4939 const lcElement = transformCaseFunc(element); 4940 if (lcElement !== element) { 4941 // Config presets (e.g. tags.js, attrs.js) are immutable. 4942 if (!isFrozen(array)) { 4943 array[l] = lcElement; 4944 } 4945 element = lcElement; 4946 } 4947 } 4948 set[element] = true; 4949 } 4950 return set; 4951} 4952/** 4953 * Clean up an array to harden against CSPP 4954 * 4955 * @param array - The array to be cleaned. 4956 * @returns The cleaned version of the array 4957 */ 4958function cleanArray(array) { 4959 for (let index = 0; index < array.length; index++) { 4960 const isPropertyExist = objectHasOwnProperty(array, index); 4961 if (!isPropertyExist) { 4962 array[index] = null; 4963 } 4964 } 4965 return array; 4966} 4967/** 4968 * Shallow clone an object 4969 * 4970 * @param object - The object to be cloned. 4971 * @returns A new object that copies the original. 4972 */ 4973function clone(object) { 4974 const newObject = create(null); 4975 for (const [property, value] of entries(object)) { 4976 const isPropertyExist = objectHasOwnProperty(object, property); 4977 if (isPropertyExist) { 4978 if (Array.isArray(value)) { 4979 newObject[property] = cleanArray(value); 4980 } else if (value && typeof value === 'object' && value.constructor === Object) { 4981 newObject[property] = clone(value); 4982 } else { 4983 newObject[property] = value; 4984 } 4985 } 4986 } 4987 return newObject; 4988} 4989/** 4990 * This method automatically checks if the prop is function or getter and behaves accordingly. 4991 * 4992 * @param object - The object to look up the getter function in its prototype chain. 4993 * @param prop - The property name for which to find the getter function. 4994 * @returns The getter function found in the prototype chain or a fallback function. 4995 */ 4996function lookupGetter(object, prop) { 4997 while (object !== null) { 4998 const desc = getOwnPropertyDescriptor(object, prop); 4999 if (desc) { 5000 if (desc.get) { 5001 return unapply(desc.get); 5002 } 5003 if (typeof desc.value === 'function') { 5004 return unapply(desc.value); 5005 } 5006 } 5007 object = getPrototypeOf(object); 5008 } 5009 function fallbackValue() { 5010 return null; 5011 } 5012 return fallbackValue; 5013} 5014 5015const 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']); 5016const 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']); 5017const 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']); 5018// List of SVG elements that are disallowed by default. 5019// We still need to know them so that we can do namespace 5020// checks properly in case one wants to add them to 5021// allow-list. 5022const 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']); 5023const 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']); 5024// Similarly to SVG, we want to know all MathML elements, 5025// even those that we disallow by default. 5026const mathMlDisallowed = freeze(['maction', 'maligngroup', 'malignmark', 'mlongdiv', 'mscarries', 'mscarry', 'msgroup', 'mstack', 'msline', 'msrow', 'semantics', 'annotation', 'annotation-xml', 'mprescripts', 'none']); 5027const text = freeze(['#text']); 5028 5029const html = freeze(['accept', 'action', 'align', 'alt', 'autocapitalize', 'autocomplete', 'autopictureinpicture', 'autoplay', 'background', 'bgcolor', 'border', 'capture', 'cellpadding', 'cellspacing', 'checked', 'cite', 'class', 'clear', 'color', 'cols', 'colspan', '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', 'slot']); 5030const 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', '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-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']); 5031const mathMl = freeze(['accent', 'accentunder', 'align', 'bevelled', 'close', 'columnsalign', 'columnlines', 'columnspan', 'denomalign', 'depth', 'dir', 'display', 'displaystyle', 'encoding', 'fence', 'frame', 'height', 'href', 'id', 'largeop', 'length', 'linethickness', 'lspace', 'lquote', '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']); 5032const xml = freeze(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']); 5033 5034// eslint-disable-next-line unicorn/better-regex 5035const MUSTACHE_EXPR = seal(/\{\{[\w\W]*|[\w\W]*\}\}/gm); // Specify template detection regex for SAFE_FOR_TEMPLATES mode 5036const ERB_EXPR = seal(/<%[\w\W]*|[\w\W]*%>/gm); 5037const TMPLIT_EXPR = seal(/\$\{[\w\W]*/gm); // eslint-disable-line unicorn/better-regex 5038const DATA_ATTR = seal(/^data-[\-\w.\u00B7-\uFFFF]+$/); // eslint-disable-line no-useless-escape 5039const ARIA_ATTR = seal(/^aria-[\-\w]+$/); // eslint-disable-line no-useless-escape 5040const 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 5041); 5042const IS_SCRIPT_OR_DATA = seal(/^(?:\w+script|data):/i); 5043const ATTR_WHITESPACE = seal(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g // eslint-disable-line no-control-regex 5044); 5045const DOCTYPE_NAME = seal(/^html$/i); 5046const CUSTOM_ELEMENT = seal(/^[a-z][.\w]*(-[.\w]+)+$/i); 5047 5048var EXPRESSIONS = /*#__PURE__*/Object.freeze({ 5049 __proto__: null, 5050 ARIA_ATTR: ARIA_ATTR, 5051 ATTR_WHITESPACE: ATTR_WHITESPACE, 5052 CUSTOM_ELEMENT: CUSTOM_ELEMENT, 5053 DATA_ATTR: DATA_ATTR, 5054 DOCTYPE_NAME: DOCTYPE_NAME, 5055 ERB_EXPR: ERB_EXPR, 5056 IS_ALLOWED_URI: IS_ALLOWED_URI, 5057 IS_SCRIPT_OR_DATA: IS_SCRIPT_OR_DATA, 5058 MUSTACHE_EXPR: MUSTACHE_EXPR, 5059 TMPLIT_EXPR: TMPLIT_EXPR 5060}); 5061 5062/* eslint-disable @typescript-eslint/indent */ 5063// https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType 5064const NODE_TYPE = { 5065 element: 1, 5066 text: 3, 5067 // Deprecated 5068 progressingInstruction: 7, 5069 comment: 8, 5070 document: 9}; 5071const getGlobal = function getGlobal() { 5072 return typeof window === 'undefined' ? null : window; 5073}; 5074/** 5075 * Creates a no-op policy for internal use only. 5076 * Don't export this function outside this module! 5077 * @param trustedTypes The policy factory. 5078 * @param purifyHostElement The Script element used to load DOMPurify (to determine policy name suffix). 5079 * @return The policy created (or null, if Trusted Types 5080 * are not supported or creating the policy failed). 5081 */ 5082const _createTrustedTypesPolicy = function _createTrustedTypesPolicy(trustedTypes, purifyHostElement) { 5083 if (typeof trustedTypes !== 'object' || typeof trustedTypes.createPolicy !== 'function') { 5084 return null; 5085 } 5086 // Allow the callers to control the unique policy name 5087 // by adding a data-tt-policy-suffix to the script element with the DOMPurify. 5088 // Policy creation with duplicate names throws in Trusted Types. 5089 let suffix = null; 5090 const ATTR_NAME = 'data-tt-policy-suffix'; 5091 if (purifyHostElement && purifyHostElement.hasAttribute(ATTR_NAME)) { 5092 suffix = purifyHostElement.getAttribute(ATTR_NAME); 5093 } 5094 const policyName = 'dompurify' + (suffix ? '#' + suffix : ''); 5095 try { 5096 return trustedTypes.createPolicy(policyName, { 5097 createHTML(html) { 5098 return html; 5099 }, 5100 createScriptURL(scriptUrl) { 5101 return scriptUrl; 5102 } 5103 }); 5104 } catch (_) { 5105 // Policy creation failed (most likely another DOMPurify script has 5106 // already run). Skip creating the policy, as this will only cause errors 5107 // if TT are enforced. 5108 console.warn('TrustedTypes policy ' + policyName + ' could not be created.'); 5109 return null; 5110 } 5111}; 5112const _createHooksMap = function _createHooksMap() { 5113 return { 5114 afterSanitizeAttributes: [], 5115 afterSanitizeElements: [], 5116 afterSanitizeShadowDOM: [], 5117 beforeSanitizeAttributes: [], 5118 beforeSanitizeElements: [], 5119 beforeSanitizeShadowDOM: [], 5120 uponSanitizeAttribute: [], 5121 uponSanitizeElement: [], 5122 uponSanitizeShadowNode: [] 5123 }; 5124}; 5125function createDOMPurify() { 5126 let window = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getGlobal(); 5127 const DOMPurify = root => createDOMPurify(root); 5128 DOMPurify.version = '3.3.
51280
vendor: 14,276 bytes, lines 5128-5423
5128'; 5129 DOMPurify.removed = []; 5130 if (!window || !window.document || window.document.nodeType !== NODE_TYPE.document || !window.Element) { 5131 // Not running in a browser, provide a factory function 5132 // so that you can pass your own Window 5133 DOMPurify.isSupported = false; 5134 return DOMPurify; 5135 } 5136 let { 5137 document 5138 } = window; 5139 const originalDocument = document; 5140 const currentScript = originalDocument.currentScript; 5141 const { 5142 DocumentFragment, 5143 HTMLTemplateElement, 5144 Node, 5145 Element, 5146 NodeFilter, 5147 NamedNodeMap = window.NamedNodeMap || window.MozNamedAttrMap, 5148 HTMLFormElement, 5149 DOMParser, 5150 trustedTypes 5151 } = window; 5152 const ElementPrototype = Element.prototype; 5153 const cloneNode = lookupGetter(ElementPrototype, 'cloneNode'); 5154 const remove = lookupGetter(ElementPrototype, 'remove'); 5155 const getNextSibling = lookupGetter(ElementPrototype, 'nextSibling'); 5156 const getChildNodes = lookupGetter(ElementPrototype, 'childNodes'); 5157 const getParentNode = lookupGetter(ElementPrototype, 'parentNode'); 5158 // As per issue #47, the web-components registry is inherited by a 5159 // new document created via createHTMLDocument. As per the spec 5160 // (http://w3c.github.io/webcomponents/spec/custom/#creating-and-passing-registries) 5161 // a new empty registry is used when creating a template contents owner 5162 // document, so we use that as our parent document to ensure nothing 5163 // is inherited. 5164 if (typeof HTMLTemplateElement === 'function') { 5165 const template = document.createElement('template'); 5166 if (template.content && template.content.ownerDocument) { 5167 document = template.content.ownerDocument; 5168 } 5169 } 5170 let trustedTypesPolicy; 5171 let emptyHTML = ''; 5172 const { 5173 implementation, 5174 createNodeIterator, 5175 createDocumentFragment, 5176 getElementsByTagName 5177 } = document; 5178 const { 5179 importNode 5180 } = originalDocument; 5181 let hooks = _createHooksMap(); 5182 /** 5183 * Expose whether this browser supports running the full DOMPurify. 5184 */ 5185 DOMPurify.isSupported = typeof entries === 'function' && typeof getParentNode === 'function' && implementation && implementation.createHTMLDocument !== undefined; 5186 const { 5187 MUSTACHE_EXPR, 5188 ERB_EXPR, 5189 TMPLIT_EXPR, 5190 DATA_ATTR, 5191 ARIA_ATTR, 5192 IS_SCRIPT_OR_DATA, 5193 ATTR_WHITESPACE, 5194 CUSTOM_ELEMENT 5195 } = EXPRESSIONS; 5196 let { 5197 IS_ALLOWED_URI: IS_ALLOWED_URI$1 5198 } = EXPRESSIONS; 5199 /** 5200 * We consider the elements and attributes below to be safe. Ideally 5201 * don't add any new ones but feel free to remove unwanted ones. 5202 */ 5203 /* allowed element names */ 5204 let ALLOWED_TAGS = null; 5205 const DEFAULT_ALLOWED_TAGS = addToSet({}, [...html$1, ...svg$1, ...svgFilters, ...mathMl$1, ...text]); 5206 /* Allowed attribute names */ 5207 let ALLOWED_ATTR = null; 5208 const DEFAULT_ALLOWED_ATTR = addToSet({}, [...html, ...svg, ...mathMl, ...xml]); 5209 /* 5210 * Configure how DOMPurify should handle custom elements and their attributes as well as customized built-in elements. 5211 * @property {RegExp|Function|null} tagNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any custom elements) 5212 * @property {RegExp|Function|null} attributeNameCheck one of [null, regexPattern, predicate]. Default: `null` (disallow any attributes not on the allow list) 5213 * @property {boolean} allowCustomizedBuiltInElements allow custom elements derived from built-ins if they pass CUSTOM_ELEMENT_HANDLING.tagNameCheck. Default: `false`. 5214 */ 5215 let CUSTOM_ELEMENT_HANDLING = Object.seal(create(null, { 5216 tagNameCheck: { 5217 writable: true, 5218 configurable: false, 5219 enumerable: true, 5220 value: null 5221 }, 5222 attributeNameCheck: { 5223 writable: true, 5224 configurable: false, 5225 enumerable: true, 5226 value: null 5227 }, 5228 allowCustomizedBuiltInElements: { 5229 writable: true, 5230 configurable: false, 5231 enumerable: true, 5232 value: false 5233 } 5234 })); 5235 /* Explicitly forbidden tags (overrides ALLOWED_TAGS/ADD_TAGS) */ 5236 let FORBID_TAGS = null; 5237 /* Explicitly forbidden attributes (overrides ALLOWED_ATTR/ADD_ATTR) */ 5238 let FORBID_ATTR = null; 5239 /* Config object to store ADD_TAGS/ADD_ATTR functions (when used as functions) */ 5240 const EXTRA_ELEMENT_HANDLING = Object.seal(create(null, { 5241 tagCheck: { 5242 writable: true, 5243 configurable: false, 5244 enumerable: true, 5245 value: null 5246 }, 5247 attributeCheck: { 5248 writable: true, 5249 configurable: false, 5250 enumerable: true, 5251 value: null 5252 } 5253 })); 5254 /* Decide if ARIA attributes are okay */ 5255 let ALLOW_ARIA_ATTR = true; 5256 /* Decide if custom data attributes are okay */ 5257 let ALLOW_DATA_ATTR = true; 5258 /* Decide if unknown protocols are okay */ 5259 let ALLOW_UNKNOWN_PROTOCOLS = false; 5260 /* Decide if self-closing tags in attributes are allowed. 5261 * Usually removed due to a mXSS issue in jQuery 3.0 */ 5262 let ALLOW_SELF_CLOSE_IN_ATTR = true; 5263 /* Output should be safe for common template engines. 5264 * This means, DOMPurify removes data attributes, mustaches and ERB 5265 */ 5266 let SAFE_FOR_TEMPLATES = false; 5267 /* Output should be safe even for XML used within HTML and alike. 5268 * This means, DOMPurify removes comments when containing risky content. 5269 */ 5270 let SAFE_FOR_XML = true; 5271 /* Decide if document with <html>... should be returned */ 5272 let WHOLE_DOCUMENT = false; 5273 /* Track whether config is already set on this instance of DOMPurify. */ 5274 let SET_CONFIG = false; 5275 /* Decide if all elements (e.g. style, script) must be children of 5276 * document.body. By default, browsers might move them to document.head */ 5277 let FORCE_BODY = false; 5278 /* Decide if a DOM `HTMLBodyElement` should be returned, instead of a html 5279 * string (or a TrustedHTML object if Trusted Types are supported). 5280 * If `WHOLE_DOCUMENT` is enabled a `HTMLHtmlElement` will be returned instead 5281 */ 5282 let RETURN_DOM = false; 5283 /* Decide if a DOM `DocumentFragment` should be returned, instead of a html 5284 * string (or a TrustedHTML object if Trusted Types are supported) */ 5285 let RETURN_DOM_FRAGMENT = false; 5286 /* Try to return a Trusted Type object instead of a string, return a string in 5287 * case Trusted Types are not supported */ 5288 let RETURN_TRUSTED_TYPE = false; 5289 /* Output should be free from DOM clobbering attacks? 5290 * This sanitizes markups named with colliding, clobberable built-in DOM APIs. 5291 */ 5292 let SANITIZE_DOM = true; 5293 /* Achieve full DOM Clobbering protection by isolating the namespace of named 5294 * properties and JS variables, mitigating attacks that abuse the HTML/DOM spec rules. 5295 * 5296 * HTML/DOM spec rules that enable DOM Clobbering: 5297 * - Named Access on Window (§7.3.3) 5298 * - DOM Tree Accessors (§3.1.5) 5299 * - Form Element Parent-Child Relations (§4.10.3) 5300 * - Iframe srcdoc / Nested WindowProxies (§4.8.5) 5301 * - HTMLCollection (§4.2.10.2) 5302 * 5303 * Namespace isolation is implemented by prefixing `id` and `name` attributes 5304 * with a constant string, i.e., `user-content-` 5305 */ 5306 let SANITIZE_NAMED_PROPS = false; 5307 const SANITIZE_NAMED_PROPS_PREFIX = 'user-content-'; 5308 /* Keep element content when removing element? */ 5309 let KEEP_CONTENT = true; 5310 /* If a `Node` is passed to sanitize(), then performs sanitization in-place instead 5311 * of importing it into a new Document and returning a sanitized copy */ 5312 let IN_PLACE = false; 5313 /* Allow usage of profiles like html, svg and mathMl */ 5314 let USE_PROFILES = {}; 5315 /* Tags to ignore content of when KEEP_CONTENT is true */ 5316 let FORBID_CONTENTS = null; 5317 const DEFAULT_FORBID_CONTENTS = addToSet({}, ['annotation-xml', 'audio', 'colgroup', 'desc', 'foreignobject', 'head', 'iframe', 'math', 'mi', 'mn', 'mo', 'ms', 'mtext', 'noembed', 'noframes', 'noscript', 'plaintext', 'script', 'style', 'svg', 'template', 'thead', 'title', 'video', 'xmp']); 5318 /* Tags that are safe for data: URIs */ 5319 let DATA_URI_TAGS = null; 5320 const DEFAULT_DATA_URI_TAGS = addToSet({}, ['audio', 'video', 'img', 'source', 'image', 'track']); 5321 /* Attributes safe for values like "javascript:" */ 5322 let URI_SAFE_ATTRIBUTES = null; 5323 const DEFAULT_URI_SAFE_ATTRIBUTES = addToSet({}, ['alt', 'class', 'for', 'id', 'label', 'name', 'pattern', 'placeholder', 'role', 'summary', 'title', 'value', 'style', 'xmlns']); 5324 const MATHML_NAMESPACE = 'http://www.w3.org/1998/Math/MathML'; 5325 const SVG_NAMESPACE = 'http://www.w3.org/2000/svg'; 5326 const HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml'; 5327 /* Document namespace */ 5328 let NAMESPACE = HTML_NAMESPACE; 5329 let IS_EMPTY_INPUT = false; 5330 /* Allowed XHTML+XML namespaces */ 5331 let ALLOWED_NAMESPACES = null; 5332 const DEFAULT_ALLOWED_NAMESPACES = addToSet({}, [MATHML_NAMESPACE, SVG_NAMESPACE, HTML_NAMESPACE], stringToString); 5333 let MATHML_TEXT_INTEGRATION_POINTS = addToSet({}, ['mi', 'mo', 'mn', 'ms', 'mtext']); 5334 let HTML_INTEGRATION_POINTS = addToSet({}, ['annotation-xml']); 5335 // Certain elements are allowed in both SVG and HTML 5336 // namespace. We need to specify them explicitly 5337 // so that they don't get erroneously deleted from 5338 // HTML namespace. 5339 const COMMON_SVG_AND_HTML_ELEMENTS = addToSet({}, ['title', 'style', 'font', 'a', 'script']); 5340 /* Parsing of strict XHTML documents */ 5341 let PARSER_MEDIA_TYPE = null; 5342 const SUPPORTED_PARSER_MEDIA_TYPES = ['application/xhtml+xml', 'text/html']; 5343 const DEFAULT_PARSER_MEDIA_TYPE = 'text/html'; 5344 let transformCaseFunc = null; 5345 /* Keep a reference to config to pass to hooks */ 5346 let CONFIG = null; 5347 /* Ideally, do not touch anything below this line */ 5348 /* ______________________________________________ */ 5349 const formElement = document.createElement('form'); 5350 const isRegexOrFunction = function isRegexOrFunction(testValue) { 5351 return testValue instanceof RegExp || testValue instanceof Function; 5352 }; 5353 /** 5354 * _parseConfig 5355 * 5356 * @param cfg optional config literal 5357 */ 5358 // eslint-disable-next-line complexity 5359 const _parseConfig = function _parseConfig() { 5360 let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 5361 if (CONFIG && CONFIG === cfg) { 5362 return; 5363 } 5364 /* Shield configuration object from tampering */ 5365 if (!cfg || typeof cfg !== 'object') { 5366 cfg = {}; 5367 } 5368 /* Shield configuration object from prototype pollution */ 5369 cfg = clone(cfg); 5370 PARSER_MEDIA_TYPE = 5371 // eslint-disable-next-line unicorn/prefer-includes 5372 SUPPORTED_PARSER_MEDIA_TYPES.indexOf(cfg.PARSER_MEDIA_TYPE) === -1 ? DEFAULT_PARSER_MEDIA_TYPE : cfg.PARSER_MEDIA_TYPE; 5373 // HTML tags and attributes are not case-sensitive, converting to lowercase. Keeping XHTML as is. 5374 transformCaseFunc = PARSER_MEDIA_TYPE === 'application/xhtml+xml' ? stringToString : stringToLowerCase; 5375 /* Set configuration parameters */ 5376 ALLOWED_TAGS = objectHasOwnProperty(cfg, 'ALLOWED_TAGS') ? addToSet({}, cfg.ALLOWED_TAGS, transformCaseFunc) : DEFAULT_ALLOWED_TAGS; 5377 ALLOWED_ATTR = objectHasOwnProperty(cfg, 'ALLOWED_ATTR') ? addToSet({}, cfg.ALLOWED_ATTR, transformCaseFunc) : DEFAULT_ALLOWED_ATTR; 5378 ALLOWED_NAMESPACES = objectHasOwnProperty(cfg, 'ALLOWED_NAMESPACES') ? addToSet({}, cfg.ALLOWED_NAMESPACES, stringToString) : DEFAULT_ALLOWED_NAMESPACES; 5379 URI_SAFE_ATTRIBUTES = objectHasOwnProperty(cfg, 'ADD_URI_SAFE_ATTR') ? addToSet(clone(DEFAULT_URI_SAFE_ATTRIBUTES), cfg.ADD_URI_SAFE_ATTR, transformCaseFunc) : DEFAULT_URI_SAFE_ATTRIBUTES; 5380 DATA_URI_TAGS = objectHasOwnProperty(cfg, 'ADD_DATA_URI_TAGS') ? addToSet(clone(DEFAULT_DATA_URI_TAGS), cfg.ADD_DATA_URI_TAGS, transformCaseFunc) : DEFAULT_DATA_URI_TAGS; 5381 FORBID_CONTENTS = objectHasOwnProperty(cfg, 'FORBID_CONTENTS') ? addToSet({}, cfg.FORBID_CONTENTS, transformCaseFunc) : DEFAULT_FORBID_CONTENTS; 5382 FORBID_TAGS = objectHasOwnProperty(cfg, 'FORBID_TAGS') ? addToSet({}, cfg.FORBID_TAGS, transformCaseFunc) : clone({}); 5383 FORBID_ATTR = objectHasOwnProperty(cfg, 'FORBID_ATTR') ? addToSet({}, cfg.FORBID_ATTR, transformCaseFunc) : clone({}); 5384 USE_PROFILES = objectHasOwnProperty(cfg, 'USE_PROFILES') ? cfg.USE_PROFILES : false; 5385 ALLOW_ARIA_ATTR = cfg.ALLOW_ARIA_ATTR !== false; // Default true 5386 ALLOW_DATA_ATTR = cfg.ALLOW_DATA_ATTR !== false; // Default true 5387 ALLOW_UNKNOWN_PROTOCOLS = cfg.ALLOW_UNKNOWN_PROTOCOLS || false; // Default false 5388 ALLOW_SELF_CLOSE_IN_ATTR = cfg.ALLOW_SELF_CLOSE_IN_ATTR !== false; // Default true 5389 SAFE_FOR_TEMPLATES = cfg.SAFE_FOR_TEMPLATES || false; // Default false 5390 SAFE_FOR_XML = cfg.SAFE_FOR_XML !== false; // Default true 5391 WHOLE_DOCUMENT = cfg.WHOLE_DOCUMENT || false; // Default false 5392 RETURN_DOM = cfg.RETURN_DOM || false; // Default false 5393 RETURN_DOM_FRAGMENT = cfg.RETURN_DOM_FRAGMENT || false; // Default false 5394 RETURN_TRUSTED_TYPE = cfg.RETURN_TRUSTED_TYPE || false; // Default false 5395 FORCE_BODY = cfg.FORCE_BODY || false; // Default false 5396 SANITIZE_DOM = cfg.SANITIZE_DOM !== false; // Default true 5397 SANITIZE_NAMED_PROPS = cfg.SANITIZE_NAMED_PROPS || false; // Default false 5398 KEEP_CONTENT = cfg.KEEP_CONTENT !== false; // Default true 5399 IN_PLACE = cfg.IN_PLACE || false; // Default false 5400 IS_ALLOWED_URI$1 = cfg.ALLOWED_URI_REGEXP || IS_ALLOWED_URI; 5401 NAMESPACE = cfg.NAMESPACE || HTML_NAMESPACE; 5402 MATHML_TEXT_INTEGRATION_POINTS = cfg.MATHML_TEXT_INTEGRATION_POINTS || MATHML_TEXT_INTEGRATION_POINTS; 5403 HTML_INTEGRATION_POINTS = cfg.HTML_INTEGRATION_POINTS || HTML_INTEGRATION_POINTS; 5404 CUSTOM_ELEMENT_HANDLING = cfg.CUSTOM_ELEMENT_HANDLING || {}; 5405 if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck)) { 5406 CUSTOM_ELEMENT_HANDLING.tagNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.tagNameCheck; 5407 } 5408 if (cfg.CUSTOM_ELEMENT_HANDLING && isRegexOrFunction(cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)) { 5409 CUSTOM_ELEMENT_HANDLING.attributeNameCheck = cfg.CUSTOM_ELEMENT_HANDLING.attributeNameCheck; 5410 } 5411 if (cfg.CUSTOM_ELEMENT_HANDLING && typeof cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements === 'boolean') { 5412 CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements = cfg.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements; 5413 } 5414 if (SAFE_FOR_TEMPLATES) { 5415 ALLOW_DATA_ATTR = false; 5416 } 5417 if (RETURN_DOM_FRAGMENT) { 5418 RETURN_DOM = true; 5419 } 5420 /* Parse profile info */ 5421 if (USE_PROFILES) { 5422 ALLOWED_TAGS = addToSet({}, text); 5423 ALLOWED_ATTR =
vendor: 1,583 bytes, lines 5423-5470
5423[]; 5424 if (USE_PROFILES.html === true) { 5425 addToSet(ALLOWED_TAGS, html$1); 5426 addToSet(ALLOWED_ATTR, html); 5427 } 5428 if (USE_PROFILES.svg === true) { 5429 addToSet(ALLOWED_TAGS, svg$1); 5430 addToSet(ALLOWED_ATTR, svg); 5431 addToSet(ALLOWED_ATTR, xml); 5432 } 5433 if (USE_PROFILES.svgFilters === true) { 5434 addToSet(ALLOWED_TAGS, svgFilters); 5435 addToSet(ALLOWED_ATTR, svg); 5436 addToSet(ALLOWED_ATTR, xml); 5437 } 5438 if (USE_PROFILES.mathMl === true) { 5439 addToSet(ALLOWED_TAGS, mathMl$1); 5440 addToSet(ALLOWED_ATTR, mathMl); 5441 addToSet(ALLOWED_ATTR, xml); 5442 } 5443 } 5444 /* Merge configuration parameters */ 5445 if (cfg.ADD_TAGS) { 5446 if (typeof cfg.ADD_TAGS === 'function') { 5447 EXTRA_ELEMENT_HANDLING.tagCheck = cfg.ADD_TAGS; 5448 } else { 5449 if (ALLOWED_TAGS === DEFAULT_ALLOWED_TAGS) { 5450 ALLOWED_TAGS = clone(ALLOWED_TAGS); 5451 } 5452 addToSet(ALLOWED_TAGS, cfg.ADD_TAGS, transformCaseFunc); 5453 } 5454 } 5455 if (cfg.ADD_ATTR) { 5456 if (typeof cfg.ADD_ATTR === 'function') { 5457 EXTRA_ELEMENT_HANDLING.attributeCheck = cfg.ADD_ATTR; 5458 } else { 5459 if (ALLOWED_ATTR === DEFAULT_ALLOWED_ATTR) { 5460 ALLOWED_ATTR = clone(ALLOWED_ATTR); 5461 } 5462 addToSet(ALLOWED_ATTR, cfg.ADD_ATTR, transformCaseFunc); 5463 } 5464 } 5465 if (cfg.ADD_URI_SAFE_ATTR) { 5466 addToSet(URI_SAFE_ATTRIBUTES, cfg.ADD_URI_SAFE_ATTR, transformCaseFunc); 5467 } 5468 if (cfg.FORBID_CONTENTS) { 5469 if (FORBID_CONTENTS === DEFAULT_FORBID_CONTENTS) { 5470 FORBID_CONTENTS = clone
vendor: 8,107 bytes, lines 5470-5679
5470(FORBID_CONTENTS); 5471 } 5472 addToSet(FORBID_CONTENTS, cfg.FORBID_CONTENTS, transformCaseFunc); 5473 } 5474 /* Add #text in case KEEP_CONTENT is set to true */ 5475 if (KEEP_CONTENT) { 5476 ALLOWED_TAGS['#text'] = true; 5477 } 5478 /* Add html, head and body to ALLOWED_TAGS in case WHOLE_DOCUMENT is true */ 5479 if (WHOLE_DOCUMENT) { 5480 addToSet(ALLOWED_TAGS, ['html', 'head', 'body']); 5481 } 5482 /* Add tbody to ALLOWED_TAGS in case tables are permitted, see #286, #365 */ 5483 if (ALLOWED_TAGS.table) { 5484 addToSet(ALLOWED_TAGS, ['tbody']); 5485 delete FORBID_TAGS.tbody; 5486 } 5487 if (cfg.TRUSTED_TYPES_POLICY) { 5488 if (typeof cfg.TRUSTED_TYPES_POLICY.createHTML !== 'function') { 5489 throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.'); 5490 } 5491 if (typeof cfg.TRUSTED_TYPES_POLICY.createScriptURL !== 'function') { 5492 throw typeErrorCreate('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.'); 5493 } 5494 // Overwrite existing TrustedTypes policy. 5495 trustedTypesPolicy = cfg.TRUSTED_TYPES_POLICY; 5496 // Sign local variables required by `sanitize`. 5497 emptyHTML = trustedTypesPolicy.createHTML(''); 5498 } else { 5499 // Uninitialized policy, attempt to initialize the internal dompurify policy. 5500 if (trustedTypesPolicy === undefined) { 5501 trustedTypesPolicy = _createTrustedTypesPolicy(trustedTypes, currentScript); 5502 } 5503 // If creating the internal policy succeeded sign internal variables. 5504 if (trustedTypesPolicy !== null && typeof emptyHTML === 'string') { 5505 emptyHTML = trustedTypesPolicy.createHTML(''); 5506 } 5507 } 5508 // Prevent further manipulation of configuration. 5509 // Not available in IE8, Safari 5, etc. 5510 if (freeze) { 5511 freeze(cfg); 5512 } 5513 CONFIG = cfg; 5514 }; 5515 /* Keep track of all possible SVG and MathML tags 5516 * so that we can perform the namespace checks 5517 * correctly. */ 5518 const ALL_SVG_TAGS = addToSet({}, [...svg$1, ...svgFilters, ...svgDisallowed]); 5519 const ALL_MATHML_TAGS = addToSet({}, [...mathMl$1, ...mathMlDisallowed]); 5520 /** 5521 * @param element a DOM element whose namespace is being checked 5522 * @returns Return false if the element has a 5523 * namespace that a spec-compliant parser would never 5524 * return. Return true otherwise. 5525 */ 5526 const _checkValidNamespace = function _checkValidNamespace(element) { 5527 let parent = getParentNode(element); 5528 // In JSDOM, if we're inside shadow DOM, then parentNode 5529 // can be null. We just simulate parent in this case. 5530 if (!parent || !parent.tagName) { 5531 parent = { 5532 namespaceURI: NAMESPACE, 5533 tagName: 'template' 5534 }; 5535 } 5536 const tagName = stringToLowerCase(element.tagName); 5537 const parentTagName = stringToLowerCase(parent.tagName); 5538 if (!ALLOWED_NAMESPACES[element.namespaceURI]) { 5539 return false; 5540 } 5541 if (element.namespaceURI === SVG_NAMESPACE) { 5542 // The only way to switch from HTML namespace to SVG 5543 // is via <svg>. If it happens via any other tag, then 5544 // it should be killed. 5545 if (parent.namespaceURI === HTML_NAMESPACE) { 5546 return tagName === 'svg'; 5547 } 5548 // The only way to switch from MathML to SVG is via` 5549 // svg if parent is either <annotation-xml> or MathML 5550 // text integration points. 5551 if (parent.namespaceURI === MATHML_NAMESPACE) { 5552 return tagName === 'svg' && (parentTagName === 'annotation-xml' || MATHML_TEXT_INTEGRATION_POINTS[parentTagName]); 5553 } 5554 // We only allow elements that are defined in SVG 5555 // spec. All others are disallowed in SVG namespace. 5556 return Boolean(ALL_SVG_TAGS[tagName]); 5557 } 5558 if (element.namespaceURI === MATHML_NAMESPACE) { 5559 // The only way to switch from HTML namespace to MathML 5560 // is via <math>. If it happens via any other tag, then 5561 // it should be killed. 5562 if (parent.namespaceURI === HTML_NAMESPACE) { 5563 return tagName === 'math'; 5564 } 5565 // The only way to switch from SVG to MathML is via 5566 // <math> and HTML integration points 5567 if (parent.namespaceURI === SVG_NAMESPACE) { 5568 return tagName === 'math' && HTML_INTEGRATION_POINTS[parentTagName]; 5569 } 5570 // We only allow elements that are defined in MathML 5571 // spec. All others are disallowed in MathML namespace. 5572 return Boolean(ALL_MATHML_TAGS[tagName]); 5573 } 5574 if (element.namespaceURI === HTML_NAMESPACE) { 5575 // The only way to switch from SVG to HTML is via 5576 // HTML integration points, and from MathML to HTML 5577 // is via MathML text integration points 5578 if (parent.namespaceURI === SVG_NAMESPACE && !HTML_INTEGRATION_POINTS[parentTagName]) { 5579 return false; 5580 } 5581 if (parent.namespaceURI === MATHML_NAMESPACE && !MATHML_TEXT_INTEGRATION_POINTS[parentTagName]) { 5582 return false; 5583 } 5584 // We disallow tags that are specific for MathML 5585 // or SVG and should never appear in HTML namespace 5586 return !ALL_MATHML_TAGS[tagName] && (COMMON_SVG_AND_HTML_ELEMENTS[tagName] || !ALL_SVG_TAGS[tagName]); 5587 } 5588 // For XHTML and XML documents that support custom namespaces 5589 if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && ALLOWED_NAMESPACES[element.namespaceURI]) { 5590 return true; 5591 } 5592 // The code should never reach this place (this means 5593 // that the element somehow got namespace that is not 5594 // HTML, SVG, MathML or allowed via ALLOWED_NAMESPACES). 5595 // Return false just in case. 5596 return false; 5597 }; 5598 /** 5599 * _forceRemove 5600 * 5601 * @param node a DOM node 5602 */ 5603 const _forceRemove = function _forceRemove(node) { 5604 arrayPush(DOMPurify.removed, { 5605 element: node 5606 }); 5607 try { 5608 // eslint-disable-next-line unicorn/prefer-dom-node-remove 5609 getParentNode(node).removeChild(node); 5610 } catch (_) { 5611 remove(node); 5612 } 5613 }; 5614 /** 5615 * _removeAttribute 5616 * 5617 * @param name an Attribute name 5618 * @param element a DOM node 5619 */ 5620 const _removeAttribute = function _removeAttribute(name, element) { 5621 try { 5622 arrayPush(DOMPurify.removed, { 5623 attribute: element.getAttributeNode(name), 5624 from: element 5625 }); 5626 } catch (_) { 5627 arrayPush(DOMPurify.removed, { 5628 attribute: null, 5629 from: element 5630 }); 5631 } 5632 element.removeAttribute(name); 5633 // We void attribute values for unremovable "is" attributes 5634 if (name === 'is') { 5635 if (RETURN_DOM || RETURN_DOM_FRAGMENT) { 5636 try { 5637 _forceRemove(element); 5638 } catch (_) {} 5639 } else { 5640 try { 5641 element.setAttribute(name, ''); 5642 } catch (_) {} 5643 } 5644 } 5645 }; 5646 /** 5647 * _initDocument 5648 * 5649 * @param dirty - a string of dirty markup 5650 * @return a DOM, filled with the dirty markup 5651 */ 5652 const _initDocument = function _initDocument(dirty) { 5653 /* Create a HTML document */ 5654 let doc = null; 5655 let leadingWhitespace = null; 5656 if (FORCE_BODY) { 5657 dirty = '<remove></remove>' + dirty; 5658 } else { 5659 /* If FORCE_BODY isn't used, leading whitespace needs to be preserved manually */ 5660 const matches = stringMatch(dirty, /^[\r\n\t ]+/); 5661 leadingWhitespace = matches && matches[0]; 5662 } 5663 if (PARSER_MEDIA_TYPE === 'application/xhtml+xml' && NAMESPACE === HTML_NAMESPACE) { 5664 // Root of XHTML doc must contain xmlns declaration (see https://www.w3.org/TR/xhtml1/normative.html#strict) 5665 dirty = '<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>' + dirty + '</body></html>'; 5666 } 5667 const dirtyPayload = trustedTypesPolicy ? trustedTypesPolicy.createHTML(dirty) : dirty; 5668 /* 5669 * Use the DOMParser API by default, fallback later if needs be 5670 * DOMParser not work for svg when has multiple root element. 5671 */ 5672 if (NAMESPACE === HTML_NAMESPACE) { 5673 try { 5674 doc = new DOMParser().parseFromString(dirtyPayload, PARSER_MEDIA_TYPE); 5675 } catch (_) {} 5676 } 5677 /* Use createHTMLDocument in case DOMParser is not available */ 5678 if (!doc || !doc.documentElement) { 5679 doc = implementation.createDocument(NAMESPACE, 'template', null);
vendor: 4,359 bytes, lines 5680-5775
5680 try { 5681 doc.documentElement.innerHTML = IS_EMPTY_INPUT ? emptyHTML : dirtyPayload; 5682 } catch (_) { 5683 // Syntax error if dirtyPayload is invalid xml 5684 } 5685 } 5686 const body = doc.body || doc.documentElement; 5687 if (dirty && leadingWhitespace) { 5688 body.insertBefore(document.createTextNode(leadingWhitespace), body.childNodes[0] || null); 5689 } 5690 /* Work on whole document or just its body */ 5691 if (NAMESPACE === HTML_NAMESPACE) { 5692 return getElementsByTagName.call(doc, WHOLE_DOCUMENT ? 'html' : 'body')[0]; 5693 } 5694 return WHOLE_DOCUMENT ? doc.documentElement : body; 5695 }; 5696 /** 5697 * Creates a NodeIterator object that you can use to traverse filtered lists of nodes or elements in a document. 5698 * 5699 * @param root The root element or node to start traversing on. 5700 * @return The created NodeIterator 5701 */ 5702 const _createNodeIterator = function _createNodeIterator(root) { 5703 return createNodeIterator.call(root.ownerDocument || root, root, 5704 // eslint-disable-next-line no-bitwise 5705 NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_TEXT | NodeFilter.SHOW_PROCESSING_INSTRUCTION | NodeFilter.SHOW_CDATA_SECTION, null); 5706 }; 5707 /** 5708 * _isClobbered 5709 * 5710 * @param element element to check for clobbering attacks 5711 * @return true if clobbered, false if safe 5712 */ 5713 const _isClobbered = function _isClobbered(element) { 5714 return element instanceof HTMLFormElement && (typeof element.nodeName !== 'string' || typeof element.textContent !== 'string' || typeof element.removeChild !== 'function' || !(element.attributes instanceof NamedNodeMap) || typeof element.removeAttribute !== 'function' || typeof element.setAttribute !== 'function' || typeof element.namespaceURI !== 'string' || typeof element.insertBefore !== 'function' || typeof element.hasChildNodes !== 'function'); 5715 }; 5716 /** 5717 * Checks whether the given object is a DOM node. 5718 * 5719 * @param value object to check whether it's a DOM node 5720 * @return true is object is a DOM node 5721 */ 5722 const _isNode = function _isNode(value) { 5723 return typeof Node === 'function' && value instanceof Node; 5724 }; 5725 function _executeHooks(hooks, currentNode, data) { 5726 arrayForEach(hooks, hook => { 5727 hook.call(DOMPurify, currentNode, data, CONFIG); 5728 }); 5729 } 5730 /** 5731 * _sanitizeElements 5732 * 5733 * @protect nodeName 5734 * @protect textContent 5735 * @protect removeChild 5736 * @param currentNode to check for permission to exist 5737 * @return true if node was killed, false if left alive 5738 */ 5739 const _sanitizeElements = function _sanitizeElements(currentNode) { 5740 let content = null; 5741 /* Execute a hook if present */ 5742 _executeHooks(hooks.beforeSanitizeElements, currentNode, null); 5743 /* Check if element is clobbered or can clobber */ 5744 if (_isClobbered(currentNode)) { 5745 _forceRemove(currentNode); 5746 return true; 5747 } 5748 /* Now let's check the element's type and name */ 5749 const tagName = transformCaseFunc(currentNode.nodeName); 5750 /* Execute a hook if present */ 5751 _executeHooks(hooks.uponSanitizeElement, currentNode, { 5752 tagName, 5753 allowedTags: ALLOWED_TAGS 5754 }); 5755 /* Detect mXSS attempts abusing namespace confusion */ 5756 if (SAFE_FOR_XML && currentNode.hasChildNodes() && !_isNode(currentNode.firstElementChild) && regExpTest(/<[/\w!]/g, currentNode.innerHTML) && regExpTest(/<[/\w!]/g, currentNode.textContent)) { 5757 _forceRemove(currentNode); 5758 return true; 5759 } 5760 /* Remove any occurrence of processing instructions */ 5761 if (currentNode.nodeType === NODE_TYPE.progressingInstruction) { 5762 _forceRemove(currentNode); 5763 return true; 5764 } 5765 /* Remove any kind of possibly harmful comments */ 5766 if (SAFE_FOR_XML && currentNode.nodeType === NODE_TYPE.comment && regExpTest(/<[/\w]/g, currentNode.data)) { 5767 _forceRemove(currentNode); 5768 return true; 5769 } 5770 /* Remove element if anything forbids its presence */ 5771 if (!(EXTRA_ELEMENT_HANDLING.tagCheck instanceof Function && EXTRA_ELEMENT_HANDLING.tagCheck(tagName)) && (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName])) { 5772 /* Check if we have a custom element to handle */ 5773 if (!FORBID_TAGS[tagName] && _isBasicCustomElement(tagName)) { 5774 if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof RegExp && regExpTest(CUSTOM_ELEMENT_HANDLING.tagNameCheck, tagName)) { 5775 return false;
vendor: 9,812 bytes, lines 5776-5979
5776 } 5777 if (CUSTOM_ELEMENT_HANDLING.tagNameCheck instanceof Function && CUSTOM_ELEMENT_HANDLING.tagNameCheck(tagName)) { 5778 return false; 5779 } 5780 } 5781 /* Keep content except for bad-listed elements */ 5782 if (KEEP_CONTENT && !FORBID_CONTENTS[tagName]) { 5783 const parentNode = getParentNode(currentNode) || currentNode.parentNode; 5784 const childNodes = getChildNodes(currentNode) || currentNode.childNodes; 5785 if (childNodes && parentNode) { 5786 const childCount = childNodes.length; 5787 for (let i = childCount - 1; i >= 0; --i) { 5788 const childClone = cloneNode(childNodes[i], true); 5789 childClone.__removalCount = (currentNode.__removalCount || 0) + 1; 5790 parentNode.insertBefore(childClone, getNextSibling(currentNode)); 5791 } 5792 } 5793 } 5794 _forceRemove(currentNode); 5795 return true; 5796 } 5797 /* Check whether element has a valid namespace */ 5798 if (currentNode instanceof Element && !_checkValidNamespace(currentNode)) { 5799 _forceRemove(currentNode); 5800 return true; 5801 } 5802 /* Make sure that older browsers don't get fallback-tag mXSS */ 5803 if ((tagName === 'noscript' || tagName === 'noembed' || tagName === 'noframes') && regExpTest(/<\/no(script|embed|frames)/i, currentNode.innerHTML)) { 5804 _forceRemove(currentNode); 5805 return true; 5806 } 5807 /* Sanitize element content to be template-safe */ 5808 if (SAFE_FOR_TEMPLATES && currentNode.nodeType === NODE_TYPE.text) { 5809 /* Get the element's text content */ 5810 content = currentNode.textContent; 5811 arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => { 5812 content = stringReplace(content, expr, ' '); 5813 }); 5814 if (currentNode.textContent !== content) { 5815 arrayPush(DOMPurify.removed, { 5816 element: currentNode.cloneNode() 5817 }); 5818 currentNode.textContent = content; 5819 } 5820 } 5821 /* Execute a hook if present */ 5822 _executeHooks(hooks.afterSanitizeElements, currentNode, null); 5823 return false; 5824 }; 5825 /** 5826 * _isValidAttribute 5827 * 5828 * @param lcTag Lowercase tag name of containing element. 5829 * @param lcName Lowercase attribute name. 5830 * @param value Attribute value. 5831 * @return Returns true if `value` is valid, otherwise false. 5832 */ 5833 // eslint-disable-next-line complexity 5834 const _isValidAttribute = function _isValidAttribute(lcTag, lcName, value) { 5835 /* Make sure attribute cannot clobber */ 5836 if (SANITIZE_DOM && (lcName === 'id' || lcName === 'name') && (value in document || value in formElement)) { 5837 return false; 5838 } 5839 /* Allow valid data-* attributes: At least one character after "-" 5840 (https://html.spec.whatwg.org/multipage/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes) 5841 XML-compatible (https://html.spec.whatwg.org/multipage/infrastructure.html#xml-compatible and http://www.w3.org/TR/xml/#d0e804) 5842 We don't need to check the value; it's always URI safe. */ 5843 if (ALLOW_DATA_ATTR && !FORBID_ATTR[lcName] && regExpTest(DATA_ATTR, lcName)) ; else if (ALLOW_ARIA_ATTR && regExpTest(ARIA_ATTR, lcName)) ; else if (EXTRA_ELEMENT_HANDLING.attributeCheck instanceof Function && EXTRA_ELEMENT_HANDLING.attributeCheck(lcName, lcTag)) ; else if (!ALLOWED_ATTR[lcName] || FORBID_ATTR[lcName]) { 5844 if ( 5845 // First condition does a very basic check if a) it's basically a valid custom element tagname AND 5846 // b) if the tagName passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck 5847 // and c) if the attribute name passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.attributeNameCheck 5848 _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)) || 5849 // Alternative, second condition checks if it's an `is`-attribute, AND 5850 // the value passes whatever the user has configured for CUSTOM_ELEMENT_HANDLING.tagNameCheck 5851 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 { 5852 return false; 5853 } 5854 /* Check value is safe. First, is attr inert? If so, is safe */ 5855 } else if (URI_SAFE_ATTRIBUTES[lcName]) ; else if (regExpTest(IS_ALLOWED_URI$1, stringReplace(value, ATTR_WHITESPACE, ''))) ; 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, stringReplace(value, ATTR_WHITESPACE, ''))) ; else if (value) { 5856 return false; 5857 } else ; 5858 return true; 5859 }; 5860 /** 5861 * _isBasicCustomElement 5862 * checks if at least one dash is included in tagName, and it's not the first char 5863 * for more sophisticated checking see https://github.com/sindresorhus/validate-element-name 5864 * 5865 * @param tagName name of the tag of the node to sanitize 5866 * @returns Returns true if the tag name meets the basic criteria for a custom element, otherwise false. 5867 */ 5868 const _isBasicCustomElement = function _isBasicCustomElement(tagName) { 5869 return tagName !== 'annotation-xml' && stringMatch(tagName, CUSTOM_ELEMENT); 5870 }; 5871 /** 5872 * _sanitizeAttributes 5873 * 5874 * @protect attributes 5875 * @protect nodeName 5876 * @protect removeAttribute 5877 * @protect setAttribute 5878 * 5879 * @param currentNode to sanitize 5880 */ 5881 const _sanitizeAttributes = function _sanitizeAttributes(currentNode) { 5882 /* Execute a hook if present */ 5883 _executeHooks(hooks.beforeSanitizeAttributes, currentNode, null); 5884 const { 5885 attributes 5886 } = currentNode; 5887 /* Check if we have attributes; if not we might have a text node */ 5888 if (!attributes || _isClobbered(currentNode)) { 5889 return; 5890 } 5891 const hookEvent = { 5892 attrName: '', 5893 attrValue: '', 5894 keepAttr: true, 5895 allowedAttributes: ALLOWED_ATTR, 5896 forceKeepAttr: undefined 5897 }; 5898 let l = attributes.length; 5899 /* Go backwards over all attributes; safely remove bad ones */ 5900 while (l--) { 5901 const attr = attributes[l]; 5902 const { 5903 name, 5904 namespaceURI, 5905 value: attrValue 5906 } = attr; 5907 const lcName = transformCaseFunc(name); 5908 const initValue = attrValue; 5909 let value = name === 'value' ? initValue : stringTrim(initValue); 5910 /* Execute a hook if present */ 5911 hookEvent.attrName = lcName; 5912 hookEvent.attrValue = value; 5913 hookEvent.keepAttr = true; 5914 hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set 5915 _executeHooks(hooks.uponSanitizeAttribute, currentNode, hookEvent); 5916 value = hookEvent.attrValue; 5917 /* Full DOM Clobbering protection via namespace isolation, 5918 * Prefix id and name attributes with `user-content-` 5919 */ 5920 if (SANITIZE_NAMED_PROPS && (lcName === 'id' || lcName === 'name')) { 5921 // Remove the attribute with this value 5922 _removeAttribute(name, currentNode); 5923 // Prefix the value and later re-create the attribute with the sanitized value 5924 value = SANITIZE_NAMED_PROPS_PREFIX + value; 5925 } 5926 /* Work around a security issue with comments inside attributes */ 5927 if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|title|textarea)/i, value)) { 5928 _removeAttribute(name, currentNode); 5929 continue; 5930 } 5931 /* Make sure we cannot easily use animated hrefs, even if animations are allowed */ 5932 if (lcName === 'attributename' && stringMatch(value, 'href')) { 5933 _removeAttribute(name, currentNode); 5934 continue; 5935 } 5936 /* Did the hooks approve of the attribute? */ 5937 if (hookEvent.forceKeepAttr) { 5938 continue; 5939 } 5940 /* Did the hooks approve of the attribute? */ 5941 if (!hookEvent.keepAttr) { 5942 _removeAttribute(name, currentNode); 5943 continue; 5944 } 5945 /* Work around a security issue in jQuery 3.0 */ 5946 if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(/\/>/i, value)) { 5947 _removeAttribute(name, currentNode); 5948 continue; 5949 } 5950 /* Sanitize attribute content to be template-safe */ 5951 if (SAFE_FOR_TEMPLATES) { 5952 arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => { 5953 value = stringReplace(value, expr, ' '); 5954 }); 5955 } 5956 /* Is `value` valid for this attribute? */ 5957 const lcTag = transformCaseFunc(currentNode.nodeName); 5958 if (!_isValidAttribute(lcTag, lcName, value)) { 5959 _removeAttribute(name, currentNode); 5960 continue; 5961 } 5962 /* Handle attributes that require Trusted Types */ 5963 if (trustedTypesPolicy && typeof trustedTypes === 'object' && typeof trustedTypes.getAttributeType === 'function') { 5964 if (namespaceURI) ; else { 5965 switch (trustedTypes.getAttributeType(lcTag, lcName)) { 5966 case 'TrustedHTML': 5967 { 5968 value = trustedTypesPolicy.createHTML(value); 5969 break; 5970 } 5971 case 'TrustedScriptURL': 5972 { 5973 value = trustedTypesPolicy.createScriptURL(value); 5974 break; 5975 } 5976 } 5977 } 5978 } 5979 /* Handle invalid data-* attribute set by try-catching it */
vendor: 8,193 bytes, lines 5980-6198
5980 if (value !== initValue) { 5981 try { 5982 if (namespaceURI) { 5983 currentNode.setAttributeNS(namespaceURI, name, value); 5984 } else { 5985 /* Fallback to setAttribute() for browser-unrecognized namespaces e.g. "x-schema". */ 5986 currentNode.setAttribute(name, value); 5987 } 5988 if (_isClobbered(currentNode)) { 5989 _forceRemove(currentNode); 5990 } else { 5991 arrayPop(DOMPurify.removed); 5992 } 5993 } catch (_) { 5994 _removeAttribute(name, currentNode); 5995 } 5996 } 5997 } 5998 /* Execute a hook if present */ 5999 _executeHooks(hooks.afterSanitizeAttributes, currentNode, null); 6000 }; 6001 /** 6002 * _sanitizeShadowDOM 6003 * 6004 * @param fragment to iterate over recursively 6005 */ 6006 const _sanitizeShadowDOM = function _sanitizeShadowDOM(fragment) { 6007 let shadowNode = null; 6008 const shadowIterator = _createNodeIterator(fragment); 6009 /* Execute a hook if present */ 6010 _executeHooks(hooks.beforeSanitizeShadowDOM, fragment, null); 6011 while (shadowNode = shadowIterator.nextNode()) { 6012 /* Execute a hook if present */ 6013 _executeHooks(hooks.uponSanitizeShadowNode, shadowNode, null); 6014 /* Sanitize tags and elements */ 6015 _sanitizeElements(shadowNode); 6016 /* Check attributes next */ 6017 _sanitizeAttributes(shadowNode); 6018 /* Deep shadow DOM detected */ 6019 if (shadowNode.content instanceof DocumentFragment) { 6020 _sanitizeShadowDOM(shadowNode.content); 6021 } 6022 } 6023 /* Execute a hook if present */ 6024 _executeHooks(hooks.afterSanitizeShadowDOM, fragment, null); 6025 }; 6026 // eslint-disable-next-line complexity 6027 DOMPurify.sanitize = function (dirty) { 6028 let cfg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 6029 let body = null; 6030 let importedNode = null; 6031 let currentNode = null; 6032 let returnNode = null; 6033 /* Make sure we have a string to sanitize. 6034 DO NOT return early, as this will return the wrong type if 6035 the user has requested a DOM object rather than a string */ 6036 IS_EMPTY_INPUT = !dirty; 6037 if (IS_EMPTY_INPUT) { 6038 dirty = '<!-->'; 6039 } 6040 /* Stringify, in case dirty is an object */ 6041 if (typeof dirty !== 'string' && !_isNode(dirty)) { 6042 if (typeof dirty.toString === 'function') { 6043 dirty = dirty.toString(); 6044 if (typeof dirty !== 'string') { 6045 throw typeErrorCreate('dirty is not a string, aborting'); 6046 } 6047 } else { 6048 throw typeErrorCreate('toString is not a function'); 6049 } 6050 } 6051 /* Return dirty HTML if DOMPurify cannot run */ 6052 if (!DOMPurify.isSupported) { 6053 return dirty; 6054 } 6055 /* Assign config vars */ 6056 if (!SET_CONFIG) { 6057 _parseConfig(cfg); 6058 } 6059 /* Clean up removed elements */ 6060 DOMPurify.removed = []; 6061 /* Check if dirty is correctly typed for IN_PLACE */ 6062 if (typeof dirty === 'string') { 6063 IN_PLACE = false; 6064 } 6065 if (IN_PLACE) { 6066 /* Do some early pre-sanitization to avoid unsafe root nodes */ 6067 if (dirty.nodeName) { 6068 const tagName = transformCaseFunc(dirty.nodeName); 6069 if (!ALLOWED_TAGS[tagName] || FORBID_TAGS[tagName]) { 6070 throw typeErrorCreate('root node is forbidden and cannot be sanitized in-place'); 6071 } 6072 } 6073 } else if (dirty instanceof Node) { 6074 /* If dirty is a DOM element, append to an empty document to avoid 6075 elements being stripped by the parser */ 6076 body = _initDocument('<!---->'); 6077 importedNode = body.ownerDocument.importNode(dirty, true); 6078 if (importedNode.nodeType === NODE_TYPE.element && importedNode.nodeName === 'BODY') { 6079 /* Node is already a body, use as is */ 6080 body = importedNode; 6081 } else if (importedNode.nodeName === 'HTML') { 6082 body = importedNode; 6083 } else { 6084 // eslint-disable-next-line unicorn/prefer-dom-node-append 6085 body.appendChild(importedNode); 6086 } 6087 } else { 6088 /* Exit directly if we have nothing to do */ 6089 if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT && 6090 // eslint-disable-next-line unicorn/prefer-includes 6091 dirty.indexOf('<') === -1) { 6092 return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(dirty) : dirty; 6093 } 6094 /* Initialize the document to work on */ 6095 body = _initDocument(dirty); 6096 /* Check we have a DOM node from the data */ 6097 if (!body) { 6098 return RETURN_DOM ? null : RETURN_TRUSTED_TYPE ? emptyHTML : ''; 6099 } 6100 } 6101 /* Remove first element node (ours) if FORCE_BODY is set */ 6102 if (body && FORCE_BODY) { 6103 _forceRemove(body.firstChild); 6104 } 6105 /* Get node iterator */ 6106 const nodeIterator = _createNodeIterator(IN_PLACE ? dirty : body); 6107 /* Now start iterating over the created document */ 6108 while (currentNode = nodeIterator.nextNode()) { 6109 /* Sanitize tags and elements */ 6110 _sanitizeElements(currentNode); 6111 /* Check attributes next */ 6112 _sanitizeAttributes(currentNode); 6113 /* Shadow DOM detected, sanitize it */ 6114 if (currentNode.content instanceof DocumentFragment) { 6115 _sanitizeShadowDOM(currentNode.content); 6116 } 6117 } 6118 /* If we sanitized `dirty` in-place, return it. */ 6119 if (IN_PLACE) { 6120 return dirty; 6121 } 6122 /* Return sanitized string or DOM */ 6123 if (RETURN_DOM) { 6124 if (RETURN_DOM_FRAGMENT) { 6125 returnNode = createDocumentFragment.call(body.ownerDocument); 6126 while (body.firstChild) { 6127 // eslint-disable-next-line unicorn/prefer-dom-node-append 6128 returnNode.appendChild(body.firstChild); 6129 } 6130 } else { 6131 returnNode = body; 6132 } 6133 if (ALLOWED_ATTR.shadowroot || ALLOWED_ATTR.shadowrootmode) { 6134 /* 6135 AdoptNode() is not used because internal state is not reset 6136 (e.g. the past names map of a HTMLFormElement), this is safe 6137 in theory but we would rather not risk another attack vector. 6138 The state that is cloned by importNode() is explicitly defined 6139 by the specs. 6140 */ 6141 returnNode = importNode.call(originalDocument, returnNode, true); 6142 } 6143 return returnNode; 6144 } 6145 let serializedHTML = WHOLE_DOCUMENT ? body.outerHTML : body.innerHTML; 6146 /* Serialize doctype if allowed */ 6147 if (WHOLE_DOCUMENT && ALLOWED_TAGS['!doctype'] && body.ownerDocument && body.ownerDocument.doctype && body.ownerDocument.doctype.name && regExpTest(DOCTYPE_NAME, body.ownerDocument.doctype.name)) { 6148 serializedHTML = '<!DOCTYPE ' + body.ownerDocument.doctype.name + '>\n' + serializedHTML; 6149 } 6150 /* Sanitize final string template-safe */ 6151 if (SAFE_FOR_TEMPLATES) { 6152 arrayForEach([MUSTACHE_EXPR, ERB_EXPR, TMPLIT_EXPR], expr => { 6153 serializedHTML = stringReplace(serializedHTML, expr, ' '); 6154 }); 6155 } 6156 return trustedTypesPolicy && RETURN_TRUSTED_TYPE ? trustedTypesPolicy.createHTML(serializedHTML) : serializedHTML; 6157 }; 6158 DOMPurify.setConfig = function () { 6159 let cfg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 6160 _parseConfig(cfg); 6161 SET_CONFIG = true; 6162 }; 6163 DOMPurify.clearConfig = function () { 6164 CONFIG = null; 6165 SET_CONFIG = false; 6166 }; 6167 DOMPurify.isValidAttribute = function (tag, attr, value) { 6168 /* Initialize shared config vars if necessary. */ 6169 if (!CONFIG) { 6170 _parseConfig({}); 6171 } 6172 const lcTag = transformCaseFunc(tag); 6173 const lcName = transformCaseFunc(attr); 6174 return _isValidAttribute(lcTag, lcName, value); 6175 }; 6176 DOMPurify.addHook = function (entryPoint, hookFunction) { 6177 if (typeof hookFunction !== 'function') { 6178 return; 6179 } 6180 arrayPush(hooks[entryPoint], hookFunction); 6181 }; 6182 DOMPurify.removeHook = function (entryPoint, hookFunction) { 6183 if (hookFunction !== undefined) { 6184 const index = arrayLastIndexOf(hooks[entryPoint], hookFunction); 6185 return index === -1 ? undefined : arraySplice(hooks[entryPoint], index, 1)[0]; 6186 } 6187 return arrayPop(hooks[entryPoint]); 6188 }; 6189 DOMPurify.removeHooks = function (entryPoint) { 6190 hooks[entryPoint] = []; 6191 }; 6192 DOMPurify.removeAllHooks = function () { 6193 hooks = _createHooksMap(); 6194 }; 6195 return DOMPurify; 6196} 6197var purify = createDOMPurify(); 6198
6199/** 6200 * Copyright (c) Meta Platforms, Inc. and affiliates. 6201 * 6202 * This source code is licensed under the MIT license found in the 6203 * LICENSE file in the root directory of this source tree. 6204 * 6205 */ 6206 6207function 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},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}
6207function _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);
6207else 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();
6207if(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;
6207case "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));
6207else 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;
6207const 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
6207h(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;
6207this.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}
6207:{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;
62070===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);
6207if(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];
6207if(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();}
6207o.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);
6207[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);
6207isFinite(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;
6207for(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;
6207for(;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 6207
6207=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();
6207return 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=>
6207{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;
6207if(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;
6207if(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;
6207const 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 6207-6279
6207[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;}} 6208 6209var Lexical_prod = /*#__PURE__*/Object.freeze({ 6210 __proto__: null, 6211 $addUpdateTag: Os, 6212 $applyNodeReplacement: zs, 6213 $caretFromPoint: ql, 6214 $caretRangeFromSelection: Ql, 6215 $cloneWithProperties: il, 6216 $cloneWithPropertiesEphemeral: ol, 6217 $comparePointCaretNext: Jl, 6218 $copyNode: Ks, 6219 $create: fl, 6220 $createChildrenArray: hl, 6221 $createLineBreakNode: or, 6222 $createNodeSelection: Hr, 6223 $createParagraphNode: eo, 6224 $createPoint: Mr, 6225 $createRangeSelection: qr, 6226 $createRangeSelectionFromDom: Gr, 6227 $createTabNode: wr, 6228 $createTextNode: kr, 6229 $extendCaretToRange: Rl, 6230 $findMatchingParent: dl, 6231 $getAdjacentChildCaret: Ll, 6232 $getAdjacentNode: vs, 6233 $getAdjacentSiblingOrParentSiblingCaret: cc, 6234 $getCaretInDirection: oc, 6235 $getCaretRange: Wl, 6236 $getCaretRangeInDirection: sc, 6237 $getCharacterOffsets: zr, 6238 $getChildCaret: Pl, 6239 $getChildCaretAtIndex: lc, 6240 $getChildCaretOrSelf: Fl, 6241 $getCollapsedCaretRange: Bl, 6242 $getCommonAncestor: Yl, 6243 $getCommonAncestorResultBranchOrder: jl, 6244 $getEditor: Zs, 6245 $getEditorDOMRenderConfig: tl, 6246 $getNearestNodeFromDOMNode: Go, 6247 $getNearestRootOrShadowRoot: Ls, 6248 $getNodeByKey: Yo, 6249 $getNodeByKeyOrThrow: Bs, 6250 $getNodeFromDOMNode: qo, 6251 $getPreviousSelection: Zr, 6252 $getRoot: Zo, 6253 $getSelection: Qr, 6254 $getSiblingCaret: Ol, 6255 $getState: st$2, 6256 $getStateChange: lt$3, 6257 $getTextContent: ci, 6258 $getTextNodeOffset: Al, 6259 $getTextPointCaret: Ml, 6260 $getTextPointCaretSlice: Dl, 6261 $getWritableNodeState: ft$2, 6262 $hasAncestor: As, 6263 $hasUpdateTag: Es, 6264 $insertNodes: li, 6265 $isBlockElementNode: Vr, 6266 $isChildCaret: Nl, 6267 $isDecoratorNode: ji, 6268 $isEditorState: Gi, 6269 $isElementNode: Wi, 6270 $isExtendableTextPointCaret: ic, 6271 $isInlineElementOrDecoratorNode: Fs, 6272 $isLeafNode: Wo, 6273 $isLexicalNode: Bn, 6274 $isLineBreakNode: sr, 6275 $isNodeCaret: kl, 6276 $isNodeSelection: Ir, 6277 $isParagraphNode: no, 6278 $isRangeSelection: Fr, 6279 $isRootNode: Vi,
6280 $isRootOrShadowRoot: Is, 6281 $isSiblingCaret: Tl, 6282 $isTabNode: Er, 6283 $isTextNode: Tr, 6284 $isTextPointCaret: vl, 6285 $isTextPointCaretSlice: zl, 6286 $isTokenOrSegmented: Io, 6287 $isTokenOrTab: Lo, 6288 $nodesOfType: Cs, 6289 $normalizeCaret: rc, 6290 $normalizeSelection__EXPERIMENTAL: St$3, 6291 $onUpdate: Ms, 6292 $parseSerializedNode: Ei, 6293 $removeTextFromCaretRange: nc, 6294 $rewindSiblingCaret: Zl, 6295 $selectAll: ys, 6296 $setCompositionKey: Uo, 6297 $setPointFromCaret: Hl, 6298 $setSelection: es, 6299 $setSelectionFromCaretRange: Gl, 6300 $setState: ct$2, 6301 $splitAtPointCaretNext: fc, 6302 $splitNode: Us, 6303 $updateRangeSelectionFromCaretRange: Xl, 6304 ArtificialNode__DO_NOT_USE: Qi, 6305 BEFORE_INPUT_COMMAND: le$3, 6306 BLUR_COMMAND: Xe$2, 6307 CAN_REDO_COMMAND: qe$2, 6308 CAN_UNDO_COMMAND: He$2, 6309 CLEAR_EDITOR_COMMAND: Ve$2, 6310 CLEAR_HISTORY_COMMAND: Ye$1, 6311 CLICK_COMMAND: se$5, 6312 COLLABORATION_TAG: Un, 6313 COMMAND_PRIORITY_BEFORE_CRITICAL: ho, 6314 COMMAND_PRIORITY_BEFORE_EDITOR: co, 6315 COMMAND_PRIORITY_BEFORE_HIGH: fo, 6316 COMMAND_PRIORITY_BEFORE_LOW: ao, 6317 COMMAND_PRIORITY_BEFORE_NORMAL: uo, 6318 COMMAND_PRIORITY_CRITICAL: lo, 6319 COMMAND_PRIORITY_EDITOR: ro, 6320 COMMAND_PRIORITY_HIGH: so, 6321 COMMAND_PRIORITY_LOW: io, 6322 COMMAND_PRIORITY_NORMAL: oo, 6323 COMPOSITION_END_COMMAND: ue$4, 6324 COMPOSITION_END_TAG: Xn, 6325 COMPOSITION_START_COMMAND: ae$4, 6326 COMPOSITION_START_TAG: Gn, 6327 CONTROLLED_TEXT_INSERTION_COMMAND: ge$3, 6328 COPY_COMMAND: Je$2, 6329 CUT_COMMAND: je$2, 6330 DEFAULT_EDITOR_DOM_CONFIG: po, 6331 DELETE_CHARACTER_COMMAND: fe$4, 6332 DELETE_LINE_COMMAND: me$3,
6333 DELETE_WORD_COMMAND: ye$2, 6334 DRAGEND_COMMAND: $e$2, 6335 DRAGOVER_COMMAND: We$2, 6336 DRAGSTART_COMMAND: Be$2, 6337 DROP_COMMAND: ze$2, 6338 DecoratorNode: Ji, 6339 ElementNode: Bi, 6340 FOCUS_COMMAND: Ge$2, 6341 FORMAT_ELEMENT_COMMAND: Re$1, 6342 FORMAT_TEXT_COMMAND: xe, 6343 HISTORIC_TAG: Wn$1, 6344 HISTORY_MERGE_TAG: Jn, 6345 HISTORY_PUSH_TAG: $n$1, 6346 INDENT_CONTENT_COMMAND: Ie$3, 6347 INPUT_COMMAND: ce$4, 6348 INSERT_LINE_BREAK_COMMAND: de$4, 6349 INSERT_PARAGRAPH_COMMAND: he$3, 6350 INSERT_TAB_COMMAND: Le$2, 6351 INTERNAL_$isBlock: Qs, 6352 IS_ALL_FORMATTING: T$2, 6353 IS_BOLD: p, 6354 IS_CODE: C$4, 6355 IS_HIGHLIGHT: k$3, 6356 IS_ITALIC: y$1, 6357 IS_STRIKETHROUGH: m$1, 6358 IS_SUBSCRIPT: S$1, 6359 IS_SUPERSCRIPT: v$1, 6360 IS_UNDERLINE: x$1, 6361 KEY_ARROW_DOWN_COMMAND: Ee$3, 6362 KEY_ARROW_LEFT_COMMAND: Ne$1, 6363 KEY_ARROW_RIGHT_COMMAND: ke$2, 6364 KEY_ARROW_UP_COMMAND: we$1, 6365 KEY_BACKSPACE_COMMAND: Ae$3, 6366 KEY_DELETE_COMMAND: Pe$2, 6367 KEY_DOWN_COMMAND: ve$2, 6368 KEY_ENTER_COMMAND: Oe$2, 6369 KEY_ESCAPE_COMMAND: De$2, 6370 KEY_MODIFIER_COMMAND: Qe$1, 6371 KEY_SPACE_COMMAND: Me$2, 6372 KEY_TAB_COMMAND: Fe$2, 6373 LineBreakNode: rr, 6374 MOVE_TO_END: Te$2, 6375 MOVE_TO_START: be$1, 6376 NODE_STATE_KEY: j$7, 6377 OUTDENT_CONTENT_COMMAND: Ke$2, 6378 PASTE_COMMAND: _e$2, 6379 PASTE_TAG: jn, 6380 ParagraphNode: Zi, 6381 REDO_COMMAND: Se$2, 6382 REMOVE_TEXT_COMMAND: pe$3, 6383 RootNode: Ui, 6384 SELECTION_CHANGE_COMMAND: ie$4, 6385 SELECTION_INSERT_CLIPBOARD_NODES_COMMAND: oe$6, 6386 SELECT_ALL_COMMAND: Ue$2, 6387 SKIP_COLLAB_TAG: Vn, 6388 SKIP_DOM_SELECTION_TAG: qn, 6389 SKIP_SCROLL_INTO_VIEW_TAG: Yn, 6390 SKIP_SELECTION_FOCUS_TAG: Hn, 6391 TEXT_TYPE_TO_FORMAT: z$7, 6392 TabNode: br, 6393 TextNode: gr, 6394 UNDO_COMMAND: Ce$2, 6395 addClassNamesToElement: mc, 6396 buildImportMap: In, 6397 configExtension: hc, 6398 createCommand: re$5, 6399 createEditor: yo, 6400 createSharedNodeState: at$3, 6401 createState: ot$3, 6402 declarePeerDependency: gc, 6403 defineExtension: dc, 6404 flipDirection: ml, 6405 getDOMOwnerDocument: ws, 6406 getDOMSelection: Js, 6407 getDOMSelectionFromTarget: js, 6408 getDOMTextNode: Ro, 6409 getEditorPropertyFromDOMNode: Po, 6410 getNearestEditorFromDOMNode: Do, 6411 getRegisteredNode: bo, 6412 getRegisteredNodeOrThrow: No, 6413 getStaticNodeConfig: ul, 6414 getStyleObjectFromCSS: Zn, 6415 getTextDirection: Fo, 6416 getTransformSetFromKlass: _o, 6417 isBlockDomNode: Xs, 6418 isCurrentlyReadOnlyMode: mi, 6419 isDOMDocumentNode: zo, 6420 isDOMNode: qs, 6421 isDOMTextNode: Ko, 6422 isDOMUnmanaged: cl, 6423 isDocumentFragment: Hs, 6424 isExactShortcutMatch: ds, 6425 isHTMLAnchorElement: Vs, 6426 isHTMLElement: Ys, 6427 isInlineDomNode: Gs, 6428 isLexicalEditor: Ao, 6429 isModifierMatch: fs, 6430 isSelectionCapturedInDecoratorInput: Oo, 6431 isSelectionWithinEditor: Mo, 6432 makeStepwiseIterator: $l, 6433 mergeRegister: Cc, 6434 normalizeClassNames: yc, 6435 removeClassNamesFromElement: xc, 6436 removeFromParent: Jo, 6437 resetRandomKey: To, 6438 safeCast: _c, 6439 setDOMStyleFromCSS: nr, 6440 setDOMStyleObject: er, 6441 setDOMUnmanaged: ll, 6442 setNodeIndentFromDOM: sl, 6443 shallowMergeConfig: pc, 6444 toggleTextFormatType: Bo 6445}); 6446 6447/** 6448 * Copyright (c) Meta Platforms, Inc. and affiliates. 6449 * 6450 * This source code is licensed under the MIT license found in the 6451 * LICENSE file in the root directory of this source tree. 6452 * 6453 */ 6454 6455function 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()}
6455function 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; 6456 6457const ALLOWED_HTML_ATTRIBUTES = [ "class", "contenteditable", "href", "src", "style", "title" ]; 6458 6459const ALLOWED_STYLE_PROPERTIES = [ "color", "background-color" ]; 6460 6461function styleFilterHook(_currentNode, hookEvent) { 6462 if (hookEvent.attrName === "style" && hookEvent.attrValue) { 6463 const styles = { ...oe$5(hookEvent.attrValue) }; 6464 const sanitizedStyles = { }; 6465 6466 for (const property in styles) { 6467 if (ALLOWED_STYLE_PROPERTIES.includes(property)) { 6468 sanitizedStyles[property] = styles[property]; 6469 } 6470 } 6471 6472 if (Object.keys(sanitizedStyles).length) { 6473 hookEvent.attrValue = F$6(sanitizedStyles); 6474 } else { 6475 hookEvent.keepAttr = false; 6476 } 6477 } 6478} 6479 6480purify.addHook("uponSanitizeAttribute", styleFilterHook); 6481 6482purify.addHook("uponSanitizeElement", (node, data) => { 6483 if (data.tagName === "strong" || data.tagName === "em") { 6484 node.removeAttribute("class"); 6485 } 6486}); 6487 6488function buildConfig(allowedElements ) { 6489 const tagAttributes = {}; 6490 6491 for (const element of allowedElements) { 6492 if (typeof element === "string") { 6493 tagAttributes[element] ||= []; 6494 } else { 6495 tagAttributes[element.tag] ||= []; 6496 tagAttributes[element.tag].push(...element.attributes); 6497 } 6498 } 6499 6500 return { 6501 ALLOWED_TAGS: Object.keys(tagAttributes), 6502 ALLOWED_ATTR: ALLOWED_HTML_ATTRIBUTES, 6503 ADD_ATTR: (attribute, tag) => tagAttributes[tag]?.includes(attribute), 6504 ADD_URI_SAFE_ATTR: [ "caption", "filename" ], 6505 SAFE_FOR_XML: false // So that it does not strip attributes that contains serialized HTML (like content) 6506 } 6507} 6508 6509function getNonce() { 6510 const element = document.head.querySelector("meta[name=csp-nonce]"); 6511 return element?.content 6512} 6513 6514// Register an event listener with a return function to deregister the listener. Both the element and 6515// the listener are WeakRefs so neither is pinned in memory by the deregister function. 6516function registerEventListener(element, type, listener, options) { 6517 element.addEventListener(type, listener, options); 6518 const elementRef = new WeakRef(element); 6519 const listenerRef = new WeakRef(listener); 6520 6521 return function deregisterListener() { 6522 const listener = listenerRef.deref(); 6523 if (listener) elementRef.deref()?.removeEventListener(type, listener, options); 6524 } 6525} 6526 6527class ListenerBin { 6528 #listeners = [] 6529 6530 track(...listeners) { 6531 this.#listeners.push(...listeners); 6532 } 6533 6534 dispose() { 6535 while (this.#listeners.length) { 6536 const teardown = this.#listeners.pop(); 6537 teardown(); 6538 } 6539 } 6540} 6541 6542function handlingDefault(handler) { 6543 return event => { 6544 const handled = handler(event); 6545 if (handled) event.preventDefault(); 6546 return handled 6547 } 6548} 6549 6550function createElement(name, properties, content = "") { 6551 const element = document.createElement(name); 6552 for (const [ key, value ] of Object.entries(properties || {})) { 6553 if (key === "dataset") { 6554 Object.entries(value).forEach(([ key, value ]) => (element.dataset[key] = value)); 6555 } else if (key in element) { 6556 element[key] = value; 6557 } else if (value !== null && value !== undefined) { 6558 element.setAttribute(key, value); 6559 } 6560 } 6561 if (content) { 6562 element.innerHTML = content; 6563 } 6564 return element 6565} 6566 6567function parseHtml(html) { 6568 const parser = new DOMParser(); 6569 return parser.parseFromString(html, "text/html") 6570} 6571 6572function createAttachmentFigure(contentType, isPreviewable, fileName) { 6573 const extension = fileName ? fileName.split(".").pop().toLowerCase() : "unknown"; 6574 return createElement("figure", { 6575 className: `attachment attachment--${isPreviewable ? "preview" : "file"} attachment--${extension}`, 6576 "data-content-type": contentType 6577 }) 6578} 6579 6580function isPreviewableImage(contentType) { 6581 return contentType.startsWith("image/") && !contentType.includes("svg") 6582} 6583 6584function dispatch(element, eventName, detail = null, cancelable = false) { 6585 return element.dispatchEvent(new CustomEvent(eventName, { bubbles: true, detail, cancelable })) 6586} 6587 6588function addBlockSpacing(doc) { 6589 const selector = "body > :not(h1, h2, h3, h4, h5, h6) + *, blockquote > :not(h1, h2, h3, h4, h5, h6) + *"; 6590 for (const block of doc.querySelectorAll(selector)) { 6591 const spacer = doc.createElement("p"); 6592 spacer.appendChild(doc.createElement("br")); 6593 block.before(spacer); 6594 } 6595} 6596 6597function generateDomId(prefix) { 6598 const randomPart = Math.random().toString(36).slice(2, 10); 6599 return `${prefix}-${randomPart}` 6600} 6601 6602function extractPlainTextFromHtml(innerHtml = "") { 6603 return parseHtml(innerHtml).body.textContent.trim() 6604} 6605 6606function isActiveAndVisible(element) { 6607 return element && !element.disabled && checkVisibility(element) 6608} 6609 6610// no `checkVisibility` in Safari < 17.4 6611// https://developer.mozilla.org/en-US/docs/Web/API/Element/checkVisibility#browser_compatibility 6612function checkVisibility(element, options) { 6613 if (element.checkVisibility) { 6614 return element.checkVisibility(options) 6615 } else { 6616 // Will not work for body or a fixed position element child of the body 6617 // which is OK since that doesn't apply in the toolbar where this is used 6618 return Boolean(element.offsetParent) 6619 } 6620} 6621 6622function handleRollingTabIndex(elements, event) { 6623 const previousActiveElement = document.activeElement; 6624 6625 if (elements.includes(previousActiveElement)) { 6626 const finder = new NextElementFinder(elements, event.key); 6627 6628 if (finder.selectNext(previousActiveElement)) { 6629 event.preventDefault(); 6630 } 6631 } 6632} 6633 6634class NextElementFinder { 6635 constructor(elements, key) { 6636 this.elements = elements; 6637 this.key = key; 6638 } 6639 6640 selectNext(fromElement) { 6641 const nextElement = this.#findNextElement(fromElement); 6642 6643 if (nextElement) { 6644 const inactiveElements = this.elements.filter(element => element !== nextElement); 6645 this.#unsetTabIndex(inactiveElements); 6646 this.#focusWithActiveTabIndex(nextElement); 6647 return true 6648 } 6649 6650 return false 6651 } 6652 6653 #findNextElement(fromElement) { 6654 switch (this.key) { 6655 case "ArrowRight": 6656 case "ArrowDown": 6657 return this.#findNextSibling(fromElement) 6658 6659 case "ArrowLeft": 6660 case "ArrowUp": 6661 return this.#findPreviousSibling(fromElement) 6662 6663 case "Home": 6664 return this.#findFirst() 6665 6666 case "End": 6667 return this.#findLast() 6668 } 6669 } 6670 6671 #findFirst(elements = this.elements) { 6672 return elements.find(isActiveAndVisible) 6673 } 6674 6675 #findLast(elements = this.elements) { 6676 return elements.findLast(isActiveAndVisible) 6677 } 6678 6679 #findNextSibling(element) { 6680 const afterElements = this.elements.slice(this.#indexOf(element) + 1); 6681 return this.#findFirst(afterElements) 6682 } 6683 6684 #findPreviousSibling(element) { 6685 const beforeElements = this.elements.slice(0, this.#indexOf(element)); 6686 return this.#findLast(beforeElements) 6687 } 6688 6689 #indexOf(element) { 6690 return this.elements.indexOf(element) 6691 } 6692 6693 #focusWithActiveTabIndex(element) { 6694 if (isActiveAndVisible(element)) { 6695 element.tabIndex = 0; 6696 element.focus(); 6697 } 6698 } 6699 6700 #unsetTabIndex(elements) {
6701 elements.forEach(element => element.tabIndex = -1); 6702 } 6703} 6704 6705var ToolbarIcons = { 6706 "bold": 6707 `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> 6708 <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"/> 6709 </svg>`, 6710 6711 "italic": 6712 `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> 6713 <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"/> 6714 </svg>`, 6715 6716 "strikethrough": 6717 `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> 6718 <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"/> 6719 <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"/> 6720 </svg>`, 6721 6722 "underline": 6723 `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> 6724 <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"/> 6725 <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"/> 6726 </svg>`, 6727 6728 "heading": 6729 `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> 6730 <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"/> 6731 </svg>`, 6732 6733 "h1": 6734 `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> 6735 <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"/> 6736 </svg>`, 6737 6738 "h2": 6739 `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> 6740 <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
67405 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"/> 6741 </svg>`, 6742 6743 "h3": 6744 `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> 6745 <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"/> 6746 </svg>`, 6747 6748 "h4": 6749 `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> 6750 <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"/> 6751 </svg>`, 6752 6753 "h5": 6754 `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> 6755 <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"/> 6756 </svg>`, 6757 6758 "h6": 6759 `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> 6760 <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.
676002345V10.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"/> 6761 </svg>`, 6762 6763 "paragraph": 6764 `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> 6765 <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"/> 6766 </svg>`, 6767 6768 "clearFormatting": 6769 `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> 6770 <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"/> 6771 </svg>`, 6772 6773 "highlight": 6774 `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> 6775 <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"/> 6776 </svg>`, 6777 6778 "link": 6779 `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> 6780 <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"/> 6781 <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"/> 6782 </svg>`, 6783 6784 "quote": 6785 `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> 6786 <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"/> 6787 </svg>`, 6788 6789 "code": 6790 `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> 6791 <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
67915 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"/> 6792 <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"/> 6793 </svg>`, 6794 6795 "ul": 6796 `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> 6797 <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"/> 6798 </svg>`, 6799 6800 "ol": 6801 `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> 6802 <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"/> 6803 <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"/> 6804 <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"/> 6805 <path d="M2.84155 6V3.01367H2.79053L1.85596 3.64478V2.79614L2.84155 2.12476H3.82715V6H2.84155Z"/> 6806 </svg>`, 6807 6808 "image": 6809 `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> 6810 <path d="M14 2C15.6569 2 17 3.34315 17 5V13C17 14.6569 15.6569
681016 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"/> 6811 </svg>`, 6812 6813 "attachment": 6814 `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> 6815 <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"/> 6816 </svg>`, 6817 6818 "table": 6819 `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> 6820 <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"/> 6821 </svg>`, 6822 6823 "hr": 6824 `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> 6825 <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"/> 6826 </svg>`, 6827 6828 "undo": 6829 `<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> 6830 <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"/> 6831 </svg>`, 6832 6833 "redo": 6834 `<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> 6835 <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" /> 6836 </svg>`, 6837 6838 "overflow": 6839 `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> 6840 <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"/> 6841 </svg>` 6842}; 6843 6844class LexicalToolbarElement extends HTMLElement { 6845 static observedAttributes = [ "connected" ] 6846 #listeners = new ListenerBin() 6847 #refreshToolbarAF = null 6848 6849 constructor() { 6850 super(); 6851 this.internals = this.attachInternals(); 6852 this.internals.role = "toolbar"; 6853 6854 this.#createEditorPromise(); 6855 } 6856 6857 connectedCallback() { 6858 this.requestOverflowRefresh(); 6859 this.setAttribute("role", "toolbar"); 6860 this.#installResizeObserver(); 6861 } 6862 6863 disconnectedCallback() { 6864 this.dispose(); 6865 } 6866 6867 dispose() { 6868 this.#listeners.dispose(); 6869 6870 cancelAnimationFrame(this.#refreshToolbarAF); 6871 6872 this.editorElement = null; 6873 this.editor = null; 6874 this.selection = null; 6875 this.#refreshToolbarAF = null; 6876 6877 this.#createEditorPromise(); 6878 } 6879 6880 attributeChangedCallback(name, oldValue, newValue) { 6881 if (name === "connected" && this.isConnected && oldValue != null && oldValue !== newValue) { 6882 requestAnimationFrame(() => this.#reconnect()); 6883 } 6884 } 6885 6886 configure(config) { 6887 if (typeof config === "object" && config !== null) { 6888 for (const [ button, value ] of Object.entries(config)) { 6889 this.setAttribute(`data-${button}`, value); 6890 } 6891 } 6892 } 6893 6894 setEditor(editorElement) { 6895 this.editorElement = editorElement; 6896 this.editor = editorElement.editor; 6897 this.selection = editorElement.selection; 6898 this.#bindButtons(); 6899 this.#bindHotkeys(); 6900 this.#resetTabIndexValues(); 6901 this.#monitorSelectionChanges(); 6902 this.#monitorHistoryChanges(); 6903 this.requestOverflowRefresh(); 6904 this.#bindFocusListeners(); 6905 6906 this.resolveEditorPromise(editorElement); 6907 6908 this.toggleAttribute("connected", true); 6909 } 6910 6911 async getEditorElement() { 6912 return this.editorElement || await this.editorPromise 6913 } 6914 6915 requestOverflowRefresh() { 6916 if (this.#refreshToolbarAF != null) return 6917 6918 this.#refreshToolbarAF = requestAnimationFrame(() => { 6919 this.#refreshOverflow(); 6920 this.#refreshToolbarAF = null; 6921 }); 6922 } 6923 6924 closeDropdowns({ except } = {}) { 6925 this.#dropdowns.forEach((dropdown) => { 6926 if (dropdown !== except) { 6927 dropdown.close({ focusEditor: false }); 6928 } 6929 }); 6930 } 6931 6932 #reconnect() { 6933 this.disconnectedCallback(); 6934 this.connectedCallback(); 6935 } 6936 6937 async #createEditorPromise() { 6938 this.editorPromise = new Promise((resolve) => { 6939 this.resolveEditorPromise = resolve; 6940 }); 6941 6942 this.editorElement = await this.editorPromise; 6943 } 6944 6945 #installResizeObserver() { 6946 const resizeObserver = new ResizeObserver(() => this.requestOverflowRefresh()); 6947 resizeObserver.observe(this); 6948 this.#listeners.track(() => resizeObserver.disconnect()); 6949 } 6950 6951 #bindButtons() { 6952 this.#listeners.track(registerEventListener(this, "click", this.#handleButtonClicked)); 6953 } 6954 6955 #handleButtonClicked = (event) => { 6956 this.#handleTargetClicked(event, "[data-command]", this.#dispatchButtonCommand.bind(this)); 6957 } 6958 6959 #handleTargetClicked(event, selector, callback) { 6960 const button = event.target.closest(selector); 6961 if (button) { 6962 callback(event, button); 6963 } 6964 } 6965 6966 #dispatchButtonCommand(event, { dataset: { command, payload } }) { 6967 const isKeyboard = event instanceof PointerEvent && event.pointerId === -1; 6968 6969 this.editor.update(() => { 6970 this.editor.dispatchCommand(command, payload); 6971 }, { tag: isKeyboard ? qn : undefined }); 6972 6973 if (!isKeyboard) this.editor.focus(); 6974 } 6975 6976 #bindHotkeys() { 6977 this.#listeners.track(registerEventListener(this.editorElement, "keydown", this.#handleHotkey)); 6978 } 6979 6980 #handleHotkey = (event) => { 6981 const buttons = this.querySelectorAll("[data-hotkey]"); 6982 buttons.forEach((button) => { 6983 const hotkeys = button.dataset.hotkey.toLowerCase().split(/\s+/); 6984 if (hotkeys.includes(this.#keyCombinationFor(event))) { 6985 event.preventDefault(); 6986 event.stopPropagation(); 6987 button.click(); 6988 } 6989 }); 6990 } 6991 6992 #keyCombinationFor(event) { 6993 const pressedKey = event.key.toLowerCase(); 6994 const modifiers = [ 6995 event.ctrlKey ? "ctrl" : null, 6996 event.metaKey ? "cmd" : null, 6997 event.altKey ? "alt" : null, 6998 event.shiftKey ? "shift" : null,
vendor: 8,058 bytes, lines 6999-7244
6999 ].filter(Boolean); 7000 7001 return [ ...modifiers, pressedKey ].join("+") 7002 } 7003 7004 #bindFocusListeners() { 7005 this.#listeners.track( 7006 registerEventListener(this.editorElement, "lexxy:focus", this.#handleEditorFocus), 7007 registerEventListener(this.editorElement, "lexxy:blur", this.#handleEditorBlur), 7008 registerEventListener(this, "keydown", this.#handleKeydown) 7009 ); 7010 } 7011 7012 #handleEditorFocus = () => { 7013 const firstVisible = this.#buttons.find(isActiveAndVisible); 7014 if (firstVisible) firstVisible.tabIndex = 0; 7015 } 7016 7017 #handleEditorBlur = () => { 7018 this.#resetTabIndexValues(); 7019 } 7020 7021 #handleKeydown = (event) => { 7022 handleRollingTabIndex(this.#buttons, event); 7023 } 7024 7025 #resetTabIndexValues() { 7026 this.#buttons.forEach((button) => { 7027 button.tabIndex = -1; 7028 }); 7029 } 7030 7031 #monitorSelectionChanges() { 7032 this.#listeners.track(this.editor.registerUpdateListener(({ editorState }) => { 7033 editorState.read(() => { 7034 this.#updateButtonStates(); 7035 this.closeDropdowns(); 7036 }); 7037 })); 7038 } 7039 7040 #monitorHistoryChanges() { 7041 this.#listeners.track( 7042 this.editor.registerCommand(He$2, (enabled) => { this.#setButtonDisabled("undo", !enabled); }, io), 7043 this.editor.registerCommand(qe$2, (enabled) => { this.#setButtonDisabled("redo", !enabled); }, io), 7044 ); 7045 } 7046 7047 #updateButtonStates() { 7048 const selection = Qr(); 7049 if (!Fr(selection)) return 7050 7051 const anchorNode = selection.anchor.getNode(); 7052 if (!anchorNode.getParent()) { return } 7053 7054 const { isBold, isItalic, isStrikethrough, isUnderline, isHighlight, isInLink, isInQuote, isInHeading, 7055 headingTag, isInCode, isInList, listType, isInTable } = this.selection.getFormat(); 7056 7057 this.#setButtonPressed("bold", isBold); 7058 this.#setButtonPressed("italic", isItalic); 7059 this.#setButtonPressed("strikethrough", isStrikethrough); 7060 this.#setButtonPressed("underline", isUnderline); 7061 7062 this.#setButtonPressed("format", isInHeading); 7063 this.#setButtonPressed("paragraph", !isInHeading); 7064 7065 this.querySelector("lexxy-heading-dropdown") 7066 ?.updateActiveHeading(headingTag); 7067 7068 this.#setButtonPressed("lists", isInList); 7069 this.#setButtonPressed("unordered-list", isInList && listType === "bullet"); 7070 this.#setButtonPressed("ordered-list", isInList && listType === "number"); 7071 7072 this.#setButtonPressed("highlight", isHighlight); 7073 this.#setButtonPressed("link", isInLink); 7074 this.#setButtonPressed("quote", isInQuote); 7075 this.#setButtonPressed("code", isInCode); 7076 7077 this.#setButtonPressed("table", isInTable); 7078 } 7079 7080 #setButtonPressed(name, isPressed) { 7081 const button = this.querySelector(`[name="${name}"]`); 7082 if (button) { 7083 const next = isPressed.toString(); 7084 if (button.getAttribute("aria-pressed") !== next) { 7085 button.setAttribute("aria-pressed", next); 7086 } 7087 } 7088 } 7089 7090 #setButtonDisabled(name, isDisabled) { 7091 const button = this.querySelector(`[name="${name}"]`); 7092 if (button) { 7093 if (button.disabled !== isDisabled) { 7094 button.disabled = isDisabled; 7095 } 7096 const next = isDisabled.toString(); 7097 if (button.getAttribute("aria-disabled") !== next) { 7098 button.setAttribute("aria-disabled", next); 7099 } 7100 } 7101 } 7102 7103 #refreshOverflow() { 7104 this.#hideOverflowMenuButton(); 7105 this.#resetToolbarOverflow(); 7106 this.#reindexToolbarItems(); 7107 this.#compactMenu(); 7108 7109 const isOverflowing = this.#overflowMenuDropdown.children.length > 0; 7110 7111 this.toggleAttribute("overflowing", isOverflowing); 7112 this.#setOverflowMenuNonce(); 7113 this.#showOverflowMenuButton(isOverflowing); 7114 } 7115 7116 #resetToolbarOverflow() { 7117 const items = Array.from(this.#overflowMenuDropdown.children); 7118 items.sort((a, b) => this.#itemPosition(b) - this.#itemPosition(a)); 7119 7120 for (const item of items) { 7121 const nextItem = this.querySelector(`[data-position="${this.#itemPosition(item) + 1}"]`) ?? this.#overflowMenuButton; 7122 item.removeAttribute("role"); 7123 this.insertBefore(item, nextItem); 7124 } 7125 } 7126 7127 #showOverflowMenuButton(show = true) { 7128 this.#overflowMenuDropdown.toggleAttribute("disabled", !show); 7129 this.#overflowMenuButton.style.display = show ? "block" : "none"; 7130 } 7131 7132 #hideOverflowMenuButton() { 7133 this.#showOverflowMenuButton(false); 7134 } 7135 7136 #itemPosition(item) { 7137 return parseInt(item.dataset.position ?? "999") 7138 } 7139 7140 #reindexToolbarItems() { 7141 this.#toolbarItems.forEach((item, index) => { 7142 item.dataset.position = index; 7143 }); 7144 } 7145 7146 #compactMenu() { 7147 const overflowWidth = this.#getOverflowWidth(); 7148 7149 if (overflowWidth > 0) { 7150 this.#showOverflowMenuButton(); 7151 const gap = this.#getToolbarGap(); 7152 const spaceForOverflow = gap + this.#overflowMenuButton.offsetWidth; 7153 this.#reclaimWidth(overflowWidth + spaceForOverflow, { gap }); 7154 } 7155 } 7156 7157 #getOverflowWidth() { 7158 return this.scrollWidth - this.clientWidth 7159 } 7160 7161 #reclaimWidth(overflowWidth, { gap }) { 7162 const buttons = this.#overflowableButtons; 7163 const overflowButtons = []; 7164 let recoveredWidth = 0; 7165 7166 while (recoveredWidth < overflowWidth && buttons.length) { 7167 const button = buttons.pop(); 7168 7169 overflowButtons.push(button); 7170 button.role = "menuitem"; 7171 recoveredWidth += button.offsetWidth + gap; 7172 } 7173 7174 this.#overflowMenuDropdown.append(...overflowButtons.reverse()); 7175 } 7176 7177 #setOverflowMenuNonce() { 7178 this.#overflowMenuButton.setAttribute("nonce", getNonce()); 7179 } 7180 7181 #getToolbarGap() { 7182 return parseFloat(window.getComputedStyle(this).columnGap) || 0 7183 } 7184 7185 get #dropdowns() { 7186 return this.querySelectorAll(":scope .lexxy-editor__toolbar-dropdown") 7187 } 7188 7189 get #overflowMenuButton() { 7190 return this.querySelector(".lexxy-editor__toolbar-overflow") 7191 } 7192 7193 get #overflowMenuDropdown() { 7194 return this.#overflowMenuButton?.querySelector(":scope > [data-dropdown-panel]") 7195 } 7196 7197 get #overflowableButtons() { 7198 return Array.from(this.querySelectorAll(":scope > button:not([data-prevent-overflow])")) 7199 } 7200 7201 get #buttons() { 7202 return Array.from(this.querySelectorAll(":scope button")) 7203 } 7204 7205 get #toolbarItems() { 7206 return Array.from(this.querySelectorAll(":scope > *:not(.lexxy-editor__toolbar-overflow)")) 7207 } 7208 7209 static get defaultTemplate() { 7210 const linkInputId = generateDomId("lexxy-link-url"); 7211 7212 return ` 7213 <button class="lexxy-editor__toolbar-button" type="button" name="image" data-command="uploadImage" data-prevent-overflow="true" title="Add images and video"> 7214 ${ToolbarIcons.image} 7215 </button> 7216 7217 <button class="lexxy-editor__toolbar-button lexxy-editor__toolbar-group-end" type="button" name="file" data-command="uploadFile" title="Upload files"> 7218 ${ToolbarIcons.attachment} 7219 </button> 7220 7221 <button class="lexxy-editor__toolbar-button" type="button" name="bold" data-command="bold" title="Bold"> 7222 ${ToolbarIcons.bold} 7223 </button> 7224 7225 <button class="lexxy-editor__toolbar-button" type="button" name="italic" data-command="italic" title="Italic"> 7226 ${ToolbarIcons.italic} 7227 </button> 7228 7229 <button class="lexxy-editor__toolbar-button" type="button" name="strikethrough" data-command="strikethrough" title="Strikethrough"> 7230 ${ToolbarIcons.strikethrough} 7231 </button> 7232 7233 <button class="lexxy-editor__toolbar-button lexxy-editor__toolbar-group-end" type="button" name="underline" data-command="underline" title="Underline"> 7234 ${ToolbarIcons.underline} 7235 </button> 7236 7237 <lexxy-toolbar-dropdown class="lexxy-editor__toolbar-dropdown"> 7238 <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"> 7239 ${ToolbarIcons.heading} 7240 </button> 7241 <div data-dropdown-panel role="menu" class="lexxy-editor__toolbar-dropdown-list" hidden> 7242 <button type="button" name="paragraph" data-command="setFormatParagraph" title="Paragraph" role="menuitem"> 7243 ${ToolbarIcons.paragraph} <span>Normal</span> 7244 </button>
7245 <lexxy-heading-dropdown> 7246 <div class="lexxy-heading-options"></div> 7247 </lexxy-heading-dropdown> 7248 <div class="lexxy-editor__toolbar-separator" role="separator"></div> 7249 <button type="button" name="clear-formatting" data-command="clearFormatting" title="Clear formatting" role="menuitem"> 7250 ${ToolbarIcons.clearFormatting} <span>Clear formatting</span> 7251 </button> 7252 </div> 7253 </lexxy-toolbar-dropdown> 7254 7255 <lexxy-highlight-dropdown class="lexxy-editor__toolbar-dropdown lexxy-editor__toolbar-dropdown--highlight"> 7256 <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"> 7257 ${ToolbarIcons.highlight} 7258 </button> 7259 <div data-dropdown-panel role="menu" hidden> 7260 <div class="lexxy-highlight-colors"></div> 7261 <button data-command="removeHighlight" type="button" class="lexxy-editor__toolbar-button lexxy-editor__toolbar-dropdown-reset" role="menuitem">Remove all coloring</button> 7262 </div> 7263 </lexxy-highlight-dropdown> 7264 7265 <lexxy-link-dropdown class="lexxy-editor__toolbar-dropdown lexxy-editor__toolbar-dropdown--link"> 7266 <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"> 7267 ${ToolbarIcons.link} 7268 </button> 7269 <div data-dropdown-panel role="dialog" aria-label="Link" hidden> 7270 <input type="url" placeholder="Enter a URLâ¦" class="input" id="${linkInputId}"> 7271 <div class="lexxy-editor__toolbar-dropdown-actions"> 7272 <button type="button" class="lexxy-editor__toolbar-button" value="link">Link</button> 7273 <button type="button" class="lexxy-editor__toolbar-button" value="unlink">Unlink</button> 7274 </div> 7275 </div> 7276 </lexxy-link-dropdown> 7277 7278 <button class="lexxy-editor__toolbar-button" type="button" name="quote" data-command="insertQuoteBlock" title="Quote"> 7279 ${ToolbarIcons.quote} 7280 </button> 7281 7282 <button class="lexxy-editor__toolbar-button" type="button" name="code" data-command="insertCodeBlock" title="Code"> 7283 ${ToolbarIcons.code} 7284 </button> 7285 7286 <button class="lexxy-editor__toolbar-button" type="button" name="unordered-list" data-command="insertUnorderedList" title="Bullet list"> 7287 ${ToolbarIcons.ul} 7288 </button> 7289 <button class="lexxy-editor__toolbar-button lexxy-editor__toolbar-group-end" type="button" name="ordered-list" data-command="insertOrderedList" title="Numbered list"> 7290 ${ToolbarIcons.ol} 7291 </button> 7292 7293 <button class="lexxy-editor__toolbar-button" type="button" name="table" data-command="insertTable" title="Insert a table"> 7294 ${ToolbarIcons.table} 7295 </button> 7296 7297 <button class="lexxy-editor__toolbar-button" type="button" name="divider" data-command="insertHorizontalDivider" title="Insert a divider"> 7298 ${ToolbarIcons.hr} 7299 </button> 7300 7301 <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"> 7302 ${ToolbarIcons.undo} 7303 </button> 7304 7305 <button class="lexxy-editor__toolbar-button" type="button" name="redo" data-command="redo" title="Redo" disabled aria-disabled="true"> 7306 ${ToolbarIcons.redo} 7307 </button> 7308 7309 <lexxy-toolbar-dropdown class="lexxy-editor__toolbar-dropdown lexxy-editor__toolbar-button--push-right lexxy-editor__toolbar-overflow"> 7310 <button data-dropdown-trigger class="lexxy-editor__toolbar-button" type="button" aria-haspopup="menu" aria-expanded="false" aria-label="Show more toolbar buttons"> 7311 ${ToolbarIcons.overflow} 7312 </button> 7313 <div data-dropdown-panel role="menu" class="lexxy-editor__toolbar-overflow-menu" aria-label="More toolbar buttons" hidden></div> 7314 </lexxy-toolbar-dropdown> 7315 ` 7316 } 7317} 7318 7319function debounce(fn, wait) { 7320 let timeout; 7321 7322 return (...args) => { 7323 clearTimeout(timeout); 7324 timeout = setTimeout(() => fn(...args), wait); 7325 } 7326} 7327 7328function debounceAsync(fn, wait) { 7329 let timeout; 7330 7331 return (...args) => { 7332 clearTimeout(timeout); 7333 7334 return new Promise((resolve, reject) => { 7335 timeout = setTimeout(async () => { 7336 try { 7337 const result = await fn(...args); 7338 resolve(result); 7339 } catch (err) { 7340 reject(err); 7341 } 7342 }, wait); 7343 }) 7344 } 7345} 7346 7347function delay(ms) { 7348 return new Promise((resolve) => setTimeout(resolve, ms)) 7349} 7350 7351function nextFrame() { 7352 return new Promise(requestAnimationFrame) 7353} 7354 7355class ToolbarDropdown extends HTMLElement { 7356 #listeners = new ListenerBin() 7357 7358 connectedCallback() { 7359 this.#onToolbarEditor(() => { 7360 this.#registerListeners(); 7361 this.editorReady(); 7362 }); 7363 } 7364 7365 disconnectedCallback() { 7366 this.#listeners.dispose(); 7367 } 7368 7369 editorReady() {} 7370 onOpen() {} 7371 onClose() {} 7372 7373 get trigger() { 7374 return this.querySelector(":scope > [data-dropdown-trigger]") 7375 } 7376 7377 get panel() { 7378 return this.querySelector(":scope > [data-dropdown-panel]") 7379 } 7380 7381 get toolbar() { 7382 return this.closest("lexxy-toolbar") 7383 } 7384 7385 get editorElement() { 7386 return this.toolbar?.editorElement 7387 } 7388 7389 get editor() { 7390 return this.toolbar?.editor 7391 } 7392 7393 get isOpen() { 7394 return this.panel.hidden === false 7395 } 7396 7397 get isClosed() { 7398 return !this.isOpen 7399 } 7400 7401 track(...listeners) { 7402 this.#listeners.track(...listeners); 7403 } 7404 7405 open() { 7406 if (this.isOpen) return 7407 this.trigger.setAttribute("aria-expanded", "true"); 7408 this.panel.hidden = false;
vendor: 3,722 bytes, lines 7409-7564
7409 this.onOpen(); 7410 this.#focusFirstInteractive(); 7411 } 7412 7413 close({ focusEditor = true } = {}) { 7414 if (focusEditor) this.editor?.focus(); 7415 7416 if (this.isClosed) return 7417 this.trigger.setAttribute("aria-expanded", "false"); 7418 this.panel.hidden = true; 7419 this.onClose(); 7420 } 7421 7422 #registerListeners() { 7423 this.#listeners.track( 7424 registerEventListener(this, "keydown", this.#handleKeyDown), 7425 registerEventListener(this.trigger, "click", this.#handleTriggerClick) 7426 ); 7427 } 7428 7429 #handleTriggerClick = () => { 7430 if (this.isOpen) { 7431 this.close({ focusEditor: false }); 7432 } else { 7433 this.toolbar?.closeDropdowns({ except: this }); 7434 this.open(); 7435 } 7436 } 7437 7438 async #onToolbarEditor(callback) { 7439 if (!this.toolbar) return 7440 7441 await this.toolbar.getEditorElement(); 7442 if (this.isConnected && this.toolbar) callback(); 7443 } 7444 7445 #handleKeyDown = (event) => { 7446 if (event.key === "Escape") { 7447 event.stopPropagation(); 7448 this.close(); 7449 } 7450 } 7451 7452 async #focusFirstInteractive() { 7453 this.#interactiveElements[0]?.focus(); 7454 await this.#resetTabIndexValues(); 7455 } 7456 7457 async #resetTabIndexValues() { 7458 await nextFrame(); 7459 this.#buttons.forEach((element, index) => { 7460 element.setAttribute("tabindex", index === 0 ? 0 : "-1"); 7461 }); 7462 } 7463 7464 get #interactiveElements() { 7465 return Array.from(this.panel.querySelectorAll("button, input")) 7466 } 7467 7468 get #buttons() { 7469 return Array.from(this.panel.querySelectorAll("button")) 7470 } 7471} 7472 7473const HEADING_BUTTON_SELECTOR = "button.lexxy-heading-button"; 7474 7475const HEADING_PRESETS = [ 7476 { label: "Large Heading", name: "heading-large", command: "setFormatHeadingLarge" }, 7477 { label: "Medium Heading", name: "heading-medium", command: "setFormatHeadingMedium" }, 7478 { label: "Small Heading", name: "heading-small", command: "setFormatHeadingSmall" } 7479]; 7480 7481class HeadingDropdown extends HTMLElement { 7482 static labelFor(tag, index) { 7483 if (index < HEADING_PRESETS.length) { 7484 return HEADING_PRESETS[index].label 7485 } else { 7486 const level = tag.match(/^h(\d+)$/)?.[1]; 7487 if (level) { 7488 return `Heading ${level}` 7489 } else { 7490 return tag.toUpperCase() 7491 } 7492 } 7493 } 7494 7495 static nameFor(tag, index) { 7496 if (index < HEADING_PRESETS.length) { 7497 return HEADING_PRESETS[index].name 7498 } else { 7499 const level = tag.match(/^h(\d+)$/)?.[1]; 7500 if (level) { 7501 return `heading-${level}` 7502 } else { 7503 return `heading-${tag}` 7504 } 7505 } 7506 } 7507 7508 static commandFor(index) { 7509 if (index < HEADING_PRESETS.length) { 7510 return HEADING_PRESETS[index].command 7511 } else { 7512 return "applyHeadingFormat" 7513 } 7514 } 7515 7516 #listeners = new ListenerBin() 7517 7518 connectedCallback() { 7519 this.style.display = "contents"; 7520 7521 this.#onToolbarEditor(() => { 7522 this.#buttonContainer.style.display = "contents"; 7523 this.#setUpButtons(); 7524 this.#registerButtonHandlers(); 7525 this.#syncActiveHeading(); 7526 }); 7527 } 7528 7529 disconnectedCallback() { 7530 this.#listeners.dispose(); 7531 } 7532 7533 updateActiveHeading(tag) { 7534 this.#headingButtons.forEach(button => { 7535 const next = (button.dataset.heading === tag).toString(); 7536 if (button.getAttribute("aria-pressed") !== next) { 7537 button.setAttribute("aria-pressed", next); 7538 } 7539 }); 7540 } 7541 7542 get #toolbar() { 7543 return this.closest("lexxy-toolbar") 7544 } 7545 7546 get #editorElement() { 7547 return this.#toolbar?.editorElement 7548 } 7549 7550 get #editor() { 7551 return this.#toolbar?.editor 7552 } 7553 7554 async #onToolbarEditor(callback) { 7555 const toolbar = this.#toolbar; 7556 if (!toolbar) return 7557 7558 await toolbar.getEditorElement(); 7559 if (this.isConnected && this.#toolbar) callback(); 7560 } 7561 7562 #setUpButtons() { 7563 this.#buttonContainer.innerHTML = ""; 7564
7565 this.#configuredHeadings.forEach((tag, index) => { 7566 this.#buttonContainer.appendChild(this.#createButton(tag, index)); 7567 }); 7568 } 7569 7570 #createButton(tag, index) { 7571 const label = HeadingDropdown.labelFor(tag, index); 7572 const name = HeadingDropdown.nameFor(tag, index); 7573 const icon = ToolbarIcons[tag] || ""; 7574 7575 const button = document.createElement("button"); 7576 button.type = "button"; 7577 button.dataset.heading = tag; 7578 button.dataset.command = HeadingDropdown.commandFor(index); 7579 button.classList.add("lexxy-heading-button"); 7580 button.name = name; 7581 button.title = label; 7582 button.setAttribute("role", "menuitem"); 7583 button.innerHTML = `${icon} <span>${label}</span>`; 7584 return button 7585 } 7586 7587 #registerButtonHandlers() { 7588 this.#headingButtons.forEach(button => { 7589 this.#listeners.track(registerEventListener(button, "click", (event) => { 7590 if (!this.#editor) return 7591 7592 event.preventDefault(); 7593 this.#editor.dispatchCommand(button.dataset.command, button.dataset.heading); 7594 this.#editor.focus(); 7595 })); 7596 }); 7597 } 7598 7599 #syncActiveHeading() { 7600 const { headingTag } = this.#editor.read(() => this.#editorElement.selection.getFormat()); 7601 this.updateActiveHeading(headingTag ?? null); 7602 } 7603 7604 get #configuredHeadings() { 7605 return this.#editorElement.config.get("headings") 7606 } 7607 7608 get #buttonContainer() { 7609 return this.querySelector(".lexxy-heading-options") 7610 } 7611 7612 get #headingButtons() { 7613 return Array.from(this.querySelectorAll(HEADING_BUTTON_SELECTOR)) 7614 } 7615} 7616 7617const APPLY_HIGHLIGHT_SELECTOR = "button.lexxy-highlight-button"; 7618const REMOVE_HIGHLIGHT_SELECTOR = "[data-command='removeHighlight']"; 7619 7620// Use Symbol instead of null since $getSelectionStyleValueForProperty 7621// responds differently for backward selections if null is the default 7622// see https://github.com/facebook/lexical/issues/8013 7623const NO_STYLE = Symbol("no_style"); 7624 7625class HighlightDropdown extends ToolbarDropdown { 7626 editorReady() { 7627 this.#setUpButtons(); 7628 this.#registerButtonHandlers(); 7629 } 7630 7631 onOpen() { 7632 this.editor.getEditorState().read(() => { 7633 this.#updateColorButtonStates(Qr()); 7634 }); 7635 } 7636 7637 #registerButtonHandlers() { 7638 this.#colorButtons.forEach(button => { 7639 this.track(registerEventListener(button, "click", this.#handleColorButtonClick)); 7640 }); 7641 } 7642 7643 #setUpButtons() { 7644 this.#buttonContainer.innerHTML = ""; 7645 7646 const colorGroups = this.editorElement.config.get("highlight.buttons"); 7647 7648 this.#populateButtonGroup("color", colorGroups.color); 7649 this.#populateButtonGroup("background-color", colorGroups["background-color"]); 7650 7651 const maxNumberOfColors = Math.max(colorGroups.color.length, colorGroups["background-color"].length); 7652 this.panel.style.setProperty("--max-colors", maxNumberOfColors); 7653 } 7654 7655 #populateButtonGroup(attribute, values) { 7656 values.forEach((value, index) => { 7657 this.#buttonContainer.appendChild(this.#createButton(attribute, value, index)); 7658 }); 7659 } 7660 7661 #createButton(attribute, value, index) { 7662 return createElement("button", { 7663 type: "button", 7664 dataset: { value, style: attribute }, 7665 style: `${attribute}: ${value}`, 7666 class: "lexxy-editor__toolbar-button lexxy-highlight-button", 7667 name: `${attribute}-${index}`, 7668 role: "menuitem" 7669 }) 7670 } 7671 7672 #handleColorButtonClick = (event) => { 7673 event.preventDefault(); 7674 7675 const button = event.target.closest(APPLY_HIGHLIGHT_SELECTOR); 7676 if (!button) return 7677 7678 const { style, value } = button.dataset; 7679 7680 this.editor.dispatchCommand("toggleHighlight", { [style]: value }); 7681 this.close(); 7682 } 7683 7684 #updateColorButtonStates(selection) { 7685 if (!Fr(selection)) { return } 7686 7687 // Use non-"" default, so "" indicates mixed highlighting 7688 const textColor = ne$4(selection, "color", NO_STYLE); 7689 const backgroundColor = ne$4(selection, "background-color", NO_STYLE); 7690 7691 this.#colorButtons.forEach(button => { 7692 const matchesSelection = button.dataset.value === textColor || button.dataset.value === backgroundColor; 7693 const next = matchesSelection.toString(); 7694 if (button.getAttribute("aria-pressed") !== next) { 7695 button.setAttribute("aria-pressed", next); 7696 } 7697 }); 7698 7699 const hasHighlight = textColor !== NO_STYLE || backgroundColor !== NO_STYLE; 7700 this.panel.querySelector(REMOVE_HIGHLIGHT_SELECTOR).disabled = !hasHighlight; 7701 } 7702 7703 get #buttonContainer() { 7704 return this.panel.querySelector(".lexxy-highlight-colors") 7705 } 7706 7707 get #colorButtons() { 7708 return Array.from(this.panel.querySelectorAll(APPLY_HIGHLIGHT_SELECTOR)) 7709 } 7710} 7711 7712/** 7713 * Copyright (c) Meta Platforms, Inc. and affiliates. 7714 * 7715 * This source code is licensed under the MIT license found in the 7716 * LICENSE file in the root directory of this source tree. 7717 * 7718 */ 7719 7720function 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;
7720return $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()})} 7721 7722/** 7723 * Copyright (c) Meta Platforms, Inc. and affiliates. 7724 * 7725 * This source code is licensed under the MIT license found in the 7726 * LICENSE file in the root directory of this source tree. 7727 * 7728 */ 7729 7730const 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)&<$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;
7730e=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();}}
7730,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;
7730return 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});
7730return 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} 7731 7732/** 7733 * Copyright (c) Meta Platforms, Inc. and affiliates. 7734 * 7735 * This source code is licensed under the MIT license found in the 7736 * LICENSE file in the root directory of this source tree. 7737 * 7738 */ 7739 7740const 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;
7740const 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));
7740return 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}`} 7741 7742class LinkDropdown extends ToolbarDropdown { 7743 editorReady() { 7744 this.input = this.panel.querySelector("input"); 7745 7746 this.track( 7747 registerEventListener(this.input, "keydown", this.#handleEnter), 7748 registerEventListener(this.linkButton, "click", this.#handleLink), 7749 registerEventListener(this.unlinkButton, "click", this.#handleUnlink) 7750 ); 7751 } 7752 7753 onOpen() { 7754 this.input.value = this.#selectedLinkUrl; 7755 this.input.required = true; 7756 } 7757 7758 onClose() { 7759 this.input.required = false; 7760 } 7761 7762 get linkButton() { 7763 return this.panel.querySelector("[value='link']") 7764 } 7765 7766 get unlinkButton() { 7767 return this.panel.querySelector("[value='unlink']") 7768 } 7769 7770 #handleEnter = (event) => { 7771 if (event.key === "Enter") { 7772 event.preventDefault(); 7773 event.stopPropagation(); 7774 this.#handleLink(event); 7775 } 7776 } 7777 7778 #handleLink = () => { 7779 if (!this.input.checkValidity()) { 7780 this.input.reportValidity(); 7781 return 7782 } 7783 7784 this.editor.dispatchCommand("link", this.input.value); 7785 this.close(); 7786 } 7787 7788 #handleUnlink = () => { 7789 this.editor.dispatchCommand("unlink"); 7790 this.close(); 7791 } 7792 7793 get #selectedLinkUrl() { 7794 return this.editor.getEditorState().read(() => { 7795 const linkNode = this.editorElement.selection.nearestNodeOfType(F$4); 7796 return linkNode?.getURL() ?? "" 7797 }) 7798 } 7799} 7800 7801/** 7802 * Copyright (c) Meta Platforms, Inc. and affiliates. 7803 * 7804 * This source code is licensed under the MIT license found in the 7805 * LICENSE file in the root directory of this source tree. 7806 * 7807 */ 7808 7809function 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
7809or.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);
7809r.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);}
7809return 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)}};
7809function _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);}}))} 7810 7811/** 7812 * Copyright (c) Meta Platforms, Inc. and affiliates. 7813 * 7814 * This source code is licensed under the MIT license found in the 7815 * LICENSE file in the root directory of this source tree. 7816 * 7817 */ 7818 7819function 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);}}
7819}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} 7820 7821/** 7822 * Copyright (c) Meta Platforms, Inc. and affiliates. 7823 * 7824 * This source code is licensed under the MIT license found in the 7825 * LICENSE file in the root directory of this source tree. 7826 * 7827 */ 7828 7829function _$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
7829ist");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;
7829const 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"}); 7830 7831/** 7832 * Copyright (c) Meta Platforms, Inc. and affiliates. 7833 * 7834 * This source code is licensed under the MIT license found in the 7835 * LICENSE file in the root directory of this source tree. 7836 * 7837 */ 7838 7839function 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))}); 7840 7841/** 7842 * Copyright (c) Meta Platforms, Inc. and affiliates. 7843 * 7844 * This source code is licensed under the MIT license found in the 7845 * LICENSE file in the root directory of this source tree. 7846 * 7847 */ 7848 7849const 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;
7849const 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))} 7850 7851/** 7852 * Copyright (c) Meta Platforms, Inc. and affiliates. 7853 * 7854 * This source code is licensed under the MIT license found in the 7855 * LICENSE file in the root directory of this source tree. 7856 * 7857 */ 7858 7859function 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();
7859return 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());
7859return 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;
7859const 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}); 7860 7861function deepMerge(target, source) { 7862 const result = { ...target, ...source }; 7863 for (const [ key, value ] of Object.entries(source)) { 7864 if (arePlainHashes(target[key], value)) { 7865 result[key] = deepMerge(target[key], value); 7866 } 7867 } 7868 7869 return result 7870} 7871 7872function arePlainHashes(...values) { 7873 return values.every(value => value && value.constructor == Object) 7874} 7875 7876class Configuration { 7877 #tree = {} 7878 7879 constructor(...configs) { 7880 this.merge(...configs); 7881 } 7882 7883 merge(...configs) { 7884 return this.#tree = configs.reduce(deepMerge, this.#tree) 7885 } 7886 7887 get(path) { 7888 const keys = path.split("."); 7889 return keys.reduce((node, key) => node[key], this.#tree) 7890 } 7891} 7892 7893function range(from, to) { 7894 return [ ...Array(1 + to - from).keys() ].map(i => i + from) 7895} 7896 7897const global$1 = new Configuration({ 7898 attachmentTagName: "action-text-attachment", 7899 attachmentContentTypeNamespace: "actiontext", 7900 authenticatedUploads: false, 7901 extensions: [] 7902}); 7903 7904const presets = new Configuration({ 7905 default: { 7906 attachments: true, 7907 markdown: true, 7908 multiLine: true, 7909 permittedAttachmentTypes: null, 7910 richText: true, 7911 toolbar: { 7912 upload: "both" 7913 }, 7914 headings: [ "h2", "h3", "h4" ], 7915 highlight: { 7916 buttons: { 7917 color: range(1, 9).map(n => `var(--highlight-${n})`), 7918 "background-color": range(1, 9).map(n => `var(--highlight-bg-${n})`), 7919 }, 7920 permit: { 7921 color: [], 7922 "background-color": [] 7923 } 7924 } 7925 } 7926}); 7927 7928var Lexxy = { 7929 global: global$1, 7930 presets, 7931 configure({ global: newGlobal, ...newPresets }) { 7932 if (newGlobal) { 7933 global$1.merge(newGlobal); 7934 } 7935 presets.merge(newPresets); 7936 } 7937}; 7938 7939function setSanitizerConfig(allowedTags) { 7940 purify.clearConfig(); 7941 purify.setConfig(buildConfig(allowedTags)); 7942} 7943 7944function sanitize(html) { 7945 return purify.sanitize(html) 7946} 7947 7948function bytesToHumanSize(bytes) { 7949 if (bytes === 0) return "0 B" 7950 const sizes = [ "B", "KB", "MB", "GB", "TB", "PB" ]; 7951 const i = Math.floor(Math.log(bytes) / Math.log(1024)); 7952 const value = bytes / Math.pow(1024, i); 7953 return `${ value.toFixed(2) } ${ sizes[i] }` 7954} 7955 7956function extractFileName(string) { 7957 return string.split("/").pop() 7958} 7959 7960// The content attribute is raw HTML (matching Trix/ActionText). Older Lexxy 7961// versions JSON-encoded it, so try JSON.parse first for backward compatibility. 7962function parseAttachmentContent(content) { 7963 try { 7964 return JSON.parse(content) 7965 } catch { 7966 return content 7967 } 7968} 7969 7970function mimeTypeToExtension(mimeType) { 7971 if (!mimeType) return null 7972 7973 const extension = mimeType.split("/")[1]; 7974 return extension 7975}
7975 7976 7977class CustomActionTextAttachmentNode extends Ji { 7978 static getType() { 7979 return "custom_action_text_attachment" 7980 } 7981 7982 static clone(node) { 7983 return new CustomActionTextAttachmentNode({ ...node }, node.__key) 7984 } 7985 7986 static importJSON(serializedNode) { 7987 return new CustomActionTextAttachmentNode({ ...serializedNode }) 7988 } 7989 7990 static importDOM() { 7991 return { 7992 [this.TAG_NAME]: (element) => { 7993 if (!element.getAttribute("content")) { 7994 return null 7995 } 7996 7997 return { 7998 conversion: (attachment) => { 7999 // Preserve initial space if present since Lexical removes it 8000 const nodes = []; 8001 const previousSibling = attachment.previousSibling; 8002 if (previousSibling && previousSibling.nodeType === Node.TEXT_NODE && /\s$/.test(previousSibling.textContent)) { 8003 nodes.push(kr(" ")); 8004 } 8005 8006 const innerHtml = parseAttachmentContent(attachment.getAttribute("content")); 8007 8008 nodes.push(new CustomActionTextAttachmentNode({ 8009 sgid: attachment.getAttribute("sgid"), 8010 innerHtml, 8011 plainText: attachment.textContent.trim() || extractPlainTextFromHtml(innerHtml), 8012 contentType: attachment.getAttribute("content-type") 8013 })); 8014 8015 const nextSibling = attachment.nextSibling; 8016 if (nextSibling && nextSibling.nodeType === Node.TEXT_NODE && /^\s/.test(nextSibling.textContent)) { 8017 nodes.push(kr(" ")); 8018 } 8019 8020 return { node: nodes } 8021 }, 8022 priority: 2 8023 } 8024 } 8025 } 8026 } 8027 8028 static get TAG_NAME() { 8029 return Lexxy.global.get("attachmentTagName") 8030 } 8031 8032 constructor({ tagName, sgid, contentType, innerHtml, plainText }, key) { 8033 super(key); 8034 8035 const contentTypeNamespace = Lexxy.global.get("attachmentContentTypeNamespace"); 8036 8037 this.tagName = tagName || CustomActionTextAttachmentNode.TAG_NAME; 8038 this.sgid = sgid; 8039 this.contentType = contentType || `application/vnd.${contentTypeNamespace}.unknown`; 8040 this.innerHtml = innerHtml; 8041 this.plainText = plainText ?? extractPlainTextFromHtml(innerHtml); 8042 } 8043 8044 createDOM() { 8045 const figure = createElement(this.tagName, { "content-type": this.contentType, "data-lexxy-decorator": true, draggable: true }); 8046 figure.dataset.lexicalNodeKey = this.__key; 8047 8048 figure.insertAdjacentHTML("beforeend", sanitize(this.innerHtml)); 8049 8050 const deleteButton = createElement("lexxy-node-delete-button"); 8051 figure.appendChild(deleteButton); 8052 8053 return figure 8054 } 8055 8056 updateDOM() { 8057 return false 8058 } 8059 8060 getTextContent() { 8061 return "\ufeff" 8062 } 8063 8064 getReadableTextContent() { 8065 return this.plainText || `[${this.contentType}]` 8066 } 8067 8068 isInline() { 8069 return true 8070 } 8071 8072 exportDOM() { 8073 const attachment = createElement(this.tagName, { 8074 sgid: this.sgid, 8075 content: this.innerHtml, 8076 "content-type": this.contentType 8077 }); 8078 8079 return { element: attachment } 8080 } 8081 8082 exportJSON() { 8083 return { 8084 type: "custom_action_text_attachment", 8085 version: 1, 8086 tagName: this.tagName, 8087 sgid: this.sgid, 8088 contentType: this.contentType, 8089 innerHtml: this.innerHtml, 8090 plainText: this.plainText 8091 } 8092 } 8093 8094 decorate() { 8095 return null 8096 } 8097} 8098 8099function $isCustomActionTextAttachmentNode(node) { 8100 return node instanceof CustomActionTextAttachmentNode 8101} 8102 8103function dasherize(value) { 8104 return value.replace(/([A-Z])/g, (_, char) => `-${char.toLowerCase()}`) 8105} 8106 8107function isAutolinkableURL(string) { 8108 return /^(?:[a-z0-9]+:\/\/|www\.)[^\s]+$/i.test(string) 8109} 8110 8111function normalizeFilteredText(string) { 8112 return string 8113 .toLowerCase() 8114 .normalize("NFD").replace(/[\u0300-\u036f]/g, "") // Remove diacritics 8115} 8116 8117function filterMatchPosition(text, potentialMatch) { 8118 const normalizedText = normalizeFilteredText(text); 8119 const normalizedMatch = normalizeFilteredText(potentialMatch); 8120 8121 if (!normalizedMatch) return 0 8122 8123 const match = normalizedText.match(new RegExp(`(?<![\\p{L}\\p{N}])${escapeForRegExp(normalizedMatch)}`, "u")); 8124 return match ? match.index : -1 8125} 8126 8127function upcaseFirst(string) { 8128 return string.charAt(0).toUpperCase() + string.slice(1) 8129} 8130 8131function escapeForRegExp(string) { 8132 return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") 8133} 8134 8135// Parses a value that may arrive as a boolean or as a string (e.g. from DOM 8136// getAttribute) into a proper boolean. Ensures "false" doesn't evaluate as truthy. 8137function parseBoolean(value) { 8138 if (typeof value === "string") return value === "true" 8139 return Boolean(value) 8140} 8141 8142/** 8143 * Copyright (c) Meta Platforms, Inc. and affiliates. 8144 * 8145 * This source code is licensed under the MIT license found in the 8146 * LICENSE file in the root directory of this source tree. 8147 * 8148 */ 8149 8150function 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>
81501){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;}function 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;});}})}); 8151 8152class LexxyExtension { 8153 #editorElement 8154 8155 constructor(editorElement) { 8156 this.#editorElement = editorElement; 8157 } 8158 8159 get editorElement() { 8160 return this.#editorElement 8161 } 8162 8163 get editorConfig() { 8164 return this.#editorElement.config 8165 } 8166 8167 // optional: defaults to true 8168 get enabled() { 8169 return true 8170 } 8171 8172 get lexicalExtension() { 8173 return null 8174 } 8175 8176 get allowedElements() { 8177 return [] 8178 } 8179 8180 defineExtension(...args) { 8181 return dc(...args) 8182 } 8183 8184 initializeToolbar(_lexxyToolbar) { 8185 } 8186 8187 setEditorValidity(flags, message) { 8188 this.editorElement.setElementValidity(this, flags, message); 8189 } 8190 8191 dispose() { 8192 } 8193} 8194 8195function $containsRangeSelection(node, selection = Qr()) { 8196 if (Fr(selection)) { 8197 const { commonAncestor } = Yl(selection.focus.getNode(), selection.anchor.getNode()); 8198 return dl(commonAncestor, parent => parent.is(node)) 8199 } else { 8200 return false 8201 } 8202} 8203 8204function $createNodeSelectionWith(...nodes) { 8205 const selection = Hr();
vendor: 26,690 bytes, lines 8206-9066
8206 nodes.forEach(node => selection.add(node.getKey())); 8207 return selection 8208} 8209 8210function $isShadowRoot(node) { 8211 return Wi(node) && Is(node) && !Vi(node) 8212} 8213 8214function $isSafeForRoot(node) { 8215 return (Wi(node) || ji(node)) && !node.isParentRequired() 8216} 8217 8218function $makeSafeForRoot(node) { 8219 if ($isSafeForRoot(node)) { 8220 return node 8221 } else if (node.getParent()) { 8222 return Tt$4(node, () => node.createParentElementNode()) 8223 } else { 8224 // Detached nodes (e.g. clipboard nodes being inserted) can't be `replace`d in place, 8225 // so append them into a fresh required parent instead. 8226 return node.createParentElementNode().append(node) 8227 } 8228} 8229 8230function getListType(node) { 8231 const list = At$2(node, me$2); 8232 return list?.getListType() ?? null 8233} 8234 8235function isEditorFocused(editor) { 8236 const rootElement = editor.getRootElement(); 8237 return rootElement !== null && rootElement.contains(document.activeElement) 8238} 8239 8240function $isAtNodeEdge(point, atStart = null) { 8241 if (atStart === null) { 8242 return $isAtNodeEdge(point, true) || $isAtNodeEdge(point, false) 8243 } else { 8244 return atStart ? $isAtNodeStart(point) : A$2(point) 8245 } 8246} 8247 8248function $isAtNodeStart(point) { 8249 return point.offset === 0 8250} 8251 8252function extendTextNodeConversion(conversionName, ...callbacks) { 8253 return extendConversion(gr, conversionName, (conversionOutput, element) => ({ 8254 ...conversionOutput, 8255 forChild: (lexicalNode, parentNode) => { 8256 const originalForChild = conversionOutput?.forChild ?? (x => x); 8257 let childNode = originalForChild(lexicalNode, parentNode); 8258 8259 8260 if (Tr(childNode)) { 8261 childNode = callbacks.reduce( 8262 (childNode, callback) => callback(childNode, element) ?? childNode, 8263 childNode 8264 ); 8265 return childNode 8266 } 8267 } 8268 })) 8269} 8270 8271function extendConversion(nodeKlass, conversionName, callback = (output => output)) { 8272 return (element) => { 8273 const converter = nodeKlass.importDOM()?.[conversionName]?.(element); 8274 if (!converter) return null 8275 8276 const conversionOutput = converter.conversion(element); 8277 if (!conversionOutput) return conversionOutput 8278 8279 return callback(conversionOutput, element) ?? conversionOutput 8280 } 8281} 8282 8283function $isCursorOnLastLine(selection) { 8284 const anchorNode = selection.anchor.getNode(); 8285 const elementNode = Wi(anchorNode) ? anchorNode : anchorNode.getParentOrThrow(); 8286 const children = elementNode.getChildren(); 8287 if (children.length === 0) return true 8288 8289 const lastChild = children[children.length - 1]; 8290 8291 if (anchorNode === elementNode.getLatest() && selection.anchor.offset === children.length) return true 8292 if (anchorNode === lastChild) return true 8293 8294 const lastLineBreakIndex = children.findLastIndex(child => sr(child)); 8295 if (lastLineBreakIndex === -1) return true 8296 8297 const anchorIndex = children.indexOf(anchorNode); 8298 return anchorIndex > lastLineBreakIndex 8299} 8300 8301function $isBlankNode(node) { 8302 if (node.getTextContent().trim() !== "") return false 8303 8304 const children = node.getChildren?.(); 8305 if (!children || children.length === 0) return true 8306 8307 return children.every(child => { 8308 if (sr(child)) return true 8309 return $isBlankNode(child) 8310 }) 8311} 8312 8313function $trimTrailingBlankNodes(parent) { 8314 for (const child of zt$4(parent)) { 8315 if ($isBlankNode(child)) { 8316 child.remove(); 8317 } else { 8318 break 8319 } 8320 } 8321} 8322 8323// A list item is structurally empty if it contains no meaningful content. 8324// Unlike getTextContent().trim() === "", this walks descendants to ensure 8325// decorator nodes (mentions, attachments whose getTextContent() may return 8326// invisible characters like \ufeff) are treated as non-empty content. 8327function $isListItemStructurallyEmpty(listItem) { 8328 const children = listItem.getChildren(); 8329 for (const child of children) { 8330 if (ji(child)) return false 8331 if (sr(child)) continue 8332 if (Tr(child)) { 8333 if (child.getTextContent().trim() !== "") return false 8334 } else if (Wi(child)) { 8335 if (child.getTextContent().trim() !== "") return false 8336 } 8337 } 8338 return true 8339} 8340 8341// Returns the document text up to `offset` inside `targetNode`. Non-inline 8342// element siblings are joined with `\n\n`, matching Lexical's own 8343// ElementNode.getTextContent behavior. 8344function $textBeforeOffset(targetNode, offset) { 8345 const parts = []; 8346 let done = false; 8347 8348 function visit(node) { 8349 if (done) return 8350 if (node === targetNode) { 8351 parts.push(node.getTextContent().slice(0, offset)); 8352 done = true; 8353 return 8354 } 8355 if (Wi(node)) { 8356 const children = node.getChildren(); 8357 for (let i = 0; i < children.length; i++) { 8358 visit(children[i]); 8359 if (done) return 8360 const child = children[i]; 8361 if (Wi(child) && !child.isInline() && i < children.length - 1) { 8362 parts.push("\n\n"); 8363 } 8364 } 8365 } else { 8366 parts.push(node.getTextContent()); 8367 } 8368 } 8369 8370 visit(Zo()); 8371 return parts.join("") 8372} 8373 8374function isAttachmentSpacerTextNode(node, previousNode, index, childCount) { 8375 return Tr(node) 8376 && node.getTextContent() === " " 8377 && index === childCount - 1 8378 && previousNode instanceof CustomActionTextAttachmentNode 8379} 8380 8381function $splitSelectedParagraphsAtInnerLineBreaks(selection) { 8382 const topLevelElements = new Set(); 8383 for (const node of selection.getNodes()) { 8384 const topLevel = node.getTopLevelElement(); 8385 if (topLevel) topLevelElements.add(topLevel); 8386 } 8387 8388 for (const element of topLevelElements) { 8389 if (!no(element)) continue 8390 8391 const children = element.getChildren(); 8392 if (!children.some(sr)) continue 8393 8394 const groups = [ [] ]; 8395 for (const child of children) { 8396 if (sr(child)) { 8397 groups.push([]); 8398 child.remove(); 8399 } else { 8400 groups[groups.length - 1].push(child); 8401 } 8402 } 8403 8404 for (const group of groups) { 8405 if (group.length === 0) continue 8406 const paragraph = eo(); 8407 group.forEach(child => paragraph.append(child)); 8408 element.insertBefore(paragraph); 8409 } 8410 if (groups.some(group => group.length > 0)) element.remove(); 8411 } 8412} 8413 8414function $expandSelectionToLineBreaksAndSplitAtEdges(selection, fallbackAncestor = (node) => node.getTopLevelElement()) { 8415 j$6(selection); 8416 $shrinkSelectionPastBlockEdges(selection); 8417 8418 const focusCaret = ql(selection.focus, "next"); 8419 const anchorCaret = ql(selection.anchor, "previous"); 8420 8421 // A collapsed cursor adjacent to a <br> would claim it from both sides via 8422 // inward-edge; force outward-only walks so each side finds its own boundary. 8423 const skipInwardEdge = selection.isCollapsed(); 8424 const focusBrCaret = $getCaretAtLineBreakBoundary(focusCaret, skipInwardEdge); 8425 let anchorBrCaret = $getCaretAtLineBreakBoundary(anchorCaret, skipInwardEdge); 8426 8427 if (focusBrCaret?.origin.is(anchorBrCaret?.origin)) { 8428 anchorBrCaret = null; 8429 } 8430 8431 // Splitting focus first keeps the anchor <br>'s position stable. 8432 const focusOuter = focusBrCaret && $splitAroundLineBreak(focusBrCaret); 8433 const anchorOuter = anchorBrCaret && $splitAroundLineBreak(anchorBrCaret); 8434 8435 const innerStart = anchorOuter?.getNextSibling() ?? fallbackAncestor(selection.anchor.getNode()); 8436 const innerEnd = focusOuter?.getPreviousSibling() ?? fallbackAncestor(selection.focus.getNode()); 8437 if (!innerStart || !innerEnd) return 8438 8439 Gl(Wl( 8440 rc(Pl(innerStart, "next")), 8441 oc( 8442 rc(Pl(innerEnd, "previous")), 8443 "next", 8444 ), 8445 )); 8446} 8447 8448// A selection whose anchor sits at the very end of one block while its focus 8449// lives in a later block (e.g. selecting a pasted paragraph when the browser 8450// anchors at the end of the line above) contributes nothing from the anchor's 8451// block. Pull each endpoint that is flush against a block edge into the block 8452// that actually holds the selected content, so we don't wrap the empty edge 8453// block too. 8454function $shrinkSelectionPastBlockEdges(selection) { 8455 if (selection.isCollapsed()) return 8456 8457 const anchorBlock = selection.anchor.getNode().getTopLevelElement(); 8458 const focusBlock = selection.focus.getNode().getTopLevelElement(); 8459 if (!anchorBlock || !focusBlock || anchorBlock.is(focusBlock)) return 8460 8461 if ($isAtBlockEnd(selection.anchor, anchorBlock)) { 8462 const nextBlock = $nearestElementSibling(anchorBlock, "next"); 8463 if (nextBlock) selection.anchor.set(nextBlock.getKey(), 0, "element"); 8464 } 8465 8466 if ($isAtBlockStart(selection.focus, focusBlock)) { 8467 const previousBlock = $nearestElementSibling(focusBlock, "previous"); 8468 if (previousBlock) selection.focus.set(previousBlock.getKey(), previousBlock.getChildrenSize(), "element"); 8469 } 8470 8471 // Shrinking moves the endpoints toward each other, so they can cross when 8472 // both were flush against block edges; callers assume a forward selection. 8473 j$6(selection); 8474} 8475 8476// Top-level decorator blocks (attachments, horizontal dividers) can't hold a 8477// selection point, so walk past them to the nearest element sibling. Returns 8478// null when no element sibling exists in that direction. 8479function $nearestElementSibling(block, direction) { 8480 let sibling = block; 8481 do { 8482 sibling = direction === "next" ? sibling.getNextSibling() : sibling.getPreviousSibling(); 8483 } while (sibling && !Wi(sibling)) 8484 return sibling 8485} 8486 8487function $isAtBlockEnd(point, block) { 8488 return $isAtBlockBoundary(ql(point, "next"), block) 8489} 8490 8491function $isAtBlockStart(point, block) { 8492 return $isAtBlockBoundary(ql(point, "previous"), block) 8493} 8494 8495// A text point sitting mid-node still has content ahead of it in the caret's 8496// direction, even though that content is not a sibling node. $getNodeAtCaret 8497// only sees siblings, so check the text edge before walking the block. 8498function $isAtBlockBoundary(caret, block) { 8499 if (vl(caret) && ic(caret)) return false 8500 8501 let cursor = rc(caret); 8502 while (cursor && block.isParentOf(cursor.origin)) { 8503 if (cursor.getNodeAtCaret()) return false 8504 cursor = cursor.getParentCaret(); 8505 } 8506 return true 8507} 8508 8509function $getCaretAtLineBreakBoundary(caret, skipInwardEdge = false) { 8510 const paragraph = caret.origin.getTopLevelElement(); 8511 if (!paragraph || !no(paragraph)) return null 8512 8513 const lineBreak = (skipInwardEdge ? null : $inwardEdgeLineBreak(caret, paragraph)) 8514 ?? $outwardLineBreak(caret, paragraph); 8515 8516 return lineBreak ? Ol(lineBreak, caret.direction) : null 8517} 8518 8519// Prefer a <br> the cursor is sitting flush against, except when a further <br> 8520// also exists outward â that one is the real paragraph break for this side. 8521function $inwardEdgeLineBreak(caret, paragraph) { 8522 let candidateCaret; 8523 8524 if ( 8525 (Nl(caret) && caret.origin.is(paragraph)) || 8526 (vl(caret) && ic(caret.getFlipped())) 8527 ) { 8528 candidateCaret = null; 8529 } else if (Tl(caret) && caret.getParentAtCaret().is(paragraph)) { 8530 candidateCaret = caret; 8531 } else { 8532 const childCaret = $paragraphChildCaretAtInwardEdge(caret, paragraph); 8533 candidateCaret = childCaret ? Zl(childCaret) : null; 8534 } 8535 8536 if (candidateCaret && sr(candidateCaret.origin)) { 8537 return $candidateUnlessShadowed(candidateCaret) 8538 } else { 8539 return null 8540 } 8541} 8542 8543function $candidateUnlessShadowed(candidateCaret) { 8544 const outward = candidateCaret.getNodeAtCaret(); 8545 return sr(outward) ? null : candidateCaret.origin 8546} 8547 8548function $outwardLineBreak(caret, paragraph) { 8549 const startCaret = $outwardWalkStartCaret(caret, paragraph); 8550 if (!startCaret) return null 8551 8552 for (const { origin } of startCaret) { 8553 if (!origin.getParent().is(paragraph)) break 8554 if (sr(origin)) return origin 8555 } 8556 return null 8557} 8558 8559function $outwardWalkStartCaret(caret, paragraph) { 8560 if (caret.getParentAtCaret().is(paragraph)) { 8561 return caret 8562 } else { 8563 return $paragraphChildCaretContaining(caret, paragraph) 8564 } 8565} 8566 8567function $paragraphChildCaretContaining(caret, paragraph) { 8568 let cursor = caret.getSiblingCaret(); 8569 while (cursor && !cursor.origin.getParent()?.is(paragraph)) { 8570 cursor = cursor.getParentCaret(); 8571 } 8572 return cursor?.origin.getParent()?.is(paragraph) ? cursor : null 8573} 8574 8575// Only succeeds when the cursor is flush against the inward edge of every 8576// ancestor between itself and the paragraph child. 8577function $paragraphChildCaretAtInwardEdge(caret, paragraph) { 8578 let cursor = caret.getSiblingCaret(); 8579 while (cursor && !cursor.origin.getParent()?.is(paragraph)) { 8580 if (cursor.getNodeAtCaret()) return null 8581 cursor = cursor.getParentCaret(); 8582 } 8583 return cursor?.origin.getParent()?.is(paragraph) ? cursor : null 8584} 8585 8586function $splitAroundLineBreak(lineBreakCaret) { 8587 let outer = null; 8588 8589 if (lineBreakCaret.getNodeAtCaret() === null) { 8590 lineBreakCaret.origin.remove(); 8591 } else { 8592 const lineBreak = lineBreakCaret.origin; 8593 const splitCaret = oc(Zl(lineBreakCaret), "next"); 8594 8595 fc(splitCaret); 8596 outer = lineBreak.getTopLevelElement(); 8597 lineBreak.remove(); 8598 } 8599 8600 return outer 8601} 8602 8603// Lexical's RangeSelection.insertNodes/insertLineBreak require every selection point to have a 8604// block ancestor with inline children. An element point on a container of block nodes â e.g. a 8605// quote holding paragraphs â has none, so Lexical throws invariant #211 or #212. This detects 8606// such a point so callers can descend it to a leaf before inserting. 8607function $isPointOnBlockContainer(point) { 8608 if (point.type !== "element") return false 8609 8610 const firstChild = point.getNode().getFirstChild(); 8611 return (Wi(firstChild) || ji(firstChild)) && !firstChild.isInline() 8612} 8613 8614function $hasPointOnBlockContainer(selection) { 8615 return Fr(selection) && 8616 [ selection.anchor, selection.focus ].some($isPointOnBlockContainer) 8617} 8618 8619// Descend any block-container element point in the selection to a leaf position, so a subsequent 8620// Lexical insert (insertNodes, insertLineBreak, INSERT_PARAGRAPH) doesn't throw invariant #211/#212. 8621function $normalizeBlockContainerSelection(selection = Qr()) { 8622 if (!$hasPointOnBlockContainer(selection)) return false 8623 8624 St$3(selection); 8625 return true 8626} 8627 8628function $consecutiveSiblingGroups(blocks) { 8629 const ordered = [ ...blocks ].sort((a, b) => a.getIndexWithinParent() - b.getIndexWithinParent()); 8630 const groups = []; 8631 8632 for (const block of ordered) { 8633 const lastGroup = groups.at(-1); 8634 const previous = lastGroup?.at(-1); 8635 8636 if (previous && previous.getParent().is(block.getParent()) && previous.getNextSibling()?.is(block)) { 8637 lastGroup.push(block); 8638 } else { 8639 groups.push([ block ]); 8640 } 8641 } 8642 8643 return groups 8644} 8645 8646// Payload: Record<nodeKey, { patch?, replace? }> 8647// - patch: plain object, shallow-merged into the existing node's properties 8648// - replace: a LexicalNode instance that replaces the node 8649const REWRITE_HISTORY_COMMAND = re$5("REWRITE_HISTORY_COMMAND"); 8650 8651class RewritableHistoryExtension extends LexxyExtension { 8652 #historyState = null 8653 8654 get lexicalExtension() { 8655 return dc({ 8656 name: "lexxy/rewritable-history", 8657 dependencies: [ O$1 ], 8658 register: (editor, _config, state) => { 8659 const historyOutput = state.getDependency(O$1).output; 8660 this.#historyState = historyOutput.historyState.value; 8661 8662 return editor.registerCommand( 8663 REWRITE_HISTORY_COMMAND, 8664 (rewrites) => this.#rewriteHistory(rewrites), 8665 ro 8666 ) 8667 } 8668 }) 8669 } 8670 8671 get historyState() { 8672 return this.#historyState 8673 } 8674 8675 get #allHistoryEntries() { 8676 const entries = Array.from(this.#historyState.undoStack); 8677 if (this.#historyState.current) entries.push(this.#historyState.current); 8678 return entries.concat(this.#historyState.redoStack) 8679 } 8680 8681 #rewriteHistory(rewrites) { 8682 this.#applyRewritesImmediatelyToCurrentState(rewrites); 8683 this.#applyRewritesToHistory(rewrites); 8684 8685 return true 8686 } 8687 8688 #applyRewritesImmediatelyToCurrentState(rewrites) { 8689 Zs().update(() => { 8690 for (const [ nodeKey, { patch, replace } ] of Object.entries(rewrites)) { 8691 const node = Yo(nodeKey); 8692 if (!node) continue 8693 8694 if (patch) Object.assign(node.getWritable(), patch); 8695 if (replace) node.replace(replace); 8696 } 8697 }, { discrete: true, tag: this.#getBackgroundUpdateTags() }); 8698 } 8699 8700 #applyRewritesToHistory(rewrites) { 8701 const nodeKeys = Object.keys(rewrites); 8702 8703 for (const entry of this.#allHistoryEntries) { 8704 if (!this.#entryHasSomeKeys(entry, nodeKeys)) continue 8705 8706 const editorState = entry.editorState = safeCloneEditorState(entry.editorState); 8707 8708 for (const [ nodeKey, { patch, replace } ] of Object.entries(rewrites)) { 8709 const node = editorState._nodeMap.get(nodeKey); 8710 if (!node) continue 8711 8712 if (patch) { 8713 this.#patchNodeInEditorState(editorState, node, patch); 8714 } else if (replace) { 8715 this.#replaceNodeInEditorState(editorState, node, replace); 8716 } 8717 } 8718 } 8719 } 8720 8721 #entryHasSomeKeys(entry, nodeKeys) { 8722 return nodeKeys.some(key => entry.editorState._nodeMap.has(key)) 8723 } 8724 8725 #getBackgroundUpdateTags() { 8726 const tags = [ Jn, Yn ]; 8727 if (!isEditorFocused(this.editorElement.editor)) { tags.push(qn); } 8728 return tags 8729 } 8730 8731 #patchNodeInEditorState(editorState, node, patch) { 8732 editorState._nodeMap.set(node.__key, $cloneNodeWithPatch(node, patch)); 8733 } 8734 8735 #replaceNodeInEditorState(editorState, node, replaceWith) { 8736 editorState._nodeMap.set(node.__key, $cloneNodeAdoptingKeys(replaceWith, node)); 8737 } 8738} 8739 8740function $cloneNodeWithPatch(node, patch) { 8741 const clone = il(node); 8742 Object.assign(clone, patch); 8743 return clone 8744} 8745 8746function $cloneNodeAdoptingKeys(node, previousNode) { 8747 const clone = il(node); 8748 clone.__key = previousNode.__key; 8749 clone.__parent = previousNode.__parent; 8750 clone.__prev = previousNode.__prev; 8751 clone.__next = previousNode.__next; 8752 return clone 8753} 8754 8755// EditorState#clone() keeps the same map reference. 8756// A new Map is needed to prevent editing Lexical's internal map 8757// Warning: this bypasses DEV's safety map freezing 8758function safeCloneEditorState(editorState) { 8759 const clone = editorState.clone(); 8760 clone._nodeMap = new Map(editorState._nodeMap); 8761 return clone 8762} 8763 8764const INITIAL_PREVIEW_POLL_DELAY_MS = 3000; 8765const MAX_PREVIEW_POLL_DELAY_MS = 120000; 8766const MAX_PREVIEW_POLL_ATTEMPTS = 20; 8767 8768 8769class ActionTextAttachmentNode extends Ji { 8770 static getType() { 8771 return "action_text_attachment" 8772 } 8773 8774 static clone(node) { 8775 return new ActionTextAttachmentNode({ ...node }, node.__key) 8776 } 8777 8778 static importJSON(serializedNode) { 8779 return new ActionTextAttachmentNode({ ...serializedNode }) 8780 } 8781 8782 static importDOM() { 8783 return { 8784 [this.TAG_NAME]: () => { 8785 return { 8786 conversion: (attachment) => ({ 8787 node: new ActionTextAttachmentNode({ 8788 sgid: attachment.getAttribute("sgid"), 8789 src: attachment.getAttribute("url"), 8790 previewable: attachment.getAttribute("previewable"), 8791 altText: attachment.getAttribute("alt"), 8792 caption: attachment.getAttribute("caption"), 8793 contentType: attachment.getAttribute("content-type"), 8794 fileName: attachment.getAttribute("filename"), 8795 fileSize: attachment.getAttribute("filesize"), 8796 width: attachment.getAttribute("width"), 8797 height: attachment.getAttribute("height") 8798 }) 8799 }), priority: 1 8800 } 8801 }, 8802 "img": () => { 8803 return { 8804 conversion: (img) => { 8805 const fileName = extractFileName(img.getAttribute("src") ?? ""); 8806 return { 8807 node: new ActionTextAttachmentNode({ 8808 src: img.getAttribute("src"), 8809 fileName: fileName, 8810 caption: img.getAttribute("alt") || "", 8811 contentType: "image/*", 8812 width: img.getAttribute("width"), 8813 height: img.getAttribute("height") 8814 }) 8815 } 8816 }, priority: 1 8817 } 8818 }, 8819 "video": () => { 8820 return { 8821 conversion: (video) => { 8822 const videoSource = video.getAttribute("src") || video.querySelector("source")?.src; 8823 const fileName = videoSource?.split("/")?.pop(); 8824 const contentType = video.querySelector("source")?.getAttribute("content-type") || "video/*"; 8825 8826 return { 8827 node: new ActionTextAttachmentNode({ 8828 src: videoSource, 8829 fileName: fileName, 8830 contentType: contentType 8831 }) 8832 } 8833 }, priority: 1 8834 } 8835 } 8836 } 8837 } 8838 8839 static get TAG_NAME() { 8840 return Lexxy.global.get("attachmentTagName") 8841 } 8842 8843 constructor({ tagName, sgid, src, previewSrc, previewable, previewStatusUrl, pendingPreview, altText, caption, contentType, fileName, fileSize, width, height, uploadError }, key) { 8844 super(key); 8845 8846 this.tagName = tagName || ActionTextAttachmentNode.TAG_NAME; 8847 this.sgid = sgid; 8848 this.src = src; 8849 this.previewSrc = previewSrc; 8850 this.previewable = parseBoolean(previewable); 8851 this.previewStatusUrl = previewStatusUrl; 8852 this.pendingPreview = pendingPreview; 8853 this.altText = altText || ""; 8854 this.caption = caption || ""; 8855 this.contentType = contentType || ""; 8856 this.fileName = fileName || ""; 8857 this.fileSize = fileSize; 8858 this.width = width; 8859 this.height = height; 8860 this.uploadError = uploadError; 8861 8862 this.editor = Zs(); 8863 } 8864 8865 createDOM() { 8866 if (this.uploadError) return this.createDOMForError() 8867 if (this.pendingPreview) return this.#createDOMForPendingPreview() 8868 8869 const figure = this.createAttachmentFigure(); 8870 8871 if (this.isPreviewableAttachment) { 8872 figure.appendChild(this.#createDOMForImage()); 8873 figure.appendChild(this.#createEditableCaption()); 8874 } else if (this.isVideo) { 8875 figure.appendChild(this.#createDOMForFile()); 8876 figure.appendChild(this.#createEditableCaption()); 8877 } else { 8878 figure.appendChild(this.#createDOMForFile()); 8879 figure.appendChild(this.#createDOMForNotImage()); 8880 } 8881 8882 return figure 8883 } 8884 8885 updateDOM(prevNode, dom) { 8886 if (this.uploadError !== prevNode.uploadError) return true 8887 8888 const caption = dom.querySelector("figcaption textarea"); 8889 if (caption && this.caption) { 8890 caption.value = this.caption; 8891 } 8892 8893 return false 8894 } 8895 8896 getTextContent() { 8897 return `[${this.caption || this.fileName}]\n\n` 8898 } 8899 8900 isInline() { 8901 return this.isAttached() && !this.getParent().is(Ls(this)) 8902 } 8903 8904 exportDOM() { 8905 const attachment = createElement(this.tagName, { 8906 sgid: this.sgid, 8907 previewable: this.previewable || null, 8908 url: this.src, 8909 alt: this.altText, 8910 caption: this.caption, 8911 "content-type": this.contentType, 8912 filename: this.fileName, 8913 filesize: this.fileSize, 8914 width: this.width, 8915 height: this.height, 8916 presentation: "gallery" 8917 }); 8918 8919 return { element: attachment } 8920 } 8921 8922 exportJSON() { 8923 return { 8924 type: "action_text_attachment", 8925 version: 1, 8926 tagName: this.tagName, 8927 sgid: this.sgid, 8928 src: this.src, 8929 previewable: this.previewable, 8930 previewStatusUrl: this.previewStatusUrl, 8931 pendingPreview: this.pendingPreview, 8932 altText: this.altText, 8933 caption: this.caption, 8934 contentType: this.contentType, 8935 fileName: this.fileName, 8936 fileSize: this.fileSize, 8937 width: this.width, 8938 height: this.height 8939 } 8940 } 8941 8942 decorate() { 8943 return null 8944 } 8945 8946 createDOMForError() { 8947 const figure = this.createAttachmentFigure(); 8948 figure.classList.add("attachment--error"); 8949 figure.appendChild(createElement("div", { innerText: `Error uploading ${this.fileName || "file"}` })); 8950 return figure 8951 } 8952 8953 createAttachmentFigure(previewable = this.isPreviewableAttachment) { 8954 const figure = createAttachmentFigure(this.contentType, previewable, this.fileName); 8955 figure.draggable = true; 8956 figure.dataset.lexicalNodeKey = this.__key; 8957 8958 const deleteButton = createElement("lexxy-node-delete-button"); 8959 figure.appendChild(deleteButton); 8960 8961 return figure 8962 } 8963 8964 get isPreviewableAttachment() { 8965 return this.isPreviewableImage || this.previewable 8966 } 8967 8968 get isPreviewableImage() { 8969 return isPreviewableImage(this.contentType) 8970 } 8971 8972 get isVideo() { 8973 return this.contentType.startsWith("video/") 8974 } 8975 8976 #createDOMForPendingPreview() { 8977 const figure = this.createAttachmentFigure(false); 8978 figure.appendChild(this.#createDOMForFile()); 8979 figure.appendChild(this.#createDOMForNotImage()); 8980 this.#pollForPreview(figure); 8981 return figure 8982 } 8983 8984 patchAndRewriteHistory(patch) { 8985 this.editor.dispatchCommand(REWRITE_HISTORY_COMMAND, { 8986 [this.getKey()]: { patch } 8987 }); 8988 } 8989 8990 replaceAndRewriteHistory(node) { 8991 this.editor.dispatchCommand(REWRITE_HISTORY_COMMAND, { 8992 [this.getKey()]: { replace: node } 8993 }); 8994 } 8995 8996 #createDOMForImage(options = {}) { 8997 const initialSrc = this.previewSrc || this.src; 8998 const img = createElement("img", { src: initialSrc, draggable: false, alt: this.altText, ...this.#imageDimensions, ...options }); 8999 9000 if (this.previewable && !this.isPreviewableImage) { 9001 img.onerror = () => this.#swapPreviewToFileDOM(img); 9002 } 9003 9004 if (this.previewSrc) { 9005 this.#preloadAndSwapSrc(img); 9006 } 9007 9008 const container = createElement("div", { className: "attachment__container" }); 9009 container.appendChild(img); 9010 return container 9011 } 9012 9013 #preloadAndSwapSrc(img) { 9014 const previewSrc = this.previewSrc; 9015 const serverImage = new Image(); 9016 9017 serverImage.onload = () => this.#handleImageLoaded(img, previewSrc); 9018 serverImage.onerror = () => this.#handleImageLoadError(previewSrc); 9019 serverImage.src = this.src; 9020 } 9021 9022 #handleImageLoaded(img, previewSrc) { 9023 img.src = this.src; 9024 this.patchAndRewriteHistory({ previewSrc: null }); 9025 this.#revokePreviewSrc(previewSrc); 9026 } 9027 9028 #handleImageLoadError(previewSrc) { 9029 this.patchAndRewriteHistory({ 9030 previewSrc: null, 9031 uploadError: true 9032 }); 9033 this.#revokePreviewSrc(previewSrc); 9034 } 9035 9036 #revokePreviewSrc(previewSrc) { 9037 if (previewSrc?.startsWith("blob:")) URL.revokeObjectURL(previewSrc); 9038 } 9039 9040 #swapPreviewToFileDOM(img) { 9041 const figure = img.closest("figure.attachment"); 9042 if (!figure) return 9043 9044 this.#swapFigureContent(figure, "attachment--preview", "attachment--file", () => { 9045 figure.appendChild(this.#createDOMForFile()); 9046 figure.appendChild(this.#createDOMForNotImage()); 9047 }); 9048 } 9049 9050 // While the file-icon is shown, watch for the preview to become ready. 9051 // With a status URL, poll it (2xx = processing, anything else = ready). 9052 // Without one, preload the preview URL once and swap on load. 9053 #pollForPreview(figure) { 9054 if (this.previewStatusUrl) { 9055 this.#waitForPreviewByPollingStatus(figure); 9056 } else { 9057 this.#waitForPreviewByPreloadingImage(figure); 9058 } 9059 } 9060 9061 #waitForPreviewByPollingStatus(figure) { 9062 let attempt = 0; 9063 9064 const tryStatus = async () => { 9065 if (!this.editor.read(() => this.isAttached())) return 9066
9067 try { 9068 // redirect: "manual" prevents fetch from transparently following a 9069 // 3xx response â without it, a status endpoint that redirected to, 9070 // say, the preview URL would resolve to a 200 and look like 9071 // "still processing." The contract is "any non-2xx means done." 9072 const response = await fetch(this.previewStatusUrl, { credentials: "include", redirect: "manual" }); 9073 9074 if (!this.editor.read(() => this.isAttached())) return 9075 9076 if (response.ok) { 9077 retry(); 9078 } else { 9079 this.#swapToPreviewDOM(figure, this.src); 9080 } 9081 } catch { 9082 retry(); 9083 } 9084 }; 9085 9086 const retry = () => { 9087 attempt++; 9088 if (attempt < MAX_PREVIEW_POLL_ATTEMPTS && this.editor.read(() => this.isAttached())) { 9089 const delay = Math.min(2000 * Math.pow(1.5, attempt), MAX_PREVIEW_POLL_DELAY_MS); 9090 setTimeout(tryStatus, delay); 9091 } 9092 }; 9093 9094 // Give the server time to start processing before the first attempt 9095 setTimeout(tryStatus, INITIAL_PREVIEW_POLL_DELAY_MS); 9096 } 9097 9098 #waitForPreviewByPreloadingImage(figure) { 9099 const img = new Image(); 9100 img.onload = () => { 9101 if (!this.editor.read(() => this.isAttached())) return 9102 this.#swapToPreviewDOM(figure, this.src); 9103 }; 9104 img.onerror = () => { 9105 // Clear pendingPreview so undo/redo or any JSON round-trip doesn't 9106 // re-enter the pending flow and issue another fetch. The file icon 9107 // stays as the stable fallback. 9108 if (!this.editor.read(() => this.isAttached())) return 9109 this.patchAndRewriteHistory({ pendingPreview: false }); 9110 }; 9111 img.src = this.src; 9112 } 9113 9114 #swapToPreviewDOM(figure, previewSrc) { 9115 this.#swapFigureContent(figure, "attachment--file", "attachment--preview", () => { 9116 const img = createElement("img", { src: previewSrc, draggable: false, alt: this.altText }); 9117 img.onerror = () => this.#swapPreviewToFileDOM(img); 9118 const container = createElement("div", { className: "attachment__container" }); 9119 container.appendChild(img); 9120 figure.appendChild(container); 9121 figure.appendChild(this.#createEditableCaption()); 9122 }); 9123 9124 this.patchAndRewriteHistory({ pendingPreview: false }); 9125 } 9126 9127 #swapFigureContent(figure, fromClass, toClass, renderContent) { 9128 figure.className = figure.className.replace(fromClass, toClass); 9129 9130 for (const child of [ ...figure.querySelectorAll(".attachment__container, .attachment__icon, figcaption") ]) { 9131 child.remove(); 9132 } 9133 9134 renderContent(); 9135 } 9136 9137 get #imageDimensions() { 9138 if (this.width && this.height) { 9139 return { width: this.width, height: this.height } 9140 } else { 9141 return {} 9142 } 9143 } 9144 9145 #createDOMForFile() { 9146 const extension = this.fileName ? this.fileName.split(".").pop().toLowerCase() : "unknown"; 9147 return createElement("span", { className: "attachment__icon", textContent: `${extension}` }) 9148 } 9149 9150 #createDOMForNotImage() { 9151 const figcaption = createElement("figcaption", { className: "attachment__caption" }); 9152 9153 const nameTag = createElement("strong", { className: "attachment__name", textContent: this.caption || this.fileName }); 9154 9155 figcaption.appendChild(nameTag); 9156 9157 if (this.fileSize) { 9158 const sizeSpan = createElement("span", { className: "attachment__size", textContent: bytesToHumanSize(this.fileSize) }); 9159 figcaption.appendChild(sizeSpan); 9160 } 9161 9162 return figcaption 9163 } 9164 9165 #createEditableCaption() { 9166 const caption = createElement("figcaption", { className: "attachment__caption" }); 9167 const input = createElement("textarea", { 9168 value: this.caption, 9169 placeholder: this.fileName, 9170 rows: "1" 9171 }); 9172 9173 input.addEventListener("focusin", () => input.placeholder = "Add caption..."); 9174 input.addEventListener("blur", (event) => this.#handleCaptionInputBlurred(event)); 9175 input.addEventListener("keydown", (event) => this.#handleCaptionInputKeydown(event)); 9176 input.addEventListener("copy", (event) => event.stopPropagation()); 9177 input.addEventListener("cut", (event) => event.stopPropagation()); 9178 input.addEventListener("paste", (event) => event.stopPropagation()); 9179 9180 caption.appendChild(input); 9181 9182 return caption 9183 } 9184 9185 #handleCaptionInputBlurred(event) { 9186 this.#updateCaptionValueFromInput(event.target); 9187 } 9188 9189 #updateCaptionValueFromInput(input) { 9190 input.placeholder = this.fileName; 9191 this.editor.update(() => { 9192 this.getWritable().caption = input.value; 9193 }); 9194 } 9195 9196 #handleCaptionInputKeydown(event) { 9197 if (event.key === "Enter") { 9198 event.preventDefault(); 9199 event.target.blur(); 9200 9201 this.editor.update(() => { 9202 // Place the cursor after the current image 9203 this.selectNext(0, 0); 9204 }, { 9205 tag: Jn 9206 }); 9207 } 9208 9209 // Stop all keydown events from bubbling to the Lexical root element. 9210 // The caption textarea is outside Lexical's content model and should 9211 // handle its own keyboard events natively (Ctrl+A, Ctrl+C, Ctrl+X, etc.). 9212 event.stopPropagation(); 9213 } 9214} 9215 9216function $createActionTextAttachmentNode(...args) { 9217 return new ActionTextAttachmentNode(...args) 9218} 9219 9220function $isActionTextAttachmentNode(node) { 9221 return node instanceof ActionTextAttachmentNode 9222} 9223 9224function filterDisallowedAttachmentNodes(nodes, editorElement) { 9225 return nodes 9226 .filter(node => !isDisallowedAttachment(node, editorElement)) 9227 .map(node => { 9228 Ht$3([ node ], descendant => isDisallowedAttachment(descendant, editorElement)) 9229 .forEach(descendant =>
9229 descendant.remove()); 9230 return node 9231 }) 9232} 9233 9234function isDisallowedAttachment(node, editorElement) { 9235 const isAttachmentNode = 9236 node instanceof CustomActionTextAttachmentNode || 9237 node instanceof ActionTextAttachmentNode; 9238 return isAttachmentNode && 9239 !editorElement.permitsAttachmentContentType(node.contentType) 9240} 9241 9242// Replaces inline `data:image/...` attachments with upload nodes that flow through the normal 9243// file upload pipeline. 9244// 9245// Without this step, pasted-from-Google-Docs-style content lands in the editor with the entire 9246// base64 image embedded in the attachment's `src`, which then persists into the saved HTML and 9247// bloats the stored document. 9248// 9249// Each conversion dispatches the cancelable `lexxy:file-accept` event so the host's allowlist (and 9250// any other listener) can refuse the synthesized File before it's accepted into the upload 9251// pipeline; on refusal, the node is dropped silently â matching how `Contents#uploadFiles` handles 9252// file-picker rejections. 9253function $convertInlineImageDataURIs(nodes, editorElement) { 9254 const topLevel = nodes 9255 .map(node => isInlineImageDataURIAttachment(node) ? $tryCreateUploadFromDataURI(node, editorElement) : node) 9256 .filter(node => node !== null); 9257 9258 for (const node of topLevel) { 9259 for (const desc of Ht$3([ node ], isInlineImageDataURIAttachment)) { 9260 const upload = $tryCreateUploadFromDataURI(desc, editorElement); 9261 if (upload) { 9262 desc.replace(upload); 9263 } else { 9264 desc.remove(); 9265 } 9266 } 9267 } 9268 9269 return topLevel 9270} 9271 9272function isInlineImageDataURIAttachment(node) { 9273 return node instanceof ActionTextAttachmentNode && 9274 /^data:image\/[^,]*;base64,/i.test(node.src ?? "") 9275} 9276 9277function $tryCreateUploadFromDataURI(node, editorElement) { 9278 const file = dataURIToFile(node.src); 9279 if (file && editorElement.acceptsFile(file)) { 9280 return editorElement.contents.$createUploadNode(file) 9281 } 9282 return null 9283} 9284 9285function dataURIToFile(dataURI) { 9286 try { 9287 const [ header, data ] = dataURI.split(","); 9288 9289 // https://datatracker.ietf.org/doc/html/rfc6838#section-4.2 9290 const mimeType = header.match(/^data:(image\/[A-Za-z0-9][A-Za-z0-9!#$&\-^_.+]*)/)?.[1]; 9291 if (mimeType) { 9292 const bytes = Uint8Array.from(atob(data), (c) => c.charCodeAt(0)); 9293 const extension = mimeTypeToExtension(mimeType) ?? "png"; 9294 return new File([ bytes ], `pasted-image-${Date.now()}.${extension}`, { type: mimeType }) 9295 } else { 9296 return null 9297 } 9298 } catch { 9299 return null 9300 } 9301} 9302 9303/** 9304 * Copyright (c) Meta Platforms, Inc. and affiliates. 9305 * 9306 * This source code is licensed under the MIT license found in the 9307 * LICENSE file in the root directory of this source tree. 9308 * 9309 */ 9310 9311function 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}
9311const 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();
9311return 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} 9312 9313/** 9314 * Copyright (c) Meta Platforms, Inc. and affiliates. 9315 * 9316 * This source code is licensed under the MIT license found in the 9317 * LICENSE file in the root directory of this source tree. 9318 * 9319 */ 9320 9321function 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}}
9321async 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>
93210){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)} 9322 9323/** 9324 * Copyright (c) Meta Platforms, Inc. and affiliates. 9325 * 9326 * This source code is licensed under the MIT license found in the 9327 * LICENSE file in the root directory of this source tree. 9328 * 9329 */ 9330 9331const o=Q$1,a=V$1,r=ie$1,L$1=he$1; 9332 9333/** 9334 * Copyright (c) Meta Platforms, Inc. and affiliates. 9335 * 9336 * This source code is licensed under the MIT license found in the 9337 * LICENSE file in the root directory of this source tree. 9338 * 9339 */ 9340 9341function 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"}
9341,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;
9341for(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))} 9342 9343class HorizontalDividerNode extends Ji { 9344 static getType() { 9345 return "horizontal_divider" 9346 } 9347 9348 static clone(node) { 9349 return new HorizontalDividerNode(node.__key) 9350 } 9351 9352 static importJSON(serializedNode) { 9353 return new HorizontalDividerNode() 9354 } 9355 9356 static importDOM() { 9357 return { 9358 "hr": (hr) => { 9359 return { 9360 conversion: () => ({ 9361 node: new HorizontalDividerNode() 9362 }), 9363 priority: 1 9364 } 9365 } 9366 } 9367 } 9368 9369 constructor(key) { 9370 super(key); 9371 } 9372 9373 createDOM() { 9374 const figure = createElement("figure", { className: "horizontal-divider" }); 9375 const hr = createElement("hr"); 9376 9377 figure.appendChild(hr); 9378 9379 const deleteButton = createElement("lexxy-node-delete-button"); 9380 figure.appendChild(deleteButton); 9381 9382 return figure 9383 } 9384 9385 updateDOM() { 9386 return true 9387 } 9388 9389 getTextContent() { 9390 return "â\n\n" 9391 } 9392 9393 isInline() { 9394 return false 9395 } 9396 9397 exportDOM() { 9398 const hr = createElement("hr"); 9399 return { element: hr } 9400 } 9401 9402 exportJSON() { 9403 return { 9404 type: "horizontal_divider", 9405 version: 1 9406 } 9407 } 9408 9409 decorate() { 9410 return null 9411 } 9412} 9413 9414const HORIZONTAL_DIVIDER = { 9415 dependencies: [ HorizontalDividerNode ], 9416 export: (node) => { 9417 return node instanceof HorizontalDividerNode ? "---" : null 9418 }, 9419 regExpStart: /^-{3,}\s?$/, 9420 replace: (parentNode, children, match, endMatch, linesInBetween, isImport) => { 9421 const hrNode = new HorizontalDividerNode(); 9422 parentNode.replace(hrNode); 9423 9424 if (!isImport) { 9425 const paragraph = eo(); 9426 hrNode.insertAfter(paragraph); 9427 paragraph.select(); 9428 } 9429 }, 9430 type: "multiline-element" 9431}; 9432 9433const PUNCTUATION_OR_SPACE = /[^\w]/; 9434 9435// Supplements Lexical's built-in registerMarkdownShortcuts to handle the case 9436// where a user types a leading tag before text that already ends with a 9437// trailing tag (e.g. typing ` before `hello`` or ** before **hello**). 9438// 9439// Lexical's markdown shortcut handler only triggers format transformations when 9440// the closing tag is the character just typed. When the opening tag is typed 9441// instead (e.g. typing ` before `hello`` to form ``hello``), the built-in 9442// handler doesn't match because it looks backward from the cursor for an 9443// opening tag, but the cursor is right after it. 9444// 9445// This listener detects that scenario for ALL text format transformers 9446// (backtick, bold, italic, strikethrough, etc.) and applies the appropriate 9447// format. 9448function registerMarkdownLeadingTagHandler(editor, transformers) { 9449 const textFormatTransformers = transformers 9450 .filter(t => t.type === "text-format") 9451 .sort((a, b) => b.tag.length - a.tag.length); // Longer tags first 9452 9453 return editor.registerUpdateListener(({ tags, dirtyLeaves, editorState, prevEditorState }) => { 9454 if (tags.has("historic") || tags.has("collaboration")) return 9455 if (editor.isComposing()) return 9456 9457 const selection = editorState.read(Qr); 9458 const prevSelection = prevEditorState.read(Qr); 9459 9460 if (!Fr(prevSelection) || !Fr(selection) || !selection.isCollapsed()) return 9461 9462 const anchorKey = selection.anchor.key; 9463 const anchorOffset = selection.anchor.offset; 9464 9465 if (!dirtyLeaves.has(anchorKey)) return 9466 9467 const anchorNode = editorState.read(() => Yo(anchorKey)); 9468 if (!Tr(anchorNode)) return 9469 9470 // Only trigger when cursor moved forward (typing) 9471 const prevOffset = prevSelection.anchor.key === anchorKey ? prevSelection.anchor.offset : 0; 9472 if (anchorOffset <= prevOffset) return 9473 9474 const textContent = editorState.read(() => anchorNode.getTextContent()); 9475 9476 // Try each transformer, longest tags first 9477 for (const transformer of textFormatTransformers) { 9478 const tag = transformer.tag; 9479 const tagLen = tag.length; 9480 9481 // The typed characters must end at the cursor position and form the opening tag 9482 const openTagStart = anchorOffset - tagLen; 9483 if (openTagStart < 0) continue 9484 9485 const candidateOpenTag = textContent.slice(openTagStart, anchorOffset); 9486 if (candidateOpenTag !== tag) continue 9487 9488 // Disambiguate from longer tags: if the character before the opening tag 9489 // is the same as the tag character, this might be part of a longer tag 9490 // (e.g. seeing `*` when the user is actually typing `**`) 9491 const tagChar = tag[0]; 9492 if (openTagStart > 0 && textContent[openTagStart - 1] === tagChar) continue 9493 9494 // Check intraword constraint: if intraword is false, the character before 9495 // the opening tag must be a space, punctuation, or the start of the text 9496 if (transformer.intraword === false && openTagStart > 0) { 9497 const beforeChar = textContent[openTagStart - 1]; 9498 if (beforeChar && !PUNCTUATION_OR_SPACE.test(beforeChar)) continue 9499 } 9500 9501 // Search forward for a closing tag in the same text node 9502 const searchStart = anchorOffset; 9503 const closeTagIndex = textContent.indexOf(tag, searchStart); 9504 if (closeTagIndex < 0) continue 9505 9506 // Disambiguate closing tag from longer tags: if the character r
vendor: 4,204 bytes, lines 9506-9626
9506ight after 9507 // the closing tag is the same as the tag character, skip 9508 // (e.g. `*hello**` â the first `*` at index 6 is part of `**`) 9509 if (textContent[closeTagIndex + tagLen] === tagChar) continue 9510 9511 // Also check if the character before the closing tag start is the same 9512 // tag character (e.g. the closing tag might be a suffix of a longer sequence) 9513 if (closeTagIndex > 0 && textContent[closeTagIndex - 1] === tagChar) continue 9514 9515 // There must be content between the tags (not just empty or whitespace-adjacent) 9516 const innerStart = anchorOffset; 9517 const innerEnd = closeTagIndex; 9518 if (innerEnd <= innerStart) continue 9519 9520 // No space immediately after opening tag 9521 if (textContent[innerStart] === " ") continue 9522 9523 // No space immediately before closing tag 9524 if (textContent[innerEnd - 1] === " ") continue 9525 9526 // Check intraword constraint for closing tag 9527 if (transformer.intraword === false) { 9528 const afterCloseChar = textContent[closeTagIndex + tagLen]; 9529 if (afterCloseChar && !PUNCTUATION_OR_SPACE.test(afterCloseChar)) continue 9530 } 9531 9532 editor.update(() => { 9533 const node = Yo(anchorKey); 9534 if (!node || !Tr(node)) return 9535 9536 const parent = node.getParent(); 9537 if (parent === null || W$1(parent)) return 9538 9539 $applyFormatFromLeadingTag(node, openTagStart, transformer); 9540 }); 9541 9542 break // Only apply the first (longest) matching transformer 9543 } 9544 }) 9545} 9546 9547function $applyFormatFromLeadingTag(anchorNode, openTagStart, transformer) { 9548 const tag = transformer.tag; 9549 const tagLen = tag.length; 9550 const textContent = anchorNode.getTextContent(); 9551 9552 const innerStart = openTagStart + tagLen; 9553 const closeTagIndex = textContent.indexOf(tag, innerStart); 9554 if (closeTagIndex < 0) return 9555 9556 const inner = textContent.slice(innerStart, closeTagIndex); 9557 if (inner.length === 0) return 9558 9559 // Remove both tags and apply format 9560 const before = textContent.slice(0, openTagStart); 9561 const after = textContent.slice(closeTagIndex + tagLen); 9562 9563 anchorNode.setTextContent(before + inner + after); 9564 9565 const nextSelection = qr(); 9566 es(nextSelection); 9567 9568 // Select the inner text to apply formatting 9569 nextSelection.anchor.set(anchorNode.getKey(), openTagStart, "text"); 9570 nextSelection.focus.set(anchorNode.getKey(), openTagStart + inner.length, "text"); 9571 9572 for (const format of transformer.format) { 9573 if (!nextSelection.hasFormat(format)) { 9574 nextSelection.formatText(format); 9575 } 9576 } 9577 9578 // Collapse selection to end of formatted text and clear the format 9579 // so subsequent typing is plain text 9580 nextSelection.anchor.set(nextSelection.focus.key, nextSelection.focus.offset, nextSelection.focus.type); 9581 9582 for (const format of transformer.format) { 9583 if (nextSelection.hasFormat(format)) { 9584 nextSelection.toggleFormat(format); 9585 } 9586 } 9587} 9588 9589var theme = { 9590 text: { 9591 bold: "lexxy-content__bold", 9592 italic: "lexxy-content__italic", 9593 strikethrough: "lexxy-content__strikethrough", 9594 underline: "lexxy-content__underline", 9595 highlight: "lexxy-content__highlight" 9596 }, 9597 tableCellHeader: "lexxy-content__table-cell--header", 9598 tableCellSelected: "lexxy-content__table-cell--selected", 9599 tableSelection: "lexxy-content__table--selection", 9600 tableScrollableWrapper: "lexxy-content__table-wrapper", 9601 tableCellHighlight: "lexxy-content__table-cell--highlight", 9602 tableCellFocus: "lexxy-content__table-cell--focus", 9603 list: { 9604 nested: { 9605 listitem: "lexxy-nested-listitem", 9606 } 9607 }, 9608 codeHighlight: { 9609 addition: "code-token__selector", 9610 atrule: "code-token__attr", 9611 attr: "code-token__attr", 9612 "attr-name": "code-token__attr", 9613 "attr-value": "code-token__selector", 9614 boolean: "code-token__property", 9615 bold: "code-token__variable", 9616 builtin: "code-token__selector", 9617 cdata: "code-token__comment", 9618 char: "code-token__selector", 9619 class: "code-token__function", 9620 "class-name": "code-token__function", 9621 color: "code-token__property", 9622 comment: "code-token__comment", 9623 constant: "code-token__property", 9624 coord: "code-token__comment", 9625 decorator: "code-token__function", 9626 deleted: "code-token__operator",
9627 deletion: "code-token__operator", 9628 directive: "code-token__attr", 9629 "directive-hash": "code-token__property", 9630 doctype: "code-token__comment", 9631 entity: "code-token__operator", 9632 function: "code-token__function", 9633 hexcode: "code-token__property", 9634 important: "code-token__function", 9635 inserted: "code-token__selector", 9636 italic: "code-token__comment", 9637 keyword: "code-token__attr", 9638 line: "code-token__selector", 9639 namespace: "code-token__variable", 9640 number: "code-token__property", 9641 macro: "code-token__function", 9642 operator: "code-token__operator", 9643 parameter: "code-token__variable", 9644 prolog: "code-token__comment", 9645 property: "code-token__property", 9646 punctuation: "code-token__punctuation", 9647 "raw-string": "code-token__operator", 9648 regex: "code-token__variable", 9649 script: "code-token__function", 9650 selector: "code-token__selector", 9651 string: "code-token__selector", 9652 style: "code-token__function", 9653 symbol: "code-token__property", 9654 tag: "code-token__property", 9655 title: "code-token__function", 9656 "type-definition": "code-token__function", 9657 url: "code-token__operator", 9658 variable: "code-token__variable", 9659 } 9660}; 9661 9662class UploadRequests { 9663 #requestsByKey = new Map() 9664 9665 track(key, request) { 9666 this.#requestsByKey.set(key, request); 9667 } 9668 9669 forget(key) { 9670 this.#requestsByKey.delete(key); 9671 } 9672 9673 abort(key) { 9674 const request = this.#requestsByKey.get(key); 9675 if (request) { 9676 this.#requestsByKey.delete(key); 9677 request.abort(); 9678 } 9679 } 9680 9681 clear() { 9682 this.#requestsByKey.clear(); 9683 } 9684} 9685 9686/** 9687 * Copyright (c) Meta Platforms, Inc. and affiliates. 9688 * 9689 * This source code is licensed under the MIT license found in the 9690 * LICENSE file in the root directory of this source tree. 9691 * 9692 */ 9693 9694const 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}
9694getBackgroundColor(){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)}
9694function 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&>(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 9694
9694We$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());}}
9694function 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}
9694$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();
9694t.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(()=>
9694{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);}}
9694else "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;
9694const 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;
9694if(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;
9694const[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);
9694if(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)=>
9694s.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;
9694return 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}
9694=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))} 9695 9696// Shared, strictly-contained element used to attach ephemeral nodes when we 9697// need to read computed styles (e.g. canonicalizing style values, resolving 9698// CSS custom properties). The container is created once and attached to 9699// `document.body` once; subsequent child mutations happen *inside* the 9700// contained subtree so they do not invalidate style on the rest of the page. 9701// 9702// Without this, `document.body.appendChild(...)` / `element.remove()` calls 9703// forced the browser to re-evaluate every ancestor-dependent selector (`:has()`, 9704// descendant combinators, universal sibling rules) across the document on each 9705// invocation â a 13,000+ element style recalc per call on a typical Basecamp 9706// page. 9707 9708let resolverRoot = null; 9709 9710function styleResolverRoot() { 9711 if (resolverRoot && resolverRoot.isConnected) return resolverRoot 9712 9713 resolverRoot = document.createElement("div"); 9714 resolverRoot.setAttribute("aria-hidden", "true"); 9715 resolverRoot.setAttribute("data-lexxy-style-resolver", ""); 9716 // `contain: strict` (size, layout, paint, style) isolates everything.
vendor: 106,945 bytes, lines 9717-13323
9717 // The root itself paints nothing (visibility hidden), has zero 9718 // geometric impact (position fixed, intrinsic size via contain), and 9719 // never leaks style invalidation to its ancestors. 9720 resolverRoot.style.cssText = "contain: strict; position: fixed; top: 0; left: 0; visibility: hidden; pointer-events: none; width: 0; height: 0;"; 9721 document.body.appendChild(resolverRoot); 9722 return resolverRoot 9723} 9724 9725function isSelectionHighlighted(selection) { 9726 if (!Fr(selection)) return false 9727 9728 if (selection.isCollapsed()) { 9729 return hasHighlightStyles(selection.style) 9730 } else { 9731 return selection.hasFormat("highlight") 9732 } 9733} 9734 9735function getHighlightStyles(selection) { 9736 if (!Fr(selection)) return null 9737 9738 let styles = oe$5(selection.style); 9739 if (!styles.color && !styles["background-color"]) { 9740 const anchorNode = selection.anchor.getNode(); 9741 if (Tr(anchorNode)) { 9742 styles = oe$5(anchorNode.getStyle()); 9743 } 9744 } 9745 9746 const color = styles.color || null; 9747 const backgroundColor = styles["background-color"] || null; 9748 if (!color && !backgroundColor) return null 9749 9750 return { color, backgroundColor } 9751} 9752 9753function hasHighlightStyles(cssOrStyles) { 9754 const styles = typeof cssOrStyles === "string" ? oe$5(cssOrStyles) : cssOrStyles; 9755 return !!(styles.color || styles["background-color"]) 9756} 9757 9758function applyCanonicalizers(styles, canonicalizers = []) { 9759 return canonicalizers.reduce((css, canonicalizer) => { 9760 return canonicalizer.applyCanonicalization(css) 9761 }, styles) 9762} 9763 9764class StyleCanonicalizer { 9765 constructor(property, allowedValues= []) { 9766 this._property = property; 9767 this._allowedValues = allowedValues; 9768 this._canonicalValues = this.#allowedValuesIdentityObject; 9769 } 9770 9771 applyCanonicalization(css) { 9772 const styles = { ...oe$5(css) }; 9773 9774 styles[this._property] = this.getCanonicalAllowedValue(styles[this._property]); 9775 if (!styles[this._property]) { 9776 delete styles[this._property]; 9777 } 9778 9779 return F$6(styles) 9780 } 9781 9782 getCanonicalAllowedValue(value) { 9783 return this._canonicalValues[value] ||= this.#resolveCannonicalValue(value) 9784 } 9785 9786 // Private 9787 9788 get #allowedValuesIdentityObject() { 9789 return this._allowedValues.reduce((object, value) => ({ ...object, [value]: value }), {}) 9790 } 9791 9792 #resolveCannonicalValue(value) { 9793 let index = this.#computedAllowedValues.indexOf(value); 9794 if (index === -1) { 9795 index = this.#computedAllowedValues.indexOf(computeStyleValues(this._property, [ value ])[0]); 9796 } 9797 return index === -1 ? null : this._allowedValues[index] 9798 } 9799 9800 get #computedAllowedValues() { 9801 return this._computedAllowedValues ||= computeStyleValues(this._property, this._allowedValues) 9802 } 9803} 9804 9805// Separates DOM writes from layout reads to avoid forced reflows, and attaches 9806// resolver elements to a strictly-contained root (outside the normal document 9807// flow) so neither the attach nor the detach invalidate styles on the rest of 9808// the page. Without containment, appending to `document.body` triggered a 9809// page-wide style recalc on every canonicalization pass. 9810function computeStyleValues(property, values) { 9811 const fragment = document.createDocumentFragment(); 9812 9813 const elements = values.map(value => { 9814 const element = createElement("span", { style: `display: none; ${property}: ${value};` }); 9815 fragment.appendChild(element); 9816 return element 9817 }); 9818 9819 styleResolverRoot().appendChild(fragment); 9820 9821 const computed = elements.map(element => 9822 window.getComputedStyle(element).getPropertyValue(property) 9823 ); 9824 9825 elements.forEach(element => element.remove()); 9826 return computed 9827} 9828 9829const TOGGLE_HIGHLIGHT_COMMAND = re$5(); 9830const REMOVE_HIGHLIGHT_COMMAND = re$5(); 9831const BLANK_STYLES = { "color": null, "background-color": null }; 9832 9833const hasPastedStylesState = ot$3("hasPastedStyles", { 9834 parse: (value) => value || false 9835}); 9836 9837// Stores pending highlight ranges extracted during HTML import, keyed by CodeNode key. 9838// The highlight-preserving tokenizer consumes this map when the code retokenizer 9839// first tokenizes the block. Scoped per editor instance so entries don't leak 9840// across editors or outlive a torn-down editor. 9841const pendingCodeHighlights = new WeakMap(); 9842 9843class HighlightExtension extends LexxyExtension { 9844 get enabled() { 9845 return this.editorElement.supportsRichText 9846 } 9847 9848 get lexicalExtension() { 9849 const extension = dc({ 9850 dependencies: [ Xt$2 ], 9851 name: "lexxy/highlight", 9852 config: { 9853 color: { buttons: [], permit: [] }, 9854 "background-color": { buttons: [], permit: [] } 9855 }, 9856 html: { 9857 import: { 9858 mark: $markConversion 9859 } 9860 }, 9861 register(editor, config) { 9862 // keep the ref to the canonicalizers for optimized css conversion 9863 const canonicalizers = buildCanonicalizers(config); 9864 9865 // Register the <pre> converter directly in the conversion cache so it 9866 // coexists with other extensions' "pre" converters (the extension-level 9867 // html.import uses Object.assign, which means only one "pre" per key). 9868 $registerPreConversion(editor); 9869 9870 return Cc( 9871 editor.registerCommand(TOGGLE_HIGHLIGHT_COMMAND, (styles) => $toggleSelectionStyles(editor, styles), oo), 9872 editor.registerCommand(REMOVE_HIGHLIGHT_COMMAND, () => $toggleSelectionStyles(editor, BLANK_STYLES), oo), 9873 editor.registerNodeTransform(gr, $syncHighlightWithStyle), 9874 editor.registerNodeTransform(K$1, $syncHighlightWithCodeHighlightNode), 9875 editor.registerNodeTransform(gr, (textNode) => $canonicalizePastedStyles(textNode, canonicalizers)) 9876 ) 9877 } 9878 }); 9879 9880 return [ extension, this.editorConfig.get("highlight") ] 9881 } 9882} 9883 9884function $applyHighlightStyle(textNode, element) { 9885 const elementStyles = { 9886 color: element.style?.color, 9887 "background-color": element.style?.backgroundColor 9888 }; 9889 9890 if (Es(jn)) { $setPastedStyles(textNode); } 9891 const highlightStyle = F$6(elementStyles); 9892 9893 if (highlightStyle.length) { 9894 return textNode.setStyle(textNode.getStyle() + highlightStyle) 9895 } 9896} 9897 9898function $markConversion() { 9899 return { 9900 conversion: extendTextNodeConversion("mark", $applyHighlightStyle), 9901 priority: 1 9902 } 9903} 9904 9905// Register a custom <pre> converter directly in the editor's HTML conversion 9906// cache. We can't use the extension-level html.import because Object.assign 9907// merges all extensions' converters by tag, and a later extension (e.g. 9908// TrixContentExtension) would overwrite ours. 9909function $registerPreConversion(editor) { 9910 if (!editor._htmlConversions) return 9911 9912 let preEntries = editor._htmlConversions.get("pre"); 9913 if (!preEntries) { 9914 preEntries = []; 9915 editor._htmlConversions.set("pre", preEntries); 9916 } 9917 preEntries.push($preConversionWithHighlightsFactory(editor)); 9918} 9919 9920// Returns a <pre> converter factory scoped to a specific editor instance. 9921// The factory extracts highlight ranges from <mark> elements before the code 9922// retokenizer can destroy them. The ranges are stored in pendingCodeHighlights 9923// and restored by the highlight-preserving tokenizer during retokenization. 9924function $preConversionWithHighlightsFactory(editor) { 9925 return function $preConversionWithHighlights(domNode) { 9926 const highlights = extractHighlightRanges(domNode); 9927 if (highlights.length === 0) return null 9928 9929 return { 9930 conversion: (domNode) => { 9931 const language = domNode.getAttribute("data-language"); 9932 const codeNode = I$1(language); 9933 $getPendingHighlights(editor).set(codeNode.getKey(), highlights); 9934 return { node: codeNode } 9935 }, 9936 priority: 2 9937 } 9938 } 9939} 9940 9941// Walk the DOM tree inside a <pre> element and build a list of 9942// { start, end, style } ranges for every <mark> element found. 9943function extractHighlightRanges(preElement) { 9944 const ranges = []; 9945 const codeElement = preElement.querySelector("code") || preElement; 9946 9947 let offset = 0; 9948 9949 function walk(node) { 9950 if (node.nodeType === Node.TEXT_NODE) { 9951 offset += node.textContent.length; 9952 } else if (node.nodeType === Node.ELEMENT_NODE) { 9953 // <br> maps to a LineBreakNode (1 character) in Lexical 9954 if (node.tagName === "BR") { 9955 offset += 1; 9956 return 9957 } 9958 9959 const isMark = node.tagName === "MARK"; 9960 const start = offset; 9961 9962 for (const child of node.childNodes) { 9963 walk(child); 9964 } 9965 9966 if (isMark) { 9967 const style = extractHighlightStyleFromElement(node); 9968 if (style) { 9969 ranges.push({ start, end: offset, style }); 9970 } 9971 } 9972 } 9973 } 9974 9975 for (const child of codeElement.childNodes) { 9976 walk(child); 9977 } 9978 9979 return ranges 9980} 9981 9982function $getPendingHighlights(editor) { 9983 let map = pendingCodeHighlights.get(editor); 9984 if (!map) { 9985 map = new Map(); 9986 pendingCodeHighlights.set(editor, map); 9987 } 9988 return map 9989} 9990 9991function extractHighlightStyleFromElement(element) { 9992 const styles = {}; 9993 if (element.style?.color) styles.color = element.style.color; 9994 if (element.style?.backgroundColor) styles["background-color"] = element.style.backgroundColor; 9995 const css = F$6(styles); 9996 return css.length > 0 ? css : null 9997} 9998 9999// The code retokenizer replaces a code block's children with freshly created 10000// tokens that carry no styles, which would drop color highlights on every 10001// edit. This tokenizer wraps the stock Prism tokenizer to restore them: it 10002// recovers the block's highlight ranges â staged during HTML import, or read 10003// from the children the fresh tokens are about to replace â and reapplies 10004// them to the fresh tokens before the retokenizer splices them in. 10005function buildHighlightPreservingTokenizer(editor) { 10006 return { 10007 defaultLanguage: r.defaultLanguage, 10008 tokenize(code, language) { 10009 return r.tokenize(code, language) 10010 }, 10011 $tokenize(codeNode, language) { 10012 const tokens = r.$tokenize(codeNode, language); 10013 const highlights = $takeHighlightRanges(editor, codeNode); 10014 return $applyHighlightRangesToTokens(tokens, highlights) 10015 } 10016 } 10017} 10018 10019function $takeHighlightRanges(editor, codeNode) { 10020 const pending = $getPendingHighlights(editor); 10021 const key = codeNode.getKey(); 10022 10023 if (pending.has(key)) { 10024 const highlights = pending.get(key); 10025 pending.delete(key); 10026 return highlights 10027 } else if (codeNode.getChildren().some(X$1)) { 10028 return $extractHighlightRangesFromCodeNode(codeNode) 10029 } else { 10030 // A block that was never tokenized has only plain text children. Styles 10031 // on those come from import paths that didn't stage ranges (e.g. colored 10032 // spans in Trix HTML), and the first tokenization discards them. 10033 return [] 10034 } 10035} 10036 10037function $applyHighlightRangesToTokens(tokens, highlights) { 10038 if (highlights.length === 0) return tokens 10039 10040 const styledTokens = []; 10041 let offset = 0; 10042 10043 for (const token of tokens) { 10044 if (X$1(token)) { 10045 styledTokens.push(...$splitTokenAtHighlightBoundaries(token, offset, highlights)); 10046 } else { 10047 styledTokens.push(token); 10048 } 10049 offset += token.getTextContentSize(); 10050 } 10051 10052 return styledTokens 10053} 10054 10055// Split a token into segments at highlight boundaries, styling the covered 10056// segments. We can't use TextNode.splitText() because the fresh tokens aren't 10057// attached to the tree yet, so we create CodeHighlightNode replacements. 10058function $splitTokenAtHighlightBoundaries(token, tokenStart, highlights) { 10059 const text = token.getTextContent(); 10060 const segments = segmentTextByHighlights(text, tokenStart, highlights); 10061 10062 if (segments.length === 1) { 10063 const [ segment ] = segments; 10064 if (segment.style) { 10065 $applyHighlightStyleToToken(token, segment.style); 10066 } 10067 return [ token ] 10068 } else { 10069 return segments.map((segment) => { 10070 const segmentToken = V$2(text.slice(segment.start, segment.end), token.getHighlightType()); 10071 if (segment.style) { 10072 $applyHighlightStyleToToken(segmentToken, segment.style); 10073 } 10074 return segmentToken 10075 }) 10076 } 10077} 10078 10079// Partition a token's text into consecutive { start, end, style } segments, 10080// where offsets are relative to the token and style is null for the stretches 10081// no highlight covers. 10082function segmentTextByHighlights(text, tokenStart, highlights) { 10083 const segments = []; 10084 let cursor = 0; 10085 10086 for (const { start, end, style } of highlights) { 10087 const from = Math.max(start - tokenStart, cursor); 10088 const to = Math.min(end - tokenStart, text.length); 10089 10090 if (from < to) { 10091 if (from > cursor) { 10092 segments.push({ start: cursor, end: from, style: null }); 10093 } 10094 segments.push({ start: from, end: to, style }); 10095 cursor = to; 10096 } 10097 } 10098 10099 if (cursor < text.length) { 10100 segments.push({ start: cursor, end: text.length, style: null }); 10101 } 10102 10103 return segments 10104} 10105 10106function $applyHighlightStyleToToken(token, style) { 10107 token.setStyle(style); 10108 $setCodeHighlightFormat(token, true); 10109} 10110 10111function $buildChildRanges(codeNode) { 10112 const childRanges = []; 10113 let charOffset = 0; 10114 10115 for (const child of codeNode.getChildren()) { 10116 if (X$1(child) || Tr(child)) { 10117 const text = child.getTextContent(); 10118 childRanges.push({ node: child, start: charOffset, end: charOffset + text.length }); 10119 charOffset += text.length; 10120 } else { 10121 // LineBreakNode, TabNode - count as 1 character each (\n, \t) 10122 charOffset += 1; 10123 } 10124 } 10125 10126 return childRanges 10127} 10128 10129// Extract highlight ranges from the Lexical node tree of a CodeNode. 10130// This mirrors extractHighlightRanges (which works on DOM elements during 10131// HTML import) but reads from live CodeHighlightNode children instead. 10132function $extractHighlightRangesFromCodeNode(codeNode) { 10133 const ranges = []; 10134 const childRanges = $buildChildRanges(codeNode); 10135 10136 for (const { node, start, end } of childRanges) { 10137 const style = node.getStyle(); 10138 if (style && hasHighlightStyles(style)) { 10139 ranges.push({ start, end, style }); 10140 } 10141 } 10142 10143 return ranges 10144} 10145 10146function buildCanonicalizers(config) { 10147 return [ 10148 new StyleCanonicalizer("color", [ ...config.buttons.color, ...config.permit.color ]), 10149 new StyleCanonicalizer("background-color", [ ...config.buttons["background-color"], ...config.permit["background-color"] ]) 10150 ] 10151} 10152 10153function $toggleSelectionStyles(editor, styles) { 10154 const selection = Qr(); 10155 if (!Fr(selection)) return 10156 10157 const patch = {}; 10158 for (const property in styles) { 10159 const oldValue = ne$4(selection, property); 10160 patch[property] = toggleOrReplace(oldValue, styles[property]); 10161 } 10162 10163 if ($selectionIsInCodeBlock(selection)) { 10164 $patchCodeHighlightStyles(editor, selection, patch); 10165 } else { 10166 $$3(selection, patch); 10167 } 10168} 10169 10170function $selectionIsInCodeBlock(selection) { 10171 const nodes = selection.getNodes(); 10172 return nodes.some((node) => { 10173 // A text node inside a code block may be either a CodeHighlightNode 10174 // (after retokenization) or a plain TextNode (after splitText or before 10175 // the retokenizer has run). Check the parent in both cases. 10176 if (X$1(node) || Tr(node)) { 10177 return W$1(node.getParent()) 10178 } 10179 return W$1(node) 10180 }) 10181} 10182 10183function $patchCodeHighlightStyles(editor, selection, patch) { 10184 // Capture selection state and node keys before the nested update. 10185 // Accept both CodeHighlightNode and TextNode children of a CodeNode 10186 // because splitText creates TextNode instances and the retokenizer 10187 // may not have converted them back to CodeHighlightNodes yet. 10188 const nodeKeys = selection.getNodes() 10189 .filter((node) => (X$1(node) || Tr(node)) && W$1(node.getParent())) 10190 .map((node) => ({ 10191 key: node.getKey(), 10192 startOffset: $getNodeSelectionOffsets(node, selection)[0], 10193 endOffset: $getNodeSelectionOffsets(node, selection)[1], 10194 textSize: node.getTextContentSize() 10195 })); 10196 10197 // Use skipTransforms so the retokenizer doesn't rebuild the block in the 10198 // middle of the toggle, and discrete to force a synchronous commit so the 10199 // styles are in place before editor.focus() triggers a second update cycle. 10200 editor.update(() => { 10201 for (const { key, startOffset, endOffset, textSize } of nodeKeys) { 10202 const node = Yo(key); 10203 if (!node) continue 10204 10205 const parent = node.getParent(); 10206 if (!W$1(parent)) continue 10207 if (startOffset === endOffset) continue 10208 10209 if (startOffset === 0 && endOffset === textSize) { 10210 $applyStylePatchToNode(node, patch); 10211 } else { 10212 const splitNodes = node.splitText(startOffset, endOffset); 10213 const targetNode = splitNodes[startOffset === 0 ? 0 : 1]; 10214 $applyStylePatchToNode(targetNode, patch); 10215 } 10216 } 10217 }, { skipTransforms: true, discrete: true }); 10218} 10219 10220function $getNodeSelectionOffsets(node, selection) { 10221 const nodeKey = node.getKey(); 10222 const anchorKey = selection.anchor.key; 10223 const focusKey = selection.focus.key; 10224 const textSize = node.getTextContentSize(); 10225 10226 const isAnchor = nodeKey === anchorKey; 10227 const isFocus = nodeKey === focusKey; 10228 10229 // Determine if selection is forward or backward 10230 const isForward = selection.isBackward() === false; 10231 10232 let start = 0; 10233 let end = textSize; 10234 10235 if (isForward) { 10236 if (isAnchor) start = selection.anchor.offset; 10237 if (isFocus) end = selection.focus.offset; 10238 } else { 10239 if (isFocus) start = selection.focus.offset; 10240 if (isAnchor) end = selection.anchor.offset; 10241 } 10242 10243 return [ start, end ] 10244} 10245 10246function $applyStylePatchToNode(node, patch) { 10247 const prevStyles = oe$5(node.getStyle()); 10248 const newStyles = { ...prevStyles }; 10249 10250 for (const [ key, value ] of Object.entries(patch)) { 10251 if (value === null) { 10252 delete newStyles[key]; 10253 } else { 10254 newStyles[key] = value; 10255 } 10256 } 10257 10258 const newCSSText = F$6(newStyles); 10259 node.setStyle(newCSSText); 10260 10261 // Sync the highlight format using TextNode's setFormat to bypass 10262 // CodeHighlightNode's no-op override 10263 const shouldHaveHighlight = hasHighlightStyles(newCSSText); 10264 const hasHighlight = node.hasFormat("highlight"); 10265 10266 if (shouldHaveHighlight !== hasHighlight) { 10267 $setCodeHighlightFormat(node, shouldHaveHighlight); 10268 } 10269} 10270 10271function $setCodeHighlightFormat(node, shouldHaveHighlight) { 10272 const writable = node.getWritable(); 10273 const IS_HIGHLIGHT = 1 << 7; 10274 10275 if (shouldHaveHighlight) { 10276 writable.__format |= IS_HIGHLIGHT; 10277 } else { 10278 writable.__format &= ~IS_HIGHLIGHT; 10279 } 10280} 10281 10282function toggleOrReplace(oldValue, newValue) { 10283 return oldValue === newValue ? null : newValue 10284} 10285 10286function $syncHighlightWithStyle(textNode) { 10287 if (hasHighlightStyles(textNode.getStyle()) !== textNode.hasFormat("highlight")) { 10288 textNode.toggleFormat("highlight"); 10289 } 10290} 10291 10292function $syncHighlightWithCodeHighlightNode(node) { 10293 const parent = node.getParent(); 10294 if (!W$1(parent)) return 10295 10296 const shouldHaveHighlight = hasHighlightStyles(node.getStyle()); 10297 const hasHighlight = node.hasFormat("highlight"); 10298 10299 if (shouldHaveHighlight !== hasHighlight) { 10300 $setCodeHighlightFormat(node, shouldHaveHighlight); 10301 } 10302} 10303 10304function $canonicalizePastedStyles(textNode, canonicalizers = []) { 10305 if ($hasPastedStyles(textNode)) { 10306 $setPastedStyles(textNode, false); 10307 10308 const canonicalizedCSS = applyCanonicalizers(textNode.getStyle(), canonicalizers); 10309 textNode.setStyle(canonicalizedCSS); 10310 10311 const selection = Qr(); 10312 if (textNode.isSelected(selection)) { 10313 selection.setStyle(textNode.getStyle()); 10314 selection.setFormat(textNode.getFormat()); 10315 } 10316 } 10317} 10318 10319function $setPastedStyles(textNode, value = true) { 10320 ct$2(textNode, hasPastedStylesState, value); 10321} 10322 10323function $hasPastedStyles(textNode) { 10324 return st$2(textNode, hasPastedStylesState) 10325} 10326 10327const COMMANDS = [ 10328 "bold", 10329 "italic", 10330 "strikethrough", 10331 "underline", 10332 "link", 10333 "unlink", 10334 "toggleHighlight", 10335 "removeHighlight", 10336 "setFormatHeadingLarge", 10337 "setFormatHeadingMedium", 10338 "setFormatHeadingSmall", 10339 "setFormatParagraph", 10340 "applyHeadingFormat", 10341 "clearFormatting", 10342 "insertUnorderedList", 10343 "insertOrderedList", 10344 "insertQuoteBlock", 10345 "insertCodeBlock", 10346 "setCodeLanguage", 10347 "insertHorizontalDivider", 10348 "uploadImage", 10349 "uploadFile", 10350 10351 "insertTable", 10352 10353 "undo", 10354 "redo" 10355]; 10356 10357class CommandDispatcher { 10358 #selectionBeforeDrag = null 10359 #listeners = new ListenerBin() 10360 10361 static configureFor(editorElement) { 10362 return new CommandDispatcher(editorElement) 10363 } 10364 10365 constructor(editorElement) { 10366 this.editorElement = editorElement; 10367 this.editor = editorElement.editor; 10368 this.selection = editorElement.selection; 10369 this.contents = editorElement.contents; 10370 10371 this.#registerCommands(); 10372 this.#registerKeyboardCommands(); 10373 this.#registerDragAndDropHandlers(); 10374 } 10375 10376 dispatchBold() { 10377 this.editor.dispatchCommand(xe, "bold"); 10378 } 10379 10380 dispatchItalic() { 10381 this.editor.dispatchCommand(xe, "italic"); 10382 } 10383 10384 dispatchStrikethrough() { 10385 this.editor.dispatchCommand(xe, "strikethrough"); 10386 } 10387 10388 dispatchUnderline() { 10389 this.editor.dispatchCommand(xe, "underline"); 10390 } 10391 10392 dispatchToggleHighlight(styles) { 10393 this.editor.dispatchCommand(TOGGLE_HIGHLIGHT_COMMAND, styles); 10394 } 10395 10396 dispatchRemoveHighlight() { 10397 this.editor.dispatchCommand(REMOVE_HIGHLIGHT_COMMAND); 10398 } 10399 10400 dispatchLink(url) { 10401 this.editor.update(() => { 10402 const selection = Qr(); 10403 if (!Fr(selection)) return 10404 10405 const anchorNode = selection.anchor.getNode(); 10406 10407 if (selection.isCollapsed() && !At$2(anchorNode, F$4)) { 10408 const autoLinkNode = H$5(url); 10409 const textNode = kr(url); 10410 autoLinkNode.append(textNode); 10411 selection.insertNodes([ autoLinkNode ]); 10412 } else { 10413 Q$6(url); 10414 } 10415 }); 10416 } 10417 10418 dispatchUnlink() { 10419 this.editor.update(() => { 10420 // Let adapters signal whether unlink should target a frozen link key. 10421 if (this.editorElement.adapter.unlinkFrozenNode?.()) { 10422 return 10423 } 10424 10425 Q$6(null); 10426 }); 10427 } 10428 10429 dispatchInsertUnorderedList() { 10430 const selection = Qr(); 10431 if (!Fr(selection)) return 10432 10433 const anchorNode = selection.anchor.getNode(); 10434 10435 if (this.selection.isInsideList && anchorNode && getListType(anchorNode) === "bullet") { 10436 this.contents.applyParagraphFormat(); 10437 } else { 10438 this.contents.applyUnorderedListFormat(); 10439 } 10440 } 10441 10442 dispatchInsertOrderedList() { 10443 const selection = Qr(); 10444 if (!Fr(selection)) return 10445 10446 const anchorNode = selection.anchor.getNode(); 10447 10448 if (this.selection.isInsideList && anchorNode && getListType(anchorNode) === "number") { 10449 this.contents.applyParagraphFormat(); 10450 } else { 10451 this.contents.applyOrderedListFormat(); 10452 } 10453 } 10454 10455 dispatchInsertQuoteBlock() { 10456 this.contents.toggleBlockquote(); 10457 } 10458 10459 dispatchInsertCodeBlock() { 10460 if (this.selection.hasSelectedWordsInSingleLine) { 10461 this.#toggleInlineCode(); 10462 } else { 10463 this.contents.toggleCodeBlock(); 10464 } 10465 } 10466 10467 #toggleInlineCode() { 10468 const selection = Qr(); 10469 if (!Fr(selection)) return 10470 10471 if (!selection.isCollapsed()) { 10472 const textNodes = selection.getNodes().filter(Tr); 10473 const applyingCode = !textNodes.every((node) => node.hasFormat("code")); 10474 10475 if (applyingCode) { 10476 this.#stripInlineFormattingFromSelection(selection, textNodes); 10477 } 10478 } 10479 10480 this.editor.dispatchCommand(xe, "code"); 10481 } 10482 10483 // Strip all inline formatting (bold, italic, etc.) from the selected text 10484 // nodes so that applying code produces a single merged <code> element instead 10485 // of one per differently-formatted span. 10486 #stripInlineFormattingFromSelection(selection, textNodes) { 10487 const isBackward = selection.isBackward(); 10488 const startPoint = isBackward ? selection.focus : selection.anchor; 10489 const endPoint = isBackward ? selection.anchor : selection.focus; 10490 10491 for (let i = 0; i < textNodes.length; i++) { 10492 const node = textNodes[i]; 10493 if (node.getFormat() === 0) continue 10494 10495 const isFirst = i === 0; 10496 const isLast = i === textNodes.length - 1; 10497 const startOffset = isFirst && startPoint.type === "text" ? startPoint.offset : 0; 10498 const endOffset = isLast && endPoint.type === "text" ? endPoint.offset : node.getTextContentSize(); 10499 10500 if (startOffset === 0 && endOffset === node.getTextContentSize()) { 10501 node.setFormat(0); 10502 } else { 10503 const splits = node.splitText(startOffset, endOffset); 10504 const target = startOffset === 0 ? splits[0] : splits[1]; 10505 target.setFormat(0); 10506 10507 if (isFirst && startPoint.type === "text") { 10508 startPoint.set(target.getKey(), 0, "text"); 10509 } 10510 if (isLast && endPoint.type === "text") { 10511 endPoint.set(target.getKey(), endOffset - startOffset, "text"); 10512 } 10513 } 10514 } 10515 } 10516 10517 dispatchSetCodeLanguage(language) { 10518 this.editor.update(() => { 10519 if (!this.selection.isInsideCodeBlock) return 10520 10521 const codeNode = this.selection.nearestNodeOfType(z$1); 10522 if (!codeNode) return 10523 10524 codeNode.setLanguage(language); 10525 }); 10526 } 10527 10528 dispatchInsertHorizontalDivider() { 10529 Pt$3(new HorizontalDividerNode); 10530 } 10531 10532 dispatchSetFormatHeadingLarge() { 10533 this.#applyConfiguredHeadingFormat(0); 10534 } 10535 10536 dispatchSetFormatHeadingMedium() { 10537 this.#applyConfiguredHeadingFormat(1); 10538 } 10539 10540 dispatchSetFormatHeadingSmall() { 10541 this.#applyConfiguredHeadingFormat(2); 10542 } 10543 10544 dispatchSetFormatParagraph() { 10545 this.contents.applyParagraphFormat(); 10546 } 10547 10548 dispatchApplyHeadingFormat(tag) { 10549 this.contents.applyHeadingFormat(tag); 10550 } 10551 10552 dispatchClearFormatting() { 10553 this.contents.clearFormatting(); 10554 } 10555 10556 dispatchUploadImage() { 10557 this.#dispatchUploadAttachment("image/*,video/*"); 10558 } 10559 10560 dispatchUploadFile() { 10561 this.#dispatchUploadAttachment(); 10562 } 10563 10564 #dispatchUploadAttachment(accept = null) { 10565 const attributes = { 10566 type: "file", 10567 multiple: true, 10568 style: "display: none;", 10569 onchange: ({ target: { files } }) => { 10570 this.contents.uploadFiles(files, { selectLast: true }); 10571 } 10572 }; 10573 10574 if (accept) attributes.accept = accept; 10575 10576 const input = createElement("input", attributes); 10577 10578 // Append and remove to make testable 10579 this.editorElement.appendChild(input); 10580 input.click(); 10581 setTimeout(() => input.remove(), 1000); 10582 } 10583 10584 dispatchInsertTable() { 10585 this.editor.dispatchCommand(ze$1, { "rows": 3, "columns": 3, "includeHeaders": true }); 10586 } 10587 10588 dispatchUndo() { 10589 this.editor.dispatchCommand(Ce$2, undefined); 10590 } 10591 10592 dispatchRedo() { 10593 this.editor.dispatchCommand(Se$2, undefined); 10594 } 10595 10596 dispose() { 10597 this.#listeners.dispose(); 10598 } 10599 10600 #applyConfiguredHeadingFormat(index) { 10601 const tag = this.editorElement.config.get("headings")[index]; 10602 if (tag) this.contents.applyHeadingFormat(tag); 10603 } 10604 10605 #registerCommands() { 10606 for (const command of COMMANDS) { 10607 const methodName = `dispatch${capitalize(command)}`; 10608 this.#registerCommandHandler(command, 0, this[methodName].bind(this)); 10609 } 10610 } 10611 10612 #registerCommandHandler(command, priority, handler) { 10613 this.#listeners.track(this.editor.registerCommand(command, handler, priority)); 10614 } 10615 10616 #registerKeyboardCommands() { 10617 this.#registerCommandHandler(ke$2, oo, this.#handleArrowRightKey.bind(this)); 10618 this.#registerCommandHandler(Fe$2, oo, this.#handleTabKey.bind(this)); 10619 10620 // Run before Lexical's built-in insert handlers to descend an element point on a 10621 // block container to a leaf, avoiding error #211 on Enter / Shift+Enter in a quote. 10622 this.#registerCommandHandler(de$4, so, this.#normalizeBlockContainerSelection.bind(this)); 10623 this.#registerCommandHandler(he$3, so, this.#normalizeBlockContainerSelection.bind(this)); 10624 } 10625 10626 #normalizeBlockContainerSelection() { 10627 $normalizeBlockContainerSelection(); 10628 return false 10629 } 10630 10631 #handleArrowRightKey(event) { 10632 const selection = Qr(); 10633 if (!Fr(selection) || !selection.isCollapsed()) return false 10634 if (this.selection.isInsideCodeBlock || !selection.hasFormat("code")) return false 10635 10636 const anchorNode = selection.anchor.getNode(); 10637 if (!Tr(anchorNode) || selection.anchor.offset !== anchorNode.getTextContentSize()) return false 10638 if (anchorNode.getNextSibling() !== null) return false 10639 10640 event.preventDefault(); 10641 selection.toggleFormat("code"); 10642 return true 10643 } 10644 10645 #registerDragAndDropHandlers() { 10646 if (this.editorElement.supportsAttachments) { 10647 this.dragCounter = 0; 10648 this.#listeners.track( 10649 this.editor.registerRootListener((rootElement) => { 10650 if (rootElement) { 10651 const teardowns = [ 10652 registerEventListener(rootElement, "dragover", this.#handleDragOver.bind(this)), 10653 registerEventListener(rootElement, "drop", this.#handleDrop.bind(this)), 10654 registerEventListener(rootElement, "dragenter", this.#handleDragEnter.bind(this)), 10655 registerEventListener(rootElement, "dragleave", this.#handleDragLeave.bind(this)) 10656 ]; 10657 return () => teardowns.forEach((teardown) => teardown()) 10658 } 10659 }) 10660 ); 10661 } 10662 } 10663 10664 #handleDragEnter(event) { 10665 if (this.#isInternalDrag(event)) return 10666 10667 this.dragCounter++; 10668 if (this.dragCounter === 1) { 10669 this.#saveSelectionBeforeDrag(); 10670 this.editor.getRootElement().classList.add("lexxy-editor--drag-over"); 10671 } 10672 } 10673 10674 #handleDragLeave(event) { 10675 if (this.#isInternalDrag(event)) return 10676 10677 this.dragCounter--; 10678 if (this.dragCounter === 0) { 10679 this.#selectionBeforeDrag = null; 10680 this.editor.getRootElement().classList.remove("lexxy-editor--drag-over"); 10681 } 10682 } 10683 10684 #handleDragOver(event) { 10685 if (this.#isInternalDrag(event)) return 10686 10687 event.preventDefault(); 10688 } 10689 10690 #handleDrop(event) { 10691 if (this.#isInternalDrag(event)) return 10692 10693 event.preventDefault(); 10694 10695 this.dragCounter = 0; 10696 this.editor.getRootElement().classList.remove("lexxy-editor--drag-over"); 10697 10698 const dataTransfer = event.dataTransfer; 10699 if (!dataTransfer) return 10700 10701 const files = Array.from(dataTransfer.files); 10702 if (!files.length) return 10703 10704 this.#restoreSelectionBeforeDrag(); 10705 this.contents.uploadFiles(files, { selectLast: true }); 10706 10707 this.editor.focus(); 10708 } 10709 10710 #saveSelectionBeforeDrag() { 10711 this.editor.getEditorState().read(() => { 10712 this.#selectionBeforeDrag = Qr()?.clone(); 10713 }); 10714 } 10715 10716 #restoreSelectionBeforeDrag() { 10717 if (!this.#selectionBeforeDrag) return 10718 10719 this.editor.update(() => { 10720 es(this.#selectionBeforeDrag); 10721 }); 10722 10723 this.#selectionBeforeDrag = null; 10724 } 10725 10726 #isInternalDrag(event) { 10727 return event.dataTransfer?.types.some((type) => type.startsWith("application/x-lexxy-")) 10728 } 10729 10730 #handleTabKey(event) { 10731 if (this.selection.isInsideList) { 10732 return this.#handleTabForList(event) 10733 } else if (this.selection.isInsideCodeBlock) { 10734 return this.#handleTabForCode() 10735 } 10736 return false 10737 } 10738 10739 #handleTabForList(event) { 10740 if (event.shiftKey && !this.selection.isIndentedList) return false 10741 10742 event.preventDefault(); 10743 const command = event.shiftKey? Ke$2 : Ie$3; 10744 return this.editor.dispatchCommand(command) 10745 } 10746 10747 #handleTabForCode() { 10748 const selection = Qr(); 10749 return Fr(selection) && selection.isCollapsed() 10750 } 10751 10752} 10753 10754function capitalize(str) { 10755 return str.charAt(0).toUpperCase() + str.slice(1) 10756} 10757 10758class Selection { 10759 #listeners = new ListenerBin() 10760 10761 constructor(editorElement) { 10762 this.editorElement = editorElement; 10763 this.editorContentElement = editorElement.editorContentElement; 10764 this.editor = this.editorElement.editor; 10765 this.previouslySelectedKeys = new Set(); 10766 10767 this.#listenForNodeSelections(); 10768 this.#processSelectionChangeCommands(); 10769 this.#containEditorFocus(); 10770 this.#clearStaleInlineCodeFormat(); 10771 } 10772 10773 get hasNodeSelection() { 10774 return this.editor.getEditorState().read(() => { 10775 const selection = Qr(); 10776 return selection !== null && Ir(selection) 10777 }) 10778 } 10779 10780 get cursorPosition() { 10781 let position = null; 10782 10783 this.editor.getEditorState().read(() => { 10784 const range = this.#getValidSelectionRange(); 10785 if (!range) return 10786 10787 const rect = this.#getReliableRectFromRange(range); 10788 if (this.#isRectUnreliable(rect)) return 10789 10790 position = this.#calculateCursorPosition(rect, range); 10791 }); 10792 10793 return position 10794 } 10795 10796 placeCursorAtTheEnd() { 10797 this.editor.update(() => { 10798 const root = Zo(); 10799 const lastDescendant = root.getLastDescendant(); 10800 10801 if (lastDescendant && Tr(lastDescendant)) { 10802 lastDescendant.selectEnd(); 10803 } else { 10804 root.selectEnd(); 10805 } 10806 }); 10807 } 10808 10809 selectedNodeWithOffset() { 10810 const selection = Qr(); 10811 if (!selection) return { node: null, offset: 0 } 10812 10813 if (Fr(selection)) { 10814 return { 10815 node: selection.anchor.getNode(), 10816 offset: selection.anchor.offset 10817 } 10818 } else if (Ir(selection)) { 10819 const [ node ] = selection.getNodes(); 10820 return { 10821 node, 10822 offset: 0 10823 } 10824 } 10825 10826 return { node: null, offset: 0 } 10827 } 10828 10829 getFormat() { 10830 const selection = Qr(); 10831 if (!Fr(selection)) return {} 10832 10833 const anchorNode = selection.anchor.getNode(); 10834 if (!anchorNode.getParent()) return {} 10835 10836 const topLevelElement = anchorNode.getTopLevelElementOrThrow(); 10837 const listType = getListType(anchorNode); 10838 const headingNode = this.#getNearestHeadingNode(anchorNode); 10839 10840 return { 10841 isBold: selection.hasFormat("bold"), 10842 isItalic: selection.hasFormat("italic"), 10843 isStrikethrough: selection.hasFormat("strikethrough"), 10844 isUnderline: selection.hasFormat("underline"), 10845 isHighlight: isSelectionHighlighted(selection), 10846 isInLink: At$2(anchorNode, F$4) !== null, 10847 isInQuote: Mt$2(topLevelElement), 10848 isInHeading: headingNode !== null, 10849 isInCode: this.#isInCode(selection, anchorNode), 10850 headingTag: headingNode?.getTag() ?? null, 10851 isInList: listType !== null, 10852 listType, 10853 isInTable: Ye(anchorNode) !== null 10854 } 10855 } 10856 10857 nearestNodeOfType(nodeType) { 10858 const anchorNode = Qr()?.anchor?.getNode(); 10859 return At$2(anchorNode, nodeType) 10860 } 10861 10862 get hasSelectedWordsInSingleLine() { 10863 const selection = Qr(); 10864 if (!Fr(selection)) return false 10865 10866 if (selection.isCollapsed()) return false 10867 10868 const anchorNode = selection.anchor.getNode(); 10869 const focusNode = selection.focus.getNode(); 10870 10871 if (anchorNode.getTopLevelElement() !== focusNode.getTopLevelElement()) { 10872 return false 10873 } 10874 10875 const anchorElement = anchorNode.getTopLevelElement(); 10876 if (!anchorElement) return false 10877 10878 // When anchor and focus are in different block-level children of the same 10879 // top-level element (e.g. two paragraphs inside a blockquote), this is a 10880 // multi-line selection, not a single-line one. 10881 const anchorBlock = Wi(anchorNode) ? anchorNode : anchorNode.getParent(); 10882 const focusBlock = Wi(focusNode) ? focusNode : focusNode.getParent(); 10883 if (anchorBlock !== focusBlock && anchorBlock !== anchorElement) { 10884 return false 10885 } 10886 10887 const nodes = selection.getNodes(); 10888 for (const node of nodes) { 10889 if (sr(node)) { 10890 return false 10891 } 10892 } 10893 10894 return true 10895 } 10896 10897 get isInsideList() { 10898 return this.nearestNodeOfType(ge$2) 10899 } 10900 10901 get isInsideBlockQuote() { 10902 return this.nearestNodeOfType(At$1) 10903 } 10904 10905 get isIndentedList() { 10906 const closestListNode = this.nearestNodeOfType(me$2); 10907 return closestListNode && (G$7(closestListNode) > 1) 10908 } 10909 10910 get isInsideCodeBlock() { 10911 return this.nearestNodeOfType(z$1) !== null 10912 } 10913 10914 get isTableCellSelected() { 10915 const selection = Qr(); 10916 const { anchor, focus } = selection; 10917 if (!Fr(selection) || anchor.key !== focus.key) return false 10918 10919 return this.nearestNodeOfType(Ee$1) !== null 10920 } 10921 10922 get isOnPreviewableImage() { 10923 return this.previewableImageNode != null 10924 } 10925 10926 get previewableImageNode() { 10927 const firstNode = Qr()?.getNodes().at(0); 10928 return $isActionTextAttachmentNode(firstNode) && firstNode.isPreviewableImage ? firstNode : null 10929 } 10930 10931 get isAtNodeStart() { 10932 const { anchorNode, offset } = this.#getCollapsedSelectionData(); 10933 return anchorNode && offset === 0 10934 } 10935 10936 get nodeAfterCursor() { 10937 const { anchorNode, offset } = this.#getCollapsedSelectionData(); 10938 if (!anchorNode) return null 10939 10940 if (Tr(anchorNode)) { 10941 return this.#getNodeAfterTextNode(anchorNode, offset) 10942 } 10943 10944 if (Wi(anchorNode)) { 10945 return this.#getNodeAfterElementNode(anchorNode, offset) 10946 } 10947 10948 return this.#findNextSiblingUp(anchorNode) 10949 } 10950 10951 get topLevelNodeAfterCursor() { 10952 const { anchorNode, offset } = this.#getCollapsedSelectionData(); 10953 if (!anchorNode) return null 10954 10955 if (Tr(anchorNode)) { 10956 if (offset === anchorNode.getTextContentSize()) return this.#getNextNodeFromTextEnd(anchorNode) 10957 if (this.#isCursorOnLastVisualLineOfBlock(anchorNode)) { 10958 const topLevelElement = anchorNode.getTopLevelElement(); 10959 return topLevelElement ? topLevelElement.getNextSibling() : null 10960 } 10961 return null 10962 } 10963 10964 if (Wi(anchorNode)) { 10965 return this.#getNodeAfterElementNode(anchorNode, offset) 10966 } 10967 10968 return this.#findNextSiblingUp(anchorNode) 10969 } 10970 10971 get nodeBeforeCursor() { 10972 const { anchorNode, offset } = this.#getCollapsedSelectionData(); 10973 if (!anchorNode) return null 10974 10975 if (Tr(anchorNode)) { 10976 return this.#getNodeBeforeTextNode(anchorNode, offset) 10977 } 10978 10979 if (Wi(anchorNode)) { 10980 return this.#getNodeBeforeElementNode(anchorNode, offset) 10981 } 10982 10983 return this.#findPreviousSiblingUp(anchorNode) 10984 } 10985 10986 get topLevelNodeBeforeCursor() { 10987 const { anchorNode, offset } = this.#getCollapsedSelectionData(); 10988 if (!anchorNode) return null 10989 10990 if (Tr(anchorNode)) { 10991 if (offset === 0) return this.#getPreviousNodeFromTextStart(anchorNode) 10992 if (this.#isCursorOnFirstVisualLineOfBlock(anchorNode)) { 10993 const topLevelElement = anchorNode.getTopLevelElement(); 10994 return topLevelElement ? topLevelElement.getPreviousSibling() : null 10995 } 10996 return null 10997 } 10998 10999 if (Wi(anchorNode)) { 11000 return this.#getNodeBeforeElementNode(anchorNode, offset) 11001 } 11002 11003 return this.#findPreviousSiblingUp(anchorNode) 11004 } 11005 11006 dispose() { 11007 this.editorElement = null; 11008 this.editorContentElement = null; 11009 this.editor = null; 11010 this.previouslySelectedKeys = null; 11011 11012 this.#listeners.dispose(); 11013 } 11014 11015 // When all inline code text is deleted, Lexical's selection retains the stale 11016 // code format flag. Verify the flag is backed by actual code-formatted content: 11017 // a code block ancestor or a text node that carries the code format. 11018 #isInCode(selection, anchorNode) { 11019 if (At$2(anchorNode, z$1) !== null) return true 11020 if (!selection.hasFormat("code")) return false 11021 11022 return Tr(anchorNode) && anchorNode.hasFormat("code") 11023 } 11024 11025 // After deleting all inline code text, Lexical preserves the code format on 11026 // the selection even though no code-formatted content remains. This listener 11027 // detects that stale state and clears it so newly typed text won't be 11028 // code-formatted. 11029 #clearStaleInlineCodeFormat() { 11030 this.#listeners.track(this.editor.registerUpdateListener(({ editorState, tags }) => { 11031 if (tags.has("history-merge") || tags.has("skip-dom-selection")) return 11032 11033 let isStale = false; 11034 11035 editorState.read(() => { 11036 const selection = Qr(); 11037 if (!Fr(selection) || !selection.isCollapsed()) return 11038 if (!selection.hasFormat("code")) return 11039 11040 const anchorNode = selection.anchor.getNode(); 11041 if (this.#isInCode(selection, anchorNode)) return 11042 11043 isStale = true; 11044 }); 11045 11046 if (isStale) { 11047 setTimeout(() => { 11048 this.editor.update(() => { 11049 const selection = Qr(); 11050 if (!Fr(selection) || !selection.hasFormat("code")) return 11051 11052 const anchorNode = selection.anchor.getNode(); 11053 if (this.#isInCode(selection, anchorNode)) return 11054 11055 selection.toggleFormat("code"); 11056 }); 11057 }, 0); 11058 } 11059 })); 11060 } 11061 11062 get #currentlySelectedKeys() { 11063 if (this.currentlySelectedKeys) { return this.currentlySelectedKeys } 11064 11065 this.currentlySelectedKeys = new Set(); 11066 11067 const selection = Qr(); 11068 if (selection && Ir(selection)) { 11069 for (const node of selection.getNodes()) { 11070 this.currentlySelectedKeys.add(node.getKey()); 11071 } 11072 } 11073 11074 return this.currentlySelectedKeys 11075 } 11076 11077 #processSelectionChangeCommands() { 11078 this.#listeners.track( 11079 this.editor.registerCommand(Ne$1, handlingDefault(this.#selectPreviousNode.bind(this)), io), 11080 this.editor.registerCommand(ke$2, handlingDefault(this.#selectNextNode.bind(this)), io), 11081 this.editor.registerCommand(we$1, handlingDefault(this.#selectPreviousTopLevelNode.bind(this)), io), 11082 this.editor.registerCommand(Ee$3, handlingDefault(this.#selectNextTopLevelNode.bind(this)), io), 11083 11084 this.editor.registerCommand(fe$4, this.#selectDecoratorNodeBeforeDeletion.bind(this), io), 11085 11086 this.editor.registerCommand(ie$4, () => { 11087 this.#syncSelectedClasses(); 11088 }, io), 11089 11090 this.editor.registerCommand(ie$4, () => { 11091 this.#preserveFocusOfOtherFields(); 11092 return false 11093 }, lo) 11094 ); 11095 } 11096 11097 // Firefox (152+) keeps window.getSelection() anchored inside the editor after focus 11098 // moves to another field, and fires document selectionchange for every keystroke 11099 // typed there. Lexical reads that stale selection, reconciles, and pulls focus back 11100 // into the editor â stealing it mid-typing. When another text-entry field owns focus, 11101 // tag the update so Lexical leaves the DOM selection (and with it, focus) alone. 11102 #preserveFocusOfOtherFields() { 11103 if (this.#anotherFieldIsFocused) { 11104 Os(qn); 11105 } 11106 } 11107 11108 get #anotherFieldIsFocused() { 11109 const rootElement = this.editor.getRootElement(); 11110 const activeElement = rootElement?.ownerDocument.activeElement; 11111 11112 return activeElement && !rootElement.contains(activeElement) && 11113 (activeElement.tagName === "INPUT" || activeElement.tagName === "TEXTAREA" || activeElement.isContentEditable) 11114 } 11115 11116 #listenForNodeSelections() { 11117 this.#listeners.track(this.editor.registerCommand(se$5, ({ target }) => { 11118 if (!qs(target)) return false 11119 11120 const targetNode = Go(target); 11121 return ji(targetNode) && this.#selectInLexical(targetNode) 11122 }, io)); 11123 11124 this.#listeners.track( 11125 this.editor.registerRootListener((rootElement) => { 11126 if (rootElement) { 11127 return registerEventListener(rootElement, "lexxy:internal:move-to-next-line", () => this.#selectOrAppendNextLine()) 11128 } 11129 }) 11130 ); 11131 } 11132 11133 #containEditorFocus() { 11134 // Workaround for a bizarre Chrome bug where the cursor abandons the editor to focus on not-focusable elements 11135 // above when navigating UP/DOWN when Lexical shows its fake cursor on custom decorator nodes. 11136 this.#listeners.track( 11137 this.editor.registerRootListener((rootElement) => { 11138 if (rootElement) { 11139 const handler = (event) => this.#handleArrowKeyOnLexicalCursor(event); 11140 rootElement.addEventListener("keydown", handler, true); 11141 return () => rootElement.removeEventListener("keydown", handler, true) 11142 } 11143 }) 11144 ); 11145 } 11146 11147 #handleArrowKeyOnLexicalCursor(event) { 11148 if (event.key === "ArrowUp") { 11149 const lexicalCursor = this.editor.getRootElement().querySelector("[data-lexical-cursor]"); 11150 11151 if (lexicalCursor) { 11152 let currentElement = lexicalCursor.previousElementSibling; 11153 while (currentElement && currentElement.hasAttribute("data-lexical-cursor")) { 11154 currentElement = currentElement.previousElementSibling; 11155 } 11156 11157 if (!currentElement) { 11158 event.preventDefault(); 11159 } 11160 } 11161 } 11162 11163 if (event.key === "ArrowDown") { 11164 const lexicalCursor = this.editor.getRootElement().querySelector("[data-lexical-cursor]"); 11165 11166 if (lexicalCursor) { 11167 let currentElement = lexicalCursor.nextElementSibling; 11168 while (currentElement && currentElement.hasAttribute("data-lexical-cursor")) { 11169 currentElement = currentElement.nextElementSibling; 11170 } 11171 11172 if (!currentElement) { 11173 event.preventDefault(); 11174 } 11175 } 11176 } 11177 } 11178 11179 #syncSelectedClasses() { 11180 this.#clearPreviouslyHighlightedItems(); 11181 this.#highlightNewItems(); 11182 11183 this.previouslySelectedKeys = this.#currentlySelectedKeys; 11184 this.currentlySelectedKeys = null; 11185 } 11186 11187 #clearPreviouslyHighlightedItems() { 11188 for (const key of this.previouslySelectedKeys) { 11189 if (!this.#currentlySelectedKeys.has(key)) { 11190 const dom = this.editor.getElementByKey(key); 11191 if (dom) dom.classList.remove("node--selected"); 11192 } 11193 } 11194 } 11195 11196 #highlightNewItems() { 11197 for (const key of this.#currentlySelectedKeys) { 11198 if (!this.previouslySelectedKeys.has(key)) { 11199 const nodeElement = this.editor.getElementByKey(key); 11200 if (nodeElement) nodeElement.classList.add("node--selected"); 11201 } 11202 } 11203 } 11204 11205 #selectPreviousNode(event) { 11206 if (event.shiftKey) { 11207 return this.#withCurrentNodeSelectionNode((currentNode) => { 11208 const selection = this.#rangeSelectDecorator(currentNode, "forward"); 11209 11210 // Can't rely on native pass-through with Playwright on firefox 11211 selection.modify("extend", true, "character"); 11212 return true 11213 }) 11214 } else { 11215 return this.#withCurrentNodeSelectionNode((currentNode) => currentNode.selectPrevious()) 11216 || this.#selectInLexical(this.nodeBeforeCursor) 11217 } 11218 } 11219 11220 #selectNextNode(event) { 11221 if (event.shiftKey) { 11222 return this.#withCurrentNodeSelectionNode((currentNode) => { 11223 const selection = this.#rangeSelectDecorator(currentNode, "forward"); 11224 11225 // Can't rely on native pass-through with Playwright on firefox 11226 selection.modify("extend", false, "character"); 11227 return true 11228 }) 11229 } else { 11230 return this.#withCurrentNodeSelectionNode((currentNode) => currentNode.selectNext(0, 0)) 11231 || this.#selectInLexical(this.nodeAfterCursor) 11232 } 11233 } 11234 11235 #selectPreviousTopLevelNode() { 11236 return this.#withCurrentNodeSelectionNode((currentNode) => currentNode.getTopLevelElement().selectPrevious()) 11237 || this.#selectInLexical(this.topLevelNodeBeforeCursor) 11238 } 11239 11240 #selectNextTopLevelNode() { 11241 return this.#withCurrentNodeSelectionNode((currentNode) => currentNode.getTopLevelElement().selectNext(0, 0)) 11242 || this.#selectInLexical(this.topLevelNodeAfterCursor) 11243 } 11244 11245 #withCurrentNodeSelectionNode(fn) { 11246 if (this.hasNodeSelection) { 11247 return fn(Qr().getNodes()[0]) 11248 } 11249 } 11250 11251 #rangeSelectDecorator(node, direction = "forward") { 11252 if (ji(node)) { 11253 const [ anchorOffset, focusOffset ] = direction === "forward" ? [ 0, 1 ] : [ 1, 0 ]; 11254 const indexAtNode = node.getIndexWithinParent(); 11255 11256 return node.getParent().select(indexAtNode + anchorOffset, indexAtNode + focusOffset) 11257 } 11258 } 11259 11260 async #selectOrAppendNextLine() { 11261 this.editor.update(() => { 11262 const topLevelElement = this.#getTopLevelElementFromSelection(); 11263 if (!topLevelElement) return 11264 11265 this.#moveToOrCreateNextLine(topLevelElement); 11266 }); 11267 } 11268 11269 #getTopLevelElementFromSelection() { 11270 const selection = Qr(); 11271 if (!selection) return null 11272 11273 if (Ir(selection)) { 11274 return this.#getTopLevelFromNodeSelection(selection) 11275 } 11276 11277 if (Fr(selection)) { 11278 return this.#getTopLevelFromRangeSelection(selection) 11279 } 11280 11281 return null 11282 } 11283 11284 #getTopLevelFromNodeSelection(selection) { 11285 const nodes = selection.getNodes(); 11286 return nodes.length > 0 ? nodes[0].getTopLevelElement() : null 11287 } 11288 11289 #getTopLevelFromRangeSelection(selection) { 11290 const anchorNode = selection.anchor.getNode(); 11291 return anchorNode.getTopLevelElement() 11292 } 11293 11294 #getNearestHeadingNode(anchorNode) { 11295 const topLevelElement = anchorNode.getTopLevelElementOrThrow(); 11296 11297 let headingNode = Lt$2(topLevelElement) ? topLevelElement : null; 11298 if (!headingNode) { 11299 let current = anchorNode.getParent(); 11300 while (current) { 11301 if (Lt$2(current)) { 11302 headingNode = current; 11303 break 11304 } 11305 current = current.getParent(); 11306 } 11307 } 11308 11309 return headingNode 11310 } 11311 11312 #moveToOrCreateNextLine(topLevelElement) { 11313 const nextSibling = topLevelElement.getNextSibling(); 11314 11315 if (nextSibling) { 11316 nextSibling.selectStart(); 11317 } else { 11318 this.#createAndSelectNewParagraph(); 11319 } 11320 } 11321 11322 #createAndSelectNewParagraph() { 11323 const root = Zo(); 11324 const newParagraph = eo(); 11325 root.append(newParagraph); 11326 newParagraph.selectStart(); 11327 } 11328 11329 #selectInLexical(node) { 11330 if (ji(node)) { 11331 Os(Jn); 11332 const selection = $createNodeSelectionWith(node); 11333 es(selection); 11334 return selection 11335 } else { 11336 return false 11337 } 11338 } 11339 11340 #selectDecoratorNodeBeforeDeletion(backwards) { 11341 if (backwards && this.#removeEmptyListItem()) return true 11342 11343 const node = backwards ? this.nodeBeforeCursor : this.nodeAfterCursor; 11344 if (!ji(node)) return false 11345 11346 if (this.#collapseListItemToParagraph(node)) return true 11347 11348 this.#removeEmptyElementAnchorNode(); 11349 11350 const selection = this.#selectInLexical(node); 11351 return Boolean(selection) 11352 } 11353 11354 // When backspace is pressed on an empty list item that has siblings, 11355 // handle the deletion appropriately: 11356 // 11357 // - Middle/end items (has previous sibling): remove the empty item and 11358 // place the cursor at the end of the previous sibling. Without this, 11359 // Lexical's default collapseAtStart converts the empty item into a 11360 // paragraph above the list, causing the cursor to jump away. 11361 // 11362 // - First item (no previous sibling): convert to a paragraph above the 11363 // list, matching the standard "unwrap list formatting" behavior that 11364 // users expect from pressing backspace at the start of a list item. 11365 // Inside a blockquote we instead just remove the empty item and move 11366 // the cursor into the next one â stranding a paragraph there would 11367 // leave the blank line the user is trying to close. 11368 // 11369 // When the empty item is the last/only one in the list, we return false 11370 // and let Lexical's default (convert to paragraph) provide the standard 11371 // "exit list" behavior. 11372 #removeEmptyListItem() { 11373 const selection = Qr(); 11374 if (!Fr(selection) || !selection.isCollapsed()) return false 11375 11376 const anchorNode = selection.anchor.getNode(); 11377 const listItem = At$2(anchorNode, ge$2); 11378 if (!listItem) return false 11379 11380 if (!$isListItemStructurallyEmpty(listItem)) return false 11381 11382 const nextSibling = listItem.getNextSibling(); 11383 if (!nextSibling) return false 11384 11385 const previousSibling = listItem.getPreviousSibling(); 11386 const listNode = At$2(listItem, me$2); 11387 if (!listNode) return false 11388 11389 if (previousSibling) { 11390 previousSibling.selectEnd(); 11391 listItem.remove(); 11392 } else if (Mt$2(listNode.getParent())) { 11393 nextSibling.selectStart(); 11394 listItem.remove(); 11395 } else { 11396 const paragraph = eo(); 11397 listNode.insertBefore(paragraph); 11398 listItem.remove(); 11399 paragraph.selectStart(); 11400 } 11401 11402 return true 11403 } 11404 11405 // When the cursor is inside a list item, collapse the list item into a 11406 // paragraph instead of selecting the decorator. This lets the user 11407 // delete a list that immediately follows an attachment without the 11408 // attachment becoming selected. Only applies when the decorator is 11409 // outside the list item (e.g. a block attachment before the list), 11410 // not when it's an inline mention inside the list item. 11411 #collapseListItemToParagraph(decoratorNode) { 11412 const anchorNode = Qr()?.anchor?.getNode(); 11413 const listItem = anchorNode && At$2(anchorNode, ge$2); 11414 if (!listItem) return false 11415 11416 if (listItem.isParentOf(decoratorNode)) return false 11417 11418 const listNode = At$2(listItem, me$2); 11419 if (!listNode) return false 11420 11421 const paragraph = eo(); 11422 const children = listItem.getChildren(); 11423 children.forEach(child => paragraph.append(child)); 11424 11425 if (listNode.getChildrenSize() === 1) { 11426 listNode.insertBefore(paragraph); 11427 listNode.remove(); 11428 } else { 11429 listNode.insertBefore(paragraph); 11430 listItem.remove(); 11431 } 11432 11433 paragraph.selectStart(); 11434 return true 11435 } 11436 11437 #removeEmptyElementAnchorNode(anchor = Qr()?.anchor) { 11438 const anchorNode = anchor?.getNode(); 11439 if (Wi(anchorNode) && anchorNode?.isEmpty()) anchorNode.remove(); 11440 } 11441 11442 #getValidSelectionRange() { 11443 const lexicalSelection = Qr(); 11444 if (!lexicalSelection || !lexicalSelection.isCollapsed()) return null 11445 11446 const nativeSelection = window.getSelection(); 11447 if (!nativeSelection || nativeSelection.rangeCount === 0) return null 11448 11449 return nativeSelection.getRangeAt(0) 11450 } 11451 11452 #getReliableRectFromRange(range) { 11453 let rect = range.getBoundingClientRect(); 11454 11455 if (this.#isRectUnreliable(rect)) { 11456 const marker = this.#createAndInsertMarker(range); 11457 rect = marker.getBoundingClientRect(); 11458 this.#restoreSelectionAfterMarker(marker); 11459 marker.remove(); 11460 } 11461 11462 return rect 11463 } 11464 11465 #isRectUnreliable(rect) { 11466 return rect.width === 0 && rect.height === 0 || rect.top === 0 && rect.left === 0 11467 } 11468 11469 #createAndInsertMarker(range) { 11470 const marker = this.#createMarker(); 11471 range.insertNode(marker); 11472 return marker 11473 } 11474 11475 #createMarker() { 11476 const marker = document.createElement("span"); 11477 marker.textContent = "\u200b"; 11478 marker.style.display = "inline-block"; 11479 marker.style.width = "1px"; 11480 marker.style.height = "1em"; 11481 marker.style.lineHeight = "normal"; 11482 marker.setAttribute("nonce", getNonce()); 11483 return marker 11484 } 11485 11486 #restoreSelectionAfterMarker(marker) { 11487 const nativeSelection = window.getSelection(); 11488 nativeSelection.removeAllRanges(); 11489 const newRange = document.createRange(); 11490 newRange.setStartAfter(marker); 11491 newRange.collapse(true); 11492 nativeSelection.addRange(newRange); 11493 } 11494 11495 #calculateCursorPosition(rect, range) { 11496 const rootRect = this.editor.getRootElement().getBoundingClientRect(); 11497 const x = rect.left - rootRect.left; 11498 let y = rect.top - rootRect.top; 11499 11500 const fontSize = this.#getFontSizeForCursor(range); 11501 if (!isNaN(fontSize)) { 11502 y += fontSize; 11503 } 11504 11505 return { x, y, fontSize } 11506 } 11507 11508 #getFontSizeForCursor(range) { 11509 const nativeSelection = window.getSelection(); 11510 const anchorNode = nativeSelection.anchorNode; 11511 const parentElement = this.#getElementFromNode(anchorNode); 11512 11513 if (parentElement instanceof HTMLElement) { 11514 const computed = window.getComputedStyle(parentElement); 11515 return parseFloat(computed.fontSize) 11516 } 11517 11518 return 0 11519 } 11520 11521 #getElementFromNode(node) { 11522 return node?.nodeType === Node.TEXT_NODE ? node.parentElement : node 11523 } 11524 11525 #getCollapsedSelectionData() { 11526 const selection = Qr(); 11527 if (!Fr(selection) || !selection.isCollapsed()) { 11528 return { anchorNode: null, offset: 0 } 11529 } 11530 11531 const { anchor } = selection; 11532 return { anchorNode: anchor.getNode(), offset: anchor.offset } 11533 } 11534 11535 #getNodeAfterTextNode(anchorNode, offset) { 11536 if (offset === anchorNode.getTextContentSize()) { 11537 return this.#getNextNodeFromTextEnd(anchorNode) 11538 } 11539 return null 11540 } 11541 11542 #getNextNodeFromTextEnd(anchorNode) { 11543 const nextSibling = anchorNode.getNextSibling(); 11544 if (ji(nextSibling)) { 11545 return nextSibling 11546 } 11547 if (nextSibling != null) { 11548 return null 11549 } 11550 const parent = anchorNode.getParent(); 11551 return parent ? parent.getNextSibling() : null 11552 } 11553 11554 #getNodeAfterElementNode(anchorNode, offset) { 11555 if (offset < anchorNode.getChildrenSize()) { 11556 return anchorNode.getChildAtIndex(offset) 11557 } 11558 return this.#findNextSiblingUp(anchorNode) 11559 } 11560 11561 #getNodeBeforeTextNode(anchorNode, offset) { 11562 if (offset === 0) { 11563 return this.#getPreviousNodeFromTextStart(anchorNode) 11564 } 11565 return null 11566 } 11567 11568 #getPreviousNodeFromTextStart(anchorNode) { 11569 const previousSibling = anchorNode.getPreviousSibling(); 11570 if (ji(previousSibling)) { 11571 return previousSibling 11572 } 11573 if (previousSibling != null) { 11574 return null 11575 } 11576 const parent = anchorNode.getParent(); 11577 return parent ? parent.getPreviousSibling() : null 11578 } 11579 11580 #getNodeBeforeElementNode(anchorNode, offset) { 11581 if (offset > 0) { 11582 return anchorNode.getChildAtIndex(offset - 1) 11583 } 11584 return this.#findPreviousSiblingUp(anchorNode) 11585 } 11586 11587 #findNextSiblingUp(node) { 11588 let current = node; 11589 while (current && current.getNextSibling() == null) { 11590 current = current.getParent(); 11591 } 11592 return current ? current.getNextSibling() : null 11593 } 11594 11595 #findPreviousSiblingUp(node) { 11596 let current = node; 11597 while (current && current.getPreviousSibling() == null) { 11598 current = current.getParent(); 11599 } 11600 return current ? current.getPreviousSibling() : null 11601 } 11602 11603 #isCursorOnFirstVisualLineOfBlock(anchorNode) { 11604 return this.#isCursorOnEdgeLineOfBlock(anchorNode, "first") 11605 } 11606 11607 #isCursorOnLastVisualLineOfBlock(anchorNode) { 11608 return this.#isCursorOnEdgeLineOfBlock(anchorNode, "last") 11609 } 11610 11611 // Check whether the cursor sits on the first or last visual line of its 11612 // top-level block by comparing the Y position of the cursor with the Y 11613 // position of the block's start (first line) or end (last line). 11614 #isCursorOnEdgeLineOfBlock(anchorNode, edge) { 11615 const topLevelElement = anchorNode.getTopLevelElement(); 11616 if (!topLevelElement) return false 11617 11618 const domElement = this.editor.getElementByKey(topLevelElement.getKey()); 11619 if (!domElement) return false 11620 11621 const nativeSelection = window.getSelection(); 11622 if (!nativeSelection?.rangeCount) return false 11623 11624 const cursorRect = this.#getReliableRectFromRange(nativeSelection.getRangeAt(0)); 11625 if (!cursorRect || this.#isRectUnreliable(cursorRect)) return false 11626 11627 const edgeRect = this.#getEdgeCharRect(domElement, edge); 11628 if (!edgeRect || this.#isRectUnreliable(edgeRect)) return false 11629 11630 const tolerance = edgeRect.height > 0 ? edgeRect.height * 0.5 : 5; 11631 return Math.abs(cursorRect.top - edgeRect.top) < tolerance 11632 } 11633 11634 // Get a reliable bounding rect for the first or last character in a DOM 11635 // element by creating a non-collapsed range around it. 11636 #getEdgeCharRect(element, edge) { 11637 const walker = document.createTreeWalker(element, 4 /* NodeFilter.SHOW_TEXT */); 11638 let textNode; 11639 11640 if (edge === "first") { 11641 textNode = walker.nextNode(); 11642 } else { 11643 while (walker.nextNode()) textNode = walker.currentNode; 11644 } 11645 11646 if (!textNode || textNode.length === 0) return null 11647 11648 const range = document.createRange(); 11649 if (edge === "first") { 11650 range.setStart(textNode, 0); 11651 range.setEnd(textNode, 1); 11652 } else { 11653 range.setStart(textNode, textNode.length - 1); 11654 range.setEnd(textNode, textNode.length); 11655 } 11656 11657 return range.getBoundingClientRect() 11658 } 11659} 11660 11661class EditorConfiguration { 11662 #editorElement 11663 #config 11664 11665 constructor(editorElement) { 11666 this.#editorElement = editorElement; 11667 this.#config = new Configuration( 11668 Lexxy.presets.get("default"), 11669 Lexxy.presets.get(editorElement.preset), 11670 this.#overrides 11671 ); 11672 } 11673 11674 get(path) { 11675 return this.#config.get(path) 11676 } 11677 11678 get #overrides() { 11679 const overrides = {}; 11680 for (const option of this.#defaultOptions) { 11681 const attribute = dasherize(option); 11682 if (this.#editorElement.hasAttribute(attribute)) { 11683 overrides[option] = this.#parseAttribute(attribute); 11684 } 11685 } 11686 return overrides 11687 } 11688 11689 get #defaultOptions() { 11690 return Object.keys(Lexxy.presets.get("default")) 11691 } 11692 11693 #parseAttribute(attribute) { 11694 const value = this.#editorElement.getAttribute(attribute); 11695 try { 11696 return JSON.parse(value) 11697 } catch { 11698 return value 11699 } 11700 } 11701} 11702 11703class ImageGalleryNode extends Bi { 11704 $config() { 11705 return this.config("image_gallery", { 11706 extends: Bi, 11707 }) 11708 } 11709 11710 static transform() { 11711 return (gallery) => { 11712 gallery.unwrapEmptyNode() 11713 || gallery.replaceWithSingularChild() 11714 || gallery.splitAroundInvalidChild(); 11715 } 11716 } 11717 11718 static importDOM() { 11719 return { 11720 div: (element) => { 11721 if (!this.#isGalleryElement(element)) return null 11722 11723 return { 11724 conversion: () => { 11725 return { 11726 node: $createImageGalleryNode() 11727 } 11728 }, 11729 priority: 2 11730 } 11731 } 11732 } 11733 } 11734 11735 static canCollapseWith(node) { 11736 return $isImageGalleryNode(node) || this.isValidChild(node) 11737 } 11738 11739 static isValidChild(node) { 11740 return $isActionTextAttachmentNode(node) && node.isPreviewableImage 11741 } 11742 11743 static #isGalleryElement(element) { 11744 const attachmentChildren = element.querySelectorAll(`:scope > :is(${this.#attachmentTags.join()})`); 11745 return element.textContent.trim() === "" 11746 && attachmentChildren.length > 0 11747 && element.children.length === attachmentChildren.length 11748 } 11749 11750 static get #attachmentTags() { 11751 return Object.keys(ActionTextAttachmentNode.importDOM()) 11752 } 11753 11754 createDOM() { 11755 const div = document.createElement("div"); 11756 div.className = this.#galleryClassNames; 11757 return div 11758 } 11759 11760 updateDOM(_prevNode, dom) { 11761 dom.className = this.#galleryClassNames; 11762 return false 11763 } 11764 11765 canBeEmpty() { 11766 // Return `true` to conform to `$isBlock(node)` 11767 // We clean-up empty galleries with a transform 11768 return true 11769 } 11770 11771 collapseAtStart(_selection) { 11772 return true 11773 } 11774 11775 insertNewAfter(selection, restoreSelection) { 11776 const selectionBeforeLastChild = selection.anchor.getNode().is(this) && selection.anchor.offset == this.getChildrenSize() - 1; 11777 if (selectionBeforeLastChild) { 11778 const paragraph = eo(); 11779 this.insertAfter(paragraph, false); 11780 paragraph.insertAfter(this.getLastChild(), false); 11781 paragraph.selectEnd(); 11782 11783 // return null as selection has been managed 11784 return null 11785 } 11786 11787 const newNode = $createImageGalleryNode(); 11788 this.insertAfter(newNode, restoreSelection); 11789 return newNode 11790 } 11791 11792 getImageAttachments() { 11793 const children = this.getChildren(); 11794 return children.filter($isActionTextAttachmentNode) 11795 } 11796 11797 exportDOM() { 11798 const div = document.createElement("div"); 11799 div.className = this.#galleryClassNames; 11800 return { element: div } 11801 } 11802 11803 collapseWith(node, backwards) { 11804 if (!ImageGalleryNode.canCollapseWith(node)) return false 11805 11806 if (backwards) { 11807 $t$2(this, node); 11808 } else { 11809 this.append(node); 11810 } 11811 11812 Ot$3(this, ImageGalleryNode.isValidChild); 11813 11814 return true 11815 } 11816 11817 unwrapEmptyNode() { 11818 if (this.isEmpty()) { 11819 const paragraph = eo(); 11820 return this.replace(paragraph) 11821 } 11822 } 11823 11824 replaceWithSingularChild() { 11825 if (this.#hasSingularChild) { 11826 const child = this.getFirstChild(); 11827 return this.replace($makeSafeForRoot(child)) 11828 } 11829 } 11830 11831 splitAroundInvalidChild() { 11832 for (const child of jt$2(this)) { 11833 if (ImageGalleryNode.isValidChild(child)) continue 11834 11835 const poppedNode = $makeSafeForRoot(child); 11836 const [ topGallery, secondGallery ] = this.splitAtIndex(poppedNode.getIndexWithinParent()); 11837 topGallery.insertAfter(poppedNode); 11838 poppedNode.selectEnd(); 11839 11840 // remove an empty gallery rather than let it unwrap to a paragraph 11841 if (secondGallery.isEmpty()) secondGallery.remove(); 11842 11843 break 11844 } 11845 } 11846 11847 splitAtIndex(index) { 11848 return Us(this, index) 11849 } 11850 11851 get #hasSingularChild() { 11852 return this.getChildrenSize() === 1 11853 } 11854 11855 get #galleryClassNames() { 11856 return `attachment-gallery attachment-gallery--${this.getChildrenSize()}` 11857 } 11858} 11859 11860function $createImageGalleryNode() { 11861 return new ImageGalleryNode() 11862} 11863 11864function $isImageGalleryNode(node) { 11865 return node instanceof ImageGalleryNode 11866} 11867 11868function $findOrCreateGalleryForImage(node) { 11869 if (!ImageGalleryNode.canCollapseWith(node)) return null 11870 11871 const existingGallery = At$2(node, ImageGalleryNode); 11872 return existingGallery ?? Tt$4(node, $createImageGalleryNode) 11873} 11874 11875class Uploader { 11876 #files 11877 11878 static for(editorElement, files, options = {}) { 11879 const UploaderKlass = GalleryUploader.handle(editorElement, files) ? GalleryUploader : Uploader; 11880 return new UploaderKlass(editorElement, files, options) 11881 } 11882 11883 constructor(editorElement, files, options = {}) { 11884 this.#files = files; 11885 this.options = options; 11886 11887 this.editorElement = editorElement; 11888 this.contents = editorElement.contents; 11889 this.selection = editorElement.selection; 11890 } 11891 11892 get files() { 11893 return Array.from(this.#files) 11894 } 11895 11896 $uploadFiles() { 11897 this.$createUploadNodes(); 11898 this.$insertUploadNodes(); 11899 } 11900 11901 $createUploadNodes() { 11902 this.nodes = this.files.map(file => this.#createUploadNode(file)); 11903 } 11904 11905 #createUploadNode(file) { 11906 return this.options.pending 11907 ? this.contents.$createPendingUploadNode(file) 11908 : this.contents.$createUploadNode(file) 11909 } 11910 11911 $insertUploadNodes() { 11912 this.contents.insertAtCursor(...this.nodes); 11913 } 11914} 11915 11916class GalleryUploader extends Uploader { 11917 #gallery 11918 11919 static handle(editorElement, files) { 11920 return this.isMultipleImageUpload(files) || this.gallerySelection(editorElement.selection) 11921 } 11922 11923 static isMultipleImageUpload(files) { 11924 let imageFileCount = 0; 11925 for (const file of files) { 11926 if (isPreviewableImage(file.type)) imageFileCount++; 11927 if (imageFileCount > 1) return true 11928 } 11929 return false 11930 } 11931 11932 static gallerySelection(selection) { 11933 return selection.isOnPreviewableImage || this.selectionIsAfterGalleryEdge(selection) 11934 } 11935 11936 static selectionIsAfterGalleryEdge(selection) { 11937 return selection.isAtNodeStart && ImageGalleryNode.canCollapseWith(selection.nodeBeforeCursor) 11938 } 11939 11940 $insertUploadNodes() { 11941 this.#findOrCreateGallery(); 11942 this.#insertImagesInGallery(); 11943 this.#insertNonImagesAfterGallery(); 11944 } 11945 11946 #findOrCreateGallery() { 11947 if (this.selection.isOnPreviewableImage) { 11948 // Resolve from the previewable image itself (the selection's first node), not from 11949 // #selectedNode (the anchor) â those differ when the selection runs from an image 11950 // into following text, and the anchor text node can't join a gallery (returns null). 11951 this.#gallery = $findOrCreateGalleryForImage(this.selection.previewableImageNode); 11952 } else if (this.#selectionIsAfterGalleryEdge) { 11953 this.#gallery = $findOrCreateGalleryForImage(this.selection.nodeBeforeCursor); 11954 } else { 11955 this.#gallery = $createImageGalleryNode(); 11956 this.contents.insertAtCursor(this.#gallery); 11957 } 11958 } 11959 11960 get #selectionIsAfterGalleryEdge() { 11961 return this.constructor.selectionIsAfterGalleryEdge(this.selection) 11962 } 11963 11964 get #selectedNode() { 11965 const { node } = this.selection.selectedNodeWithOffset(); 11966 return node 11967 } 11968 11969 get #galleryInsertPosition() { 11970 if (this.#selectionIsAfterGalleryEdge) return this.#gallery.getChildrenSize() 11971 11972 const anchor = Qr()?.anchor; 11973 const galleryHasElementSelection = anchor?.getNode().is(this.#gallery); 11974 if (galleryHasElementSelection) return anchor.offset 11975 11976 const selectedNode = this.#selectedNode; 11977 const childIndex = this.#gallery.isParentOf(selectedNode) && selectedNode.getIndexWithinParent(); 11978 return childIndex !== false ? (childIndex + 1) : 0 11979 } 11980 11981 get #imageNodes() { 11982 return this.nodes.filter(node => ImageGalleryNode.isValidChild(node)) 11983 } 11984 11985 get #nonImageNodes() { 11986 return this.nodes.filter(node => !ImageGalleryNode.isValidChild(node)) 11987 } 11988 11989 #insertImagesInGallery() { 11990 this.#gallery.splice(this.#galleryInsertPosition, 0, this.#imageNodes); 11991 } 11992 11993 #insertNonImagesAfterGallery() { 11994 let beforeNode = this.#gallery; 11995 11996 for (const node of this.#nonImageNodes) { 11997 beforeNode.insertAfter(node); 11998 beforeNode = node; 11999 } 12000 } 12001} 12002 12003async function loadFileIntoImage(file, image) { 12004 return new Promise((resolve) => { 12005 const reader = new FileReader(); 12006 12007 image.addEventListener("load", () => { 12008 resolve(image); 12009 }); 12010 12011 reader.onload = (event) => { 12012 image.src = event.target.result || null; 12013 }; 12014 12015 reader.readAsDataURL(file); 12016 }) 12017} 12018 12019class ActionTextAttachmentUploadNode extends ActionTextAttachmentNode { 12020 static getType() { 12021 return "action_text_attachment_upload" 12022 } 12023 12024 static clone(node) { 12025 return new ActionTextAttachmentUploadNode({ ...node }, node.__key) 12026 } 12027 12028 static importJSON(serializedNode) { 12029 return new ActionTextAttachmentUploadNode({ ...serializedNode }) 12030 } 12031 12032 // Should never run since this is a transient node. Defined to remove console warning. 12033 static importDOM() { 12034 return null 12035 } 12036 12037 constructor(node, key) { 12038 const { file, uploadUrl, blobUrlTemplate, progress, width, height, uploadError, fileName, contentType } = node; 12039 super({ ...node, contentType: file?.type ?? contentType }, key); 12040 this.file = file ?? null; 12041 this.fileName = file?.name ?? fileName; 12042 this.uploadUrl = uploadUrl; 12043 this.blobUrlTemplate = blobUrlTemplate; 12044 this.progress = progress ?? null; 12045 this.width = width; 12046 this.height = height; 12047 this.uploadError = uploadError; 12048 } 12049 12050 createDOM() { 12051 if (this.uploadError) return this.createDOMForError() 12052 12053 // This side-effect is trigged on DOM load to fire only once and avoid multiple 12054 // uploads through cloning. The upload is guarded from restarting in case the 12055 // node is reloaded from saved state such as from history. 12056 this.#startUploadIfNeeded(); 12057 12058 // Bridge-managed uploads (uploadUrl is null) don't have file data to show 12059 // an image preview, so always show the file icon during upload. 12060 const canPreviewFile = this.isPreviewableAttachment && this.uploadUrl != null; 12061 const figure = this.createAttachmentFigure(canPreviewFile); 12062 12063 if (canPreviewFile) { 12064 const img = figure.appendChild(this.#createDOMForImage()); 12065 12066 // load file locally to set dimensions and prevent vertical shifting 12067 loadFileIntoImage(this.file, img).then(img => this.#setDimensionsFromImage(img)); 12068 } else { 12069 figure.appendChild(this.#createDOMForFile()); 12070 } 12071 12072 figure.appendChild(this.#createCaption()); 12073 figure.appendChild(this.#createProgressBar()); 12074 12075 return figure 12076 } 12077 12078 updateDOM(prevNode, dom) { 12079 if (this.uploadError !== prevNode.uploadError) return true 12080 12081 if (prevNode.progress !== this.progress) { 12082 const progress = dom.querySelector("progress"); 12083 progress.value = this.progress ?? 0; 12084 } 12085 12086 return false 12087 } 12088 12089 exportDOM() { 12090 return { element: null } 12091 } 12092 12093 exportJSON() { 12094 return { 12095 ...super.exportJSON(), 12096 type: "action_text_attachment_upload", 12097 version: 1, 12098 fileName: this.fileName, 12099 contentType: this.contentType, 12100 uploadUrl: this.uploadUrl, 12101 blobUrlTemplate: this.blobUrlTemplate, 12102 progress: this.progress, 12103 width: this.width, 12104 height: this.height, 12105 uploadError: this.uploadError 12106 } 12107 } 12108 12109 get #uploadStarted() { 12110 return this.progress !== null 12111 } 12112 12113 #createDOMForImage() { 12114 return createElement("img") 12115 } 12116 12117 #createDOMForFile() { 12118 const extension = this.#getFileExtension(); 12119 const span = createElement("span", { className: "attachment__icon", textContent: extension }); 12120 return span 12121 } 12122 12123 #getFileExtension() { 12124 return (this.fileName || "").split(".").pop().toLowerCase() 12125 } 12126 12127 #createCaption() { 12128 const figcaption = createElement("figcaption", { className: "attachment__caption" }); 12129 12130 const nameSpan = createElement("span", { className: "attachment__name", textContent: this.caption || this.fileName || "" }); 12131 const sizeSpan = createElement("span", { className: "attachment__size", textContent: bytesToHumanSize(this.file?.size) }); 12132 figcaption.appendChild(nameSpan); 12133 figcaption.appendChild(sizeSpan); 12134 12135 return figcaption 12136 } 12137 12138 #createProgressBar() { 12139 return createElement("progress", { value: this.progress ?? 0, max: 100 }) 12140 } 12141 12142 #setDimensionsFromImage({ width, height }) { 12143 if (this.#hasDimensions) return 12144 12145 this.patchAndRewriteHistory({ width, height }); 12146 } 12147 12148 get #hasDimensions() { 12149 return Boolean(this.width && this.height) 12150 } 12151 12152 async #startUploadIfNeeded() { 12153 if (this.#uploadStarted) return 12154 if (!this.uploadUrl) return // Bridge-managed upload â skip DirectUpload 12155 12156 this.#setUploadStarted(); 12157 12158 const { DirectUpload } = await import('@rails/activestorage'); 12159 12160 const upload = new DirectUpload(this.file, this.uploadUrl, this); 12161 upload.delegate = this.#createUploadDelegate(); 12162 12163 this.#dispatchEvent("lexxy:upload-start", { file: this.file }); 12164 12165 upload.create((error, blob) => { 12166 this.#forgetUploadRequest(); 12167 12168 if (error) { 12169 this.#dispatchEvent("lexxy:upload-end", { file: this.file, error }); 12170 this.#handleUploadError(error); 12171 } else { 12172 this.#dispatchEvent("lexxy:upload-end", { file: this.file, error: null }); 12173 this.editor.update(() => { 12174 this.$showUploadedAttachment(blob); 12175 }); 12176 } 12177 }); 12178 } 12179 12180 #createUploadDelegate() { 12181 const shouldAuthenticateUploads = Lexxy.global.get("authenticatedUploads"); 12182 12183 return { 12184 directUploadWillCreateBlobWithXHR: (request) => { 12185 if (shouldAuthenticateUploads) request.withCredentials = true; 12186 }, 12187 directUploadWillStoreFileWithXHR: (request) => { 12188 if (shouldAuthenticateUploads) request.withCredentials = true; 12189 12190 this.#rememberUploadRequest(request); 12191 12192 const uploadProgressHandler = (event) => this.#handleUploadProgress(event, request); 12193 request.upload.addEventListener("progress", uploadProgressHandler); 12194 } 12195 } 12196 } 12197 12198 #forgetUploadRequest() { 12199 this.#editorElement?.uploadRequests.forget(this.getKey()); 12200 } 12201 12202 #rememberUploadRequest(request) { 12203 this.#editorElement?.uploadRequests.track(this.getKey(), request); 12204 } 12205 12206 get #editorElement() { 12207 return this.editor.getRootElement()?.closest("lexxy-editor") 12208 } 12209 12210 #setUploadStarted() { 12211 this.#setProgress(1); 12212 } 12213 12214 #handleUploadProgress(event, request) { 12215 const progress = Math.round(event.loaded / event.total * 100); 12216 try { 12217 this.#setProgress(progress); 12218 this.#dispatchEvent("lexxy:upload-progress", { file: this.file, progress }); 12219 } catch { 12220 request.abort(); 12221 } 12222 } 12223 12224 #setProgress(progress) { 12225 this.patchAndRewriteHistory({ progress }); 12226 } 12227 12228 #handleUploadError(error) { 12229 console.warn(`Upload error for ${this.file?.name ?? "file"}: ${error}`); 12230 12231 this.patchAndRewriteHistory({ uploadError: true }); 12232 } 12233 12234 $showUploadedAttachment(blob) { 12235 const previewSrc = this.isPreviewableImage && this.file ? URL.createObjectURL(this.file) : null; 12236 12237 const replacementNode = this.#toActionTextAttachmentNodeWith(blob, previewSrc); 12238 this.replaceAndRewriteHistory(replacementNode); 12239 12240 return replacementNode.getKey() 12241 } 12242 12243 #toActionTextAttachmentNodeWith(blob, previewSrc) { 12244 const conversion = new AttachmentNodeConversion(this, blob, previewSrc); 12245 return conversion.toAttachmentNode() 12246 } 12247 12248 #dispatchEvent(name, detail) { 12249 const figure = this.editor.getElementByKey(this.getKey()); 12250 if (figure) dispatch(figure, name, detail); 12251 } 12252} 12253 12254class AttachmentNodeConversion { 12255 constructor(uploadNode, blob, previewSrc) { 12256 this.uploadNode = uploadNode; 12257 this.blob = blob; 12258 this.previewSrc = previewSrc; 12259 } 12260 12261 toAttachmentNode() { 12262 return new ActionTextAttachmentNode({ 12263 ...this.uploadNode, 12264 ...this.#propertiesFromBlob, 12265 src: this.#src, 12266 previewSrc: this.previewSrc, 12267 pendingPreview: this.blob.previewable && !this.uploadNode.isPreviewableImage 12268 }) 12269 } 12270 12271 get #propertiesFromBlob() { 12272 const { blob } = this; 12273 return { 12274 sgid: blob.attachable_sgid, 12275 altText: blob.filename, 12276 contentType: blob.content_type, 12277 fileName: blob.filename, 12278 fileSize: blob.byte_size, 12279 previewable: blob.previewable, 12280 previewStatusUrl: blob.preview_status_url 12281 } 12282 } 12283 12284 get #src() { 12285 return this.blob.previewable ? this.blob.url : this.#blobSrc 12286 } 12287 12288 get #blobSrc() { 12289 return this.uploadNode.blobUrlTemplate 12290 .replace(":signed_id", this.blob.signed_id) 12291 .replace(":filename", encodeURIComponent(this.blob.filename)) 12292 } 12293} 12294 12295function $createActionTextAttachmentUploadNode(...args) { 12296 return new ActionTextAttachmentUploadNode(...args) 12297} 12298 12299class BaseNodeInserter { 12300 constructor(selection) { 12301 this.selection = selection; 12302 } 12303} 12304 12305class CodeNodeInserter extends BaseNodeInserter { 12306 static handles(selection) { 12307 return At$2(selection.anchor?.getNode(), z$1) 12308 } 12309 12310 insertNodes(nodes) { 12311 if (!this.selection.isCollapsed()) { this.selection.removeText(); } 12312 12313 j$6(this.selection); 12314 const focusNode = this.selection.focus.getNode(); 12315 const codeNode = At$2(focusNode, z$1); 12316 const insertionIndex = focusNode.is(codeNode) ? 0 : focusNode.getIndexWithinParent(); 12317 12318 const caret = lc(codeNode, insertionIndex + 1, "previous"); 12319 12320 // Nodes that are already in the document come from the format-toggle path (existing 12321 // content converted into this code block). Brand-new nodes (dropped/pasted content) 12322 // were never attached. 12323 const existingNodes = new Set(nodes.filter(node => node.isAttached())); 12324 const trailingNodes = []; 12325 12326 for (const node of nodes) { 12327 if (existingNodes.has(node)) { 12328 if (!node.isAttached()) continue // already pulled in when a converted ancestor was removed 12329 } else if (!this.#canJoinCodeBlock(node)) { 12330 trailingNodes.push(node); // e.g. a dropped attachment, which a code block can't hold 12331 continue 12332 } 12333 12334 if (caret.getNodeAtCaret() && Wi(node)) { caret.insert(or()); } 12335 caret.insert(this.#convertNodeToCodeChild(node)); 12336 } 12337 12338 const lastTrailingNode = this.#insertAfterCodeBlock(codeNode, trailingNodes); 12339 const nodeToSelect = lastTrailingNode ?? caret.getNodeAtCaret(); 12340 nodeToSelect?.selectEnd(); 12341 } 12342 12343 #canJoinCodeBlock(node) { 12344 return Tr(node) || sr(node) 12345 } 12346 12347 #insertAfterCodeBlock(codeNode, nodes) { 12348 let previousNode = codeNode; 12349 for (const node of nodes) { 12350 previousNode.insertAfter(node); 12351 previousNode = node; 12352 } 12353 return nodes.at(-1) 12354 } 12355 12356 #convertNodeToCodeChild(node) { 12357 if (sr(node)) { 12358 return node 12359 } else { 12360 node.remove(); 12361 return kr(node.getTextContent()) 12362 } 12363 } 12364} 12365 12366class ShadowRootNodeInserter extends BaseNodeInserter { 12367 static handles(selection) { 12368 return $isShadowRoot(selection?.anchor?.getNode()) 12369 } 12370 12371 insertNodes(nodes) { 12372 const anchorNode = this.selection.anchor.getNode(); 12373 const paragraph = eo(); 12374 anchorNode.append(paragraph); 12375 12376 paragraph.selectStart().insertNodes(nodes); 12377 } 12378} 12379 12380class NodeSelectionNodeInserter extends BaseNodeInserter { 12381 static handles(selection) { 12382 return Ir(selection) && selection.getNodes().length > 0 12383 } 12384 12385 insertNodes(nodes) { 12386 // Overrides Lexical's default behavior of _removing_ the currently selected nodes 12387 // https://github.com/facebook/lexical/blob/v0.38.2/packages/lexical/src/LexicalSelection.ts#L412 12388 let lastNode = this.selection.getNodes().at(-1); 12389 12390 for (const node of nodes) { 12391 // Inserting after a top-level node would make this one a root child. Inline nodes 12392 // can't live there (Lexical error #99), so wrap them in their required parent first. 12393 const nodeToInsert = this.#insertsIntoRoot(lastNode) ? $makeSafeForRoot(node) : node; 12394 lastNode = lastNode.insertAfter(nodeToInsert); 12395 } 12396 } 12397 12398 #insertsIntoRoot(node) { 12399 return node.is(node.getTopLevelElement()) 12400 } 12401} 12402 12403// A list item can only hold inline content, so a block node (such as an image 12404// attachment) dropped into one corrupts the list: Lexical lifts it into the 12405// wrong list item and orphans an empty bullet. Block nodes belong at the top 12406// level instead, splitting the list around the cursor. Inline content keeps 12407// Lexical's default behavior and stays within the list item. 12408class ListItemNodeInserter extends BaseNodeInserter { 12409 static handles(selection) { 12410 return Fr(selection) && 12411 At$2(selection.anchor.getNode(), ge$2) 12412 } 12413 12414 insertNodes(nodes) { 12415 if (nodes.some(node => this.#isBlockDecorator(node))) { 12416 this.#insertAroundList(nodes); 12417 } else { 12418 this.selection.insertNodes(nodes); 12419 } 12420 } 12421 12422 #insertAroundList(nodes) { 12423 if (!this.selection.isCollapsed()) { this.selection.removeText(); } 12424 12425 // Break out of any nesting to the outermost list. Splitting an inner list 12426 // would leave the block stranded inside an ancestor list item, which is the 12427 // very corruption we are avoiding. The block must land at the list's level. 12428 const anchorNode = this.selection.anchor.getNode(); 12429 const outerList = this.#outermostList(anchorNode); 12430 const topItem = this.#topLevelItemFor(anchorNode, outerList); 12431 12432 // A blank top-level bullet is just the insertion point (e.g. the user pressed 12433 // Enter to leave the list); break out of it entirely. A bullet with content â 12434 // including one wrapping a nested list â splits so its content stays in the list. 12435 const splitAfterItem = $isBlankNode(topItem) ? topItem.getPreviousSibling() : topItem; 12436 const splitIndex = splitAfterItem ? splitAfterItem.getIndexWithinParent() + 1 : 0; 12437 const [ listBefore, listAfter ] = Us(outerList, splitIndex); 12438 if ($isBlankNode(topItem)) { topItem.remove(); } 12439 12440 let anchor = listBefore ?? listAfter; 12441 for (const node of nodes) { 12442 anchor.insertAfter(node); 12443 anchor = node; 12444 } 12445 12446 this.#removeEmptyList(listBefore); 12447 this.#removeEmptyList(listAfter); 12448 nodes.at(-1).selectNext(); 12449 } 12450 12451 #outermostList(node) { 12452 return [ node, ...node.getParents() ].reverse().find(Se$1) 12453 } 12454 12455 #topLevelItemFor(node, outerList) { 12456 return [ node, ...node.getParents() ].find(ancestor => 12457 pe$2(ancestor) && ancestor.getParent()?.is(outerList) 12458 ) 12459 } 12460 12461 #removeEmptyList(list) { 12462 if (Se$1(list) && list.isEmpty()) list.remove(); 12463 } 12464 12465 // Only block decorator nodes (image/file attachments) are intercepted. A list 12466 // item cannot hold them, so they must break out. Pasted element blocks 12467 // (paragraphs, quotes) keep Lexical's own list-escape semantics. 12468 #isBlockDecorator(node) { 12469 return ji(node) && !node.isInline() 12470 } 12471} 12472 12473// Lexical's RangeSelection.insertNodes requires every selection point to have a block 12474// ancestor with inline children. An element point on a container of block nodes â e.g. 12475// a quote holding paragraphs â has none, so Lexical throws invariant #211 or #212. 12476// Descend such points to a leaf position before inserting. 12477class BlockContainerNodeInserter extends BaseNodeInserter { 12478 static handles(selection) { 12479 return $hasPointOnBlockContainer(selection) 12480 } 12481 12482 insertNodes(nodes) { 12483 St$3(this.selection); 12484 this.selection.insertNodes(nodes); 12485 } 12486} 12487 12488const INSERTERS = [ 12489 CodeNodeInserter, 12490 ShadowRootNodeInserter, 12491 NodeSelectionNodeInserter, 12492 ListItemNodeInserter, 12493 BlockContainerNodeInserter 12494]; 12495 12496// Defined here rather than on the base class so the base can stay free of any 12497// dependency on its subclasses (they import the base), avoiding an import cycle. 12498BaseNodeInserter.for = (selection) => { 12499 const inserterClass = INSERTERS.find(inserter => inserter.handles(selection)); 12500 return inserterClass ? new inserterClass(selection) : selection 12501}; 12502 12503// Word and Outlook never emit <ul>/<ol>/<li>. They simulate lists with flat 12504// paragraphs that declare their depth in an inline `mso-list:l0 level2 lfo1` 12505// and carry the bullet or number glyph in a <span style="mso-list:Ignore">. 12506// Nothing downstream understands either, so the items land as plain paragraphs 12507// with the marker baked into the text. Rebuild real lists from the level each 12508// paragraph declares. 12509// 12510// Everything this reads lives in inline attributes, so it stays correct after 12511// the pasted content formatter has dropped Office's style sheet. 12512class OfficeFormatter { 12513 constructor(doc) { 12514 this.doc = doc; 12515 } 12516 12517 format() { 12518 for (const run of this.#listRuns()) { 12519 this.#replaceWithLists(run); 12520 } 12521 } 12522 12523 // A run is a stretch of Office list paragraphs that are siblings with nothing 12524 // but whitespace and Word's conditional comments between them. Anything else 12525 // in between (a heading, a plain paragraph) ends one list and starts another. 12526 #listRuns() { 12527 const runs = []; 12528 const claimed = new Set(); 12529 12530 for (const paragraph of this.doc.querySelectorAll("p[style*='mso-list']")) { 12531 if (claimed.has(paragraph) || this.#listLevel(paragraph) === null) continue 12532 12533 const run = []; 12534 let node = paragraph; 12535 while (node) { 12536 run.push(node); 12537 claimed.add(node); 12538 node = this.#nextListParagraph(node); 12539 } 12540 runs.push(run); 12541 } 12542 12543 return runs 12544 } 12545 12546 #nextListParagraph(paragraph) { 12547 let sibling = paragraph.nextSibling; 12548 while (sibling && this.#isIgnorableBetweenListParagraphs(sibling)) { 12549 sibling = sibling.nextSibling; 12550 } 12551 12552 if (sibling && sibling.nodeType === Node.ELEMENT_NODE && this.#listLevel(sibling) !== null) { 12553 return sibling 12554 } 12555 12556 return null 12557 } 12558 12559 #isIgnorableBetweenListParagraphs(node) { 12560 if (node.nodeType === Node.COMMENT_NODE) { 12561 return true 12562 } 12563 return node.nodeType === Node.TEXT_NODE && node.textContent.trim() === "" 12564 } 12565 12566 // Word numbers levels from 1, but a copied selection often starts partway down 12567 // a list, so every paragraph declares level3 with no level1 above it. Anchoring 12568 // the run at its own shallowest level is what keeps the result from arriving 12569 // needlessly deep. 12570 #replaceWithLists(paragraphs) { 12571 const levels = paragraphs.map((paragraph) => this.#listLevel(paragraph)); 12572 const baseLevel = Math.min(...levels); 12573 const roots = []; 12574 const stack = []; 12575 12576 paragraphs.forEach((paragraph, index) => { 12577 const depth = levels[index] - baseLevel + 1; 12578 const tagName = this.#listTagName(paragraph); 12579 12580 while (stack.length > depth) { 12581 stack.pop(); 12582 } 12583 if (stack.length === depth && stack[depth - 1].tagName !== tagName.toUpperCase()) { 12584 stack.pop(); 12585 } 12586 12587 while (stack.length < depth) { 12588 const list = this.doc.createElement(tagName); 12589 if (stack.length === 0) { 12590 roots.push(list); 12591 } else { 12592 this.#lastItemOf(stack[stack.length - 1]).appendChild(list); 12593 } 12594 stack.push(list); 12595 } 12596 12597 stack[stack.length - 1].appendChild(this.#createListItem(paragraph)); 12598 }); 12599 12600 paragraphs[0].replaceWith(...roots); 12601 for (const paragraph of paragraphs.slice(1)) { 12602 paragraph.remove(); 12603 } 12604 } 12605 12606 #lastItemOf(list) { 12607 if (!list.lastElementChild) { 12608 list.appendChild(this.doc.createElement("li")); 12609 } 12610 return list.lastElementChild 12611 } 12612 12613 // Word writes bullets as the raw glyph of the marker font (Symbol's "·", 12614 // Wingdings' "§", Courier New's "o") and numbers as the rendered counter 12615 // ("1.", "a)", "iv)"). A bare letter with no delimiter after it is Courier 12616 // New's bullet, not a counter, so the delimiter is what tells them apart. 12617 #listTagName(paragraph) { 12618 const marker = paragraph.querySelector("[style*='mso-list:Ignore']"); 12619 const text = marker?.textContent || ""; 12620 12621 if (/\d/.test(text) || /^\(?[A-Za-z]+[.)]/.test(text)) { 12622 return "ol" 12623 } 12624 return "ul" 12625 } 12626 12627 #createListItem(paragraph) { 12628 for (const marker of paragraph.querySelectorAll("[style*='mso-list:Ignore']")) { 12629 marker.remove(); 12630 } 12631 12632 const item = this.doc.createElement("li"); 12633 item.append(...paragraph.childNodes); 12634 return item 12635 } 12636 12637 #listLevel(element) { 12638 const match = /mso-list:[^;"']*\blevel(\d+)/.exec(element.getAttribute("style") || ""); 12639 if (match) { 12640 return parseInt(match[1], 10) 12641 } 12642 return null 12643 } 12644} 12645 12646class PastedContentFormatter { 12647 constructor(doc) { 12648 this.doc = doc; 12649 } 12650 12651 format() { 12652 this.#stripStyleElements(); 12653 this.#unwrapPlaceholderAnchors(); 12654 this.#stripTableCellColorStyles(); 12655 new OfficeFormatter(this.doc).format(); 12656 this.#unwrapWrappedListChildren(); 12657 this.#nestStrayListChildren(); 12658 this.#stripStrayListChildren(); 12659 return this.doc 12660 } 12661 12662 // Spreadsheets (e.g. Excel) copy a <style> block whose rules (td { color: 12663 // black }, .xlNN { ... }) cascade onto the imported text. That color rides 12664 // in through the cascade rather than an inline style, so it slips past both 12665 // the cell-level stripping below and the paste style canonicalizer, leaving 12666 // pasted tables with foreign text colors that don't adapt to the theme. Drop 12667 // foreign style sheets so nothing cascades into imported content. 12668 #stripStyleElements() { 12669 for (const style of this.doc.querySelectorAll("style")) { 12670 style.remove(); 12671 } 12672 } 12673 12674 // Anchors with non-meaningful hrefs (e.g. "#", "") appear in content copied 12675 // from rendered views where mentions and interactive elements are wrapped in 12676 // <a href="#"> tags. Unwrap them so their text content pastes as plain text 12677 // and real links are preserved. 12678 #unwrapPlaceholderAnchors() { 12679 for (const anchor of this.doc.querySelectorAll("a")) { 12680 const href = anchor.getAttribute("href") || ""; 12681 if (href === "" || href === "#") { 12682 anchor.replaceWith(...anchor.childNodes); 12683 } 12684 } 12685 } 12686 12687 // Table cells copied from a page inherit the source theme's inline color 12688 // styles (e.g. dark-mode backgrounds). Strip them so pasted tables adopt 12689 // the current theme instead of carrying stale colors. 12690 #stripTableCellColorStyles() { 12691 for (const cell of this.doc.querySelectorAll("td, th")) { 12692 cell.style.removeProperty("background-color"); 12693 cell.style.removeProperty("background"); 12694 cell.style.removeProperty("color"); 12695 } 12696 } 12697 12698 // Some sources wrap runs of <li>s in a stray element (e.g. a <div> directly 12699 // inside the list). Dissolve such wrappers so their items become direct 12700 // list children and any nested list they hide becomes visible to 12701 // #nestStrayListChildren below. 12702 #unwrapWrappedListChildren() { 12703 for (const list of this.doc.querySelectorAll("ol, ul")) { 12704 let wrapper = this.#wrappedListChild(list); 12705 while (wrapper) { 12706 wrapper.replaceWith(...wrapper.childNodes); 12707 wrapper = this.#wrappedListChild(list); 12708 } 12709 } 12710 } 12711 12712 #wrappedListChild(list) { 12713 for (const child of list.children) { 12714 if (child.tagName !== "LI" && !this.#isNestedList(child) && this.#containsListItems(child)) { 12715 return child 12716 } 12717 } 12718 return null 12719 } 12720 12721 // Some sources (e.g. Gmail) nest a sublist as a direct child of the parent 12722 // <ol>/<ul> instead of inside a <li>. Move each nested list into its 12723 // preceding <li> so the import preserves the nesting instead of dropping it. 12724 #nestStrayListChildren() { 12725 for (const list of this.doc.querySelectorAll("ol, ul")) { 12726 for (const child of Array.from(list.children)) { 12727 if (child.tagName !== "OL" && child.tagName !== "UL") continue 12728 12729 const previousItem = child.previousElementSibling; 12730 if (previousItem && previousItem.tagName === "LI") { 12731 previousItem.appendChild(child); 12732 } 12733 } 12734 } 12735 } 12736 12737 // Only <li> is a valid child of a list. Unwrap remaining stray children 12738 // that still hold list items (a nested list with no preceding <li> to nest 12739 // under) so the items survive, and drop stray <br>/whitespace so the import 12740 // doesn't wrap them into an empty leading item. 12741 #stripStrayListChildren() { 12742 for (const list of this.doc.querySelectorAll("ol, ul")) { 12743 let stray = this.#firstStrayListChild(list); 12744 while (stray) { 12745 if (this.#containsListItems(stray)) { 12746 stray.replaceWith(...stray.childNodes); 12747 } else { 12748 stray.remove(); 12749 } 12750 12751 stray = this.#firstStrayListChild(list); 12752 } 12753 } 12754 } 12755 12756 #firstStrayListChild(list) { 12757 for (const child of list.childNodes) { 12758 if (child.nodeType !== Node.ELEMENT_NODE || child.tagName !== "LI") { 12759 return child 12760 } 12761 } 12762 return null 12763 } 12764 12765 #isNestedList(node) { 12766 return node.nodeType === Node.ELEMENT_NODE && (node.tagName === "OL" || node.tagName === "UL") 12767 } 12768 12769 #containsListItems(node) { 12770 return node.nodeType === Node.ELEMENT_NODE && node.querySelector("li") !== null 12771 } 12772} 12773 12774class Contents { 12775 constructor(editorElement) { 12776 this.editorElement = editorElement; 12777 this.editor = editorElement.editor; 12778 } 12779 12780 dispose() { 12781 this.editorElement = null; 12782 this.editor = null; 12783 } 12784 12785 get selection() { return this.editorElement.selection } 12786 12787 insertHtml(html, { tag } = {}) { 12788 this.insertDOM(parseHtml(html), { tag }); 12789 } 12790 12791 insertDOM(doc, { tag } = {}) { 12792 this.editor.update(() => { 12793 if (Es(jn)) this.#formatPastedDOM(doc); 12794 12795 const nodes = this.editorElement.$generateNodesFromDOM(doc); 12796 12797 if (!Es(jn) || !this.#dispatchPastedNodesCommand(nodes)) { 12798 this.#insertUploadNodes(nodes) || this.insertAtCursor(...nodes); 12799 } 12800 }, { tag }); 12801 } 12802 12803 insertText(text, { tag } = {}) { 12804 this.editor.update(() => { 12805 const paragraph = eo(); 12806 text.split("\n").forEach((line, index) => { 12807 if (index > 0) paragraph.append(or()); 12808 paragraph.append(kr(line)); 12809 }); 12810 this.insertAtCursor(paragraph); 12811 }, { tag }); 12812 } 12813 12814 // A literal "\n" stays visible in the editor, which Lexical renders with white-space: pre-wrap, 12815 // but collapses to a space once serialized to HTML, so it has to become line break nodes. 12816 insertTextWithLineBreaks(text) { 12817 const normalizedText = text?.replace(/\r\n?/g, "\n"); 12818 const selection = Qr(); 12819 12820 if (normalizedText?.includes("\n") && Fr(selection)) { 12821 selection.insertRawText(normalizedText); 12822 return true 12823 } else { 12824 return false 12825 } 12826 } 12827 12828 insertAtCursor(...nodes) { 12829 const selection = this.#insertableSelection(); 12830 const inserter = BaseNodeInserter.for(selection); 12831 12832 inserter.insertNodes(nodes); 12833 } 12834 12835 applyParagraphFormat() { 12836 const selection = Qr(); 12837 if (!Fr(selection)) return 12838 12839 $expandSelectionToLineBreaksAndSplitAtEdges(selection, (node) => Nt$2(node)); 12840 H$6(selection, () => eo()); 12841 } 12842 12843 applyHeadingFormat(tag) { 12844 const selection = Qr(); 12845 if (!Fr(selection)) return 12846 12847 $expandSelectionToLineBreaksAndSplitAtEdges(selection); 12848 H$6(selection, () => Jt$2(tag)); 12849 } 12850 12851 applyUnorderedListFormat() { 12852 this.#applyListFormat("bullet", Ee$2); 12853 } 12854 12855 applyOrderedListFormat() { 12856 this.#applyListFormat("number", Oe$1); 12857 } 12858 12859 clearFormatting() { 12860 const selection = Qr(); 12861 if (!Fr(selection)) return 12862 12863 D$3(node => { 12864 node.setFormat(0); 12865 node.setStyle(""); 12866 }); 12867 12868 Q$6(null); 12869 12870 this.#topLevelElementsInSelection(selection).filter(Mt$2).forEach(node => this.#unwrap(node)); 12871 12872 H$6(selection, () => eo()); 12873 } 12874 12875 toggleCodeBlock() { 12876 const selection = Qr(); 12877 if (!Fr(selection)) return 12878 12879 if (this.#insertNodeIfRoot(I$1("plain"))) return 12880 12881 const blockElements = this.#blockLevelElementsInSelection(selection); 12882 const allCode = blockElements.every(W$1); 12883 12884 if (allCode) { 12885 blockElements.forEach(node => this.#unwrapCodeBlock(node)); 12886 } else { 12887 $expandSelectionToLineBreaksAndSplitAtEdges(selection); 12888 const elements = this.#outermostElements(this.#blockLevelElementsInSelection(selection)); 12889 if (elements.length === 0) return 12890 12891 const codeNode = I$1("plain"); 12892 elements.at(-1).insertAfter(codeNode); 12893 codeNode.selectEnd(); 12894 this.insertAtCursor(...elements); 12895 } 12896 } 12897 12898 toggleBlockquote() { 12899 const selection = Qr(); 12900 if (!Fr(selection)) return 12901 12902 if (this.#insertNodeIfRoot(St$1())) return 12903 12904 const topLevelElements = this.#topLevelElementsInSelection(selection); 12905 12906 const allQuoted = topLevelElements.length > 0 && topLevelElements.every(Mt$2); 12907 12908 if (allQuoted) { 12909 topLevelElements.forEach(node => this.#unwrap(node)); 12910 } else { 12911 topLevelElements.filter(Mt$2).forEach(node => this.#unwrap(node)); 12912 12913 $expandSelectionToLineBreaksAndSplitAtEdges(selection); 12914 const elements = this.#topLevelElementsInSelection(selection); 12915 if (elements.length === 0) return 12916 12917 const blockquote = St$1(); 12918 elements[0].insertBefore(blockquote); 12919 elements.forEach((element) => blockquote.append(element)); 12920 } 12921 } 12922 12923 hasSelectedText() { 12924 let result = false; 12925 12926 this.editor.read(() => { 12927 const selection = Qr(); 12928 result = Fr(selection) && !selection.isCollapsed(); 12929 }); 12930 12931 return result 12932 } 12933 12934 createLink(url) { 12935 let linkNodeKey = null; 12936 12937 this.editor.update(() => { 12938 const textNode = kr(url); 12939 const linkNode = $$2(url); 12940 linkNode.append(textNode); 12941 12942 const selection = Qr(); 12943 if (Fr(selection)) { 12944 BaseNodeInserter.for(selection).insertNodes([ linkNode ]); 12945 linkNodeKey = linkNode.getKey(); 12946 } 12947 }); 12948 12949 return linkNodeKey 12950 } 12951 12952 createLinkWithSelectedText(url) { 12953 if (!this.hasSelectedText()) return 12954 12955 this.editor.update(() => { 12956 Q$6(null); 12957 Q$6(url); 12958 }); 12959 } 12960 12961 textBackUntil(string) { 12962 let result = ""; 12963 12964 this.editor.getEditorState().read(() => { 12965 const selection = Qr(); 12966 if (!selection || !selection.isCollapsed()) return 12967 12968 const anchor = selection.anchor; 12969 const anchorNode = anchor.getNode(); 12970 12971 if (!Tr(anchorNode)) return 12972 12973 const fullText = anchorNode.getTextContent(); 12974 const offset = anchor.offset; 12975 12976 const lastIndex = fullText.slice(0, offset).lastIndexOf(string); 12977 if (lastIndex !== -1) { 12978 result = fullText.slice(lastIndex + string.length, this.#endOffsetAt(fullText, offset)); 12979 } 12980 }); 12981 12982 return result 12983 } 12984 12985 // The query runs from the trigger up to the next boundary, even when the 12986 // cursor sits inside an existing word â inserting "@" before "Jack" must 12987 // filter by "Jack" rather than treating the prompt as empty. 12988 #endOffsetAt(fullText, cursorOffset) { 12989 for (let offset = cursorOffset; offset < fullText.length; offset++) { 12990 if (this.#isQueryBoundary(fullText, offset)) { 12991 return offset 12992 } 12993 } 12994 12995 return fullText.length 12996 } 12997 12998 // Whitespace always ends the query. Punctuation ends it too: with "@" typed 12999 // right before a period, extending across it would glue "." onto everything 13000 // typed ("B" would query "B."), matching the wrong names or nothing at all. 13001 // But punctuation joining two word characters is part of a name â "@" before 13002 // "Anne-Marie" or "O'Connor" must keep the whole name as the query. 13003 #isQueryBoundary(fullText, offset) { 13004 const character = fullText[offset]; 13005 if (/\s/.test(character)) return true 13006 if (!/\p{P}/u.test(character)) return false 13007 13008 return !(this.#isWordCharacter(fullText[offset - 1]) && this.#isWordCharacter(fullText[offset + 1])) 13009 } 13010 13011 #isWordCharacter(character) { 13012 return character != null && /[\p{L}\p{N}]/u.test(character) 13013 } 13014 13015 containsTextBackUntil(string) { 13016 let result = false; 13017 13018 this.editor.getEditorState().read(() => { 13019 const selection = Qr(); 13020 if (!selection || !selection.isCollapsed()) return 13021 13022 const anchor = selection.anchor; 13023 const anchorNode = anchor.getNode(); 13024 13025 if (!Tr(anchorNode)) return 13026 13027 const fullText = anchorNode.getTextContent(); 13028 const offset = anchor.offset; 13029 13030 const textBeforeCursor = fullText.slice(0, offset); 13031 13032 result = textBeforeCursor.includes(string); 13033 }); 13034 13035 return result 13036 } 13037 13038 replaceTextBackUntil(stringToReplace, replacementNodes) { 13039 replacementNodes = Array.isArray(replacementNodes) ? replacementNodes : [ replacementNodes ]; 13040 13041 const { anchorNode, offset } = this.#getTextAnchorData(); 13042 if (!anchorNode) return 13043 13044 const lastIndex = this.#findReplacementStart(anchorNode, offset, stringToReplace); 13045 if (lastIndex === -1) return 13046 13047 this.#performTextReplacement(anchorNode, lastIndex, stringToReplace, replacementNodes); 13048 } 13049 13050 uploadFiles(files, { selectLast } = {}) { 13051 if (!this.editorElement) return // Disposed (e.g. on turbo:before-cache); a late drop can still land here 13052 13053 if (!this.editorElement.supportsAttachments) { 13054 console.warn("This editor does not supports attachments (it's configured with [attachments=false])"); 13055 return 13056 } 13057 const validFiles = Array.from(files).filter(file => this.editorElement.acceptsFile(file)); 13058 13059 this.editor.update(() => { 13060 const uploader = Uploader.for(this.editorElement, validFiles); 13061 uploader.$uploadFiles(); 13062 13063 if (selectLast && uploader.nodes?.length) { 13064 const lastNode = uploader.nodes.at(-1); 13065 lastNode.selectEnd(); 13066 this.#normalizeSelectionInShadowRoot(); 13067 } 13068 }); 13069 } 13070 13071 $createUploadNode(file) { 13072 return $createActionTextAttachmentUploadNode({ 13073 file, 13074 uploadUrl: this.editorElement.directUploadUrl, 13075 blobUrlTemplate: this.editorElement.blobUrlTemplate, 13076 contentType: file.type, 13077 }) 13078 } 13079 13080 $createPendingUploadNode(file) { 13081 return $createActionTextAttachmentUploadNode({ 13082 file, 13083 uploadUrl: null, 13084 blobUrlTemplate: this.editorElement.blobUrlTemplate, 13085 contentType: file.type, 13086 }) 13087 } 13088 13089 insertPendingAttachment(file) { 13090 if (!this.editorElement.supportsAttachments) return null 13091 13092 let nodeKey = null; 13093 this.editor.update(() => { 13094 const uploadNode = this.$createPendingUploadNode(file); 13095 this.insertAtCursor(uploadNode); 13096 nodeKey = uploadNode.getKey(); 13097 }); 13098 13099 return nodeKey ? this.#pendingAttachmentHandle(nodeKey) : null 13100 } 13101 13102 insertPendingAttachments(files) { 13103 const fileList = Array.from(files); 13104 if (!this.editorElement.supportsAttachments || fileList.length === 0) return [] 13105 13106 let nodeKeys = []; 13107 this.editor.update(() => { 13108 const uploader = Uploader.for(this.editorElement, fileList, { pending: true }); 13109 uploader.$uploadFiles(); 13110 nodeKeys = (uploader.nodes ?? []).map(node => node.getKey()); 13111 }); 13112 13113 return nodeKeys.map(nodeKey => this.#pendingAttachmentHandle(nodeKey)) 13114 } 13115 13116 #pendingAttachmentHandle(initialNodeKey) { 13117 const editor = this.editor; 13118 let nodeKey = initialNodeKey; 13119 13120 return { 13121 setAttributes(blob) { 13122 editor.update(() => { 13123 const node = Yo(nodeKey); 13124 if (!(node instanceof ActionTextAttachmentUploadNode)) return 13125 13126 const replacementNodeKey = node.$showUploadedAttachment(blob); 13127 if (replacementNodeKey) { 13128 nodeKey = replacementNodeKey; 13129 } 13130 }, { tag: Jn }); 13131 }, 13132 setUploadProgress(progress) { 13133 editor.update(() => { 13134 const node = Yo(nodeKey); 13135 if (!(node instanceof ActionTextAttachmentUploadNode)) return 13136 13137 node.getWritable().progress = progress; 13138 }, { tag: Jn }); 13139 }, 13140 remove() { 13141 editor.update(() => { 13142 const node = Yo(nodeKey); 13143 if (node) node.remove(); 13144 }); 13145 } 13146 } 13147 } 13148 13149 replaceNodeWithHTML(nodeKey, html, options = {}) { 13150 this.editor.update(() => { 13151 const node = Yo(nodeKey); 13152 if (!node) return 13153 13154 const selection = Qr(); 13155 let wasSelected = false; 13156 13157 if (Fr(selection)) { 13158 const selectedNodes = selection.getNodes(); 13159 wasSelected = selectedNodes.includes(node) || selectedNodes.some(n => n.getParent() === node); 13160 13161 if (wasSelected) { 13162 es(null); 13163 } 13164 } 13165 13166 const replacementNode = options.attachment ? this.#createCustomAttachmentNodeWithHtml(html, options.attachment) : this.#createHtmlNodeWith(html); 13167 node.replace(replacementNode); 13168 13169 if (wasSelected) { 13170 replacementNode.selectEnd(); 13171 } 13172 }); 13173 } 13174 13175 insertHTMLBelowNode(nodeKey, html, options = {}) { 13176 this.editor.update(() => { 13177 const node = Yo(nodeKey); 13178 if (!node) return 13179 13180 const previousNode = node.getTopLevelElement() || node; 13181 13182 const newNode = options.attachment ? this.#createCustomAttachmentNodeWithHtml(html, options.attachment) : this.#createHtmlNodeWith(html); 13183 previousNode.insertAfter(newNode); 13184 }); 13185 } 13186 13187 #insertableSelection() { 13188 const selection = Qr(); 13189 if (Ir(selection) && selection.getNodes().length === 0) { 13190 return Zo().selectEnd() 13191 } 13192 13193 return selection ?? Zo().selectEnd() 13194 } 13195 13196 #formatPastedDOM(doc) { 13197 new PastedContentFormatter(doc).format(); 13198 } 13199 13200 #dispatchPastedNodesCommand(nodes) { 13201 return this.editor.dispatchCommand(oe$6, { 13202 nodes, selection: Qr() 13203 }) 13204 } 13205 13206 #insertNodeIfRoot(node) { 13207 const selection = Qr(); 13208 if (!Fr(selection)) return false 13209 13210 const anchorNode = selection.anchor.getNode(); 13211 if (Is(anchorNode)) { 13212 anchorNode.append(node); 13213 node.selectEnd(); 13214 13215 return true 13216 } 13217 13218 return false 13219 } 13220 13221 #unwrapCodeBlock(codeNode) { 13222 const children = codeNode.getChildren(); 13223 const groups = [ [] ]; 13224 13225 for (const child of children) { 13226 if (sr(child)) { 13227 groups.push([]); 13228 } else { 13229 groups[groups.length - 1].push(child.getTextContent()); 13230 } 13231 } 13232 13233 for (const group of groups) { 13234 const paragraph = eo(); 13235 const text = group.join(""); 13236 if (text) { 13237 paragraph.append(kr(text)); 13238 } 13239 codeNode.insertBefore(paragraph); 13240 } 13241 13242 codeNode.remove(); 13243 } 13244 13245 #applyListFormat(listType, command) { 13246 if (this.selection.isInsideBlockQuote) { 13247 this.#insertListInsideQuote(listType); 13248 } else { 13249 this.#splitParagraphsAtLineBreaksUnlessInsideList(); 13250 this.editor.dispatchCommand(command); 13251 } 13252 } 13253 13254 #insertListInsideQuote(listType) { 13255 for (const group of $consecutiveSiblingGroups(this.#quotedBlocksInSelection())) { 13256 this.#wrapBlocksInList(group, listType); 13257 } 13258 } 13259 13260 #quotedBlocksInSelection() { 13261 const selection = Qr(); 13262 if (!Fr(selection)) return [] 13263 13264 const blocks = this.#outermostElements(this.#blockLevelElementsInSelection(selection)); 13265 return blocks.filter((block) => Mt$2(block.getParent())) 13266 } 13267 13268 #wrapBlocksInList(blocks, listType) { 13269 const list = Te$1(listType); 13270 blocks[0].insertBefore(list); 13271 13272 for (const block of blocks) { 13273 const listItem = fe$2(); 13274 if (Se$1(block)) { 13275 listItem.append(...block.getChildren().flatMap((item) => item.getChildren())); 13276 } else { 13277 listItem.append(...block.getChildren()); 13278 } 13279 list.append(listItem); 13280 block.remove(); 13281 } 13282 } 13283 13284 #splitParagraphsAtLineBreaksUnlessInsideList() { 13285 if (this.selection.isInsideList) return 13286 13287 const selection = Qr(); 13288 if (!Fr(selection)) return 13289 13290 $expandSelectionToLineBreaksAndSplitAtEdges(selection); 13291 $splitSelectedParagraphsAtInnerLineBreaks(selection); 13292 } 13293 13294 #blockLevelElementsInSelection(selection) { 13295 const blocks = new Set(); 13296 for (const node of selection.getNodes()) { 13297 blocks.add(Nt$2(node)); 13298 } 13299 13300 return Array.from(blocks) 13301 } 13302 13303 #topLevelElementsInSelection(selection) { 13304 const elements = new Set(); 13305 for (const node of selection.getNodes()) { 13306 const topLevel = node.getTopLevelElement(); 13307 if (topLevel) elements.add(topLevel); 13308 } 13309 return Array.from(elements) 13310 } 13311 13312 // Selections spanning nested structures (a quote and its inner paragraphs, 13313 // nested list items) yield both an element and its ancestor. Converting the 13314 // ancestor detaches its whole subtree â including a node freshly inserted 13315 // inside it â which can leave the selection on removed nodes (Lexical 13316 // invariant #19). The outermost elements already cover their descendants' 13317 // text content, so keep only those. 13318 #outermostElements(elements) { 13319 return elements.filter((element) => { 13320 return elements.every((other) => other === element || !element.getParents().includes(other)) 13321 }) 13322 } 13323
13324 #insertUploadNodes(nodes) { 13325 if (nodes.every($isActionTextAttachmentNode)) { 13326 const uploader = Uploader.for(this.editorElement, []); 13327 uploader.nodes = nodes; 13328 uploader.$insertUploadNodes(); 13329 return true 13330 } 13331 } 13332 13333 #unwrap(node) { 13334 const children = node.getChildren(); 13335 13336 if (children.length == 0) { 13337 node.insertBefore(eo()); 13338 } else { 13339 children.forEach((child) => { 13340 if (Tr(child) && child.getTextContent().trim() !== "") { 13341 const newParagraph = eo(); 13342 newParagraph.append(child); 13343 node.insertBefore(newParagraph); 13344 } else if (!sr(child)) { 13345 node.insertBefore(child); 13346 } 13347 }); 13348 } 13349 13350 node.remove(); 13351 } 13352 13353 #getTextAnchorData() { 13354 const selection = Qr(); 13355 if (!selection || !selection.isCollapsed()) return { anchorNode: null, offset: 0 } 13356 13357 const anchor = selection.anchor; 13358 const anchorNode = anchor.getNode(); 13359 13360 if (!Tr(anchorNode)) return { anchorNode: null, offset: 0 } 13361 13362 return { anchorNode, offset: anchor.offset } 13363 } 13364 13365 // The replaced span must start before the cursor but can extend past it 13366 // (e.g. "@Jack" when "@" was just inserted before "Jack"), so we bound the 13367 // match's start with lastIndexOf's fromIndex rather than slicing the text. 13368 #findReplacementStart(anchorNode, offset, stringToReplace) { 13369 if (offset === 0) { 13370 // A negative fromIndex clamps to 0 and could match at the cursor 13371 return -1 13372 } else { 13373 return anchorNode.getTextContent().lastIndexOf(stringToReplace, offset - 1) 13374 } 13375 } 13376 13377 #performTextReplacement(anchorNode, startIndex, stringToReplace, replacementNodes) { 13378 const fullText = anchorNode.getTextContent(); 13379 const textBeforeString = fullText.slice(0, startIndex); 13380 const textAfterString = fullText.slice(startIndex + stringToReplace.length); 13381 13382 const textNodeBefore = this.#cloneTextNodeFormatting(anchorNode, textBeforeString); 13383 const textNodeAfter = this.#cloneTextNodeFormatting(anchorNode, textAfterString || " "); 13384 13385 anchorNode.replace(textNodeBefore); 13386 13387 const lastInsertedNode = this.#insertReplacementNodes(textNodeBefore, replacementNodes); 13388 lastInsertedNode.insertAfter(textNodeAfter); 13389 13390 this.#appendLineBreakIfNeeded(textNodeAfter.getParentOrThrow()); 13391 const cursorOffset = textAfterString ? 0 : 1; 13392 textNodeAfter.select(cursorOffset, cursorOffset); 13393 } 13394 13395 #cloneTextNodeFormatting(anchorNode, text) { 13396 return kr(text) 13397 .setFormat(anchorNode.getFormat()) 13398 .setDetail(anchorNode.getDetail()) 13399 .setMode(anchorNode.getMode()) 13400 .setStyle(anchorNode.getStyle()) 13401 } 13402 13403 #insertReplacementNodes(startNode, replacementNodes) { 13404 let previousNode = startNode; 13405 for (const node of replacementNodes) { 13406 previousNode.insertAfter(node); 13407 previousNode = node; 13408 } 13409 return previousNode 13410 } 13411 13412 #appendLineBreakIfNeeded(paragraph) { 13413 if (no(paragraph) && this.editorElement.supportsMultiLine) { 13414 const children = paragraph.getChildren(); 13415 const last = children[children.length - 1]; 13416 const beforeLast = children[children.length - 2]; 13417 13418 if (Tr(last) && last.getTextContent() === "" && (beforeLast && !Tr(beforeLast))) { 13419 paragraph.append(or()); 13420 } 13421 } 13422 } 13423 13424 #createCustomAttachmentNodeWithHtml(html, options = {}) { 13425 const attachmentConfig = typeof options === "object" ? options : {}; 13426 const contentType = attachmentConfig.contentType || "text/html"; 13427 if (!this.editorElement.permitsAttachmentContentType(contentType)) { 13428 return this.#createHtmlNodeWith(html) 13429 } 13430 return new CustomActionTextAttachmentNode({ 13431 sgid: attachmentConfig.sgid || null, 13432 contentType, 13433 innerHtml: html, 13434 }) 13435 } 13436 13437 #createHtmlNodeWith(html) { 13438 const htmlNodes = this.editorElement.$generateNodesFromDOM(parseHtml(html)); 13439 return htmlNodes[0] || eo() 13440 } 13441 13442 // When the selection anchor is on a shadow root (e.g. a table cell), Lexical's 13443 // insertNodes can't find a block parent and fails silently. Normalize the 13444 // selection to point inside the shadow root's content instead. 13445 #normalizeSelectionInShadowRoot() { 13446 const selection = Qr(); 13447 if (!Fr(selection)) return 13448 13449 const anchorNode = selection.anchor.getNode(); 13450 if (!$isShadowRoot(anchorNode)) return 13451 13452 // Append a paragraph inside the shadow root so there's a valid text-level 13453 // target for subsequent insertions. This is necessary because decorator 13454 // nodes (e.g. attachments) at the end of a table cell leave the selection 13455 // on the cell itself with no block-level descendant to anchor to. 13456 const paragraph = eo(); 13457 anchorNode.append(paragraph); 13458 paragraph.selectStart(); 13459 } 13460} 13461 13462/** 13463 * marked v16.4.1 - a markdown parser 13464 * Copyright (c) 2011-2025, Christopher Jeffrey. (MIT Licensed) 13465 * https://github.com/markedjs/marked 13466 */ 13467 13468/** 13469 * DO NOT EDIT THIS FILE 13470 * The code in this file is generated from files in ./src/ 13471 */ 13472 13473function 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 13473
13473:/\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 13473-13475
13473).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} *[^ 13474]`).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={"&":"&","<":"<",">":">",'"':""","'":"'"},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(` 13475`).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 13475-13498
13475=r.length?i.slice(r.length):i}).join(` 13476`)}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,` 13477`)}}}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],` 13478`)}}blockquote(e){let t=this.rules.block.blockquote.exec(e);if(t){let n=z(t[0],` 13479`).split(` 13480`),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(` 13481`),p=c.replace(this.rules.other.blockquoteSetextReplace,` 13482 $1`).replace(this.rules.other.blockquoteSetextReplace2,"");r=r?`${r} 13483${c}`:c,i=i?`${i} 13484${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+` 13485`+n.join(` 13486`),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+` 13487`+n.join(` 13488`),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(` 13489`);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(` 13490`,1)[0].replace(this.rules.other.listReplaceTabs,H=>" ".repeat(3*H.length)),d=e.split(` 13491`,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+` 13492`,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(` 13493`,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+=` 13494`+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+=` 13495`+d;}!R&&!d.trim()&&(R=true),c+=Z+` 13496`,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(` 13497`):[],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)===` 13498`?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 13498-13532
13498(!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,` 13499`),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+=` 13500`: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(` 13501`)?"":` 13502`)+r.raw,s.text+=` 13503`+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(` 13504`)?"":` 13505`)+r.raw,s.text+=` 13506`+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(` 13507`)?"":` 13508`)+r.raw,s.text+=` 13509`+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(` 13510`)?"":` 13511`)+r.raw,s.text+=` 13512`+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,"")+` 13513`;return r?'<pre><code class="language-'+w(r)+'">'+(n?i:w(i,true))+`</code></pre> 13514`:"<pre><code>"+(n?i:w(i,true))+`</code></pre> 13515`}blockquote({tokens:e}){return `<blockquote> 13516${this.parser.parse(e)}</blockquote> 13517`}html({text:e}){return e}def(e){return ""}heading({tokens:e,depth:t}){return `<h${t}>${this.parser.parseInline(e)}</h${t}> 13518`}hr(e){return `<hr> 13519`}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+`> 13520`+r+"</"+i+`> 13521`}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> 13522`}checkbox({checked:e}){return "<input "+(e?'checked="" ':"")+'disabled="" type="checkbox">'}paragraph({tokens:e}){return `<p>${this.parser.parseInline(e)}</p> 13523`}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> 13524<thead> 13525`+t+`</thead> 13526`+r+`</table> 13527`}tablerow({text:e}){return `<tr> 13528${e}</tr> 13529`}tablecell(e){let t=this.parser.parseInline(e.tokens),n=e.header?"th":"td";return (e.align?`<${n} align="${e.align}">`:`<${n}>`)+t+`</${n}> 13530`}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+=` 13531`+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+=` 13532Please 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)}
13532k.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; 13533 13534class Clipboard { 13535 #listeners = new ListenerBin() 13536 13537 constructor(editorElement) { 13538 this.editorElement = editorElement; 13539 this.editor = editorElement.editor; 13540 this.contents = editorElement.contents; 13541 13542 this.#registerPasteCommands(); 13543 } 13544 13545 dispose() { 13546 this.editorElement = null; 13547 this.editor = null; 13548 this.contents = null; 13549 13550 this.#listeners.dispose(); 13551 } 13552 13553 paste(event) { 13554 const clipboardData = event.clipboardData; 13555 13556 if (!clipboardData) return false 13557 13558 if (this.#isPastingIntoCodeBlock()) { 13559 this.#pastePlainTextIntoCodeBlock(clipboardData); 13560 event.preventDefault(); 13561 return true 13562 } 13563 13564 if (this.#isPlainTextOrURLPasted(clipboardData)) { 13565 this.#pastePlainTextOrURL(clipboardData); 13566 event.preventDefault(); 13567 return true 13568 } 13569 13570 const handled = this.#handlePastedFiles(clipboardData); 13571 if (handled) event.preventDefault(); 13572 return handled 13573 } 13574 13575 #registerPasteCommands() { 13576 this.#listeners.track( 13577 this.editor.registerCommand(_e$2, this.paste.bind(this), oo), 13578 this.editor.registerCommand( 13579 oe$6, 13580 (payload) => this.#handleParsedClipboardNodes(payload), 13581 oo 13582 ) 13583 ); 13584 } 13585 13586 #handleParsedClipboardNodes({ nodes, selection }) { 13587 const url = $bareUrlFromSingleLink(nodes); 13588 if (url && Fr(selection)) { 13589 this.#insertSingleLinkAt(selection, url); 13590 return true 13591 } 13592 } 13593 13594 #isPlainTextOrURLPasted(clipboardData) { 13595 return this.#isOnlyPlainTextPasted(clipboardData) || this.#isOnlyURLPasted(clipboardData) 13596 } 13597 13598 #isOnlyPlainTextPasted(clipboardData) { 13599 const types = Array.from(clipboardData.types); 13600 return types.length === 1 && types[0] === "text/plain" 13601 } 13602 13603 // Browsers expose a copied URL in several shapes: 13604 // Safari [ text/plain, text/uri-list ] 13605 // App ShareSheet [ text/uri-list ] 13606 // Chromium macOS [ text/plain, text/html, (?:text/link-preview) ] 13607 #isOnlyURLPasted(clipboardData) { 13608 if (this.#isLexicalClipboardData(clipboardData)) return false 13609 13610 const types = Array.from(clipboardData.types); 13611 if (types.includes("text/uri-list")) { 13612 return types.every(type =>
vendor: 34,166 bytes, lines 13612-14718
13612 type === "text/plain" || type === "text/uri-list") 13613 } 13614 13615 if (clipboardData.files.length) return false 13616 13617 const text = clipboardData.getData("text/plain").trim(); 13618 if (!isAutolinkableURL(text)) return false 13619 13620 const html = clipboardData.getData("text/html"); 13621 return !html || this.#htmlIsBareLinkToURL(html, text) 13622 } 13623 13624 #htmlIsBareLinkToURL(html, url) { 13625 const doc = parseHtml(html); 13626 if (doc.body.textContent.trim() !== url) return false 13627 13628 const links = doc.body.querySelectorAll("a"); 13629 if (links.length === 0) return true 13630 return links.length === 1 && links[0].getAttribute("href") === url 13631 } 13632 13633 #isPastingIntoCodeBlock() { 13634 let result = false; 13635 13636 this.editor.getEditorState().read(() => { 13637 const selection = Qr(); 13638 if (!Fr(selection)) return 13639 13640 let currentNode = selection.anchor.getNode(); 13641 13642 while (currentNode) { 13643 if (W$1(currentNode)) { 13644 result = true; 13645 return 13646 } 13647 currentNode = currentNode.getParent(); 13648 } 13649 }); 13650 13651 return result 13652 } 13653 13654 #pastePlainTextIntoCodeBlock(clipboardData) { 13655 const text = clipboardData.getData("text/plain"); 13656 if (!text) return 13657 13658 this.editor.update(() => { 13659 const selection = Qr(); 13660 if (Fr(selection)) selection.insertRawText(text); 13661 }, { tag: jn }); 13662 } 13663 13664 #pastePlainTextOrURL(clipboardData) { 13665 const item = this.#plainTextOrURLItem(clipboardData); 13666 item.getAsString((text) => { 13667 const url = text.trim(); 13668 if (isAutolinkableURL(url)) { 13669 this.#pasteURL(url); 13670 } else if (this.editorElement.supportsMarkdown) { 13671 this.#pasteMarkdown(text); 13672 } else { 13673 this.#pasteRichText(clipboardData); 13674 } 13675 }); 13676 } 13677 13678 #plainTextOrURLItem(clipboardData) { 13679 const items = Array.from(clipboardData.items); 13680 return items.find((item) => item.type === "text/plain") || items.find((item) => item.type === "text/uri-list") 13681 } 13682 13683 #pasteURL(url) { 13684 if (this.contents.hasSelectedText()) { 13685 this.contents.createLinkWithSelectedText(url); 13686 } else { 13687 const nodeKey = this.contents.createLink(url); 13688 this.#dispatchLinkInsertEvent(nodeKey, { url }); 13689 } 13690 } 13691 13692 #insertSingleLinkAt(selection, url) { 13693 if (!Fr(selection)) return 13694 13695 if (!selection.isCollapsed()) { 13696 Q$6(null); 13697 Q$6(url); 13698 return 13699 } 13700 13701 const linkNode = $$2(url).append(kr(url)); 13702 BaseNodeInserter.for(selection).insertNodes([ linkNode ]); 13703 13704 Ms(() => this.#dispatchLinkInsertEvent(linkNode.getKey(), { url })); 13705 } 13706 13707 #dispatchLinkInsertEvent(nodeKey, payload) { 13708 const linkManipulationMethods = { 13709 replaceLinkWith: (html, options) => this.contents.replaceNodeWithHTML(nodeKey, html, options), 13710 insertBelowLink: (html, options) => this.contents.insertHTMLBelowNode(nodeKey, html, options) 13711 }; 13712 13713 dispatch(this.editorElement, "lexxy:insert-link", { 13714 ...payload, 13715 ...linkManipulationMethods 13716 }); 13717 } 13718 13719 #pasteMarkdown(text) { 13720 const html = k(text, { breaks: true }); 13721 const doc = parseHtml(html); 13722 13723 if (this.#isPlainTextWithoutMarkdown(doc)) { 13724 this.contents.insertText(text, { tag: jn }); 13725 } else { 13726 const detail = Object.freeze({ 13727 markdown: text, 13728 document: doc, 13729 addBlockSpacing: () => addBlockSpacing(doc) 13730 }); 13731 13732 dispatch(this.editorElement, "lexxy:insert-markdown", detail); 13733 this.contents.insertDOM(doc, { tag: jn }); 13734 } 13735 } 13736 13737 // Markdown conversion collapses runs of whitespace and unescapes backslashes, 13738 // silently corrupting plain text such as Windows/UNC file paths. When the text 13739 // carries no Markdown structure, paste it verbatim instead. A path that wrapped 13740 // across lines renders as a single paragraph with <br> line breaks (marked runs 13741 // with breaks: true), which is still plain text we should preserve untouched. 13742 #isPlainTextWithoutMarkdown(doc) { 13743 const elements = Array.from(doc.body.children); 13744 if (elements.length !== 1) return false 13745 13746 const paragraph = elements[0]; 13747 return paragraph.nodeName === "P" 13748 && Array.from(paragraph.childNodes).every((node) => node.nodeType === Node.TEXT_NODE || node.nodeName === "BR") 13749 } 13750 13751 #pasteRichText(clipboardData) { 13752 this.editor.update(() => { 13753 const selection = Qr(); 13754 I$3(clipboardData, selection, this.editor); 13755 }, { tag: jn }); 13756 } 13757 13758 #handlePastedFiles(clipboardData) { 13759 if (!this.editorElement.supportsAttachments) return false 13760 13761 const html = clipboardData.getData("text/html"); 13762 const files = clipboardData.files; 13763 13764 if (files.length && this.#isCopiedImageHTML(html)) { 13765 this.#uploadFilesPreservingScroll(files); 13766 return true 13767 } 13768 13769 if (html && !this.#isLexicalClipboardData(clipboardData)) { 13770 this.contents.insertHtml(html, { tag: jn }); 13771 return true 13772 } 13773 13774 if (files.length) { 13775 this.#uploadFilesPreservingScroll(files); 13776 return true 13777 } 13778 13779 return false 13780 } 13781 13782 #isLexicalClipboardData(clipboardData) { 13783 return Array.from(clipboardData.types).includes("application/x-lexical-editor") 13784 } 13785 13786 #isCopiedImageHTML(html) { 13787 if (!html) return false 13788 13789 const doc = parseHtml(html); 13790 const elementChildren = Array.from(doc.body.children); 13791 13792 return elementChildren.length === 1 && elementChildren[0].tagName === "IMG" 13793 } 13794 13795 #uploadFilesPreservingScroll(files) { 13796 this.#preservingScrollPosition(() => { 13797 if (files.length) { 13798 this.contents.uploadFiles(files, { selectLast: true }); 13799 } 13800 }); 13801 } 13802 13803 // Deals with an issue in Safari where it scrolls to the tops after pasting attachments 13804 async #preservingScrollPosition(callback) { 13805 const scrollY = window.scrollY; 13806 const scrollX = window.scrollX; 13807 13808 callback(); 13809 13810 await nextFrame(); 13811 13812 window.scrollTo(scrollX, scrollY); 13813 this.editor.focus(); 13814 } 13815} 13816 13817function $bareUrlFromSingleLink(nodes) { 13818 if (nodes.length !== 1) return null 13819 13820 const node = nodes[0]; 13821 if (z$5(node)) return $bareUrlFromLink(node) 13822 13823 if (no(node)) { 13824 const children = node.getChildren(); 13825 if (children.length === 1 && z$5(children[0])) { 13826 return $bareUrlFromLink(children[0]) 13827 } 13828 } 13829 13830 return null 13831} 13832 13833function $bareUrlFromLink(linkNode) { 13834 const url = linkNode.getURL(); 13835 if (!url) return null 13836 return linkNode.getTextContent() === url ? url : null 13837} 13838 13839class Extensions { 13840 13841 constructor(lexxyElement) { 13842 this.lexxyElement = lexxyElement; 13843 13844 this.enabledExtensions = this.#initializeExtensions(); 13845 } 13846 13847 get lexicalExtensions() { 13848 return this.enabledExtensions.map(ext => ext.lexicalExtension).filter(Boolean) 13849 } 13850 13851 initializeToolbars() { 13852 const toolbar = this.#lexxyToolbar; 13853 if (!toolbar) return 13854 13855 this.#clearPreviousExtensionToolbarButtons(toolbar); 13856 this.#addExtensionToolbarButtons(toolbar); 13857 toolbar.requestOverflowRefresh(); 13858 } 13859 13860 dispose() { 13861 while (this.enabledExtensions.length) { 13862 this.enabledExtensions.pop().dispose(); 13863 } 13864 } 13865 13866 #clearPreviousExtensionToolbarButtons(toolbar) { 13867 toolbar.querySelectorAll("[data-lexxy-extension]").forEach(el => el.remove()); 13868 } 13869 13870 #addExtensionToolbarButtons(toolbar) { 13871 this.enabledExtensions.forEach(ext => { 13872 const childrenBefore = new Set(toolbar.children); 13873 ext.initializeToolbar(toolbar); 13874 for (const child of toolbar.children) { 13875 if (!childrenBefore.has(child)) { 13876 child.setAttribute("data-lexxy-extension", ""); 13877 } 13878 } 13879 }); 13880 } 13881 13882 get allowedElements() { 13883 return this.enabledExtensions.flatMap(ext => ext.allowedElements) 13884 } 13885 13886 get #lexxyToolbar() { 13887 return this.lexxyElement.toolbar 13888 } 13889 13890 get #baseExtensions() { 13891 return this.lexxyElement.baseExtensions 13892 } 13893 13894 get #configuredExtensions() { 13895 return Lexxy.global.get("extensions") 13896 } 13897 13898 #initializeExtensions() { 13899 const extensionDefinitions = this.#baseExtensions.concat(this.#configuredExtensions); 13900 13901 return extensionDefinitions.map( 13902 extension => new extension(this.lexxyElement) 13903 ).filter(extension => extension.enabled) 13904 } 13905} 13906 13907class BrowserAdapter { 13908 frozenLinkKey = null 13909 13910 dispatchAttributesChange(attributes, linkHref, highlight, headingTag) {} 13911 dispatchEditorInitialized(detail) {} 13912 freeze() {} 13913 thaw() {} 13914 unlinkFrozenNode() { 13915 return false 13916 } 13917} 13918 13919// Custom TextNode exportDOM that avoids redundant wrapping. 13920// 13921// Lexical's built-in TextNode.exportDOM() calls createDOM() which produces semantic tags 13922// like <strong> for bold and <em> for italic, then unconditionally wraps the result 13923// with presentational tags (<b>, <i>) for the same formats. This produces redundant markup 13924// like <b><strong>text</strong></b>. 13925// 13926// This custom export skips <b> when <strong> is already present and <i> when <em> is 13927// already present, while preserving <s> and <u> wrappers which have no semantic equivalents 13928// in createDOM's output. 13929// 13930// Any <span> elements produced by createDOM() are unwrapped, since they only carry 13931// editor classes that aren't meaningful in exported HTML. 13932 13933function exportTextNodeDOM(editor, textNode) { 13934 const element = textNode.createDOM(editor._config, editor); 13935 element.style.whiteSpace = "pre-wrap"; 13936 13937 if (textNode.hasFormat("lowercase")) { 13938 element.style.textTransform = "lowercase"; 13939 } else if (textNode.hasFormat("uppercase")) { 13940 element.style.textTransform = "uppercase"; 13941 } else if (textNode.hasFormat("capitalize")) { 13942 element.style.textTransform = "capitalize"; 13943 } 13944 13945 let result = element; 13946 13947 if (textNode.hasFormat("bold") && !containsTag(element, "strong")) { 13948 result = wrapWith(result, "b"); 13949 } 13950 if (textNode.hasFormat("italic") && !containsTag(element, "em")) { 13951 result = wrapWith(result, "i"); 13952 } 13953 if (textNode.hasFormat("strikethrough")) { 13954 result = wrapWith(result, "s"); 13955 } 13956 if (textNode.hasFormat("underline")) { 13957 result = wrapWith(result, "u"); 13958 } 13959 13960 return { element: unwrapSpans(result) } 13961} 13962 13963function containsTag(element, tagName) { 13964 const upperTag = tagName.toUpperCase(); 13965 if (element.tagName === upperTag) return true 13966 13967 return element.querySelector(tagName) !== null 13968} 13969 13970function wrapWith(element, tag) { 13971 const wrapper = document.createElement(tag); 13972 wrapper.appendChild(element); 13973 return wrapper 13974} 13975 13976function unwrapSpans(element) { 13977 if (element.tagName === "SPAN") return element.firstChild 13978 13979 for (const span of element.querySelectorAll("span")) { 13980 span.replaceWith(...span.childNodes); 13981 } 13982 13983 return element 13984} 13985 13986class ProvisionalParagraphNode extends Zi { 13987 $config() { 13988 return this.config("provisonal_paragraph", { 13989 extends: Zi, 13990 importDOM: () => null, 13991 $transform: (node) => { 13992 node.concretizeIfEdited(node); 13993 node.removeUnlessRequired(node); 13994 } 13995 }) 13996 } 13997 13998 static neededBetween(nodeBefore, nodeAfter) { 13999 return !$isSelectableElement(nodeBefore, "next") 14000 && !$isSelectableElement(nodeAfter, "previous") 14001 } 14002 14003 createDOM(editor) { 14004 const p = super.createDOM(editor); 14005 const selected = this.isSelected(Qr()); 14006 p.classList.add("provisional-paragraph"); 14007 p.classList.toggle("hidden", !selected); 14008 return p 14009 } 14010 14011 updateDOM(_prevNode, dom) { 14012 const selected = this.isSelected(Qr()); 14013 dom.classList.toggle("hidden", !selected); 14014 return false 14015 } 14016 14017 getTextContent() { 14018 return "" 14019 } 14020 14021 exportDOM() { 14022 return { 14023 element: null 14024 } 14025 } 14026 14027 // override as Lexical has an interesting view of collapsed selection in ElementNodes 14028 // https://github.com/facebook/lexical/blob/f1e4f66014377b1f2595aec2b0ee17f5b7ef4dfc/packages/lexical/src/LexicalNode.ts#L646 14029 isSelected(selection = null) { 14030 const targetSelection = selection || Qr(); 14031 if (!targetSelection) return false 14032 14033 if (targetSelection.getNodes().some(node => node.is(this) || this.isParentOf(node))) return true 14034 14035 // A collapsed range selection on the parent element at an offset adjacent to 14036 // this node means the caret is visually at this paragraph's position. Treat it 14037 // as selected so the paragraph is visible and the caret renders correctly. 14038 // 14039 // Both the offset matching our index (cursor just before us) and index + 1 14040 // (cursor just after us) count, because the provisional paragraph is an 14041 // invisible spacer: the browser resolves both offsets to the same visual spot. 14042 if (Fr(targetSelection) && targetSelection.isCollapsed()) { 14043 const { anchor } = targetSelection; 14044 const parent = this.getParent(); 14045 if (parent && anchor.getNode().is(parent) && anchor.type === "element") { 14046 const index = this.getIndexWithinParent(); 14047 return anchor.offset === index || anchor.offset === index + 1 14048 } 14049 } 14050 14051 return false 14052 } 14053 14054 removeUnlessRequired(self = this.getLatest()) { 14055 if (!self.required) self.remove(); 14056 } 14057 14058 concretizeIfEdited(self = this.getLatest()) { 14059 if (self.getTextContentSize() > 0) { 14060 self.replace(eo(), true); 14061 } 14062 } 14063 14064 14065 get required() { 14066 return this.isDirectRootChild && ProvisionalParagraphNode.neededBetween(...this.immediateSiblings) 14067 } 14068 14069 get isDirectRootChild() { 14070 const parent = this.getParent(); 14071 return Is(parent) 14072 } 14073 14074 get immediateSiblings() { 14075 return [ this.getPreviousSibling(), this.getNextSibling() ] 14076 } 14077} 14078 14079function $isProvisionalParagraphNode(node) { 14080 return node instanceof ProvisionalParagraphNode 14081} 14082 14083function $isSelectableElement(node, direction) { 14084 return Wi(node) && (direction === "next" ? node.canInsertTextBefore() : node.canInsertTextAfter()) 14085} 14086 14087class ProvisionalParagraphExtension extends LexxyExtension { 14088 get lexicalExtension() { 14089 return dc({ 14090 name: "lexxy/provisional-paragraph", 14091 nodes: [ 14092 ProvisionalParagraphNode 14093 ], 14094 register(editor) { 14095 return Cc( 14096 // Process Provisional Paragraph Nodes on RootNode changes as sibling status influences whether 14097 // they are required and their visible/hidden status 14098 editor.registerNodeTransform(Ui, $insertRequiredProvisionalParagraphs), 14099 editor.registerNodeTransform(Ui, $removeUnneededProvisionalParagraphs), 14100 editor.registerCommand(ie$4, $markAllProvisionalParagraphsDirty, so) 14101 ) 14102 } 14103 }) 14104 } 14105} 14106 14107function $insertRequiredProvisionalParagraphs(rootNode) { 14108 const nodeBeforeRootSelection = $nodeBeforeRootSelection(rootNode); 14109 14110 const firstNode = rootNode.getFirstChild(); 14111 if (ProvisionalParagraphNode.neededBetween(null, firstNode)) { 14112 $t$2(rootNode, new ProvisionalParagraphNode); 14113 } 14114 14115 for (const node of jt$2(rootNode)) { 14116 const nextNode = node.getNextSibling(); 14117 if (ProvisionalParagraphNode.neededBetween(node, nextNode)) { 14118 node.insertAfter(new ProvisionalParagraphNode); 14119 if (node.is(nodeBeforeRootSelection)) node.selectNext(); 14120 } 14121 } 14122} 14123 14124function $nodeBeforeRootSelection(rootNode) { 14125 const selection = Qr(); 14126 if (!Is(selection?.anchor?.getNode())) return null 14127 14128 return rootNode.getChildAtIndex(selection.anchor.offset - 1) 14129} 14130 14131function $removeUnneededProvisionalParagraphs(rootNode) { 14132 for (const provisionalParagraph of $getAllProvisionalParagraphs(rootNode)) { 14133 provisionalParagraph.removeUnlessRequired(); 14134 } 14135} 14136 14137function $markAllProvisionalParagraphsDirty() { 14138 // Selection-driven visibility updates must not become standalone undo steps. 14139 Os(Jn); 14140 14141 for (const provisionalParagraph of $getAllProvisionalParagraphs()) { 14142 provisionalParagraph.markDirty(); 14143 } 14144} 14145 14146function $getAllProvisionalParagraphs(rootNode = Zo()) { 14147 return Ht$3(rootNode.getChildren(), $isProvisionalParagraphNode) 14148} 14149 14150// Registers code highlighting through the extension system so its node 14151// transforms exist before the initial editor state is applied. Registering 14152// after editor creation misses code blocks loaded from the initial value: 14153// their transform pass has already run, and Lexical's catch-up dirtying 14154// only sees the committed (still empty) state. 14155class CodeHighlightingExtension extends LexxyExtension { 14156 get enabled() { 14157 return this.editorElement.supportsRichText 14158 } 14159 14160 get lexicalExtension() { 14161 return dc({ 14162 name: "lexxy/code-highlighting", 14163 register(editor) { 14164 return L$1(editor, buildHighlightPreservingTokenizer(editor)) 14165 } 14166 }) 14167 } 14168} 14169 14170const TRIX_LANGUAGE_ATTR = "language"; 14171 14172class TrixContentExtension extends LexxyExtension { 14173 14174 get enabled() { 14175 return this.editorElement.supportsRichText 14176 } 14177 14178 get lexicalExtension() { 14179 return dc({ 14180 name: "lexxy/trix-content", 14181 html: { 14182 import: { 14183 em: (element) => onlyStyledElements(element, { 14184 conversion: extendTextNodeConversion("i", $applyHighlightStyle), 14185 priority: 1 14186 }), 14187 span: (element) => onlyStyledElements(element, { 14188 conversion: extendTextNodeConversion("mark", $applyHighlightStyle), 14189 priority: 1 14190 }), 14191 strong: (element) => onlyStyledElements(element, { 14192 conversion: extendTextNodeConversion("b", $applyHighlightStyle), 14193 priority: 1 14194 }), 14195 del: () => ({ 14196 conversion: extendTextNodeConversion("s", $applyStrikethrough, $applyHighlightStyle), 14197 priority: 1 14198 }), 14199 pre: (element) => onlyPreLanguageElements(element, { 14200 conversion: extendConversion(z$1, "pre", $applyLanguage), 14201 priority: 1 14202 }) 14203 } 14204 } 14205 }) 14206 } 14207} 14208 14209function onlyStyledElements(element, conversion) { 14210 const elementHighlighted = element.style.color !== "" || element.style.backgroundColor !== ""; 14211 return elementHighlighted ? conversion : null 14212} 14213 14214function $applyStrikethrough(textNode) { 14215 if (!textNode.hasFormat("strikethrough")) textNode.toggleFormat("strikethrough"); 14216 return textNode 14217} 14218 14219function onlyPreLanguageElements(element, conversion) { 14220 return element.hasAttribute(TRIX_LANGUAGE_ATTR) ? conversion : null 14221} 14222 14223function $applyLanguage(conversionOutput, element) { 14224 const language = a(element.getAttribute(TRIX_LANGUAGE_ATTR)); 14225 conversionOutput.node.setLanguage(language); 14226} 14227 14228class WrappedTableNode extends vn { 14229 $config() { 14230 return this.config("wrapped_table_node", { extends: vn }) 14231 } 14232 14233 static importDOM() { 14234 return super.importDOM() 14235 } 14236 14237 canInsertTextBefore() { 14238 return false 14239 } 14240 14241 canInsertTextAfter() { 14242 return false 14243 } 14244 14245 exportDOM(editor) { 14246 const superExport = super.exportDOM(editor); 14247 14248 return { 14249 ...superExport, 14250 after: (tableElement) => { 14251 if (superExport.after) { 14252 tableElement = superExport.after(tableElement); 14253 const clonedTable = tableElement.cloneNode(true); 14254 const wrappedTable = createElement("figure", { className: "lexxy-content__table-wrapper" }, clonedTable.outerHTML); 14255 return wrappedTable 14256 } 14257 14258 return tableElement 14259 } 14260 } 14261 } 14262} 14263 14264class TablesExtension extends LexxyExtension { 14265 14266 get enabled() { 14267 return this.editorElement.supportsRichText 14268 } 14269 14270 get allowedElements() { 14271 return [ "figure", "tbody" ] 14272 } 14273 14274 get lexicalExtension() { 14275 return dc({ 14276 name: "lexxy/tables", 14277 nodes: [ 14278 WrappedTableNode, 14279 { 14280 replace: vn, 14281 with: () => new WrappedTableNode(), 14282 withKlass: WrappedTableNode 14283 }, 14284 Ee$1, 14285 He$1 14286 ], 14287 register(editor) { 14288 Nn(editor); 14289 14290 return Cc( 14291 Wn(editor), 14292 14293 // Lexxy registers extensions before setRootElement(), but table 14294 // drag-selection needs a root before wiring its pointer handlers. 14295 editor.registerRootListener((rootElement) => { 14296 if (rootElement) { 14297 return $n(editor, true) 14298 } 14299 }), 14300 14301 // A table in Lexxy is a Lexxy table: cell shading can't be set in the 14302 // editor, so any cell background only ever comes from foreign content 14303 // (pasted spreadsheets, loaded documents). Normalize every cell to no 14304 // background so it adopts the current theme. This also clears 14305 // Lexical's hardcoded default header background (Lexical #8089). 14306 editor.registerNodeTransform(Ee$1, (node) => { 14307 if (node.getBackgroundColor() !== "") { 14308 node.setBackgroundColor(""); 14309 } 14310 }), 14311 14312 // Bug fix: Fix column header states (Lexical #8090) 14313 editor.registerNodeTransform(Ee$1, (node) => { 14314 const headerState = node.getHeaderStyles(); 14315 14316 if (headerState !== Ae$1.ROW) return 14317 14318 const rowParent = node.getParent(); 14319 const tableNode = rowParent?.getParent(); 14320 if (!tableNode) return 14321 14322 const rows = tableNode.getChildren(); 14323 const cellIndex = rowParent.getChildren().indexOf(node); 14324 14325 const cellsInRow = rowParent.getChildren(); 14326 const isHeaderRow = cellsInRow.every(cell => 14327 cell.getHeaderStyles() !== Ae$1.NO_STATUS 14328 ); 14329 14330 const isHeaderColumn = rows.every(row => { 14331 const cell = row.getChildren()[cellIndex]; 14332 return cell && cell.getHeaderStyles() !== Ae$1.NO_STATUS 14333 }); 14334 14335 let newHeaderState = Ae$1.NO_STATUS; 14336 14337 if (isHeaderRow) newHeaderState |= Ae$1.ROW; 14338 if (isHeaderColumn) newHeaderState |= Ae$1.COLUMN; 14339 14340 if (newHeaderState !== headerState) { 14341 node.setHeaderStyles(newHeaderState, Ae$1.BOTH); 14342 } 14343 }), 14344 14345 editor.registerCommand("insertTableRowAfter", () => { 14346 nt(true); 14347 }, oo), 14348 14349 editor.registerCommand("insertTableRowBefore", () => { 14350 nt(false); 14351 }, oo), 14352 14353 editor.registerCommand("insertTableColumnAfter", () => { 14354 st(true); 14355 }, oo), 14356 14357 editor.registerCommand("insertTableColumnBefore", () => { 14358 st(false); 14359 }, oo), 14360 14361 editor.registerCommand("deleteTableRow", () => { 14362 ut(); 14363 }, oo), 14364 14365 editor.registerCommand("deleteTableColumn", () => { 14366 dt(); 14367 }, oo), 14368 14369 editor.registerCommand("deleteTable", () => { 14370 const selection = Qr(); 14371 if (!Fr(selection)) return false 14372 hn(selection.anchor.getNode())?.remove(); 14373 }, oo) 14374 ) 14375 } 14376 }) 14377 } 14378} 14379 14380const MIME_TYPE$1 = "application/x-lexxy-node-key"; 14381 14382class AttachmentDragAndDrop { 14383 #editor 14384 #draggedNodeKey = null 14385 #rafId = null 14386 #draggingRafId = null 14387 #listeners = new ListenerBin() 14388 14389 constructor(editor) { 14390 this.#editor = editor; 14391 14392 // Register Lexical commands at HIGH priority to intercept before the 14393 // base @lexical/rich-text handlers (which return true and consume the events). 14394 this.#listeners.track( 14395 editor.registerCommand(Be$2, (event) => this.#handleDragStart(event), so), 14396 editor.registerCommand(ze$2, (event) => this.#handleDrop(event), so), 14397 ); 14398 14399 // Use a root listener to register DOM-level dragover/dragend handlers 14400 // (these events need throttled rAF handling that works better as DOM listeners). 14401 this.#listeners.track(editor.registerRootListener((root, prevRoot) => { 14402 if (prevRoot) { 14403 prevRoot.removeEventListener("dragover", this.#onDragOver); 14404 prevRoot.removeEventListener("dragend", this.#onDragEnd); 14405 } 14406 if (root) { 14407 root.addEventListener("dragover", this.#onDragOver); 14408 root.addEventListener("dragend", this.#onDragEnd); 14409 } 14410 })); 14411 } 14412 14413 destroy() { 14414 this.#cleanup(); 14415 this.#listeners.dispose(); 14416 } 14417 14418 // -- Event handlers -------------------------------------------------------- 14419 14420 #handleDragStart(event) { 14421 if (event.target.closest?.("textarea")) return false 14422 14423 const figure = event.target.closest?.("figure.attachment[data-lexical-node-key]"); 14424 if (!figure) return false 14425 14426 this.#draggedNodeKey = figure.dataset.lexicalNodeKey; 14427 event.dataTransfer.setData(MIME_TYPE$1, this.#draggedNodeKey); 14428 event.dataTransfer.effectAllowed = "move"; 14429 14430 // Add dragging class after a tick so it doesn't affect the drag image 14431 this.#draggingRafId = requestAnimationFrame(() => { 14432 this.#draggingRafId = null; 14433 figure.classList.add("lexxy-dragging"); 14434 }); 14435 14436 return true 14437 } 14438 14439 #onDragOver = (event) => { 14440 if (!this.#draggedNodeKey) return 14441 14442 event.preventDefault(); 14443 event.dataTransfer.dropEffect = "move"; 14444 14445 if (!this.#rafId) { 14446 this.#rafId = requestAnimationFrame(() => { 14447 this.#rafId = null; 14448 this.#updateDropTarget(event); 14449 }); 14450 } 14451 } 14452 14453 #handleDrop(event) { 14454 if (!this.#draggedNodeKey) return false 14455 14456 event.preventDefault(); 14457 14458 const target = this.#resolveDropTarget(event); 14459 const draggedKey = this.#draggedNodeKey; 14460 this.#cleanup(); 14461 14462 if (target) { 14463 this.#performDrop(draggedKey, target); 14464 } 14465 return true 14466 } 14467 14468 #onDragEnd = () => { 14469 this.#cleanup(); 14470 } 14471 14472 // -- Drop target resolution ----------------------------------------------- 14473 14474 #updateDropTarget(event) { 14475 this.#clearDropIndicators(); 14476 14477 const target = this.#resolveDropTarget(event); 14478 if (!target) return 14479 14480 if (target.type === "gallery" || target.type === "gallery-reorder") { 14481 target.element.classList.add(`lexxy-drop-target--gallery-${target.position}`); 14482 } else if (target.type === "list-item") { 14483 target.element.classList.add(`lexxy-drop-target--list-${target.position}`); 14484 } else { 14485 target.element.classList.add(`lexxy-drop-target--block-${target.position}`); 14486 } 14487 } 14488 14489 #resolveDropTarget(event) { 14490 const element = document.elementFromPoint(event.clientX, event.clientY); 14491 if (!element) return null 14492 14493 const rootElement = this.#editor.getRootElement(); 14494 if (!rootElement || !rootElement.contains(element)) return null 14495 14496 // Check if hovering over a previewable image (for gallery merge or reorder) 14497 const targetFigure = element.closest("figure.attachment--preview[data-lexical-node-key]"); 14498 if (targetFigure && targetFigure.dataset.lexicalNodeKey !== this.#draggedNodeKey) { 14499 const targetGallery = targetFigure.closest(".attachment-gallery"); 14500 if (targetGallery) { 14501 // If the dragged image is in the same gallery, this is a reorder 14502 const draggedFigure = rootElement.querySelector(`[data-lexical-node-key="${this.#draggedNodeKey}"]`); 14503 if (draggedFigure && targetGallery.contains(draggedFigure)) { 14504 const position = this.#computeHorizontalPosition(targetFigure, event.clientX); 14505 return { type: "gallery-reorder", element: targetFigure, nodeKey: targetFigure.dataset.lexicalNodeKey, position } 14506 } 14507 } 14508 const position = this.#computeHorizontalPosition(targetFigure, event.clientX); 14509 return { type: "gallery", element: targetFigure, nodeKey: targetFigure.dataset.lexicalNodeKey, position } 14510 } 14511 14512 // Hovering over the dragged image itself inside a gallery â treat as no-op 14513 // to prevent fallthrough to the block handler, which would eject it from the gallery. 14514 if (targetFigure && targetFigure.closest(".attachment-gallery")) return null 14515 14516 // Check if hovering over a gallery's empty space (for reorder within gallery) 14517 const targetGallery = element.closest(".attachment-gallery"); 14518 if (targetGallery) { 14519 let galleryFigure = element.closest("figure.attachment[data-lexical-node-key]"); 14520 if (!galleryFigure) { 14521 galleryFigure = this.#findNearestFigureInGallery(targetGallery, event.clientX); 14522 } 14523 if (galleryFigure && galleryFigure.dataset.lexicalNodeKey !== this.#draggedNodeKey) { 14524 const position = this.#computeHorizontalPosition(galleryFigure, event.clientX); 14525 return { type: "gallery-reorder", element: galleryFigure, nodeKey: galleryFigure.dataset.lexicalNodeKey, position } 14526 } 14527 // Nearest figure is the dragged image â no-op to avoid block handler fallthrough 14528 if (galleryFigure) return null 14529 } 14530 14531 // Check if hovering over a list item (for list splitting) 14532 const listItem = element.closest("li"); 14533 if (listItem && rootElement.contains(listItem)) { 14534 const position = this.#computeVerticalPosition(listItem, event.clientY); 14535 return { type: "list-item", element: listItem, position } 14536 } 14537 14538 // Otherwise, find nearest block-level element for between-block insertion. 14539 // Normalize so each gap has exactly one indicator: prefer "after" on the 14540 // previous sibling, falling back to "before" only for the first block. 14541 const block = this.#findNearestBlock(element, rootElement, event.clientY); 14542 if (!block) return null 14543 14544 const position = this.#computeVerticalPosition(block, event.clientY); 14545 if (position === "before" && block.previousElementSibling) { 14546 return { type: "block", element: block.previousElementSibling, position: "after" } 14547 } 14548 return { type: "block", element: block, position } 14549 } 14550 14551 #findNearestBlock(element, rootElement, clientY) { 14552 let current = element; 14553 while (current && current !== rootElement) { 14554 if (current.parentElement === rootElement) return current 14555 current = current.parentElement; 14556 } 14557 14558 // elementFromPoint landed on the root itself (e.g. a margin gap between 14559 // blocks). Fall back to the nearest child by vertical distance. 14560 let nearest = null; 14561 let minDistance = Infinity; 14562 for (const child of rootElement.children) { 14563 const rect = child.getBoundingClientRect(); 14564 const distance = Math.min(Math.abs(clientY - rect.top), Math.abs(clientY - rect.bottom)); 14565 if (distance < minDistance) { 14566 minDistance = distance; 14567 nearest = child; 14568 } 14569 } 14570 return nearest 14571 } 14572 14573 #computeVerticalPosition(element, clientY) { 14574 const rect = element.getBoundingClientRect(); 14575 return clientY < rect.top + rect.height / 2 ? "before" : "after" 14576 } 14577 14578 #computeHorizontalPosition(element, clientX) { 14579 const rect = element.getBoundingClientRect(); 14580 return clientX < rect.left + rect.width / 2 ? "before" : "after" 14581 } 14582 14583 #findNearestFigureInGallery(gallery, clientX) { 14584 const figures = gallery.querySelectorAll("figure.attachment[data-lexical-node-key]"); 14585 let nearest = null; 14586 let minDistance = Infinity; 14587 for (const figure of figures) { 14588 const rect = figure.getBoundingClientRect(); 14589 const center = rect.left + rect.width / 2; 14590 const distance = Math.abs(clientX - center); 14591 if (distance < minDistance) { 14592 minDistance = distance; 14593 nearest = figure; 14594 } 14595 } 14596 return nearest 14597 } 14598 14599 // -- Drop indicator -------------------------------------------------------- 14600 14601 static #DROP_CLASSES = [ 14602 "lexxy-drop-target--gallery-before", "lexxy-drop-target--gallery-after", 14603 "lexxy-drop-target--list-before", "lexxy-drop-target--list-after", 14604 "lexxy-drop-target--block-before", "lexxy-drop-target--block-after", 14605 ] 14606 14607 #clearDropIndicators() { 14608 const rootElement = this.#editor.getRootElement(); 14609 if (!rootElement) return 14610 14611 for (const el of rootElement.querySelectorAll("[class*='lexxy-drop-target--']")) { 14612 el.classList.remove(...AttachmentDragAndDrop.#DROP_CLASSES); 14613 } 14614 } 14615 14616 // -- Node operations ------------------------------------------------------- 14617 14618 #performDrop(draggedKey, target) { 14619 const draggedNode = Yo(draggedKey); 14620 if (!draggedNode || !$isActionTextAttachmentNode(draggedNode)) return 14621 14622 if (target.type === "gallery") { 14623 this.#dropOntoImage(draggedNode, target.nodeKey, target.position); 14624 } else if (target.type === "gallery-reorder") { 14625 this.#reorderInGallery(draggedNode, target.nodeKey, target.position); 14626 } else if (target.type === "list-item") { 14627 this.#dropIntoList(draggedNode, target); 14628 } else { 14629 this.#dropBetweenBlocks(draggedNode, target); 14630 } 14631 14632 // Clear selection to prevent a second history entry. Lexical dispatches 14633 // SELECTION_CHANGE_COMMAND during commit for non-range selections, which 14634 // creates a separate update. Null selection avoids that dispatch entirely 14635 // and also prevents Firefox's follow-up selectionchange from dirtying nodes. 14636 es(null); 14637 } 14638 14639 #dropOntoImage(draggedNode, targetKey, position) { 14640 const targetNode = Yo(targetKey); 14641 if (!targetNode || !$isActionTextAttachmentNode(targetNode)) return 14642 if (draggedNode.is(targetNode)) return 14643 14644 draggedNode.remove(); 14645 14646 const gallery = $findOrCreateGalleryForImage(targetNode); 14647 if (gallery) { 14648 if (position === "before") { 14649 targetNode.insertBefore(draggedNode); 14650 } else { 14651 targetNode.insertAfter(draggedNode); 14652 } 14653 } 14654 } 14655 14656 #reorderInGallery(draggedNode, targetKey, position) { 14657 const targetNode = Yo(targetKey); 14658 if (!targetNode || draggedNode.is(targetNode)) return 14659 14660 draggedNode.remove(); 14661 14662 if (position === "before") { 14663 targetNode.insertBefore(draggedNode); 14664 } else { 14665 targetNode.insertAfter(draggedNode); 14666 } 14667 } 14668 14669 #dropIntoList(draggedNode, target) { 14670 const listItemNode = Go(target.element); 14671 if (!listItemNode || !pe$2(listItemNode)) return 14672 14673 const listNode = listItemNode.getParent(); 14674 if (!listNode || !Se$1(listNode)) return 14675 14676 const children = listNode.getChildren(); 14677 const index = children.indexOf(listItemNode); 14678 if (index === -1) return 14679 14680 const splitIndex = target.position === "before" ? index : index + 1; 14681 14682 draggedNode.remove(); 14683 14684 if (splitIndex === 0) { 14685 listNode.insertBefore(draggedNode); 14686 } else if (splitIndex >= children.length) { 14687 listNode.insertAfter(draggedNode); 14688 } else { 14689 const [ , listAfter ] = Us(listNode, splitIndex); 14690 listAfter.insertBefore(draggedNode); 14691 } 14692 } 14693 14694 #dropBetweenBlocks(draggedNode, target) { 14695 const targetNode = Go(target.element); 14696 if (!targetNode) return 14697 14698 const topLevelTarget = targetNode.getTopLevelElement?.() || targetNode; 14699 if (draggedNode.is(topLevelTarget)) return 14700 14701 draggedNode.remove(); 14702 14703 if (target.position === "before") { 14704 topLevelTarget.insertBefore(draggedNode); 14705 } else { 14706 topLevelTarget.insertAfter(draggedNode); 14707 } 14708 } 14709 14710 // -- Lifecycle helpers ----------------------------------------------------- 14711 14712 #cleanup() { 14713 this.#clearDropIndicators(); 14714 14715 if (this.#draggedNodeKey) { 14716 const rootElement = this.#editor.getRootElement(); 14717 if (rootElement) { 14718 const figure = rootElement.querySelector(`[data-lexical-node
14718-key="${this.#draggedNodeKey}"]`); 14719 figure?.classList.remove("lexxy-dragging"); 14720 } 14721 } 14722 14723 this.#draggedNodeKey = null; 14724 14725 if (this.#rafId) { 14726 cancelAnimationFrame(this.#rafId); 14727 this.#rafId = null; 14728 } 14729 14730 if (this.#draggingRafId) { 14731 cancelAnimationFrame(this.#draggingRafId); 14732 this.#draggingRafId = null; 14733 } 14734 } 14735} 14736 14737const ATTACHMENT_ATTRIBUTES = [ "alt", "caption", "content", "content-type", "data-direct-upload-id", 14738 "data-sgid", "filename", "filesize", "height", "presentation", "previewable", "sgid", "url", "width" ]; 14739 14740const UPLOADS_BUSY_MESSAGE = "Please wait for all files to upload"; 14741 14742class AttachmentsExtension extends LexxyExtension { 14743 #uploadsCount = 0 14744 14745 get enabled() { 14746 return this.editorElement.supportsAttachments 14747 } 14748 14749 get allowedElements() { 14750 return [ { tag: ActionTextAttachmentNode.TAG_NAME, attributes: ATTACHMENT_ATTRIBUTES } ] 14751 } 14752 14753 get lexicalExtension() { 14754 return dc({ 14755 name: "lexxy/action-text-attachments", 14756 nodes: [ 14757 ActionTextAttachmentNode, 14758 ActionTextAttachmentUploadNode, 14759 ImageGalleryNode 14760 ], 14761 register: (editor) => { 14762 const dragAndDrop = new AttachmentDragAndDrop(editor); 14763 14764 return Cc( 14765 editor.registerNodeTransform(ActionTextAttachmentNode, $extractAttachmentFromParagraph), 14766 editor.registerCommand(fe$4, $collapseIntoGallery, oo), 14767 editor.registerMutationListener(ActionTextAttachmentUploadNode, this.#handleUploadMutations.bind(this)), 14768 () => dragAndDrop.destroy() 14769 ) 14770 } 14771 }) 14772 } 14773 14774 #handleUploadMutations(mutations) { 14775 const previousUploadsCount = this.#uploadsCount; 14776 for (const [ key, mutation ] of mutations) { 14777 if (mutation === "created") { 14778 this.#uploadsCount++; 14779 } else if (mutation === "destroyed") { 14780 this.#uploadsCount--; 14781 this.editorElement.uploadRequests.abort(key); 14782 } 14783 } 14784 14785 if (this.#uploadsCount !== previousUploadsCount) { 14786 this.#setUploadsValidity(); 14787 } 14788 } 14789 14790 #setUploadsValidity() { 14791 if (this.#uploadsCount) { 14792 this.setEditorValidity({ customError: true }, UPLOADS_BUSY_MESSAGE); 14793 } else { 14794 this.setEditorValidity({}); 14795 } 14796 } 14797} 14798 14799// Decorator nodes can be wrapped in a Paragraph Node by Lexical when contained in a <div> 14800// We remove them, splitting the node as needed 14801function $extractAttachmentFromParagraph(attachmentNode) { 14802 const parentNode = attachmentNode.getParent(); 14803 if (!no(parentNode)) return 14804 14805 if (parentNode.getChildrenSize() === 1) { 14806 parentNode.replace(attachmentNode); 14807 } else { 14808 const index = attachmentNode.getIndexWithinParent(); 14809 const [ topParagraph, bottomParagraph ] = Us(parentNode, index); 14810 topParagraph.insertAfter(attachmentNode); 14811 14812 for (const p of [ topParagraph, bottomParagraph ]) { 14813 if (p.isEmpty()) p.remove(); 14814 } 14815 } 14816} 14817 14818function $collapseIntoGallery(backwards) { 14819 const anchor = Qr()?.anchor; 14820 if (!anchor) return false 14821 14822 if ($collapseAtGalleryEdge(anchor, backwards)) { 14823 return true 14824 } else if (backwards) { 14825 return $collapseAroundEmptyParagraph(anchor) 14826 || $moveSelectionBeforeGallery(anchor) 14827 } 14828 14829 return false 14830} 14831 14832function $collapseAroundEmptyParagraph(anchor) { 14833 const anchorNode = anchor.getNode(); 14834 if (!anchorNode) return false 14835 14836 const isWithinEmptyParagraph = no(anchorNode) && anchorNode.isEmpty(); 14837 const previousSibling = anchorNode.getPreviousSibling(); 14838 const topGallery = $findOrCreateGalleryForImage(previousSibling); 14839 const selectionIndex = topGallery?.getChildrenSize(); 14840 14841 if (isWithinEmptyParagraph && topGallery?.collapseWith(anchorNode.getNextSibling())) { 14842 topGallery.select(selectionIndex, selectionIndex); 14843 anchorNode.remove(); 14844 return true 14845 } else { 14846 return false 14847 } 14848} 14849 14850function $collapseAtGalleryEdge(anchor, backwards) { 14851 const anchorNode = anchor.getNode(); 14852 if (!$isImageGalleryNode(anchorNode)) return false 14853 14854 const isAtGalleryEdge = $isAtNodeEdge(anchor, backwards); 14855 const sibling = backwards ? anchorNode.getPreviousSibling() : anchorNode.getNextSibling(); 14856 14857 if (isAtGalleryEdge && anchorNode.collapseWith(sibling, backwards)) { 14858 const selectionOffset = backwards ? 1 : anchorNode.getChildrenSize() - 1; 14859 anchorNode.select(selectionOffset, selectionOffset); 14860 return true 14861 } else { 14862 return false 14863 } 14864} 14865 14866// Manual selection handling to prevent Lexical merging the gallery with a <p> and unwrapping it 14867function $moveSelectionBeforeGallery(anchor) { 14868 const previousNode = anchor.getNode().getPreviousSibling(); 14869 if (!$isImageGalleryNode(anchor.getNode()) || !$isAtNodeEdge(anchor, true) || !previousNode) return false 14870 14871 if (ji(previousNode)) { 14872 // Handled by Lexxy decorator selection behavior 14873 return false 14874 } else if (previousNode.isEmpty()) { 14875 previousNode.remove(); 14876 } else { 14877 previousNode.selectEnd(); 14878 } 14879 14880 return true 14881} 14882
vendor: 70,883 bytes, lines 14883-17309
14883class EarlyEscapeCodeNode extends z$1 { 14884 $config() { 14885 return this.config("early_escape_code", { extends: z$1 }) 14886 } 14887 14888 static $fromSelection(selection) { 14889 const anchorNode = selection.anchor.getNode(); 14890 return At$2(anchorNode, EarlyEscapeCodeNode) 14891 || (anchorNode instanceof EarlyEscapeCodeNode ? anchorNode : null) 14892 } 14893 14894 insertNewAfter(selection, restoreSelection) { 14895 if (Es(jn) || !selection.isCollapsed()) { 14896 return super.insertNewAfter(selection, restoreSelection) 14897 } else if (this.#isCursorAtStart(selection)) { 14898 return this.#insertParagraphBefore() 14899 } else if (this.#isCursorOnWhitespaceOnlyLastLine(selection)) { 14900 return this.#insertBlankLineBelow(selection, restoreSelection) 14901 } else if (this.#isCursorOnEmptyLastLine(selection)) { 14902 return this.#escapeToNewParagraphAfter() 14903 } else { 14904 return super.insertNewAfter(selection, restoreSelection) 14905 } 14906 } 14907 14908 #isCursorAtStart(selection) { 14909 const { anchor } = selection; 14910 if (!$isAtNodeStart(anchor)) return false 14911 14912 const anchorNode = anchor.getNode(); 14913 return this.is(anchorNode) || this.getFirstChild()?.is(anchorNode) 14914 } 14915 14916 #isCursorOnEmptyLastLine(selection) { 14917 if (!$isCursorOnLastLine(selection)) return false 14918 14919 const textContent = this.getTextContent(); 14920 return textContent === "" || textContent.endsWith("\n") 14921 } 14922 14923 #isCursorOnWhitespaceOnlyLastLine(selection) { 14924 if (!$isCursorOnLastLine(selection)) return false 14925 14926 const textContent = this.getTextContent(); 14927 const lastNewlineIndex = textContent.lastIndexOf("\n"); 14928 const lastLine = lastNewlineIndex === -1 ? textContent : textContent.slice(lastNewlineIndex + 1); 14929 return lastLine.length > 0 && lastLine.trim() === "" 14930 } 14931 14932 #insertParagraphBefore() { 14933 this.insertBefore(eo()); 14934 return null 14935 } 14936 14937 #insertBlankLineBelow(selection, restoreSelection) { 14938 super.insertNewAfter(selection, restoreSelection); 14939 this.getLastChild().remove(); 14940 return null 14941 } 14942 14943 #escapeToNewParagraphAfter() { 14944 $trimTrailingBlankNodes(this); 14945 const paragraph = eo(); 14946 this.insertAfter(paragraph); 14947 return paragraph 14948 } 14949} 14950 14951class EarlyEscapeListItemNode extends ge$2 { 14952 $config() { 14953 return this.config("early_escape_listitem", { extends: ge$2 }) 14954 } 14955 14956 insertNewAfter(selection, restoreSelection) { 14957 if (this.#shouldEscape(selection)) { 14958 return this.#escapeFromList() 14959 } 14960 14961 return super.insertNewAfter(selection, restoreSelection) 14962 } 14963 14964 get #isInBlockquote() { 14965 return Boolean(At$2(this, At$1)) 14966 } 14967 14968 #shouldEscape(selection) { 14969 if (this.#isInPasteOperation() || !this.#isInBlockquote) { 14970 return false 14971 } else if ($isBlankNode(this)) { 14972 return true 14973 } else { 14974 const paragraph = At$2(selection.anchor.getNode(), Zi); 14975 return paragraph && $isBlankNode(paragraph) && pe$2(paragraph.getParent()) 14976 } 14977 } 14978 14979 #isInPasteOperation() { 14980 return Es(jn) 14981 } 14982 14983 #escapeFromList() { 14984 const parentList = this.getParent(); 14985 if (!parentList || !Se$1(parentList)) return 14986 14987 const blockquote = parentList.getParent(); 14988 const isInBlockquote = blockquote && Mt$2(blockquote); 14989 14990 if (isInBlockquote) { 14991 const hasNonEmptyListItems = this.getNextSiblings().some( 14992 sibling => pe$2(sibling) && !$isBlankNode(sibling) 14993 ); 14994 14995 if (hasNonEmptyListItems) { 14996 return this.#splitBlockquoteWithList() 14997 } 14998 } 14999 15000 const paragraph = eo(); 15001 parentList.insertAfter(paragraph); 15002 15003 this.remove(); 15004 return paragraph 15005 } 15006 15007 #splitBlockquoteWithList() { 15008 const splitQuotes = Us(this.getParent(), this.getIndexWithinParent()); 15009 this.remove(); 15010 15011 const middleParagraph = eo(); 15012 splitQuotes[0].insertAfter(middleParagraph); 15013 15014 splitQuotes.forEach($trimTrailingBlankNodes); 15015 15016 return middleParagraph 15017 } 15018 15019} 15020 15021class FormatEscapeExtension extends LexxyExtension { 15022 15023 get enabled() { 15024 return this.editorElement.supportsRichText 15025 } 15026 15027 get allowedElements() { 15028 return [ { tag: "ol", attributes: [ "start" ] }, { tag: "li", attributes: [ "value" ] } ] 15029 } 15030 15031 get lexicalExtension() { 15032 return dc({ 15033 name: "lexxy/format-escape", 15034 nodes: [ 15035 EarlyEscapeCodeNode, 15036 { replace: z$1, with: (node) => new EarlyEscapeCodeNode(node.getLanguage()), withKlass: EarlyEscapeCodeNode }, 15037 EarlyEscapeListItemNode, 15038 { replace: ge$2, with: () => new EarlyEscapeListItemNode(), withKlass: EarlyEscapeListItemNode }, 15039 ], 15040 register(editor) { 15041 return Cc( 15042 editor.registerCommand( 15043 he$3, 15044 () => $escapeFromBlockquote(), 15045 so 15046 ), 15047 editor.registerCommand( 15048 Ee$3, 15049 (event) => $handleArrowDownInCodeBlock(event), 15050 oo 15051 ), 15052 editor.registerNodeTransform(At$1, $ensureQuoteHasParagraphChild) 15053 ) 15054 } 15055 }) 15056 } 15057} 15058 15059function $escapeFromBlockquote() { 15060 return $escapeBeforeBlockquoteStart() || $escapeFromBlankBlockquoteParagraph() 15061} 15062 15063function $escapeBeforeBlockquoteStart() { 15064 const selection = Qr(); 15065 if (!Fr(selection) || !selection.isCollapsed() || selection.anchor.offset !== 0) return false 15066 15067 const paragraph = At$2(selection.anchor.getNode(), Zi); 15068 if (paragraph && !$isBlankNode(paragraph) && !paragraph.getPreviousSibling()) { 15069 const blockquote = paragraph.getParent(); 15070 if (Mt$2(blockquote)) { 15071 blockquote.insertBefore(eo()); 15072 return true 15073 } 15074 } 15075 15076 return false 15077} 15078 15079function $escapeFromBlankBlockquoteParagraph() { 15080 const anchorNode = Qr().anchor.getNode(); 15081 15082 const paragraph = At$2(anchorNode, Zi); 15083 if (!paragraph || !$isBlankNode(paragraph)) return false 15084 15085 const blockquote = paragraph.getParent(); 15086 if (Mt$2(blockquote)) { 15087 const nonEmptySiblings = paragraph.getNextSiblings().filter(sibling => !$isBlankNode(sibling)); 15088 15089 if (nonEmptySiblings.length > 0) { 15090 $splitQuoteNode(blockquote, paragraph); 15091 } else { 15092 blockquote.insertAfter(paragraph); 15093 paragraph.selectStart(); 15094 } 15095 15096 return true 15097 } 15098 15099 return false 15100} 15101 15102function $splitQuoteNode(node, paragraph) { 15103 const splitQuotes = Us(node, paragraph.getIndexWithinParent()); 15104 splitQuotes[0].insertAfter(paragraph); 15105 splitQuotes.forEach($trimTrailingBlankNodes); 15106 paragraph.selectEnd(); 15107} 15108 15109function $handleArrowDownInCodeBlock(event) { 15110 const selection = Qr(); 15111 if (!Fr(selection) || !selection.isCollapsed()) return false 15112 15113 const codeNode = EarlyEscapeCodeNode.$fromSelection(selection); 15114 if (!codeNode) return false 15115 15116 if ($isCursorOnLastLine(selection) && !codeNode.getNextSibling()) { 15117 event?.preventDefault(); 15118 const paragraph = eo(); 15119 codeNode.insertAfter(paragraph); 15120 paragraph.selectEnd(); 15121 return true 15122 } 15123 15124 return false 15125} 15126 15127function $ensureQuoteHasParagraphChild(quoteNode) { 15128 if (!quoteNode.isEmpty()) return 15129 15130 quoteNode.append(eo()); 15131 if ($containsRangeSelection(quoteNode)) quoteNode.getFirstChild().select(); 15132} 15133 15134class LinkOpenerExtension extends LexxyExtension { 15135 get enabled() { 15136 return this.editorElement.supportsRichText 15137 } 15138 15139 get lexicalExtension() { 15140 return dc({ 15141 name: "lexxy/link-opener", 15142 register: (editor) => Cc( 15143 editor.registerCommand(se$5, this.#handleClick.bind(this), oo), 15144 registerEventListener(this.editorElement.editorContentElement, "auxclick", this.#handleAuxClick.bind(this)), 15145 registerEventListener(window, "keydown", this.#handleKey.bind(this)), 15146 registerEventListener(window, "keyup", this.#handleKey.bind(this)), 15147 registerEventListener(window, "focus", this.#handleFocus.bind(this)) 15148 ) 15149 }) 15150 } 15151 15152 #handleClick(event) { 15153 if (this.#isModified(event)) { 15154 return $openLink(event.target) 15155 } else { 15156 return false 15157 } 15158 } 15159 15160 #handleAuxClick(event) { 15161 if (event.button === 1) { 15162 this.editorElement.editor.read(() => $openLink(event.target)); 15163 } 15164 } 15165 15166 #handleKey(event) { 15167 this.#updateOpenableAttribute(event); 15168 } 15169 15170 // Chrome dispatches events without modifier keys *for a while* after changing tabs 15171 async #handleFocus() { 15172 await delay(200); 15173 this.editorElement.addEventListener("mousemove", this.#updateOpenableAttribute.bind(this), { once: true }); 15174 } 15175 15176 #updateOpenableAttribute(event) { 15177 this.editorElement.toggleAttribute("data-links-openable", this.#isModified(event)); 15178 } 15179 15180 #isModified(event) { 15181 return lt$2 ? event.metaKey : event.ctrlKey 15182 } 15183} 15184 15185function $openLink(target) { 15186 const node = Go(target); 15187 const linkNode = dl(node, z$5); 15188 if (linkNode) { 15189 const url = linkNode.sanitizeUrl(linkNode.getURL()); 15190 window.open(url, "_blank", "noopener,noreferrer"); 15191 return true 15192 } else { 15193 return false 15194 } 15195} 15196 15197class PreventLexicalTripleClickExtension extends LexxyExtension { 15198 get lexicalExtension() { 15199 return dc({ 15200 name: "lexxy/prevent-lexical-triple-click", 15201 register: (editor) => editor.registerRootListener((rootElement) => { 15202 if (rootElement) { 15203 return registerEventListener( 15204 rootElement, 15205 "click", 15206 this.#handleTripleClick.bind(this), 15207 { capture: true } 15208 ) 15209 } 15210 }) 15211 }) 15212 } 15213 15214 // Stop propagation of the triple-click to prevent Lexical's handler from running. 15215 // 15216 // Lexical's onClick handler implements a triple-click handler that is trivial/anemic/naïve. The 15217 // intention of the change, made in facebook/lexical#4512, seems to be to deal with browsers' 15218 // "overselection" behavior, where a triple-click selection might end at offset 0 of the following 15219 // block, which can cause issues when transforming the selection. But the implementation breaks 15220 // many common real-world use cases and Lexxy does not demonstrate the behavior it's intended to 15221 // work around (in headers or tables). 15222 #handleTripleClick(event) { 15223 if (event.detail === 3) { 15224 event.stopPropagation(); 15225 } 15226 } 15227} 15228 15229function caretRect(node, offset) { 15230 const range = document.createRange(); 15231 range.setStart(node, offset); 15232 range.collapse(true); 15233 15234 const rect = range.getBoundingClientRect(); 15235 if (rect.height > 0) { 15236 return rect 15237 } else { 15238 return null 15239 } 15240} 15241 15242function caretFromPoint(clientX, clientY) { 15243 if (document.caretPositionFromPoint) { 15244 const position = document.caretPositionFromPoint(clientX, clientY); 15245 if (position) return { node: position.offsetNode, offset: position.offset } 15246 } else if (document.caretRangeFromPoint) { 15247 const range = document.caretRangeFromPoint(clientX, clientY); 15248 if (range) return { node: range.startContainer, offset: range.startOffset } 15249 } 15250 15251 return null 15252} 15253 15254const MIME_TYPE = "application/x-lexxy-custom-attachment-key"; 15255 15256// Custom inline attachments reorder by dropping at a text caret, unlike block 15257// attachments which insert between blocks or into galleries. 15258class CustomAttachmentDragAndDrop { 15259 #editor 15260 #draggedNodeKey = null 15261 #draggingRafId = null 15262 #dragOverRafId = null 15263 #dropIndicator = null 15264 #listeners = new ListenerBin() 15265 15266 constructor(editor) { 15267 this.#editor = editor; 15268 15269 // Register at HIGH priority to intercept before the base @lexical/rich-text 15270 // handlers, which consume drag events. The block-attachment handler also 15271 // registers here but bails for inline custom attachments, so we get our turn. 15272 this.#listeners.track( 15273 editor.registerCommand(Be$2, (event) => this.#handleDragStart(event), so), 15274 editor.registerCommand(ze$2, (event) => this.#handleDrop(event), so) 15275 ); 15276 15277 this.#listeners.track(editor.registerRootListener((root, prevRoot) => { 15278 if (prevRoot) { 15279 prevRoot.removeEventListener("dragover", this.#onDragOver); 15280 prevRoot.removeEventListener("dragend", this.#onDragEnd); 15281 } 15282 if (root) { 15283 root.addEventListener("dragover", this.#onDragOver); 15284 root.addEventListener("dragend", this.#onDragEnd); 15285 } 15286 })); 15287 } 15288 15289 destroy() { 15290 this.#cleanup(); 15291 this.#dropIndicator?.remove(); 15292 this.#dropIndicator = null; 15293 this.#listeners.dispose(); 15294 } 15295 15296 #handleDragStart(event) { 15297 const attachment = this.#customAttachmentElementFrom(event.target); 15298 if (!attachment) return false 15299 15300 this.#draggedNodeKey = attachment.dataset.lexicalNodeKey; 15301 event.dataTransfer.setData(MIME_TYPE, this.#draggedNodeKey); 15302 event.dataTransfer.effectAllowed = "move"; 15303 15304 this.#draggingRafId = requestAnimationFrame(() => { 15305 this.#draggingRafId = null; 15306 attachment.classList.add("lexxy-dragging"); 15307 }); 15308 15309 return true 15310 } 15311 15312 #onDragOver = (event) => { 15313 if (!this.#draggedNodeKey) return 15314 15315 event.preventDefault(); 15316 event.dataTransfer.dropEffect = "move"; 15317 15318 if (!this.#dragOverRafId) { 15319 this.#dragOverRafId = requestAnimationFrame(() => { 15320 this.#dragOverRafId = null; 15321 this.#updateDropIndicator(event); 15322 }); 15323 } 15324 } 15325 15326 #onDragEnd = () => { 15327 this.#cleanup(); 15328 } 15329 15330 #handleDrop(event) { 15331 if (!this.#draggedNodeKey) return false 15332 15333 event.preventDefault(); 15334 15335 const dropPoint = this.#resolveDropPoint(event); 15336 const draggedKey = this.#draggedNodeKey; 15337 this.#cleanup(); 15338 15339 if (dropPoint) { 15340 this.#moveAttachment(draggedKey, dropPoint); 15341 } 15342 15343 return true 15344 } 15345 15346 #resolveDropPoint(event) { 15347 const rootElement = this.#editor.getRootElement(); 15348 if (!rootElement) return null 15349 15350 const caret = caretFromPoint(event.clientX, event.clientY); 15351 if (!caret || !rootElement.contains(caret.node)) return null 15352 15353 // A caret on the root itself points between blocks. Mentions behave like text: 15354 // they only drop onto an existing line, so snap to the nearest one. 15355 if (caret.node === rootElement) { 15356 return this.#nearestLineCaret(rootElement, event.clientY) 15357 } 15358 15359 // When mentions sit next to each other with no text between them, the caret 15360 // lands inside the neighbouring decorator's DOM. Lexical can't resolve a point 15361 // inside a decorator to an editable position, and the cursor has no business 15362 // showing there anyway, so snap to just before or after that mention. 15363 const decorator = this.#decoratorElementContaining(caret.node); 15364 if (decorator) { 15365 return this.#dropPointBesideDecorator(decorator, event.clientX) 15366 } else { 15367 return caret 15368 } 15369 } 15370 15371 #nearestLineCaret(rootElement, clientY) { 15372 let nearestLine = null; 15373 let nearestDistance = Infinity; 15374 15375 for (const line of rootElement.children) { 15376 const rect = line.getBoundingClientRect(); 15377 const distance = Math.min(Math.abs(clientY - rect.top), Math.abs(clientY - rect.bottom)); 15378 if (distance < nearestDistance) { 15379 nearestDistance = distance; 15380 nearestLine = line; 15381 } 15382 } 15383 15384 if (!nearestLine) return null 15385 15386 const rect = nearestLine.getBoundingClientRect(); 15387 if (clientY < rect.top) { 15388 return { node: nearestLine, offset: 0 } 15389 } else { 15390 return { node: nearestLine, offset: nearestLine.childNodes.length } 15391 } 15392 } 15393 15394 #decoratorElementContaining(node) { 15395 const element = node.nodeType === Node.ELEMENT_NODE ? node : node.parentElement; 15396 return element?.closest("[data-lexxy-decorator][data-lexical-node-key]") 15397 } 15398 15399 #dropPointBesideDecorator(decorator, clientX) { 15400 const rect = decorator.getBoundingClientRect(); 15401 const placement = clientX > rect.left + rect.width / 2 ? "after" : "before"; 15402 return { decoratorKey: decorator.dataset.lexicalNodeKey, placement } 15403 } 15404 15405 #moveAttachment(draggedKey, dropPoint) { 15406 this.#editor.update(() => { 15407 const draggedNode = Yo(draggedKey); 15408 if (!$isCustomActionTextAttachmentNode(draggedNode)) return 15409 15410 if (dropPoint.decoratorKey) { 15411 this.#moveBesideNode(draggedNode, dropPoint); 15412 } else { 15413 this.#moveToCaret(draggedNode, dropPoint); 15414 } 15415 }); 15416 } 15417 15418 #moveBesideNode(draggedNode, { decoratorKey, placement }) { 15419 const targetNode = Yo(decoratorKey); 15420 if (!targetNode || targetNode === draggedNode) return 15421 15422 draggedNode.remove(); 15423 if (placement === "after") { 15424 targetNode.insertAfter(draggedNode); 15425 } else { 15426 targetNode.insertBefore(draggedNode); 15427 } 15428 } 15429 15430 #moveToCaret(draggedNode, dropPoint) { 15431 const selection = Gr({ 15432 anchorNode: dropPoint.node, 15433 anchorOffset: dropPoint.offset, 15434 focusNode: dropPoint.node, 15435 focusOffset: dropPoint.offset 15436 }, this.#editor); 15437 if (!selection) return 15438 15439 es(selection); 15440 15441 draggedNode.remove(); 15442 selection.insertNodes([ draggedNode ]); 15443 } 15444 15445 #updateDropIndicator(event) { 15446 this.#hideCaret(); 15447 15448 const dropPoint = this.#resolveDropPoint(event); 15449 if (dropPoint) this.#showCaret(this.#caretRectFor(dropPoint)); 15450 } 15451 15452 #caretRectFor(dropPoint) { 15453 if (dropPoint.decoratorKey) { 15454 return this.#decoratorEdgeRect(dropPoint) 15455 } 15456 15457 const { node, offset } = dropPoint; 15458 const rect = caretRect(node, offset); 15459 if (rect) return rect 15460 15461 // A blank line has no text to measure, so fall back to the line's own box. 15462 const line = node.nodeType === Node.TEXT_NODE ? node.parentElement : node; 15463 if (!line) return null 15464 15465 const lineRect = line.getBoundingClientRect(); 15466 return { left: lineRect.left, top: lineRect.top, height: lineRect.height } 15467 } 15468 15469 #decoratorEdgeRect({ decoratorKey, placement }) { 15470 const decorator = this.#editor.getRootElement()?.querySelector(`[data-lexical-node-key="${decoratorKey}"]`); 15471 if (!decorator) return null 15472 15473 const rect = decorator.getBoundingClientRect(); 15474 const left = placement === "after" ? rect.right : rect.left; 15475 return { left, top: rect.top, height: rect.height } 15476 } 15477 15478 #showCaret(rect) { 15479 if (!rect) return 15480 15481 const caret = this.#ensureCaretIndicator(); 15482 caret.style.blockSize = `${rect.height}px`; 15483 caret.style.insetInlineStart = `${rect.left}px`; 15484 caret.style.insetBlockStart = `${rect.top}px`; 15485 } 15486 15487 #ensureCaretIndicator() { 15488 this.#dropIndicator ||= createElement("div", { className: "lexxy-drop-caret" }); 15489 15490 this.#editorElement().appendChild(this.#dropIndicator); 15491 this.#dropIndicator.style.display = "block"; 15492 return this.#dropIndicator 15493 } 15494 15495 #editorElement() { 15496 return this.#editor.getRootElement().closest("lexxy-editor") 15497 } 15498 15499 #hideCaret() { 15500 if (this.#dropIndicator) this.#dropIndicator.style.display = "none"; 15501 } 15502 15503 #customAttachmentElementFrom(target) { 15504 return target?.closest?.("[data-lexxy-decorator][data-lexical-node-key]") 15505 } 15506 15507 #cleanup() { 15508 if (this.#draggedNodeKey) { 15509 const rootElement = this.#editor.getRootElement(); 15510 const attachment = rootElement?.querySelector(`[data-lexical-node-key="${this.#draggedNodeKey}"]`); 15511 attachment?.classList.remove("lexxy-dragging"); 15512 } 15513 15514 this.#hideCaret(); 15515 this.#draggedNodeKey = null; 15516 15517 if (this.#draggingRafId) { 15518 cancelAnimationFrame(this.#draggingRafId); 15519 this.#draggingRafId = null; 15520 } 15521 15522 if (this.#dragOverRafId) { 15523 cancelAnimationFrame(this.#dragOverRafId); 15524 this.#dragOverRafId = null; 15525 } 15526 } 15527} 15528 15529class CustomAttachmentDragAndDropExtension extends LexxyExtension { 15530 get enabled() { 15531 return this.editorElement.supportsRichText 15532 } 15533 15534 get lexicalExtension() { 15535 return dc({ 15536 name: "lexxy/custom-attachment-drag-and-drop", 15537 register: (editor) => { 15538 const dragAndDrop = new CustomAttachmentDragAndDrop(editor); 15539 return () => dragAndDrop.destroy() 15540 } 15541 }) 15542 } 15543} 15544 15545class LexicalEditorElement extends HTMLElement { 15546 static formAssociated = true 15547 static debug = false 15548 static commands = [ "bold", "italic", "strikethrough" ] 15549 15550 static observedAttributes = [ "autocapitalize", "connected", "required" ] 15551 15552 #initialValue = "" 15553 #previousInternalFormValue = null 15554 15555 #initializeEventDispatched = false 15556 #editorInitializedDispatched = false 15557 #listeners = new ListenerBin() 15558 #disposables = [] 15559 #historyState = { undo: false, redo: false } 15560 15561 #validity = new Map() 15562 #validationTextArea = document.createElement("textarea") 15563 #uploadRequests 15564 15565 constructor() { 15566 super(); 15567 this.internals = this.attachInternals(); 15568 this.internals.role = "presentation"; 15569 } 15570 15571 get uploadRequests() { 15572 return this.#uploadRequests 15573 } 15574 15575 connectedCallback() { 15576 this.id ||= generateDomId("lexxy-editor"); 15577 this.config = new EditorConfiguration(this); 15578 this.extensions = new Extensions(this); 15579 this.#disposables.push(this.extensions); 15580 15581 this.editor = this.#createEditor(); 15582 this.#disposables.push(this.editor); 15583 this.#disposables.push(this.#listeners); 15584 15585 this.contents = new Contents(this); 15586 this.#disposables.push(this.contents); 15587 15588 this.selection = new Selection(this); 15589 this.#disposables.push(this.selection); 15590 15591 this.clipboard = new Clipboard(this); 15592 this.#disposables.push(this.clipboard); 15593 15594 this.adapter = new BrowserAdapter(); 15595 this.#uploadRequests = new UploadRequests(); 15596 15597 const commandDispatcher = CommandDispatcher.configureFor(this); 15598 this.#disposables.push(commandDispatcher); 15599 15600 this.#initialize(); 15601 15602 this.toggleAttribute("connected", true); 15603 15604 requestAnimationFrame(() => { 15605 this.#mountRoot(); 15606 this.#handleAutofocus(); 15607 this.#dispatchInitialize(); 15608 }); 15609 } 15610 15611 disconnectedCallback() { 15612 this.#initializeEventDispatched = false; 15613 this.#editorInitializedDispatched = false; 15614 15615 this.#previousInternalFormValue = null; 15616 this.valueBeforeDisconnect = this.value; 15617 15618 this.#clearCachedValues(); 15619 this.#reset(); // Prevent hangs with Safari when morphing 15620 } 15621 15622 attributeChangedCallback(name, oldValue, newValue) { 15623 if (typeof this[`${name}ChangedCallback`] === "function") { 15624 this[`${name}ChangedCallback`](oldValue, newValue); 15625 } 15626 } 15627 15628 autocapitalizeChangedCallback() { 15629 if (this.editorContentElement) { 15630 this.#transferAttributeToContentEditable(this.editorContentElement, "autocapitalize"); 15631 } 15632 } 15633 15634 connectedChangedCallback(oldValue, newValue) { 15635 if (this.isConnected && oldValue != null && oldValue !== newValue) { 15636 requestAnimationFrame(() => this.#reconnect()); 15637 } 15638 } 15639 15640 requiredChangedCallback() { 15641 if (this.isConnected) this.#requestValidityRefresh(); 15642 } 15643 15644 formResetCallback() { 15645 this.value = this.#initialValue; 15646 this.editor.dispatchCommand(Ye$1, undefined); 15647 } 15648 15649 toString() { 15650 return this.cachedStringValue ??= this.editor?.read(() => { 15651 return $getReadableTextContent(Zo()) 15652 }) 15653 } 15654 15655 get form() { 15656 return this.internals.form 15657 } 15658 15659 get name() { 15660 return this.getAttribute("name") 15661 } 15662 15663 get required() { 15664 return this.hasAttribute("required") 15665 } 15666 15667 get validity() { 15668 return this.internals.validity 15669 } 15670 15671 checkValidity() { 15672 return this.internals.checkValidity() 15673 } 15674 15675 reportValidity() { 15676 return this.internals.reportValidity() 15677 } 15678 15679 setElementValidity(key, flags, message) { 15680 this.#validity.set(key, { flags, message }); 15681 this.#requestValidityRefresh(); 15682 } 15683 15684 get toolbarElement() { 15685 if (!this.#hasToolbar) return null 15686 15687 this.toolbar ??= this.#findOrCreateDefaultToolbar(); 15688 return this.toolbar 15689 } 15690 15691 get baseExtensions() { 15692 return [ 15693 ProvisionalParagraphExtension, 15694 CodeHighlightingExtension, 15695 HighlightExtension, 15696 TrixContentExtension, 15697 TablesExtension, 15698 RewritableHistoryExtension, 15699 AttachmentsExtension, 15700 FormatEscapeExtension, 15701 LinkOpenerExtension, 15702 PreventLexicalTripleClickExtension, 15703 CustomAttachmentDragAndDropExtension 15704 ] 15705 } 15706 15707 get directUploadUrl() { 15708 return this.dataset.directUploadUrl 15709 } 15710 15711 get blobUrlTemplate() { 15712 return this.dataset.blobUrlTemplate 15713 } 15714 15715 get permittedAttachmentTypes() { 15716 const raw = this.config.get("permittedAttachmentTypes"); 15717 if (raw == null) { 15718 return null 15719 } else { 15720 const tokens = Array.isArray(raw) ? raw : String(raw).split(/\s+/); 15721 return Object.freeze(tokens.filter(t => t && t !== "false")) 15722 } 15723 } 15724 15725 permitsAttachmentContentType(contentType) { 15726 if (!this.supportsAttachments) { 15727 return false 15728 } else { 15729 const list = this.permittedAttachmentTypes; 15730 return list === null || list.includes(contentType) 15731 } 15732 } 15733 15734 acceptsFile(file) { 15735 return dispatch(this, "lexxy:file-accept", { file }, true) 15736 } 15737 15738 $generateNodesFromDOM(doc, { editor = this.editor } = {}) { 15739 let nodes = dt$1(editor, doc); 15740 if (Es(jn)) nodes = $convertInlineImageDataURIs(nodes, this); 15741 return filterDisallowedAttachmentNodes(nodes, this) 15742 } 15743 15744 get isEmpty() { 15745 return [ "<p><br></p>", "<p></p>", "" ].includes(this.value.trim()) 15746 } 15747 15748 get isBlank() { 15749 return this.isEmpty || this.toString().match(/^\s*$/g) !== null 15750 } 15751 15752 get hasOpenPrompt() { 15753 return this.querySelector(".lexxy-prompt-menu.lexxy-prompt-menu--visible") !== null 15754 } 15755 15756 get preset() { 15757 return this.getAttribute("preset") || "default" 15758 } 15759 15760 get supportsAttachments() { 15761 return this.config.get("attachments") 15762 } 15763 15764 get supportsMarkdown() { 15765 return this.supportsRichText && this.config.get("markdown") 15766 } 15767 15768 get supportsMultiLine() { 15769 return this.config.get("multiLine") && !this.isSingleLineMode 15770 } 15771 15772 get supportsRichText() { 15773 return this.config.get("richText") 15774 } 15775 15776 registerAdapter(adapter) { 15777 this.adapter = adapter; 15778 15779 if (!this.editor) return 15780 15781 this.#dispatchEditorInitialized(); 15782 this.#dispatchAttributesChange(); 15783 } 15784 15785 freezeSelection() { 15786 this.adapter.freeze(); 15787 } 15788 15789 thawSelection() { 15790 this.adapter.thaw(); 15791 } 15792 15793 dispatchAttributesChange() { 15794 this.#dispatchAttributesChange(); 15795 } 15796 15797 dispatchEditorInitialized() { 15798 this.#dispatchEditorInitialized(); 15799 } 15800 15801 // TODO: Deprecate `single-line` attribute 15802 get isSingleLineMode() { 15803 return this.hasAttribute("single-line") 15804 } 15805 15806 get contentTabIndex() { 15807 return parseInt(this.editorContentElement?.getAttribute("tabindex") ?? "0") 15808 } 15809 15810 focus() { 15811 // `editor.focus()` commits a reconciler update to position the cursor. 15812 // Skip if the contenteditable already owns focus â the update would be a 15813 // no-op but still triggers a full style/layout pass on pages with large 15814 // DOMs. 15815 if (this.#isContentFocused) return 15816 15817 this.editor.focus(() => this.#onFocus()); 15818 } 15819 15820 get #isContentFocused() { 15821 return !!this.editor && isEditorFocused(this.editor) 15822 } 15823 15824 get value() { 15825 return this.cachedValue ??= this.#readSanitizedEditorValue() 15826 } 15827 15828 set value(html) { 15829 const editorHasFocus = this.#isContentFocused; 15830 15831 this.editor.update(() => { 15832 if (editorHasFocus) { 15833 // Address Safari inconsistently placing the cursor in the contenteditable by forcing focus back onto the editor 15834 // Use direct `editor.focus` to bypass the pre-existing focus optimization and skip the callback 15835 Ms(() => this.editor.focus()); 15836 } else { 15837 Os(qn); 15838 } 15839 15840 15841 this.#setEditorHtml(html); 15842 this.#toggleEmptyStatus(); 15843 }, { discrete: true }); 15844 } 15845 15846 get canUndo() { 15847 return this.#historyState.undo 15848 } 15849 15850 get canRedo() { 15851 return this.#historyState.redo 15852 } 15853 15854 #readSanitizedEditorValue() { 15855 return this.editor?.read(() => { 15856 return sanitize(ht$1(this.editor, null)) 15857 }) ?? null 15858 } 15859 15860 #parseHtmlIntoLexicalNodes(html, { editor = this.editor } = {}) { 15861 if (!html) html = "<p></p>"; 15862 const nodes = this.$generateNodesFromDOM(parseHtml(`${html}`), { editor }); 15863 15864 return nodes 15865 .filter(this.#isNotWhitespaceOnlyNode) 15866 .map(this.#wrapTextNode) 15867 } 15868 15869 // Whitespace-only text nodes (e.g. "\n" between block elements like <div>) and stray line break 15870 // nodes are formatting artifacts from the HTML source. They can't be appended to the root node 15871 // and have no semantic meaning, so we strip them during import. 15872 #isNotWhitespaceOnlyNode(node) { 15873 if (sr(node)) return false 15874 if (Tr(node) && node.getTextContent().trim() === "") return false 15875 return true 15876 } 15877 15878 // Raw string values produce TextNodes which cannot be appended directly to the RootNode. 15879 // We wrap those in <p> 15880 #wrapTextNode(node) { 15881 if (!Tr(node)) return node 15882 15883 const paragraph = eo(); 15884 paragraph.append(node); 15885 return paragraph 15886 } 15887 15888 #initialize() { 15889 this.#registerComponents(); 15890 this.#handleEnter(); 15891 this.#handleReplacementText(); 15892 this.#registerFocusEvents(); 15893 this.#registerHistoryEvents(); 15894 this.#registerFileAcceptFilter(); 15895 this.#attachDebugHooks(); 15896 this.#attachToolbar(); 15897 this.#resetBeforeTurboCaches(); 15898 15899 this.#setInternalFormValue(this.value, { suppressEvent: true }); 15900 this.#synchronizeWithChanges(); 15901 } 15902 15903 #registerFileAcceptFilter() { 15904 this.#listeners.track( 15905 registerEventListener(this, "lexxy:file-accept", (event) => { 15906 if (!this.permitsAttachmentContentType(event.detail.file.type)) { 15907 event.preventDefault(); 15908 } 15909 }) 15910 ); 15911 } 15912 15913 #createEditor() { 15914 this.editorContentElement ||= this.#createEditorContentElement(); 15915 this.appendChild(this.editorContentElement); 15916 15917 const editor = oe$4({ 15918 name: "lexxy/core", 15919 namespace: "Lexxy", 15920 theme: theme, 15921 nodes: this.#lexicalNodes, 15922 html: { 15923 export: new Map([ [ gr, exportTextNodeDOM ], [ K$1, exportTextNodeDOM ] ]) 15924 }, 15925 $initialEditorState: (editor) => { 15926 this.#configureSanitizer(editor); 15927 this.#loadInitialValue(editor); 15928 }, 15929 }, 15930 ...this.extensions.lexicalExtensions 15931 ); 15932 15933 return editor 15934 } 15935 15936 // Toggling editable around setRootElement skips Lexical's DOM-selection sync, 15937 // which would otherwise steal focus from elsewhere on the page. 15938 #mountRoot() { 15939 this.editor.setEditable(false); 15940 this.editor.setRootElement(this.editorContentElement); 15941 this.editor.setEditable(true); 15942 } 15943 15944 get #lexicalNodes() { 15945 const nodes = [ CustomActionTextAttachmentNode ]; 15946 15947 if (this.supportsRichText) { 15948 nodes.push( 15949 At$1, 15950 It$1, 15951 me$2, 15952 ge$2, 15953 z$1, 15954 K$1, 15955 F$4, 15956 j$5, 15957 HorizontalDividerNode 15958 ); 15959 } 15960 15961 return nodes 15962 } 15963 15964 #createEditorContentElement() { 15965 const editorContentElement = createElement("div", { 15966 id: `${this.id}-content`, 15967 classList: "lexxy-editor__content", 15968 contenteditable: true, 15969 role: "textbox", 15970 "aria-multiline": true, 15971 "aria-label": this.#labelText, 15972 placeholder: this.getAttribute("placeholder") 15973 }); 15974 15975 this.#ariaAttributes.forEach(attribute => editorContentElement.setAttribute(attribute.name, attribute.value)); 15976 15977 this.#transferAttributeToContentEditable(editorContentElement, "autocapitalize"); 15978 this.#transferAttributeToContentEditable(editorContentElement, "tabindex", { defaultValue: 0, removeSource: true }); 15979 15980 return editorContentElement 15981 } 15982 15983 #transferAttributeToContentEditable(element, qualifiedName, { defaultValue = null, removeSource = false } = {}) { 15984 if (this.hasAttribute(qualifiedName)) { 15985 element.setAttribute(qualifiedName, this.getAttribute(qualifiedName)); 15986 } else if (defaultValue !== null) { 15987 element.setAttribute(qualifiedName, defaultValue); 15988 } else { 15989 element.removeAttribute(qualifiedName); 15990 } 15991 15992 if (removeSource) this.removeAttribute(qualifiedName); 15993 } 15994 15995 get #labelText() { 15996 return Array.from(this.internals.labels).map(label => label.textContent).join(" ") 15997 } 15998 15999 get #ariaAttributes() { 16000 return Array.from(this.attributes).filter(attribute => attribute.name.startsWith("aria-")) 16001 } 16002 16003 #setInternalFormValue(html, { suppressEvent = false } = {}) { 16004 const changed = html !== this.#previousInternalFormValue; 16005 16006 this.internals.setFormValue(html); 16007 this.#previousInternalFormValue = html; 16008 16009 if (changed && !suppressEvent) { 16010 dispatch(this, "lexxy:change"); 16011 } 16012 } 16013 16014 #loadInitialValue(editor) { 16015 const initialHtml = this.valueBeforeDisconnect || this.getAttribute("value") || "<p><br></p>"; 16016 16017 this.#initialValue = initialHtml; 16018 this.#setEditorHtml(initialHtml, { editor }); 16019 } 16020 16021 #setEditorHtml(html, { editor = this.editor } = { }) { 16022 Zo() 16023 .clear() 16024 .selectEnd() 16025 .insertNodes(this.#parseHtmlIntoLexicalNodes(html, { editor })); 16026 } 16027 16028 #resetBeforeTurboCaches() { 16029 this.#listeners.track( 16030 registerEventListener(document, "turbo:before-cache", this.#handleTurboBeforeCache) 16031 ); 16032 } 16033 16034 #handleTurboBeforeCache = (event) => { 16035 if (!this.closest("[data-turbo-permanent]")) { 16036 this.#reset(); 16037 } 16038 } 16039 16040 #synchronizeWithChanges() { 16041 this.#listeners.track(this.editor.registerUpdateListener(({ editorState }) => { 16042 this.#clearCachedValues(); 16043 this.#setInternalFormValue(this.value); 16044 this.#toggleEmptyStatus(); 16045 this.#requestValidityRefresh(); 16046 this.#dispatchAttributesChange(); 16047 })); 16048 } 16049 16050 async #requestValidityRefresh() { 16051 await nextFrame(); 16052 16053 if (this.isConnected) this.#refreshValidity(); 16054 } 16055 16056 #refreshValidity() { 16057 this.#refreshInternalValidity(); 16058 const { validity, message } = this.#calculateValidity(); 16059 this.internals.setValidity(validity, message, this.editorContentElement); 16060 } 16061 16062 #refreshInternalValidity() { 16063 this.#validationTextArea.required = this.required && this.isBlank; 16064 const flags = this.#validationTextArea.validity; 16065 const message = this.#validationTextArea.validationMessage; 16066 16067 this.#validity.set(this, { flags, message }); 16068 } 16069 16070 #calculateValidity() { 16071 const validity = {}; 16072 const messages = []; 16073 16074 for (const { flags, message } of this.#validity.values()) { 16075 // internal TextArea's ValidityState can contain `valid: true` 16076 if (flags.valid === true) continue 16077 16078 for (const flag in flags) { 16079 if (flags[flag]) { 16080 validity[flag] = true; 16081 messages.push(message); 16082 } 16083 } 16084 } 16085 16086 return { validity, message: messages.join("\n") } 16087 } 16088 16089 #clearCachedValues() { 16090 this.cachedValue = null; 16091 this.cachedStringValue = null; 16092 } 16093 16094 #registerComponents() { 16095 const registered = []; 16096 16097 if (this.supportsRichText) { 16098 registered.push( 16099 zt$2(this.editor), 16100 Ie$2(this.editor) 16101 ); 16102 this.#registerTableComponents(); 16103 this.#registerCodeLanguagePicker(); 16104 if (this.supportsMarkdown) { 16105 const transformers = [ ...te, HORIZONTAL_DIVIDER ]; 16106 registered.push( 16107 se$1(this.editor, transformers), 16108 registerMarkdownLeadingTagHandler(this.editor, transformers) 16109 ); 16110 } 16111 } else { 16112 registered.push(H$2(this.editor)); 16113 } 16114 16115 this.#listeners.track(...registered); 16116 } 16117 16118 #registerTableComponents() { 16119 let tableTools = this.querySelector("lexxy-table-tools"); 16120 tableTools ??= createElement("lexxy-table-tools"); 16121 this.append(tableTools); 16122 this.#disposables.push(tableTools); 16123 } 16124 16125 #registerCodeLanguagePicker() { 16126 let codeLanguagePicker = this.querySelector("lexxy-code-language-picker"); 16127 codeLanguagePicker ??= createElement("lexxy-code-language-picker"); 16128 this.append(codeLanguagePicker); 16129 this.#disposables.push(codeLanguagePicker); 16130 } 16131 16132 #handleEnter() { 16133 // We can't prevent these externally using regular keydown because Lexical handles it first. 16134 this.#listeners.track(this.editor.registerCommand( 16135 Oe$2, 16136 (event) => { 16137 // Prevent CTRL+ENTER 16138 if (event.ctrlKey || event.metaKey) { 16139 event.preventDefault(); 16140 return true 16141 } 16142 16143 // In single line mode, prevent ENTER 16144 if (!this.supportsMultiLine) { 16145 event.preventDefault(); 16146 return true 16147 } 16148 16149 return false 16150 }, 16151 oo 16152 )); 16153 } 16154 16155 #handleReplacementText() { 16156 this.#listeners.track(this.editor.registerCommand( 16157 ge$3, 16158 (event) => event instanceof InputEvent && this.contents.insertTextWithLineBreaks(event.data), 16159 oo 16160 )); 16161 } 16162 16163 #registerFocusEvents() { 16164 this.#listeners.track( 16165 registerEventListener(this, "focusin", this.#handleFocusIn), 16166 registerEventListener(this, "focusout", this.#handleFocusOut) 16167 ); 16168 } 16169 16170 #handleFocusIn(event) { 16171 if (this.#elementInEditorOrToolbar(event.target) && !this.currentlyFocused) { 16172 this.#dispatchAttributesChange(); 16173 dispatch(this, "lexxy:focus"); 16174 this.currentlyFocused = true; 16175 } 16176 } 16177 16178 #handleFocusOut(event) { 16179 if (!this.#elementInEditorOrToolbar(event.relatedTarget)) { 16180 dispatch(this, "lexxy:blur"); 16181 this.currentlyFocused = false; 16182 } 16183 } 16184 16185 #elementInEditorOrToolbar(element) { 16186 return this.contains(element) || this.toolbarElement?.contains(element) 16187 } 16188 16189 #onFocus() { 16190 if (this.isEmpty) { 16191 this.selection.placeCursorAtTheEnd(); 16192 } 16193 } 16194 16195 #handleAutofocus() { 16196 if (!document.querySelector(":focus")) { 16197 if (this.hasAttribute("autofocus") && document.querySelector("[autofocus]") === this) { 16198 this.focus(); 16199 } 16200 } 16201 } 16202 16203 #registerHistoryEvents() { 16204 this.#listeners.track( 16205 this.editor.registerCommand(He$2, (enabled) => { this.#historyState.undo = enabled; }, oo), 16206 this.editor.registerCommand(qe$2, (enabled) => { this.#historyState.redo = enabled; }, oo) 16207 ); 16208 } 16209 16210 #attachDebugHooks() { 16211 return 16212 } 16213 16214 #attachToolbar() { 16215 if (this.#hasToolbar) { 16216 this.toolbarElement.setEditor(this); 16217 if (typeof this.toolbarElement.dispose === "function") { 16218 this.#disposables.push(this.toolbarElement); 16219 } 16220 16221 this.extensions.initializeToolbars(); 16222 } 16223 } 16224 16225 #findOrCreateDefaultToolbar() { 16226 const toolbarConfig = this.config.get("toolbar"); 16227 if (typeof toolbarConfig === "string") { 16228 return document.getElementById(toolbarConfig) 16229 } else { 16230 return this.querySelector("lexxy-toolbar") ?? this.#createDefaultToolbar() 16231 } 16232 } 16233 16234 get #hasToolbar() { 16235 return this.supportsRichText && !!this.config.get("toolbar") 16236 } 16237 16238 #createDefaultToolbar() { 16239 const toolbar = createElement("lexxy-toolbar"); 16240 toolbar.innerHTML = LexicalToolbarElement.defaultTemplate; 16241 toolbar.setAttribute("data-attachments", this.supportsAttachments); // Drives toolbar CSS styles 16242 toolbar.configure(this.config.get("toolbar")); 16243 this.prepend(toolbar); 16244 return toolbar 16245 } 16246 16247 #toggleEmptyStatus() { 16248 this.classList.toggle("lexxy-editor--empty", this.isEmpty); 16249 } 16250 16251 #configureSanitizer(editor) { 16252 setSanitizerConfig(this.#getAllowedElements(editor)); 16253 } 16254 16255 #getAllowedElements(editor) { 16256 return this.#getImportableTags(editor).concat(this.extensions.allowedElements) 16257 } 16258 16259 #getImportableTags(editor) { 16260 const tags = Array.from(editor._htmlConversions.keys()); 16261 return tags.filter(tag => !tag.startsWith("#")) 16262 } 16263 16264 #dispatchAttributesChange() { 16265 let attributes = null; 16266 let linkHref = null; 16267 let highlight = null; 16268 let headingTag = null; 16269 16270 this.editor.getEditorState().read(() => { 16271 const selection = Qr(); 16272 if (!Fr(selection)) return 16273 16274 const format = this.selection.getFormat(); 16275 if (Object.keys(format).length === 0) return 16276 16277 const anchorNode = selection.anchor.getNode(); 16278 const linkNode = At$2(anchorNode, F$4); 16279 16280 attributes = { 16281 bold: { active: format.isBold, enabled: true }, 16282 italic: { active: format.isItalic, enabled: true }, 16283 strikethrough: { active: format.isStrikethrough, enabled: true }, 16284 code: { active: format.isInCode, enabled: true }, 16285 highlight: { active: format.isHighlight, enabled: true }, 16286 link: { active: format.isInLink, enabled: true }, 16287 quote: { active: format.isInQuote, enabled: true }, 16288 heading: { active: format.isInHeading, enabled: true }, 16289 "unordered-list": { active: format.isInList && format.listType === "bullet", enabled: true }, 16290 "ordered-list": { active: format.isInList && format.listType === "number", enabled: true }, 16291 undo: { active: false, enabled: this.canUndo }, 16292 redo: { active: false, enabled: this.canRedo } 16293 }; 16294 16295 linkHref = linkNode ? linkNode.getURL() : null; 16296 highlight = format.isHighlight ? getHighlightStyles(selection) : null; 16297 headingTag = format.headingTag ?? null; 16298 }); 16299 16300 if (attributes) { 16301 this.adapter.dispatchAttributesChange(attributes, linkHref, highlight, headingTag); 16302 } 16303 } 16304 16305 #dispatchEditorInitialized() { 16306 if (!this.adapter) return 16307 16308 this.#editorInitializedDispatched = true; 16309 16310 this.adapter.dispatchEditorInitialized({ 16311 highlightColors: this.#resolvedHighlightColors, 16312 headingFormats: this.#supportedHeadingFormats 16313 }); 16314 } 16315 16316 #dispatchInitialize() { 16317 if (this.isConnected && this.adapter) { 16318 if (!this.#initializeEventDispatched) { 16319 this.#initializeEventDispatched = true; 16320 dispatch(this, "lexxy:initialize"); 16321 } 16322 16323 if (!this.#editorInitializedDispatched) { 16324 this.#dispatchEditorInitialized(); 16325 } 16326 } 16327 } 16328 16329 get #resolvedHighlightColors() { 16330 const buttons = this.config.get("highlight.buttons"); 16331 if (!buttons) return null 16332 16333 const colors = this.#resolveColors("color", buttons.color || []); 16334 const backgroundColors = this.#resolveColors("background-color", buttons["background-color"] || []); 16335 return { colors, backgroundColors } 16336 } 16337 16338 get #supportedHeadingFormats() { 16339 if (!this.supportsRichText) return [] 16340 16341 const headings = this.config.get("headings"); 16342 return [ 16343 { label: "Normal", command: "setFormatParagraph", tag: null }, 16344 ...headings.map((tag, index) => ({ 16345 label: HeadingDropdown.labelFor(tag, index), 16346 command: HeadingDropdown.commandFor(index), 16347 tag 16348 })) 16349 ] 16350 } 16351 16352 // Builds one resolver element per CSS value inside a hidden container, attaches 16353 // the container in a single DOM write, then reads all computed values in one pass 16354 // â triggering at most one forced reflow. The previous implementation interleaved 16355 // setProperty/getComputedStyle/removeProperty on the same element, forcing a style 16356 // recalc on every iteration during editor initialization. 16357 #resolveColors(property, cssValues) { 16358 const container = document.createElement("span"); 16359 container.style.display = "none"; 16360 16361 const resolvers = cssValues.map(cssValue => { 16362 const element = document.createElement("span"); 16363 element.style.setProperty(property, cssValue); 16364 container.appendChild(element); 16365 return { element, name: cssValue } 16366 }); 16367 16368 styleResolverRoot().appendChild(container); 16369 16370 const resolved = resolvers.map(({ element, name }) => ({ 16371 name, 16372 value: window.getComputedStyle(element).getPropertyValue(property) 16373 })); 16374 16375 container.remove(); 16376 return resolved 16377 } 16378 16379 #reset() { 16380 this.#dispose(); 16381 this.#resetValidity(); 16382 this.#uploadRequests?.clear(); 16383 this.editorContentElement?.remove(); 16384 this.editorContentElement = null; 16385 16386 // Prevents issues with turbo morphing receiving an empty <lexxy-editor> which wipes 16387 // out the DOM for the tools, and the old toolbar reference will cause issues 16388 this.toolbar = null; 16389 } 16390 16391 #dispose() { 16392 while (this.#disposables.length) { 16393 this.#disposables.pop().dispose(); 16394 } 16395 } 16396 16397 #reconnect() { 16398 this.disconnectedCallback(); 16399 this.valueBeforeDisconnect = null; 16400 this.connectedCallback(); 16401 } 16402 16403 #resetValidity() { 16404 this.#validity = new Map(); 16405 } 16406} 16407 16408// Like $getRoot().getTextContent() but uses readable text for custom attachment nodes 16409// (e.g., mentions) instead of their single-character cursor placeholder. 16410function $getReadableTextContent(node) { 16411 if (node instanceof CustomActionTextAttachmentNode) { 16412 return node.getReadableTextContent() 16413 } 16414 16415 if (Wi(node)) { 16416 let text = ""; 16417 const children = node.getChildren(); 16418 for (let i = 0; i < children.length; i++) { 16419 const child = children[i]; 16420 const previousChild = children[i - 1]; 16421 16422 if (isAttachmentSpacerTextNode(child, previousChild, i, children.length)) continue 16423 16424 text += $getReadableTextContent(child); 16425 if (Wi(child) && i !== children.length - 1 && !child.isInline()) { 16426 text += "\n\n"; 16427 } 16428 } 16429 return text 16430 } 16431 16432 return node.getTextContent() 16433} 16434 16435class BaseSource { 16436 // Template method to override 16437 async buildListItems(filter = "") { 16438 return Promise.resolve([]) 16439 } 16440 16441 // Template method to override 16442 promptItemFor(listItem) { 16443 return null 16444 } 16445 16446 // Protected 16447 16448 buildListItemElementFor(promptItemElement) { 16449 const template = promptItemElement.querySelector("template[type='menu']"); 16450 const fragment = template.content.cloneNode(true); 16451 const listItemElement = createElement("li", { role: "option", id: generateDomId("prompt-item"), tabindex: "0" }); 16452 listItemElement.classList.add("lexxy-prompt-menu__item"); 16453 listItemElement.appendChild(fragment); 16454 return listItemElement 16455 } 16456 16457 async loadPromptItemsFromUrl(url) { 16458 try { 16459 const response = await fetch(url); 16460 const html = await response.text(); 16461 const promptItems = parseHtml(html).querySelectorAll("lexxy-prompt-item"); 16462 return Promise.resolve(Array.from(promptItems)) 16463 } catch (error) { 16464 return Promise.reject(error) 16465 } 16466 } 16467} 16468 16469const MAX_RENDERED_SUGGESTIONS$1 = 100; 16470 16471class LocalFilterSource extends BaseSource { 16472 async buildListItems(filter = "") { 16473 const promptItems = await this.fetchPromptItems(); 16474 return this.#buildListItemsFromPromptItems(promptItems, filter) 16475 } 16476 16477 // Template method to override 16478 async fetchPromptItems(filter) { 16479 return Promise.resolve([]) 16480 } 16481 16482 promptItemFor(listItem) { 16483 return this.promptItemByListItem.get(listItem) 16484 } 16485 16486 #buildListItemsFromPromptItems(promptItems, filter) { 16487 this.promptItemByListItem = new WeakMap(); 16488 16489 if (!filter) { 16490 return this.#buildAllListItems(promptItems) 16491 } 16492 16493 const matches = []; 16494 for (const promptItem of promptItems) { 16495 const searchableText = promptItem.getAttribute("search"); 16496 const position = filterMatchPosition(searchableText, filter); 16497 if (position >= 0) { 16498 matches.push({ promptItem, position }); 16499 } 16500 } 16501 16502 matches.sort((a, b) => a.position - b.position); 16503 16504 const listItems = []; 16505 for (const { promptItem } of matches) { 16506 if (listItems.length >= MAX_RENDERED_SUGGESTIONS$1) break 16507 const listItem = this.buildListItemElementFor(promptItem); 16508 this.promptItemByListItem.set(listItem, promptItem); 16509 listItems.push(listItem); 16510 } 16511 return listItems 16512 } 16513 16514 #buildAllListItems(promptItems) { 16515 const listItems = []; 16516 for (const promptItem of promptItems) { 16517 if (listItems.length >= MAX_RENDERED_SUGGESTIONS$1) break 16518 const listItem = this.buildListItemElementFor(promptItem); 16519 this.promptItemByListItem.set(listItem, promptItem); 16520 listItems.push(listItem); 16521 } 16522 return listItems 16523 } 16524} 16525 16526class InlinePromptSource extends LocalFilterSource { 16527 constructor(inlinePromptItems) { 16528 super(); 16529 this.inlinePromptItemElements = Array.from(inlinePromptItems); 16530 } 16531 16532 async fetchPromptItems() { 16533 return Promise.resolve(this.inlinePromptItemElements) 16534 } 16535} 16536 16537class DeferredPromptSource extends LocalFilterSource { 16538 constructor(url) { 16539 super(); 16540 this.url = url; 16541 16542 this.fetchPromptItems(); 16543 } 16544 16545 async fetchPromptItems() { 16546 this.promptItems ??= await this.loadPromptItemsFromUrl(this.url); 16547 16548 return Promise.resolve(this.promptItems) 16549 } 16550} 16551 16552const DEBOUNCE_INTERVAL = 200; 16553const MAX_RENDERED_SUGGESTIONS = 100; 16554 16555class RemoteFilterSource extends BaseSource { 16556 constructor(url) { 16557 super(); 16558 16559 this.baseURL = url; 16560 this.loadAndFilterListItems = debounceAsync(this.fetchFilteredListItems.bind(this), DEBOUNCE_INTERVAL); 16561 } 16562 16563 async buildListItems(filter = "") { 16564 return await this.loadAndFilterListItems(filter) 16565 } 16566 16567 promptItemFor(listItem) { 16568 return this.promptItemByListItem.get(listItem) 16569 } 16570 16571 async fetchFilteredListItems(filter) { 16572 const promptItems = await this.loadPromptItemsFromUrl(this.#urlFor(filter)); 16573 return this.#buildListItemsFromPromptItems(promptItems) 16574 } 16575 16576 #urlFor(filter) { 16577 const url = new URL(this.baseURL, window.location.origin); 16578 url.searchParams.append("filter", filter); 16579 return url.toString() 16580 } 16581 16582 #buildListItemsFromPromptItems(promptItems) { 16583 const listItems = []; 16584 this.promptItemByListItem = new WeakMap(); 16585 16586 for (const promptItem of promptItems) { 16587 if (listItems.length >= MAX_RENDERED_SUGGESTIONS) break 16588 16589 const listItem = this.buildListItemElementFor(promptItem); 16590 this.promptItemByListItem.set(listItem, promptItem); 16591 listItems.push(listItem); 16592 } 16593 16594 return listItems 16595 } 16596} 16597 16598const NOTHING_FOUND_DEFAULT_MESSAGE = "Nothing found"; 16599const FILTER_DEBOUNCE_INTERVAL = 50; 16600 16601// Start of line, or after a space or newline. 16602const DEFAULT_ONLY_AT_PATTERN = "^|[ \\n]"; 16603 16604class LexicalPromptElement extends HTMLElement { 16605 #globalListeners = new ListenerBin() 16606 #popoverListeners = new ListenerBin() 16607 #debouncedFilterOptions = debounce(() => this.#filterOptions(), FILTER_DEBOUNCE_INTERVAL) 16608 16609 constructor() { 16610 super(); 16611 this.showPopoverId = 0; 16612 } 16613 16614 static observedAttributes = [ "connected" ] 16615 16616 connectedCallback() { 16617 this.source = this.#createSource(); 16618 16619 this.#addTriggerListener(); 16620 this.#removePopoverBeforeTurboCaches(); 16621 this.toggleAttribute("connected", true); 16622 } 16623 16624 disconnectedCallback() { 16625 this.#popoverListeners.dispose(); 16626 this.#globalListeners.dispose(); 16627 this.source = null; 16628 this.#removePopover(); 16629 } 16630 16631 16632 attributeChangedCallback(name, oldValue, newValue) { 16633 if (name === "connected" && this.isConnected && oldValue != null && oldValue !== newValue) { 16634 requestAnimationFrame(() => this.#reconnect()); 16635 } 16636 } 16637 16638 get name() { 16639 return this.getAttribute("name") 16640 } 16641 16642 get trigger() { 16643 return this.getAttribute("trigger") 16644 } 16645 16646 get supportsSpaceInSearches() { 16647 return this.hasAttribute("supports-space-in-searches") 16648 } 16649 16650 get onlyAt() { 16651 return this.getAttribute("only-at") 16652 } 16653 16654 get verticalDirection() { 16655 return this.getAttribute("vertical-direction") 16656 } 16657 16658 get open() { 16659 return this.popoverElement?.classList?.contains("lexxy-prompt-menu--visible") 16660 } 16661 16662 get closed() { 16663 return !this.open 16664 } 16665 16666 get #doesSpaceSelect() { 16667 return !this.supportsSpaceInSearches 16668 } 16669 16670 #createSource() { 16671 const src = this.getAttribute("src"); 16672 if (src) { 16673 if (this.hasAttribute("remote-filtering")) { 16674 return new RemoteFilterSource(src) 16675 } else { 16676 return new DeferredPromptSource(src) 16677 } 16678 } else { 16679 return new InlinePromptSource(this.querySelectorAll("lexxy-prompt-item")) 16680 } 16681 } 16682 16683 #addTriggerListener() { 16684 if (!this.#promptContentTypePermitted) return 16685 16686 this.#popoverListeners.track(this.#editor.registerUpdateListener(({ editorState }) => { 16687 editorState.read(() => { 16688 if (this.#selection.isInsideCodeBlock) return 16689 16690 const { node, offset } = this.#selection.selectedNodeWithOffset(); 16691 if (!node) return 16692 16693 if (Tr(node)) { 16694 const fullText = node.getTextContent(); 16695 const triggerLength = this.trigger.length; 16696 16697 // Check if we have enough characters for the trigger 16698 if (offset >= triggerLength) { 16699 const textBeforeCursor = fullText.slice(offset - triggerLength, offset); 16700 16701 if (textBeforeCursor === this.trigger) { 16702 const textBeforeTrigger = $textBeforeOffset(node, offset - triggerLength); 16703 16704 if (this.#onlyAtRegExp.test(textBeforeTrigger)) { 16705 this.#popoverListeners.dispose(); 16706 this.#showPopover(); 16707 } 16708 } 16709 } 16710 } 16711 }); 16712 })); 16713 } 16714 16715 get #onlyAtRegExp() { 16716 return new RegExp(`(?:${this.onlyAt ?? DEFAULT_ONLY_AT_PATTERN})$`) 16717 } 16718 16719 get #promptContentTypePermitted() { 16720 // `insert-editable-text` prompts never create attachments, so the 16721 // editor's attachment support and content-type allowlist don't apply. 16722 if (this.hasAttribute("insert-editable-text")) return true 16723 16724 const el = this.#editorElement; 16725 if (!el.supportsAttachments) { 16726 return false 16727 } else { 16728 const templates = Array.from(this.querySelectorAll("template[type='editor']")); 16729 const types = templates.length 16730 ? templates.map(t => t.getAttribute("content-type") || this.#defaultPromptContentType) 16731 : [ this.#defaultPromptContentType ]; 16732 return types.some(t => el.permitsAttachmentContentType(t)) 16733 } 16734 } 16735 16736 #addCursorPositionListener() { 16737 this.#popoverListeners.track(this.#editor.registerUpdateListener(({ editorState }) => { 16738 if (this.closed) return 16739 16740 editorState.read(() => { 16741 if (this.#selection.isInsideCodeBlock) { 16742 this.#hidePopover(); 16743 return 16744 } 16745 16746 const { node, offset } = this.#selection.selectedNodeWithOffset(); 16747 if (!node) return 16748 16749 if (this.#cursorIsTypingSearchTerm(node, offset)) { 16750 if (!this.popoverElement.hasAttribute("data-anchored")) { 16751 this.#positionPopover(); 16752 } 16753 } else { 16754 this.#hidePopover(); 16755 } 16756 }); 16757 })); 16758 } 16759 16760 // The popover should stay open only while the cursor sits at the end of the 16761 // trigger and its search term. When the cursor moves away â before the 16762 // trigger, or past the token into later text â the text between the trigger 16763 // and the cursor breaks that run and we dismiss. A newline always breaks the 16764 // run; a space breaks it only for triggers that don't support spaces in 16765 // searches, since those that do (e.g. `person:`) expect multi-word terms. 16766 #cursorIsTypingSearchTerm(node, offset) { 16767 if (!Tr(node) || offset === 0) return false 16768 16769 const textBeforeCursor = node.getTextContent().slice(0, offset); 16770 const lastTriggerIndex = textBeforeCursor.lastIndexOf(this.trigger); 16771 if (lastTriggerIndex === -1) return false 16772 16773 const searchTerm = textBeforeCursor.slice(lastTriggerIndex + this.trigger.length); 16774 const breakPattern = this.supportsSpaceInSearches ? /\n/ : /[ \n]/; 16775 return !breakPattern.test(searchTerm) 16776 } 16777 16778 get #editor() { 16779 return this.#editorElement.editor 16780 } 16781 16782 get #editorElement() { 16783 return this.closest("lexxy-editor") 16784 } 16785 16786 get #selection() { 16787 return this.#editorElement.selection 16788 } 16789 16790 async #showPopover() { 16791 const showId = ++this.showPopoverId; 16792 this.popoverElement ??= await this.#buildPopover(); 16793 if (this.showPopoverId !== showId) return 16794 16795 this.#resetPopoverPosition(); 16796 await this.#filterOptions(); 16797 if (this.showPopoverId !== showId) return 16798 16799 this.popoverElement.classList.toggle("lexxy-prompt-menu--visible", true); 16800 this.#selectFirstOption(); 16801 16802 this.#popoverListeners.track( 16803 registerEventListener(this.#editorElement, "keydown", this.#handleKeydownOnPopover), 16804 registerEventListener(this.#editorElement, "lexxy:change", this.#debouncedFilterOptions) 16805 ); 16806 16807 this.#registerKeyListeners(); 16808 this.#addCursorPositionListener(); 16809 } 16810 16811 #registerKeyListeners() { 16812 // We can't use a regular keydown for Enter as Lexical handles it first 16813 this.#popoverListeners.track( 16814 this.#editor.registerCommand(Oe$2, this.#handleSelectedOption.bind(this), lo), 16815 this.#editor.registerCommand(Fe$2, this.#handleSelectedOption.bind(this), lo) 16816 ); 16817 16818 if (this.#doesSpaceSelect) { 16819 this.#popoverListeners.track(this.#editor.registerCommand(Me$2, this.#handleSelectedOption.bind(this), lo)); 16820 this.#popoverListeners.track(this.#editor.registerCommand(ce$4, this.#handleInputCommand.bind(this), lo)); 16821 } 16822 16823 // Register arrow keys with CRITICAL priority to prevent Lexical's selection handlers from running 16824 this.#popoverListeners.track( 16825 this.#editor.registerCommand(we$1, this.#handleArrowUp.bind(this), lo), 16826 this.#editor.registerCommand(Ee$3, this.#handleArrowDown.bind(this), lo) 16827 ); 16828 } 16829 16830 #handleArrowUp(event) { 16831 this.#moveSelectionUp(); 16832 event.preventDefault(); 16833 return true 16834 } 16835 16836 #handleArrowDown(event) { 16837 this.#moveSelectionDown(); 16838 event.preventDefault(); 16839 return true 16840 } 16841 16842 #selectFirstOption() { 16843 const firstOption = this.#listItemElements[0]; 16844 16845 if (firstOption) { 16846 this.#selectOption(firstOption); 16847 } 16848 } 16849 16850 get #listItemElements() { 16851 return Array.from(this.popoverElement.querySelectorAll(".lexxy-prompt-menu__item")) 16852 } 16853 16854 #selectOption(listItem, { scrollIntoView = false } = {}) { 16855 this.#clearListItemSelection(); 16856 listItem.toggleAttribute("aria-selected", true); 16857 if (scrollIntoView) { 16858 listItem.scrollIntoView({ block: "nearest", container: "nearest", behavior: "smooth" }); 16859 } 16860 16861 this.#setEditorAssociationAttribute("aria-controls", this.popoverElement.id); 16862 this.#setEditorAssociationAttribute("aria-activedescendant", listItem.id); 16863 this.#setEditorAssociationAttribute("aria-haspopup", "listbox"); 16864 } 16865 16866 #clearListItemSelection() { 16867 this.#listItemElements.forEach((item) => { item.toggleAttribute("aria-selected", false); }); 16868 } 16869 16870 #clearSelection() { 16871 this.#clearListItemSelection(); 16872 this.#editorContentElement.removeAttribute("aria-controls"); 16873 this.#editorContentElement.removeAttribute("aria-activedescendant"); 16874 this.#editorContentElement.removeAttribute("aria-haspopup"); 16875 } 16876 16877 #setEditorAssociationAttribute(name, value) { 16878 if (this.#editorContentElement.getAttribute(name) !== value) { 16879 this.#editorContentElement.setAttribute(name, value); 16880 } 16881 } 16882 16883 // Right after a Turbo history restore the editor reconnects before the DOM selection 16884 // is re-established, so the cursor geometry is momentarily unavailable. Anchoring then 16885 // would pin the menu to the editor's left edge for the rest of the open cycle, so we 16886 // skip it and let a later reposition anchor it once the selection is ready. The menu 16887 // stays hidden until anchored (see the `[data-anchored]` rule in the stylesheet). 16888 #positionPopover() { 16889 const cursorPosition = this.#selection.cursorPosition; 16890 if (!cursorPosition) return 16891 16892 const { x, y, fontSize } = cursorPosition; 16893 const editorRect = this.#editorElement.getBoundingClientRect(); 16894 const contentRect = this.#editorContentElement.getBoundingClientRect(); 16895 const verticalOffset = contentRect.top - editorRect.top; 16896 16897 if (!this.popoverElement.hasAttribute("data-anchored")) { 16898 this.#setPopoverOffsetX(x); 16899 this.#setPopoverOffsetY(y + verticalOffset); 16900 this.popoverElement.toggleAttribute("data-anchored", true); 16901 } 16902 16903 const popoverRect = this.popoverElement.getBoundingClientRect(); 16904 16905 if (popoverRect.right > editorRect.right) { 16906 this.popoverElement.toggleAttribute("data-clipped-at-right", true); 16907 } 16908 16909 const forceTop = this.verticalDirection === "top"; 16910 const forceBottom = this.verticalDirection === "bottom"; 16911 const overflowsWindow = popoverRect.bottom > window.innerHeight; 16912 16913 if (!forceBottom && (forceTop || overflowsWindow)) { 16914 this.#setPopoverOffsetY(contentRect.height - y + fontSize); 16915 this.popoverElement.toggleAttribute("data-clipped-at-bottom", true); 16916 } 16917 } 16918 16919 #setPopoverOffsetX(value) { 16920 this.popoverElement.style.setProperty("--lexxy-prompt-offset-x", `${value}px`); 16921 } 16922 16923 #setPopoverOffsetY(value) { 16924 this.popoverElement.style.setProperty("--lexxy-prompt-offset-y", `${value}px`); 16925 } 16926 16927 #resetPopoverPosition() { 16928 this.popoverElement.removeAttribute("data-clipped-at-bottom"); 16929 this.popoverElement.removeAttribute("data-clipped-at-right"); 16930 this.popoverElement.removeAttribute("data-anchored"); 16931 } 16932 16933 async #hidePopover() { 16934 this.showPopoverId++; 16935 this.#clearSelection(); 16936 this.popoverElement.classList.toggle("lexxy-prompt-menu--visible", false); 16937 this.#popoverListeners.dispose(); 16938 16939 await nextFrame(); 16940 this.#addTriggerListener(); 16941 } 16942 16943 // The popover is appended to the <lexxy-editor> subtree, so Turbo serializes it 16944 // into the page cache. Removing it before caching prevents an orphaned, unmanaged 16945 // popover from being restored on history back/forward. 16946 #removePopoverBeforeTurboCaches() { 16947 this.#globalListeners.track( 16948 registerEventListener(document, "turbo:before-cache", () => this.#removePopover()) 16949 ); 16950 } 16951 16952 #removePopover() { 16953 this.#popoverListeners.dispose(); 16954 this.popoverElement?.remove(); 16955 this.popoverElement = null; 16956 } 16957 16958 #filterOptions = async () => { 16959 if (this.initialPrompt) { 16960 this.initialPrompt = false; 16961 return 16962 } 16963 16964 if (this.#editorContents.containsTextBackUntil(this.trigger)) { 16965 await this.#showFilteredOptions(); 16966 16967 // Re-check after async operation â the trigger may have been consumed 16968 // (e.g. markdown heading shortcut converted "# " to h1 during the fetch) 16969 if (!this.#editorContents.containsTextBackUntil(this.trigger)) { 16970 this.#hidePopover(); 16971 return 16972 } 16973 16974 await nextFrame(); 16975 this.#positionPopover(); 16976 } else { 16977 this.#hidePopover(); 16978 } 16979 } 16980 16981 async #showFilteredOptions() { 16982 const showId = this.showPopoverId; 16983 const filter = this.#editorContents.textBackUntil(this.trigger); 16984 const filteredListItems = await this.source.buildListItems(filter); 16985 if (this.showPopoverId !== showId) return 16986 if (!this.#editorContents.containsTextBackUntil(this.trigger)) return 16987 16988 this.popoverElement.innerHTML = ""; 16989 16990 if (filteredListItems.length > 0) { 16991 this.#showResults(filteredListItems); 16992 } else { 16993 this.#showEmptyResults(); 16994 } 16995 this.#selectFirstOption(); 16996 } 16997 16998 #showResults(filteredListItems) { 16999 this.popoverElement.classList.remove("lexxy-prompt-menu--empty"); 17000 this.popoverElement.append(...filteredListItems); 17001 } 17002 17003 #showEmptyResults() { 17004 this.popoverElement.classList.add("lexxy-prompt-menu--empty"); 17005 const el = createElement("li", { textContent: this.#emptyResultsMessage }); 17006 el.classList.add("lexxy-prompt-menu__item--empty"); 17007 this.popoverElement.append(el); 17008 } 17009 17010 get #emptyResultsMessage() { 17011 return this.getAttribute("empty-results") || NOTHING_FOUND_DEFAULT_MESSAGE 17012 } 17013 17014 #handleKeydownOnPopover = (event) => { 17015 if (event.key === "Escape") { 17016 this.#hidePopover(); 17017 this.#editorElement.focus(); 17018 event.stopPropagation(); 17019 } else if (event.key === ",") { 17020 event.preventDefault(); 17021 event.stopPropagation(); 17022 this.#optionWasSelected(); 17023 this.#editor.update(() => { 17024 const selection = Qr(); 17025 if (Fr(selection)) { 17026 selection.insertText(","); 17027 } 17028 }); 17029 } 17030 // Arrow keys are handled via Lexical commands 17031 } 17032 17033 // Android Mobile keyboard doesn't trigger KEY_SPACE_COMMAND 17034 #handleInputCommand(event) { 17035 if (event.inputType === "insertText" && event.data === " ") return this.#handleSelectedOption(event) 17036 } 17037 17038 #moveSelectionDown() { 17039 const nextIndex = this.#selectedIndex + 1; 17040 if (nextIndex < this.#listItemElements.length) this.#selectOption(this.#listItemElements[nextIndex], { scrollIntoView: true }); 17041 } 17042 17043 #moveSelectionUp() { 17044 const previousIndex = this.#selectedIndex - 1; 17045 if (previousIndex >= 0) this.#selectOption(this.#listItemElements[previousIndex], { scrollIntoView: true }); 17046 } 17047 17048 get #selectedIndex() { 17049 return this.#listItemElements.findIndex((item) => item.hasAttribute("aria-selected")) 17050 } 17051 17052 get #selectedListItem() { 17053 return this.#listItemElements[this.#selectedIndex] 17054 } 17055 17056 #handleSelectedOption(event) { 17057 event.preventDefault(); 17058 event.stopPropagation(); 17059 this.#optionWasSelected(); 17060 return true 17061 } 17062 17063 #optionWasSelected() { 17064 this.#replaceTriggerWithSelectedItem(); 17065 this.#hidePopover(); 17066 this.#editorElement.focus(); 17067 } 17068 17069 #replaceTriggerWithSelectedItem() { 17070 const promptItem = this.source.promptItemFor(this.#selectedListItem); 17071 17072 if (!promptItem) { return } 17073 17074 const templates = Array.from(promptItem.querySelectorAll("template[type='editor']")); 17075 const stringToReplace = `${this.trigger}${this.#editorContents.textBackUntil(this.trigger)}`; 17076 17077 if (this.hasAttribute("insert-editable-text")) { 17078 this.#insertTemplatesAsEditableText(templates, stringToReplace); 17079 } else { 17080 this.#insertTemplatesAsAttachments(templates, stringToReplace, promptItem.getAttribute("sgid")); 17081 } 17082 } 17083 17084 #insertTemplatesAsEditableText(templates, stringToReplace) { 17085 this.#editor.update(() => { 17086 const nodes = templates.flatMap(template => this.#buildEditableTextNodes(template)); 17087 this.#editorContents.replaceTextBackUntil(stringToReplace, nodes); 17088 }); 17089 } 17090 17091 #buildEditableTextNodes(template) { 17092 return this.#editorElement.$generateNodesFromDOM(parseHtml(`${template.innerHTML}`)) 17093 } 17094 17095 #insertTemplatesAsAttachments(templates, stringToReplace, fallbackSgid = null) { 17096 this.#editor.update(() => { 17097 const attachmentNodes = this.#buildAttachmentNodes(templates, fallbackSgid); 17098 const spacedAttachmentNodes = attachmentNodes.flatMap(node => [ node, this.#getSpacerTextNode() ]).slice(0, -1); 17099 this.#editorContents.replaceTextBackUntil(stringToReplace, spacedAttachmentNodes); 17100 }); 17101 } 17102 17103 #buildAttachmentNodes(templates, fallbackSgid = null) { 17104 return templates 17105 .filter(template => this.#editorElement.permitsAttachmentContentType( 17106 template.getAttribute("content-type") || this.#defaultPromptContentType)) 17107 .map(template => this.#buildAttachmentNode( 17108 template.innerHTML, 17109 template.getAttribute("content-type") || this.#defaultPromptContentType, 17110 template.getAttribute("sgid") || fallbackSgid 17111 )) 17112 } 17113 17114 #getSpacerTextNode() { 17115 return kr(" ") 17116 } 17117 17118 get #defaultPromptContentType() { 17119 const attachmentContentTypeNamespace = Lexxy.global.get("attachmentContentTypeNamespace"); 17120 return `application/vnd.${attachmentContentTypeNamespace}.${this.name}` 17121 } 17122 17123 #buildAttachmentNode(innerHtml, contentType, sgid) { 17124 return new CustomActionTextAttachmentNode({ sgid, contentType, innerHtml }) 17125 } 17126 17127 get #editorContents() { 17128 return this.#editorElement.contents 17129 } 17130 17131 get #editorContentElement() { 17132 return this.#editorElement.editorContentElement 17133 } 17134 17135 async #buildPopover() { 17136 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. 17137 popoverContainer.classList.add("lexxy-prompt-menu"); 17138 popoverContainer.style.position = "absolute"; 17139 popoverContainer.setAttribute("nonce", getNonce()); 17140 popoverContainer.append(...await this.source.buildListItems()); 17141 this.#globalListeners.track(registerEventListener(popoverContainer, "click", this.#handlePopoverClick)); 17142 this.#editorElement.appendChild(popoverContainer); 17143 return popoverContainer 17144 } 17145 17146 #handlePopoverClick = (event) => { 17147 const listItem = event.target.closest(".lexxy-prompt-menu__item"); 17148 if (listItem) { 17149 this.#selectOption(listItem); 17150 this.#optionWasSelected(); 17151 } 17152 } 17153 17154 #reconnect() { 17155 this.disconnectedCallback(); 17156 this.connectedCallback(); 17157 } 17158} 17159 17160class CodeLanguagePicker extends HTMLElement { 17161 #abortController = null 17162 #listeners = new ListenerBin() 17163 17164 connectedCallback() { 17165 this.editorElement = this.closest("lexxy-editor"); 17166 this.editor = this.editorElement.editor; 17167 this.classList.add("lexxy-floating-controls"); 17168 this.#abortController = new AbortController(); 17169 this.#listeners.track(() => this.#abortController?.abort()); 17170 17171 this.#attachLanguagePicker(); 17172 this.#hide(); 17173 this.#monitorForCodeBlockSelection(); 17174 } 17175 17176 disconnectedCallback() { 17177 this.dispose(); 17178 } 17179 17180 dispose() { 17181 this.#listeners.dispose(); 17182 } 17183 17184 #attachLanguagePicker() { 17185 this.languagePickerElement = this.#findLanguagePicker() ?? this.#createLanguagePicker(); 17186 17187 const signal = this.#abortController.signal; 17188 17189 this.#listeners.track(registerEventListener(this.languagePickerElement, "change", () => { 17190 this.#updateCodeBlockLanguage(this.languagePickerElement.value); 17191 }, { signal })); 17192 17193 this.#listeners.track(registerEventListener(this.languagePickerElement, "mousedown", (event) => { 17194 this.#dispatchOpenEvent(event); 17195 }, { signal })); 17196 17197 this.languagePickerElement.setAttribute("nonce", getNonce()); 17198 this.appendChild(this.languagePickerElement); 17199 } 17200 17201 #findLanguagePicker() { 17202 return this.querySelector("select") 17203 } 17204 17205 #createLanguagePicker() { 17206 const selectElement = createElement("select", { className: "lexxy-code-language-picker", "aria-label": "Pick a languageâ¦", name: "lexxy-code-language" }); 17207 17208 for (const [ value, label ] of Object.entries(this.#languages)) { 17209 const option = document.createElement("option"); 17210 option.value = value; 17211 option.textContent = label; 17212 selectElement.appendChild(option); 17213 } 17214 17215 return selectElement 17216 } 17217 17218 get #languages() { 17219 const languages = { ...o }; 17220 17221 languages.ruby ||= "Ruby"; 17222 languages.php ||= "PHP"; 17223 languages.go ||= "Go"; 17224 languages.bash ||= "Bash"; 17225 languages.json ||= "JSON"; 17226 languages.diff ||= "Diff"; 17227 languages.kotlin ||= "Kotlin"; 17228 17229 17230 // Place the "plain" entry first, then the rest of language sorted alphabetically 17231 delete languages.plain; 17232 const sortedEntries = Object.entries(languages) 17233 .sort((a, b) => a[1].localeCompare(b[1])); 17234 return { plain: "Plain text", ...Object.fromEntries(sortedEntries) } 17235 } 17236 17237 #dispatchOpenEvent(event) { 17238 const handled = !dispatch(this.editorElement, "lexxy:code-language-picker-open", { 17239 languages: this.#bridgeLanguages, 17240 currentLanguage: this.languagePickerElement.value 17241 }, true); 17242 17243 if (handled) { 17244 event.preventDefault(); 17245 } 17246 } 17247 17248 get #bridgeLanguages() { 17249 return Object.entries(this.#languages).map(([ key, name ]) => ({ key, name })) 17250 } 17251 17252 #updateCodeBlockLanguage(language) { 17253 this.editor.update(() => { 17254 const codeNode = this.#getCurrentCodeNode(); 17255 17256 if (codeNode) { 17257 codeNode.setLanguage(language); 17258 } 17259 }); 17260 } 17261 17262 #monitorForCodeBlockSelection() { 17263 this.#listeners.track(this.editor.registerUpdateListener(({ editorState }) => { 17264 editorState.read(() => { 17265 const codeNode = this.#getCurrentCodeNode(); 17266 17267 if (codeNode) { 17268 this.#codeNodeWasSelected(codeNode); 17269 } else { 17270 this.#hide(); 17271 } 17272 }); 17273 })); 17274 } 17275 17276 #getCurrentCodeNode() { 17277 return this.editorElement.selection.nearestNodeOfType(z$1) 17278 } 17279 17280 #codeNodeWasSelected(codeNode) { 17281 const language = codeNode.getLanguage(); 17282 17283 this.#updateLanguagePickerWith(language); 17284 this.#show(); 17285 this.#positionLanguagePicker(codeNode); 17286 } 17287 17288 #updateLanguagePickerWith(language) { 17289 if (this.languagePickerElement && language) { 17290 const normalizedLanguage = a(language); 17291 this.languagePickerElement.value = normalizedLanguage; 17292 } 17293 } 17294 17295 #positionLanguagePicker(codeNode) { 17296 const codeElement = this.editor.getElementByKey(codeNode.getKey()); 17297 if (!codeElement) return 17298 17299 const codeRect = codeElement.getBoundingClientRect(); 17300 const editorRect = this.editorElement.getBoundingClientRect(); 17301 const relativeTop = codeRect.top - editorRect.top; 17302 const relativeRight = editorRect.right - codeRect.right; 17303 17304 this.style.top = `${relativeTop}px`; 17305 this.style.right = `${relativeRight}px`; 17306 } 17307 17308 #show() { 17309 this.hidden = false;
17310 } 17311 17312 #hide() { 17313 this.hidden = true; 17314 } 17315} 17316 17317const DELETE_ICON = `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> 17318 <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"/> 17319</svg>`; 17320 17321class NodeDeleteButton extends HTMLElement { 17322 connectedCallback() { 17323 this.editorElement = this.closest("lexxy-editor"); 17324 this.editor = this.editorElement.editor; 17325 this.classList.add("lexxy-floating-controls"); 17326 17327 if (!this.querySelector(".lexxy-node-delete")) { 17328 this.#attachDeleteButton(); 17329 } 17330 } 17331 17332 disconnectedCallback() { 17333 this.editor = null; 17334 this.editorElement = null; 17335 } 17336 17337 #attachDeleteButton() { 17338 const container = createElement("div", { className: "lexxy-floating-controls__group" }); 17339 17340 this.deleteButton = createElement("button", { 17341 className: "lexxy-node-delete", 17342 type: "button", 17343 "aria-label": "Remove" 17344 }); 17345 this.deleteButton.tabIndex = -1; 17346 this.deleteButton.innerHTML = DELETE_ICON; 17347 17348 this.handleDeleteClick = () => this.#deleteNode(); 17349 this.deleteButton.addEventListener("click", this.handleDeleteClick); 17350 container.appendChild(this.deleteButton); 17351 17352 this.appendChild(container); 17353 } 17354 17355 #deleteNode() { 17356 this.editor.update(() => { 17357 const node = Go(this); 17358 node?.remove(); 17359 }); 17360 } 17361} 17362 17363class TableController { 17364 #listeners = new ListenerBin() 17365 17366 constructor(editorElement) { 17367 this.editor = editorElement.editor; 17368 this.contents = editorElement.contents; 17369 this.selection = editorElement.selection; 17370 17371 this.currentTableNodeKey = null; 17372 this.currentCellKey = null; 17373 17374 this.#registerKeyHandlers(); 17375 } 17376 17377 destroy() { 17378 this.currentTableNodeKey = null; 17379 this.currentCellKey = null; 17380 17381 this.#listeners.dispose(); 17382 } 17383 17384 get currentCell() { 17385 if (!this.currentCellKey) return null 17386 17387 return this.editor.getEditorState().read(() => { 17388 const cell = Yo(this.currentCellKey); 17389 return (cell instanceof Ee$1) ? cell : null 17390 }) 17391 } 17392 17393 get currentTableNode() { 17394 if (!this.currentTableNodeKey) return null 17395 17396 return this.editor.getEditorState().read(() => { 17397 const tableNode = Yo(this.currentTableNodeKey); 17398 return (tableNode instanceof vn) ? tableNode : null 17399 }) 17400 } 17401 17402 get currentRowCells() { 17403 const currentRowIndex = this.currentRowIndex; 17404 17405 const rows = this.tableRows; 17406 if (!rows) return null 17407 17408 return this.editor.getEditorState().read(() => { 17409 return rows[currentRowIndex]?.getChildren() ?? null 17410 }) ?? null 17411 } 17412 17413 get currentRowIndex() { 17414 const currentCell = this.currentCell; 17415 if (!currentCell) return 0 17416 17417 return this.editor.getEditorState().read(() => { 17418 return Ve$1(currentCell) 17419 }) ?? 0 17420 } 17421 17422 get currentColumnCells() { 17423 const columnIndex = this.currentColumnIndex; 17424 17425 const rows = this.tableRows; 17426 if (!rows) return null 17427 17428 return this.editor.getEditorState().read(() => { 17429 return rows.map(row => row.getChildAtIndex(columnIndex)) 17430 }) ?? null 17431 } 17432 17433 get currentColumnIndex() { 17434 const currentCell = this.currentCell; 17435 if (!currentCell) return 0 17436 17437 return this.editor.getEditorState().read(() => { 17438 return Ge$1(currentCell) 17439 }) ?? 0 17440 } 17441 17442 get tableRows() { 17443 return this.editor.getEditorState().read(() => { 17444 return this.currentTableNode?.getChildren() 17445 }) ?? null 17446 } 17447 17448 updateSelectedTable() {
vendor: 9,676 bytes, lines 17449-17740
17449 let cellNode = null; 17450 let tableNode = null; 17451 17452 this.editor.getEditorState().read(() => { 17453 const selection = Qr(); 17454 if (!selection || !this.selection.isTableCellSelected) return 17455 17456 const node = selection.getNodes()[0]; 17457 17458 cellNode = un(node); 17459 tableNode = hn(node); 17460 }); 17461 17462 this.currentCellKey = cellNode?.getKey() ?? null; 17463 this.currentTableNodeKey = tableNode?.getKey() ?? null; 17464 17465 return tableNode 17466 } 17467 17468 executeTableCommand(command, customIndex = null) { 17469 if (command.action === "delete" && command.childType === "table") { 17470 this.#deleteTable(); 17471 return 17472 } 17473 17474 if (command.action === "toggle") { 17475 this.#executeToggleStyle(command); 17476 return 17477 } 17478 17479 this.#executeCommand(command, customIndex); 17480 } 17481 17482 #executeCommand(command, customIndex = null) { 17483 this.#selectCellAtSelection(); 17484 this.editor.dispatchCommand(this.#commandName(command)); 17485 this.#selectNextBestCell(command, customIndex); 17486 } 17487 17488 #executeToggleStyle(command) { 17489 const childType = command.childType; 17490 17491 let cells = null; 17492 let headerState = null; 17493 17494 if (childType === "row") { 17495 cells = this.currentRowCells; 17496 headerState = Ae$1.ROW; 17497 } else if (childType === "column") { 17498 cells = this.currentColumnCells; 17499 headerState = Ae$1.COLUMN; 17500 } 17501 17502 if (!cells || cells.length === 0) return 17503 17504 this.editor.update(() => { 17505 const firstCell = Ye(cells[0]); 17506 if (!firstCell) return 17507 17508 const currentStyle = firstCell.getHeaderStyles(); 17509 const newStyle = currentStyle ^ headerState; 17510 17511 cells.forEach(cell => { 17512 this.#setHeaderStyle(cell, newStyle, headerState); 17513 }); 17514 }); 17515 } 17516 17517 #deleteTable() { 17518 this.#selectCellAtSelection(); 17519 this.editor.dispatchCommand("deleteTable"); 17520 } 17521 17522 #selectCellAtSelection() { 17523 this.editor.update(() => { 17524 const selection = Qr(); 17525 if (!selection) return 17526 17527 const node = selection.getNodes()[0]; 17528 17529 un(node)?.selectEnd(); 17530 }); 17531 } 17532 17533 #commandName(command) { 17534 const { action, childType, direction } = command; 17535 17536 const childTypeSuffix = upcaseFirst(childType); 17537 const directionSuffix = action == "insert" ? upcaseFirst(direction) : ""; 17538 return `${action}Table${childTypeSuffix}${directionSuffix}` 17539 } 17540 17541 #setHeaderStyle(cell, newStyle, headerState) { 17542 const tableCellNode = Ye(cell); 17543 tableCellNode?.setHeaderStyles(newStyle, headerState); 17544 } 17545 17546 async #selectCellAtIndex(rowIndex, columnIndex) { 17547 // We wait for next frame, otherwise table operations might not have completed yet. 17548 await nextFrame(); 17549 17550 if (!this.currentTableNode) return 17551 17552 const rows = this.tableRows; 17553 if (!rows) return 17554 17555 const row = rows[rowIndex]; 17556 if (!row) return 17557 17558 this.editor.update(() => { 17559 const cell = Ye(row.getChildAtIndex(columnIndex)); 17560 cell?.selectEnd(); 17561 }); 17562 } 17563 17564 #selectNextBestCell(command, customIndex = null) { 17565 const { childType, direction } = command; 17566 17567 let rowIndex = this.currentRowIndex; 17568 let columnIndex = customIndex !== null ? customIndex : this.currentColumnIndex; 17569 17570 const deleteOffset = command.action === "delete" ? -1 : 0; 17571 const offset = direction === "after" ? 1 : deleteOffset; 17572 17573 if (childType === "row") { 17574 rowIndex += offset; 17575 } else if (childType === "column") { 17576 columnIndex += offset; 17577 } 17578 17579 this.#selectCellAtIndex(rowIndex, columnIndex); 17580 } 17581 17582 #selectNextRow() { 17583 const rows = this.tableRows; 17584 if (!rows) return 17585 17586 const nextRow = rows.at(this.currentRowIndex + 1); 17587 if (!nextRow) return 17588 17589 this.editor.update(() => { 17590 nextRow.getChildAtIndex(this.currentColumnIndex)?.selectEnd(); 17591 }); 17592 } 17593 17594 #selectPreviousCell() { 17595 const cell = this.currentCell; 17596 if (!cell) return 17597 17598 this.editor.update(() => { 17599 cell.selectPrevious(); 17600 }); 17601 } 17602 17603 #insertRowAndSelectFirstCell() { 17604 this.executeTableCommand({ action: "insert", childType: "row", direction: "after" }, 0); 17605 } 17606 17607 #deleteRowAndSelectLastCell() { 17608 this.executeTableCommand({ action: "delete", childType: "row" }, -1); 17609 } 17610 17611 #deleteRowAndSelectNextNode() { 17612 const tableNode = this.currentTableNode; 17613 this.executeTableCommand({ action: "delete", childType: "row" }); 17614 17615 this.editor.update(() => { 17616 const next = tableNode?.getNextSibling(); 17617 if (no(next)) { 17618 next.selectStart(); 17619 } else { 17620 const newParagraph = eo(); 17621 this.currentTableNode.insertAfter(newParagraph); 17622 newParagraph.selectStart(); 17623 } 17624 }); 17625 } 17626 17627 #isCurrentCellEmpty() { 17628 if (!this.currentTableNode) return false 17629 17630 const cell = this.currentCell; 17631 if (!cell) return false 17632 17633 return cell.getTextContent().trim() === "" 17634 } 17635 17636 #isCurrentRowLast() { 17637 if (!this.currentTableNode) return false 17638 17639 const rows = this.tableRows; 17640 if (!rows) return false 17641 17642 return rows.length === this.currentRowIndex + 1 17643 } 17644 17645 #isCurrentRowEmpty() { 17646 if (!this.currentTableNode) return false 17647 17648 const cells = this.currentRowCells; 17649 if (!cells) return false 17650 17651 return cells.every(cell => cell.getTextContent().trim() === "") 17652 } 17653 17654 #isFirstCellInRow() { 17655 if (!this.currentTableNode) return false 17656 17657 const cells = this.currentRowCells; 17658 if (!cells) return false 17659 17660 return cells.indexOf(this.currentCell) === 0 17661 } 17662 17663 #registerKeyHandlers() { 17664 // We can't prevent these externally using regular keydown because Lexical handles it first. 17665 this.#listeners.track( 17666 this.editor.registerCommand(Ae$3, (event) => this.#handleBackspaceKey(event), so), 17667 this.editor.registerCommand(Oe$2, (event) => this.#handleEnterKey(event), so) 17668 ); 17669 } 17670 17671 #handleBackspaceKey(event) { 17672 if (!this.currentTableNode) return false 17673 17674 if (this.#isCurrentRowEmpty() && this.#isFirstCellInRow()) { 17675 event.preventDefault(); 17676 this.#deleteRowAndSelectLastCell(); 17677 return true 17678 } 17679 17680 if (this.#isCurrentCellEmpty() && !this.#isFirstCellInRow()) { 17681 event.preventDefault(); 17682 this.#selectPreviousCell(); 17683 return true 17684 } 17685 17686 return false 17687 } 17688 17689 #handleEnterKey(event) { 17690 if ((event.ctrlKey || event.metaKey) || event.shiftKey || !this.currentTableNode) return false 17691 17692 if (this.selection.isInsideList || this.selection.isInsideCodeBlock) return false 17693 17694 event.preventDefault(); 17695 17696 if (this.#isCurrentRowLast() && this.#isCurrentRowEmpty()) { 17697 this.#deleteRowAndSelectNextNode(); 17698 } else if (this.#isCurrentRowLast()) { 17699 this.#insertRowAndSelectFirstCell(); 17700 } else { 17701 this.#selectNextRow(); 17702 } 17703 17704 return true 17705 } 17706} 17707 17708var TableIcons = { 17709 "insert-row-before": 17710 `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> 17711 <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"/> 17712 <path d="M4.5 4.5H7.5V7.5H9V4.5H12L12 3L9 3V6.55671e-08L7.5 0V3L4.5 3V4.5Z"/> 17713 </svg>`, 17714 17715 "insert-row-after": 17716 `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> 17717 <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"/> 17718 <path d="M7.5 15V18H9V15H12V13.5H9V10.5H7.5V13.5H4.5V15H7.5Z"/> 17719 </svg>`, 17720 17721 "delete-row": 17722 `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> 17723 <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"/> 17724 <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"/> 17725 </svg>`, 17726 17727 "toggle-row": 17728 `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> 17729 <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"/> 17730 </svg>`, 17731 17732 "insert-column-before": 17733 `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> 17734 <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"/> 17735 <path d="M3 7.5H0V9H3V12H4.5V9H7.5V7.5H4.5V4.5H3V7.5Z"/> 17736 </svg>`, 17737 17738 "insert-column-after": 17739 `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> 17740 <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
1774015H7.5V1.5H3V15Z"/> 17741 <path d="M15 7.5H18V9H15V12H13.5V9H10.5V7.5H13.5V4.5H15V7.5Z"/> 17742 </svg>`, 17743 17744 "delete-column": 17745 `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> 17746 <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"/> 17747 <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"/> 17748 </svg>`, 17749 17750 "toggle-column": 17751 `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> 17752 <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"/> 17753 </svg>`, 17754 17755 "delete-table": 17756 `<svg viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg"> 17757 <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"/> 17758 </svg>` 17759}; 17760 17761class TableTools extends HTMLElement { 17762 #listeners = new ListenerBin() 17763 17764 connectedCallback() { 17765 this.tableController = new TableController(this.#editorElement); 17766 this.classList.add("lexxy-floating-controls"); 17767 this.role = "toolbar"; 17768 17769 this.#setUpButtons(); 17770 this.#hide(); 17771 this.#monitorForTableSelection(); 17772 this.#registerKeyboardShortcuts(); 17773 } 17774 17775 disconnectedCallback() { 17776 this.dispose(); 17777 } 17778 17779 dispose() { 17780 this.#listeners.dispose(); 17781 17782 this.tableController?.destroy(); 17783 this.tableController = null; 17784 } 17785 17786 get #editor() { 17787 return this.#editorElement.editor 17788 } 17789 17790 get #editorElement() { 17791 return this.closest("lexxy-editor") 17792 } 17793 17794 get #tableToolsButtons() { 17795 return Array.from(this.querySelectorAll("button, details > summary")) 17796 } 17797 17798 #setUpButtons() { 17799 this.innerHTML = ""; 17800 17801 this.appendChild(this.#createRowButtonsContainer()); 17802 this.appendChild(this.#createColumnButtonsContainer()); 17803 17804 this.appendChild(this.#createDeleteTableButton()); 17805 this.#listeners.track(registerEventListener(this, "keydown", this.#handleToolsKeydown)); 17806 } 17807 17808 #createButtonsContainer(childType, setCountProperty, moreMenu) { 17809 const container = createElement("div", { className: `lexxy-floating-controls__group lexxy-table-control lexxy-table-control--${childType}` }); 17810 17811 const plusButton = this.#createButton(`Add ${childType}`, { action: "insert", childType, direction: "after" }, "+"); 17812 const minusButton = this.#createButton(`Remove ${childType}`, { action: "delete", childType }, "â"); 17813 17814 const dropdown = createElement("details", { className: "lexxy-table-control__more-menu" }); 17815 dropdown.setAttribute("name", "lexxy-dropdown"); 17816 dropdown.tabIndex = -1; 17817 17818 const count = createElement("summary", {}, `_ ${childType}s`); 17819 setCountProperty(count); 17820 dropdown.appendChild(count); 17821 17822 dropdown.appendChild(moreMenu); 17823 17824 container.appendChild(minusButton); 17825 container.appendChild(dropdown); 17826 container.appendChild(plusButton); 17827 17828 return container 17829 } 17830 17831 #createRowButtonsContainer() { 17832 return this.#createButtonsContainer( 17833 "row", 17834 (count) => { this.rowCount = count; }, 17835 this.#createMoreMenuSection("row") 17836 ) 17837 } 17838 17839 #createColumnButtonsContainer() { 17840 return this.#createButtonsContainer( 17841 "column", 17842 (count) => { this.columnCount = count; }, 17843 this.#createMoreMenuSection("column") 17844 ) 17845 } 17846 17847 #createMoreMenuSection(childType) { 17848 const section = createElement("div", { className: "lexxy-floating-control
vendor: 4,464 bytes, lines 17848-17989
17848s__group lexxy-table-control__more-menu-details" }); 17849 const addBeforeButton = this.#createButton(`Add ${childType} before`, { action: "insert", childType, direction: "before" }); 17850 const addAfterButton = this.#createButton(`Add ${childType} after`, { action: "insert", childType, direction: "after" }); 17851 const toggleStyleButton = this.#createButton(`Toggle ${childType} style`, { action: "toggle", childType }); 17852 const deleteButton = this.#createButton(`Remove ${childType}`, { action: "delete", childType }); 17853 17854 section.appendChild(addBeforeButton); 17855 section.appendChild(addAfterButton); 17856 section.appendChild(toggleStyleButton); 17857 section.appendChild(deleteButton); 17858 17859 return section 17860 } 17861 17862 #createDeleteTableButton() { 17863 const container = createElement("div", { className: "lexxy-table-control lexxy-floating-controls__group" }); 17864 17865 const deleteTableButton = this.#createButton("Delete this table?", { action: "delete", childType: "table" }); 17866 deleteTableButton.classList.add("lexxy-table-control__button--delete-table"); 17867 17868 container.appendChild(deleteTableButton); 17869 17870 this.deleteContainer = container; 17871 17872 return container 17873 } 17874 17875 #createButton(label, command = {}, icon = this.#icon(command)) { 17876 const button = createElement("button", { 17877 className: "lexxy-table-control__button", 17878 "aria-label": label, 17879 type: "button" 17880 }); 17881 button.tabIndex = -1; 17882 button.innerHTML = `${icon} <span>${label}</span>`; 17883 17884 button.dataset.action = command.action; 17885 button.dataset.childType = command.childType; 17886 button.dataset.direction = command.direction; 17887 17888 button.addEventListener("click", () => this.#executeTableCommand(command)); 17889 17890 button.addEventListener("mouseover", () => this.#handleCommandButtonHover()); 17891 button.addEventListener("focus", () => this.#handleCommandButtonHover()); 17892 button.addEventListener("mouseout", () => this.#handleCommandButtonHover()); 17893 17894 return button 17895 } 17896 17897 #registerKeyboardShortcuts() { 17898 this.#listeners.track(this.#editor.registerCommand(ve$2, this.#focusToolbarOnAltF10, so)); 17899 } 17900 17901 #focusToolbarOnAltF10 = (event) => { 17902 if (this.#hasSelectedTable && event.altKey && event.key === "F10") { 17903 event.preventDefault(); 17904 // Ask for the ring explicitly: a programmatic focus coming from a mouse-focused 17905 // editor otherwise inherits the mouse modality and paints no focus ring. 17906 this.#tableToolsButtons[0]?.focus({ focusVisible: true }); 17907 return true 17908 } else { 17909 return false 17910 } 17911 } 17912 17913 get #hasSelectedTable() { 17914 return this.tableController?.currentTableNodeKey != null 17915 } 17916 17917 #handleToolsKeydown = (event) => { 17918 if (event.key === "Escape") { 17919 this.#handleEscapeKey(); 17920 } else { 17921 handleRollingTabIndex(this.#tableToolsButtons, event); 17922 } 17923 } 17924 17925 #handleEscapeKey() { 17926 const cell = this.tableController.currentCell; 17927 if (!cell) return 17928 17929 this.#editor.update(() => { 17930 cell.select(); 17931 this.#editor.focus(); 17932 }); 17933 17934 this.#update(); 17935 } 17936 17937 async #handleCommandButtonHover() { 17938 await nextFrame(); 17939 17940 this.#clearCellStyles(); 17941 17942 const activeElement = this.querySelector("button:hover, button:focus"); 17943 if (!activeElement) return 17944 17945 const command = { 17946 action: activeElement.dataset.action, 17947 childType: activeElement.dataset.childType, 17948 direction: activeElement.dataset.direction 17949 }; 17950 17951 let cellsToHighlight = null; 17952 17953 switch (command.childType) { 17954 case "row": 17955 cellsToHighlight = this.tableController.currentRowCells; 17956 break 17957 case "column": 17958 cellsToHighlight = this.tableController.currentColumnCells; 17959 break 17960 case "table": 17961 cellsToHighlight = this.tableController.tableRows; 17962 break 17963 } 17964 17965 if (!cellsToHighlight) return 17966 17967 cellsToHighlight.forEach(cell => { 17968 const cellElement = this.#editor.getElementByKey(cell.getKey()); 17969 if (!cellElement) return 17970 17971 cellElement.classList.toggle(theme.tableCellHighlight, true); 17972 Object.assign(cellElement.dataset, command); 17973 }); 17974 } 17975 17976 #monitorForTableSelection() { 17977 this.#listeners.track(this.#editor.registerUpdateListener(() => { 17978 const tableNode = this.#editor.getRootElement() && this.tableController.updateSelectedTable(); 17979 17980 if (tableNode) { 17981 this.#show(); 17982 } else { 17983 this.#hide(); 17984 } 17985 })); 17986 } 17987 17988 #executeTableCommand(command) { 17989 this.tableController.executeTableCommand(command);
17990 this.#update(); 17991 } 17992 17993 #show() { 17994 this.#updateButtonsPosition(); 17995 this.style.display = "flex"; 17996 this.#updateRowColumnCount(); 17997 this.#closeMoreMenu(); 17998 this.#handleCommandButtonHover(); 17999 } 18000 18001 #hide() { 18002 this.style.display = "none"; 18003 this.#clearCellStyles(); 18004 } 18005 18006 #update() { 18007 this.#updateButtonsPosition(); 18008 this.#updateRowColumnCount(); 18009 this.#closeMoreMenu(); 18010 this.#handleCommandButtonHover(); 18011 } 18012 18013 #closeMoreMenu() { 18014 this.querySelector("details[open]")?.removeAttribute("open"); 18015 } 18016 18017 #updateButtonsPosition() { 18018 const tableNode = this.tableController.currentTableNode; 18019 if (!tableNode) return 18020 18021 const tableElement = this.#editor.getElementByKey(tableNode.getKey()); 18022 if (!tableElement) return 18023 18024 const tableRect = tableElement.getBoundingClientRect(); 18025 const editorRect = this.#editorElement.getBoundingClientRect(); 18026 18027 const relativeTop = tableRect.top - editorRect.top; 18028 const relativeCenter = (tableRect.left + tableRect.right) / 2 - editorRect.left; 18029 this.style.top = `${relativeTop}px`; 18030 this.style.left = `${relativeCenter}px`; 18031 } 18032 18033 #updateRowColumnCount() { 18034 const tableNode = this.tableController.currentTableNode; 18035 if (!tableNode) return 18036 18037 const tableElement = xn(this.#editor, tableNode); 18038 if (!tableElement) return 18039 18040 const rowCount = tableElement.rows; 18041 const columnCount = tableElement.columns; 18042 18043 this.rowCount.textContent = `${rowCount} row${rowCount === 1 ? "" : "s"}`; 18044 this.columnCount.textContent = `${columnCount} column${columnCount === 1 ? "" : "s"}`; 18045 } 18046 18047 #setTableCellFocus() { 18048 const cell = this.tableController.currentCell; 18049 if (!cell) return 18050 18051 const cellElement = this.#editor.getElementByKey(cell.getKey()); 18052 if (!cellElement) return 18053 18054 cellElement.classList.add(theme.tableCellFocus); 18055 } 18056 18057 #clearCellStyles() { 18058 this.#editorElement.querySelectorAll(`.${theme.tableCellFocus}`)?.forEach(cell => { 18059 cell.classList.remove(theme.tableCellFocus); 18060 }); 18061 18062 this.#editorElement.querySelectorAll(`.${theme.tableCellHighlight}`)?.forEach(cell => { 18063 cell.classList.remove(theme.tableCellHighlight); 18064 cell.removeAttribute("data-action"); 18065 cell.removeAttribute("data-child-type"); 18066 cell.removeAttribute("data-direction"); 18067 }); 18068 18069 this.#setTableCellFocus(); 18070 } 18071 18072 #icon(command) { 18073 const { action, childType } = command; 18074 const direction = (action == "insert" ? command.direction : null); 18075 const iconId = [ action, childType, direction ].filter(Boolean).join("-"); 18076 return TableIcons[iconId] 18077 } 18078} 18079 18080function defineElements() { 18081 const elements = { 18082 // Toolbar must be registered BEFORE Editor 18083 "lexxy-toolbar": LexicalToolbarElement, 18084 "lexxy-toolbar-dropdown": ToolbarDropdown, 18085 "lexxy-heading-dropdown": HeadingDropdown, 18086 "lexxy-highlight-dropdown": HighlightDropdown, 18087 "lexxy-link-dropdown": LinkDropdown, 18088 18089 "lexxy-editor": LexicalEditorElement, 18090 18091 // Prompt must be registered AFTER Editor 18092 "lexxy-prompt": LexicalPromptElement, 18093 "lexxy-code-language-picker": CodeLanguagePicker, 18094 "lexxy-node-delete-button": NodeDeleteButton, 18095 "lexxy-table-tools": TableTools 18096 }; 18097 18098 Object.entries(elements).forEach(([ name, element ]) => { 18099 customElements.define(name, element); 18100 }); 18101} 18102 18103function highlightCode(root = document) { 18104 const elements = root.querySelectorAll("pre[data-language]:not([data-highlighted])"); 18105 18106 elements.forEach(preElement => { 18107 highlightElement(preElement); 18108 }); 18109} 18110 18111function highlightElement(preElement) { 18112 if (preElement.dataset.highlighted === "true") return 18113 18114 const language = preElement.getAttribute("data-language"); 18115 18116 const grammar = Prism$1.languages?.[language]; 18117 if (!grammar) return 18118 18119 // Read the source text and <mark> ranges in a single walk, before Prism 18120 // rewrites the element. Sharing one traversal keeps the highlight offsets 18121 // aligned with the code string and preserves leading whitespace â deriving 18122 // either of them separately (e.g. textContent through DOMParser) collapses 18123 // leading whitespace and shifts every range, re-indenting the rendered block. 18124 const { code, highlights } = extractCodeAndHighlights(preElement); 18125 18126 const highlightedHtml = Prism$1.highlight(code, grammar, language); 18127 preElement.innerHTML = highlightedHtml; 18128 18129 if (highlights.length > 0) { 18130 applyHighlightRanges(preElement, highlights); 18131 } 18132 18133 preElement.dataset.highlighted = "true"; 18134} 18135 18136// Walk the <pre> once, building Prism's source text and the <mark> ranges 18137// together: a text node contributes its text verbatim, a <br> contributes a 18138// newline, and a <mark>
18138 records the slice of code it covers. Because both 18139// outputs come from the same walk, every range offset is just a position in 18140// `code` â so the highlights can't drift out of sync with the source, and the 18141// block's leading whitespace survives (HTML parsing would collapse it). 18142function extractCodeAndHighlights(preElement) { 18143 const root = preElement.querySelector("code") || preElement; 18144 const highlights = []; 18145 let code = ""; 18146 18147 function walk(node) { 18148 if (node.nodeType === Node.TEXT_NODE) { 18149 code += node.textContent; 18150 } else if (node.nodeType === Node.ELEMENT_NODE) { 18151 if (node.tagName === "BR") { 18152 code += "\n"; 18153 } else if (node.tagName === "MARK") { 18154 const start = code.length; 18155 for (const child of node.childNodes) { 18156 walk(child); 18157 } 18158 const style = extractStyle(node); 18159 if (style) { 18160 highlights.push({ start, end: code.length, style }); 18161 } 18162 } else { 18163 for (const child of node.childNodes) { 18164 walk(child); 18165 } 18166 } 18167 } 18168 } 18169 18170 for (const child of root.childNodes) { 18171 walk(child); 18172 } 18173 18174 return { code, highlights } 18175} 18176 18177function extractStyle(element) { 18178 const parts = []; 18179 if (element.style?.color) parts.push(`color: ${element.style.color};`); 18180 if (element.style?.backgroundColor) parts.push(`background-color: ${element.style.backgroundColor};`); 18181 return parts.length > 0 ? parts.join(" ") : null 18182} 18183 18184// Wrap character ranges in <mark> elements within a Prism-highlighted DOM tree. 18185// Each range is applied independently, re-collecting text nodes each time to 18186// account for splits from previous ranges. 18187function applyHighlightRanges(element, highlights) { 18188 for (const { start, end, style } of highlights) { 18189 wrapRange(element, start, end, style); 18190 } 18191} 18192 18193function wrapRange(container, rangeStart, rangeEnd, style) { 18194 const textNodes = collectTextNodes(container); 18195 18196 // Process in reverse so DOM mutations don't shift earlier text node offsets 18197 for (let i = textNodes.length - 1; i >= 0; i--) { 18198 const { node, start: nodeStart, end: nodeEnd } = textNodes[i]; 18199 const overlapStart = Math.max(rangeStart, nodeStart); 18200 const overlapEnd = Math.min(rangeEnd, nodeEnd); 18201 if (overlapStart >= overlapEnd) continue 18202 18203 const relStart = overlapStart - nodeStart; 18204 const relEnd = overlapEnd - nodeStart; 18205 const text = node.textContent; 18206 const parent = node.parentNode; 18207 18208 const mark = document.createElement("mark"); 18209 mark.setAttribute("style", style); 18210 mark.textContent = text.slice(relStart, relEnd); 18211 18212 if (relEnd < text.length) { 18213 parent.insertBefore(document.createTextNode(text.slice(relEnd)), node.nextSibling); 18214 } 18215 parent.insertBefore(mark, node.nextSibling); 18216 18217 if (relStart > 0) { 18218 node.textContent = text.slice(0, relStart); 18219 } else { 18220 parent.removeChild(node); 18221 } 18222 } 18223} 18224 18225function collectTextNodes(root) { 18226 const nodes = []; 18227 let offset = 0; 18228 const walker = document.createTreeWalker(root, 4 /* NodeFilter.SHOW_TEXT */); 18229 18230 let node; 18231 while ((node = walker.nextNode())) { 18232 const length = node.textContent.length; 18233 nodes.push({ node, start: offset, end: offset + length }); 18234 offset += length; 18235 } 18236 18237 return nodes 18238} 18239 18240class NativeAdapter { 18241 frozenLinkKey = null 18242 18243 constructor(editorElement) { 18244 this.editorElement = editorElement; 18245 this.editorContentElement = editorElement.editorContentElement; 18246 } 18247 18248 dispatchAttributesChange(attributes, linkHref, highlight, headingTag) { 18249 dispatch(this.editorElement, "lexxy:attributes-change", { 18250 attributes, 18251 link: linkHref ? { href: linkHref } : null, 18252 highlight, 18253 headingTag 18254 }); 18255 } 18256 18257 dispatchEditorInitialized(detail) { 18258 dispatch(this.editorElement, "lexxy:editor-initialized", detail); 18259 } 18260 18261 freeze() { 18262 let frozenLinkKey = null; 18263 this.editorElement.editor?.getEditorState().read(() => { 18264 const selection = Qr(); 18265 if (!Fr(selection)) return 18266 18267 const linkNode = At$2(selection.anchor.getNode(), F$4); 18268 if (linkNode) { 18269 frozenLinkKey = linkNode.getKey(); 18270 } 18271 }); 18272 18273 this.frozenLinkKey = frozenLinkKey; 18274 this.editorContentElement.contentEditable = "false"; 18275 } 18276 18277 thaw() { 18278 this.editorContentElement.contentEditable = "true"; 18279 } 18280 18281 unlinkFrozenNode() {
vendor: 2,108 bytes, lines 18282-18344
18282 const key = this.frozenLinkKey; 18283 if (!key) return false 18284 18285 const linkNode = Yo(key); 18286 if (!z$5(linkNode)) { 18287 this.frozenLinkKey = null; 18288 return false 18289 } 18290 18291 const children = linkNode.getChildren(); 18292 for (const child of children) { 18293 linkNode.insertBefore(child); 18294 } 18295 linkNode.remove(); 18296 18297 // Select the former link text so a follow-up createLink can re-wrap it. 18298 const firstText = this.#findFirstTextDescendant(children); 18299 const lastText = this.#findLastTextDescendant(children); 18300 if (firstText && lastText) { 18301 const selection = Qr(); 18302 if (Fr(selection)) { 18303 selection.anchor.set(firstText.getKey(), 0, "text"); 18304 selection.focus.set(lastText.getKey(), lastText.getTextContent().length, "text"); 18305 } 18306 } 18307 18308 this.frozenLinkKey = null; 18309 return true 18310 } 18311 18312 #findFirstTextDescendant(nodes) { 18313 for (const node of nodes) { 18314 if (Tr(node)) return node 18315 if (Wi(node)) { 18316 const nestedTextNode = this.#findFirstTextDescendant(node.getChildren()); 18317 if (nestedTextNode) return nestedTextNode 18318 } 18319 } 18320 18321 return null 18322 } 18323 18324 #findLastTextDescendant(nodes) { 18325 for (let index = nodes.length - 1; index >= 0; index--) { 18326 const node = nodes[index]; 18327 if (Tr(node)) return node 18328 if (Wi(node)) { 18329 const nestedTextNode = this.#findLastTextDescendant(node.getChildren()); 18330 if (nestedTextNode) return nestedTextNode 18331 } 18332 } 18333 18334 return null 18335 } 18336} 18337 18338const configure = Lexxy.configure; 18339 18340// Pushing elements definition to after the current call stack to allow global configuration to take place first 18341setTimeout(defineElements, 0); 18342 18343export { $createActionTextAttachmentNode, $createActionTextAttachmentUploadNode, $isActionTextAttachmentNode, $isCustomActionTextAttachmentNode, ActionTextAttachmentNode, ActionTextAttachmentUploadNode, CustomActionTextAttachmentNode, LexxyExtension as Extension, HorizontalDividerNode, Lexical_prod as Lexical, NativeAdapter, REWRITE_HISTORY_COMMAND, configure, highlightCode, highlightElement }; 18344//# sourceMappingURL=/assets/lexxy-30ea2c9e.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.